[Sheepdog] [RFC PATCH] corosync: fix cluster hang

Liu Yuan namei.unix at gmail.com
Sat Apr 28 14:30:17 CEST 2012


From: Liu Yuan <tailai.ly at taobao.com>

Consider two nodes cluster, A is the master and B is going
to join.
		A: I'm the master
B: send_join_msg
		A: crached before sending join_response
B: blocked for ever

The fix is let B go as far as possible, where B can find himself
become the master.

1) path the code to simulate the problem:

@@ -280,6 +280,7 @@ static int __corosync_dispatch_one(struct
corosync_event *cevent)
        enum cluster_join_result res;
        struct sd_node entries[SD_MAX_NODES];
        int idx;
+       static int i;

        switch (cevent->type) {
        case COROSYNC_EVENT_TYPE_JOIN:
@@ -300,6 +301,12 @@ static int __corosync_dispatch_one(struct
corosync_event *cevent)
                        if (res == CJ_RES_MASTER_TRANSFER)
                                nr_cpg_nodes = 0;

+                       i++;
+                       if (i == 2) {
+                               dprintf("%d\n", i);
+                               panic("Okay, I am forced out\n");
+                       }
+
                        send_message(COROSYNC_MSG_TYPE_JOIN_RESPONSE, res,
                                     &cevent->sender, cpg_nodes,
nr_cpg_nodes,
                                     cevent->msg, cevent->msg_len);

2) run the following script:
for i in 0 1 2; do sheep/sheep -a -d /home/tailai.ly/sheepdog/store/$i -z $i -p 700$i;sleep 1;done

Now we can handle this very case nicely, that mastership is transferred from 0 to 1, and from 1 to 2
dispite of master is crashed before sending response.

But, we can't handle below script yet:
for i in 0 ; do sheep/sheep -a -d /home/tailai.ly/sheepdog/store/$i -z $i -p 700$i;sleep 1;done
for i in 1 2; do sheep/sheep -a -d /home/tailai.ly/sheepdog/store/$i -z $i -p 700$i;done #no sleep

Question is:
 Do we really need to handle above artificial scenario?

Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
 sheep/cluster/corosync.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/sheep/cluster/corosync.c b/sheep/cluster/corosync.c
index 4a588e9..66d1e03 100644
--- a/sheep/cluster/corosync.c
+++ b/sheep/cluster/corosync.c
@@ -592,6 +592,14 @@ static void cdrv_cpg_confchg(cpg_handle_t handle,
 		cevent->type = COROSYNC_EVENT_TYPE_LEAVE;
 		cevent->sender = left_sheep[i];
 
+		if (member_list_entries == left_list_entries - joined_list_entries) {
+		/* I am the last one in the cluster */
+			struct corosync_event *event;
+			event = find_block_event(COROSYNC_EVENT_TYPE_JOIN, &this_node);
+			if (event)
+				event->first_node = 1;
+		}
+
 		list_add_tail(&cevent->list, &corosync_event_list);
 	}
 
-- 
1.7.8.2




More information about the sheepdog mailing list