aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/dlm
diff options
context:
space:
mode:
authorXue jiufei <xuejiufei@huawei.com>2014-06-04 19:06:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-04 19:53:54 -0400
commit01c6222f876062355599e5a63560c514b6de25d2 (patch)
treebf29b34aac8ea3a95fefc0e11873ea3a77ffa858 /fs/ocfs2/dlm
parenta9e9acaeb0a981a6dfa54b32dd756103aeefa6a7 (diff)
ocfs2/dlm: disallow node joining when recovery is on going
We found a race situation when dlm recovery and node joining occurs simultaneously if the network state is bad. N1 N4 start joining dlm and send query join to all live nodes set joining node to N1, return OK send query join to other live nodes and it may take a while call dlm_send_join_assert() to send assert join message when N2 is down, so keep trying to send message to N2 until find N2 is down send assert join message to N3, but connection is down with N3, so it may take a while become the recovery master for N2 and send begin reco message to other nodes in domain map but no N1 connection with N3 is rebuild, then send assert join to N4 call dlm_assert_joined_handler(), add N1 to domain_map dlm recovery done, send finalize message to nodes in domain map, including N1 receiving finalize message, trigger the BUG() because recovery master mismatch. Signed-off-by: joyce.xue <xuejiufei@huawei.com> Cc: Mark Fasheh <mfasheh@suse.com> Cc: Joel Becker <jlbec@evilplan.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ocfs2/dlm')
-rw-r--r--fs/ocfs2/dlm/dlmdomain.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index c973690dc0bc..8d4690795a5d 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -959,6 +959,14 @@ static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data,
959 * domain. Set him in the map and clean up our 959 * domain. Set him in the map and clean up our
960 * leftover join state. */ 960 * leftover join state. */
961 BUG_ON(dlm->joining_node != assert->node_idx); 961 BUG_ON(dlm->joining_node != assert->node_idx);
962
963 if (dlm->reco.state & DLM_RECO_STATE_ACTIVE) {
964 mlog(0, "dlm recovery is ongoing, disallow join\n");
965 spin_unlock(&dlm->spinlock);
966 spin_unlock(&dlm_domain_lock);
967 return -EAGAIN;
968 }
969
962 set_bit(assert->node_idx, dlm->domain_map); 970 set_bit(assert->node_idx, dlm->domain_map);
963 clear_bit(assert->node_idx, dlm->exit_domain_map); 971 clear_bit(assert->node_idx, dlm->exit_domain_map);
964 __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN); 972 __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN);
@@ -1517,6 +1525,7 @@ static int dlm_send_one_join_assert(struct dlm_ctxt *dlm,
1517 unsigned int node) 1525 unsigned int node)
1518{ 1526{
1519 int status; 1527 int status;
1528 int ret;
1520 struct dlm_assert_joined assert_msg; 1529 struct dlm_assert_joined assert_msg;
1521 1530
1522 mlog(0, "Sending join assert to node %u\n", node); 1531 mlog(0, "Sending join assert to node %u\n", node);
@@ -1528,11 +1537,13 @@ static int dlm_send_one_join_assert(struct dlm_ctxt *dlm,
1528 1537
1529 status = o2net_send_message(DLM_ASSERT_JOINED_MSG, DLM_MOD_KEY, 1538 status = o2net_send_message(DLM_ASSERT_JOINED_MSG, DLM_MOD_KEY,
1530 &assert_msg, sizeof(assert_msg), node, 1539 &assert_msg, sizeof(assert_msg), node,
1531 NULL); 1540 &ret);
1532 if (status < 0) 1541 if (status < 0)
1533 mlog(ML_ERROR, "Error %d when sending message %u (key 0x%x) to " 1542 mlog(ML_ERROR, "Error %d when sending message %u (key 0x%x) to "
1534 "node %u\n", status, DLM_ASSERT_JOINED_MSG, DLM_MOD_KEY, 1543 "node %u\n", status, DLM_ASSERT_JOINED_MSG, DLM_MOD_KEY,
1535 node); 1544 node);
1545 else
1546 status = ret;
1536 1547
1537 return status; 1548 return status;
1538} 1549}