[sheepdog] [PATCH 1/2] sheep: check join result in the joining node

MORITA Kazutaka morita.kazutaka at gmail.com
Fri Jul 12 22:42:51 CEST 2013


From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>

This moves the join check from the master's sd_check_join_cb() to the
joining node's sd_join_handler().  With this patch, we can completely
remove join failure handling from the cluster drivers.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 include/internal_proto.h      |    8 ---
 include/shepherd.h            |    3 -
 sheep/cluster.h               |    9 ++-
 sheep/cluster/corosync.c      |   62 +++++++---------
 sheep/cluster/local.c         |   11 +--
 sheep/cluster/shepherd.c      |   19 ++---
 sheep/cluster/zookeeper.c     |   47 +++++--------
 sheep/group.c                 |  156 ++++++++++++++++-------------------------
 shepherd/shepherd.c           |    6 --
 tests/unit/sheep/mock_group.c |    9 +--
 10 files changed, 119 insertions(+), 211 deletions(-)

diff --git a/include/internal_proto.h b/include/internal_proto.h
index 617556e..0463eae 100644
--- a/include/internal_proto.h
+++ b/include/internal_proto.h
@@ -184,14 +184,6 @@ struct sd_md_info {
 	int nr;
 };
 
-enum cluster_join_result {
-	/* Success */
-	CJ_RES_SUCCESS,
-
-	/* Fail to join. The joining node has an invalid epoch. */
-	CJ_RES_FAIL,
-};
-
 static inline __attribute__((used)) void __sd_epoch_format_build_bug_ons(void)
 {
 	/* never called, only for checking BUILD_BUG_ON()s */
diff --git a/include/shepherd.h b/include/shepherd.h
index e1fbac1..fcb4655 100644
--- a/include/shepherd.h
+++ b/include/shepherd.h
@@ -38,7 +38,6 @@ struct sph_msg {
 #include "internal_proto.h"
 
 struct sph_msg_join {
-	uint32_t res;		/* original type: enum cluster_join_result */
 	struct sd_node new_node;
 	uint8_t master_elected;
 
@@ -48,14 +47,12 @@ struct sph_msg_join {
 };
 
 struct sph_msg_join_reply {
-	uint32_t res;		/* original type: enum cluster_join_result */
 	struct sd_node nodes[SD_MAX_NODES];
 	uint32_t nr_nodes;
 	uint8_t opaque[0];
 };
 
 struct sph_msg_join_node_finish {
-	uint32_t res;		/* original type: enum cluster_join_result */
 	struct sd_node new_node;
 
 	struct sd_node nodes[SD_MAX_NODES];
diff --git a/sheep/cluster.h b/sheep/cluster.h
index 041578b..efb7c1e 100644
--- a/sheep/cluster.h
+++ b/sheep/cluster.h
@@ -164,8 +164,7 @@ static inline const char *get_cdrv_option(const struct cluster_driver *cdrv,
 
 /* callbacks back into sheepdog from the cluster drivers */
 void sd_join_handler(const struct sd_node *joined,
-		     const struct sd_node *members,
-		     size_t nr_members, enum cluster_join_result result,
+		     const struct sd_node *members, size_t nr_members,
 		     const void *opaque);
 void sd_leave_handler(const struct sd_node *left, const struct sd_node *members,
 		      size_t nr_members);
@@ -173,9 +172,9 @@ void sd_notify_handler(const struct sd_node *sender, void *msg, size_t msg_len);
 bool sd_block_handler(const struct sd_node *sender);
 int sd_reconnect_handler(void);
 void sd_update_node_handler(struct sd_node *);
-enum cluster_join_result sd_check_join_cb(const struct sd_node *joining,
-					  const struct sd_node *nodes,
-					  size_t nr_nodes, void *opaque);
+void sd_check_join_cb(const struct sd_node *joining,
+		      const struct sd_node *nodes, size_t nr_nodes,
+		      void *opaque);
 void recalculate_vnodes(struct sd_node *nodes, int nr_nodes);
 
 #endif
diff --git a/sheep/cluster/corosync.c b/sheep/cluster/corosync.c
index cc5d4d7..fa81b55 100644
--- a/sheep/cluster/corosync.c
+++ b/sheep/cluster/corosync.c
@@ -72,7 +72,6 @@ struct corosync_event {
 	void *msg;
 	size_t msg_len;
 
-	enum cluster_join_result result;
 	uint32_t nr_nodes;
 	struct cpg_node nodes[SD_MAX_NODES];
 
@@ -83,10 +82,9 @@ struct corosync_event {
 
 struct corosync_message {
 	struct cpg_node sender;
-	enum corosync_message_type type:4;
-	enum cluster_join_result result:4;
+	enum corosync_message_type type:16;
+	uint16_t nr_nodes;
 	uint32_t msg_len;
-	uint32_t nr_nodes;
 	struct cpg_node nodes[SD_MAX_NODES];
 	uint8_t msg[0];
 };
@@ -165,7 +163,6 @@ static int corosync_get_local_addr(uint8_t *addr)
 }
 
 static int send_message(enum corosync_message_type type,
-			enum cluster_join_result result,
 			struct cpg_node *sender, struct cpg_node *nodes,
 			size_t nr_nodes, void *msg, size_t msg_len)
 {
@@ -174,7 +171,6 @@ static int send_message(enum corosync_message_type type,
 	struct corosync_message cmsg = {
 		.type = type,
 		.msg_len = msg_len,
-		.result = result,
 		.sender = *sender,
 		.nr_nodes = nr_nodes,
 	};
@@ -280,7 +276,6 @@ static void build_node_list(const struct cpg_node *nodes, size_t nr_nodes,
  */
 static bool __corosync_dispatch_one(struct corosync_event *cevent)
 {
-	enum cluster_join_result res;
 	struct sd_node entries[SD_MAX_NODES], *node;
 	struct cpg_node *n;
 	int idx;
@@ -299,27 +294,21 @@ static bool __corosync_dispatch_one(struct corosync_event *cevent)
 			return false;
 
 		build_node_list(cpg_nodes, nr_cpg_nodes, entries);
-		res = sd_check_join_cb(&cevent->sender.node, entries,
-				       nr_cpg_nodes, cevent->msg);
-		send_message(COROSYNC_MSG_TYPE_JOIN_RESPONSE, res,
-			     &cevent->sender, cpg_nodes, nr_cpg_nodes,
-			     cevent->msg, cevent->msg_len);
+		sd_check_join_cb(&cevent->sender.node, entries, nr_cpg_nodes,
+				 cevent->msg);
+		send_message(COROSYNC_MSG_TYPE_JOIN_RESPONSE, &cevent->sender,
+			     cpg_nodes, nr_cpg_nodes, cevent->msg,
+			     cevent->msg_len);
 
 		cevent->callbacked = true;
 		return false;
 	case COROSYNC_EVENT_TYPE_JOIN_RESPONSE:
-		switch (cevent->result) {
-		case CJ_RES_SUCCESS:
-			add_cpg_node(cpg_nodes, nr_cpg_nodes, &cevent->sender);
-			nr_cpg_nodes++;
-			/* fall through */
-		case CJ_RES_FAIL:
-			build_node_list(cpg_nodes, nr_cpg_nodes, entries);
-			sd_join_handler(&cevent->sender.node, entries,
-					nr_cpg_nodes, cevent->result,
-					cevent->msg);
-			break;
-		}
+		add_cpg_node(cpg_nodes, nr_cpg_nodes, &cevent->sender);
+		nr_cpg_nodes++;
+
+		build_node_list(cpg_nodes, nr_cpg_nodes, entries);
+		sd_join_handler(&cevent->sender.node, entries, nr_cpg_nodes,
+				cevent->msg);
 		break;
 	case COROSYNC_EVENT_TYPE_LEAVE:
 		n = xlfind(&cevent->sender, cpg_nodes, nr_cpg_nodes,
@@ -554,7 +543,6 @@ static void cdrv_cpg_deliver(cpg_handle_t handle,
 			break;
 
 		cevent->type = COROSYNC_EVENT_TYPE_JOIN_RESPONSE;
-		cevent->result = cmsg->result;
 		cevent->nr_nodes = cmsg->nr_nodes;
 		memcpy(cevent->nodes, cmsg->nodes,
 		       sizeof(*cmsg->nodes) * cmsg->nr_nodes);
@@ -714,34 +702,34 @@ retry:
 
 	this_node.node = *myself;
 
-	ret = send_message(COROSYNC_MSG_TYPE_JOIN_REQUEST, 0, &this_node,
-			   NULL, 0, opaque, opaque_len);
+	ret = send_message(COROSYNC_MSG_TYPE_JOIN_REQUEST, &this_node, NULL, 0,
+			   opaque, opaque_len);
 
 	return ret;
 }
 
 static int corosync_leave(void)
 {
-	return send_message(COROSYNC_MSG_TYPE_LEAVE, 0, &this_node, NULL, 0,
-			    NULL, 0);
+	return send_message(COROSYNC_MSG_TYPE_LEAVE, &this_node, NULL, 0, NULL,
+			    0);
 }
 
 static int corosync_block(void)
 {
-	return send_message(COROSYNC_MSG_TYPE_BLOCK, 0, &this_node, NULL, 0,
-			    NULL, 0);
+	return send_message(COROSYNC_MSG_TYPE_BLOCK, &this_node, NULL, 0, NULL,
+			    0);
 }
 
 static int corosync_unblock(void *msg, size_t msg_len)
 {
-	return send_message(COROSYNC_MSG_TYPE_UNBLOCK, 0, &this_node, NULL, 0,
-			    msg, msg_len);
+	return send_message(COROSYNC_MSG_TYPE_UNBLOCK, &this_node, NULL, 0, msg,
+			    msg_len);
 }
 
 static int corosync_notify(void *msg, size_t msg_len)
 {
-	return send_message(COROSYNC_MSG_TYPE_NOTIFY, 0, &this_node,
-			    NULL, 0, msg, msg_len);
+	return send_message(COROSYNC_MSG_TYPE_NOTIFY, &this_node, NULL, 0, msg,
+			    msg_len);
 }
 
 static void corosync_handler(int listen_fd, int events, void *data)
@@ -832,8 +820,8 @@ static int corosync_update_node(struct sd_node *node)
 
 	cnode.node = *node;
 
-	return send_message(COROSYNC_MSG_TYPE_UPDATE_NODE, 0, &cnode,
-			    NULL, 0, NULL, 0);
+	return send_message(COROSYNC_MSG_TYPE_UPDATE_NODE, &cnode, NULL, 0,
+			    NULL, 0);
 }
 
 static struct cluster_driver cdrv_corosync = {
diff --git a/sheep/cluster/local.c b/sheep/cluster/local.c
index d00ab2c..707224c 100644
--- a/sheep/cluster/local.c
+++ b/sheep/cluster/local.c
@@ -82,8 +82,6 @@ struct local_event {
 
 	size_t nr_lnodes; /* the number of sheep processes */
 	struct local_node lnodes[SD_MAX_NODES];
-
-	enum cluster_join_result join_result;
 };
 
 
@@ -385,7 +383,6 @@ static int local_unblock(void *msg, size_t msg_len)
 static bool local_process_event(void)
 {
 	struct local_event *ev;
-	enum cluster_join_result res;
 	int i;
 	struct sd_node nodes[SD_MAX_NODES];
 	size_t nr_nodes;
@@ -438,9 +435,8 @@ static bool local_process_event(void)
 	case EVENT_JOIN_REQUEST:
 		/* nodes[nr_nodes - 1] is a sender, so don't include it */
 		assert(node_eq(&ev->sender.node, &nodes[nr_nodes - 1]));
-		res = sd_check_join_cb(&ev->sender.node, nodes, nr_nodes - 1,
-				       ev->buf);
-		ev->join_result = res;
+		sd_check_join_cb(&ev->sender.node, nodes, nr_nodes - 1,
+				 ev->buf);
 		ev->type = EVENT_JOIN_RESPONSE;
 		msync(ev, sizeof(*ev), MS_SYNC);
 
@@ -448,8 +444,7 @@ static bool local_process_event(void)
 
 		return false;
 	case EVENT_JOIN_RESPONSE:
-		sd_join_handler(&ev->sender.node, nodes, nr_nodes,
-				ev->join_result, ev->buf);
+		sd_join_handler(&ev->sender.node, nodes, nr_nodes, ev->buf);
 		break;
 	case EVENT_LEAVE:
 		if (ev->sender.gateway) {
diff --git a/sheep/cluster/shepherd.c b/sheep/cluster/shepherd.c
index 3aebfc1..28ffc66 100644
--- a/sheep/cluster/shepherd.c
+++ b/sheep/cluster/shepherd.c
@@ -89,7 +89,6 @@ static void interpret_msg_pre_join(void)
 	int ret;
 	struct sph_msg snd, rcv;
 	struct sph_msg_join_reply *join_reply;
-	enum cluster_join_result res;
 
 retry:
 	read_msg(&rcv);
@@ -115,12 +114,7 @@ retry:
 		 * FIXME: member change events must be ordered with nonblocked
 		 *        events
 		 */
-		res = sd_check_join_cb(&join->new_node, NULL, 0, join->opaque);
-		if (res == CJ_RES_FAIL) {
-			sd_eprintf("sd_check_join_cb() failed");
-			exit(1);
-		}
-		assert(res == CJ_RES_SUCCESS);
+		sd_check_join_cb(&join->new_node, NULL, 0, join->opaque);
 
 		/* FIXME: join->master_elected is needed? */
 		assert(join->master_elected);
@@ -166,8 +160,7 @@ retry:
 	nr_nodes = join_reply->nr_nodes;
 
 	/* FIXME: member change events must be ordered with nonblocked events */
-	sd_join_handler(&this_node, nodes, nr_nodes,
-			join_reply->res, join_reply->opaque);
+	sd_join_handler(&this_node, nodes, nr_nodes, join_reply->opaque);
 
 	free(join_reply);
 
@@ -317,7 +310,6 @@ static void msg_new_node(struct sph_msg *rcv)
 	int ret;
 	struct sph_msg_join *join;
 	struct sph_msg snd;
-	enum cluster_join_result res;
 
 	if (!is_master) {
 		sd_printf(SDOG_EMERG, "I am not a master but received"
@@ -333,9 +325,7 @@ static void msg_new_node(struct sph_msg *rcv)
 	}
 
 	/* FIXME: member change events must be ordered with nonblocked events */
-	res = sd_check_join_cb(&join->new_node, nodes, nr_nodes, join->opaque);
-
-	join->res = res;
+	sd_check_join_cb(&join->new_node, nodes, nr_nodes, join->opaque);
 
 	memset(&snd, 0, sizeof(snd));
 	snd.type = SPH_CLI_MSG_NEW_NODE_REPLY;
@@ -371,8 +361,7 @@ static void msg_new_node_finish(struct sph_msg *rcv)
 		   node_to_str(&join_node_finish->new_node));
 
 	/* FIXME: member change events must be ordered with nonblocked events */
-	sd_join_handler(&join_node_finish->new_node, nodes, nr_nodes,
-			join_node_finish->res, jm);
+	sd_join_handler(&join_node_finish->new_node, nodes, nr_nodes, jm);
 
 	free(join_node_finish);
 }
diff --git a/sheep/cluster/zookeeper.c b/sheep/cluster/zookeeper.c
index cb86024..3fa22d0 100644
--- a/sheep/cluster/zookeeper.c
+++ b/sheep/cluster/zookeeper.c
@@ -62,7 +62,6 @@ struct zk_event {
 	uint64_t id;
 	enum zk_event_type type;
 	struct zk_node sender;
-	enum cluster_join_result join_result;
 	size_t msg_len;
 	size_t nr_nodes;
 	size_t buf_len;
@@ -839,8 +838,6 @@ static int zk_unblock(void *msg, size_t msg_len)
 
 static void zk_handle_join_request(struct zk_event *ev)
 {
-	enum cluster_join_result res;
-
 	sd_dprintf("sender: %s", node_to_str(&ev->sender.node));
 	if (!uatomic_is_true(&is_master)) {
 		/* Let's await master acking the join-request */
@@ -848,9 +845,7 @@ static void zk_handle_join_request(struct zk_event *ev)
 		return;
 	}
 
-	res = sd_check_join_cb(&ev->sender.node, sd_nodes, nr_sd_nodes,
-			       ev->buf);
-	ev->join_result = res;
+	sd_check_join_cb(&ev->sender.node, sd_nodes, nr_sd_nodes, ev->buf);
 	push_join_response(ev);
 
 	sd_dprintf("I'm the master now");
@@ -895,32 +890,26 @@ static void zk_handle_join_response(struct zk_event *ev)
 		/* newly joined node */
 		init_node_list(ev);
 
-	sd_dprintf("%s, %d", node_to_str(&ev->sender.node), ev->join_result);
-	switch (ev->join_result) {
-	case CJ_RES_SUCCESS:
-		snprintf(path, sizeof(path), MEMBER_ZNODE"/%s",
-			 node_to_str(&ev->sender.node));
-		if (node_eq(&ev->sender.node, &this_node.node)) {
-			joined = true;
-			sd_dprintf("create path:%s", path);
-			rc = zk_create_node(path,
-					    (char *)zoo_client_id(zhandle),
-					    sizeof(clientid_t),
-					    &ZOO_OPEN_ACL_UNSAFE,
-					    ZOO_EPHEMERAL, NULL, 0);
-			RETURN_VOID_IF_ERROR(rc, "");
-		} else
-			zk_node_exists(path);
+	sd_dprintf("%s", node_to_str(&ev->sender.node));
 
-		zk_tree_add(&ev->sender);
-		break;
-	default:
-		break;
-	}
+	snprintf(path, sizeof(path), MEMBER_ZNODE"/%s",
+		 node_to_str(&ev->sender.node));
+	if (node_eq(&ev->sender.node, &this_node.node)) {
+		joined = true;
+		sd_dprintf("create path:%s", path);
+		rc = zk_create_node(path,
+				    (char *)zoo_client_id(zhandle),
+				    sizeof(clientid_t),
+				    &ZOO_OPEN_ACL_UNSAFE,
+				    ZOO_EPHEMERAL, NULL, 0);
+		RETURN_VOID_IF_ERROR(rc, "");
+	} else
+		zk_node_exists(path);
+
+	zk_tree_add(&ev->sender);
 
 	build_node_list();
-	sd_join_handler(&ev->sender.node, sd_nodes, nr_sd_nodes,
-			ev->join_result, ev->buf);
+	sd_join_handler(&ev->sender.node, sd_nodes, nr_sd_nodes, ev->buf);
 }
 
 static void kick_block_event(void)
diff --git a/sheep/group.c b/sheep/group.c
index e5256ba..87746d7 100644
--- a/sheep/group.c
+++ b/sheep/group.c
@@ -386,16 +386,19 @@ int epoch_log_read_remote(uint32_t epoch, struct sd_node *nodes, int len,
 	return 0;
 }
 
-static int cluster_ctime_check(const struct join_message *jm)
+static bool cluster_ctime_check(const struct join_message *jm)
 {
+	if (jm->cinfo.epoch == 0 || sys->cinfo.epoch == 0)
+		return true;
+
 	if (jm->cinfo.ctime != sys->cinfo.ctime) {
 		sd_eprintf("joining node ctime doesn't match: %"
 			   PRIu64 " vs %" PRIu64, jm->cinfo.ctime,
 			   sys->cinfo.ctime);
-		return CJ_RES_FAIL;
+		return false;
 	}
 
-	return CJ_RES_SUCCESS;
+	return true;
 }
 
 /*
@@ -428,25 +431,19 @@ static int cluster_wait_check(const struct sd_node *joining,
 			      const struct sd_node *nodes, size_t nr_nodes,
 			      struct join_message *jm)
 {
-	int ret;
-
-	if (jm->cinfo.epoch != 0 && sys->cinfo.epoch != 0) {
-		/* check whether joining node is valid or not */
-		ret = cluster_ctime_check(jm);
-		if (ret != CJ_RES_SUCCESS)
-			return ret;
+	if (!cluster_ctime_check(jm)) {
+		sd_dprintf("joining node is invalid");
+		return sys->status;
 	}
 
-	if (jm->cinfo.epoch > sys->cinfo.epoch)
+	if (jm->cinfo.epoch > sys->cinfo.epoch) {
+		sd_dprintf("joining node has a larger epoch, %" PRIu32 ", %"
+			   PRIu32, jm->cinfo.epoch, sys->cinfo.epoch);
 		sys->cinfo = jm->cinfo;
-	else if (jm->cinfo.epoch < sys->cinfo.epoch) {
+	} else if (jm->cinfo.epoch < sys->cinfo.epoch) {
 		sd_dprintf("joining node has a smaller epoch, %" PRIu32 ", %"
 			   PRIu32, jm->cinfo.epoch, sys->cinfo.epoch);
 		jm->cinfo = sys->cinfo;
-	} else if (memcmp(jm->cinfo.nodes, sys->cinfo.nodes,
-			  sizeof(*jm->cinfo.nodes) * jm->cinfo.nr_nodes) != 0) {
-		sd_eprintf("epoch log entries does not match");
-		return CJ_RES_FAIL;
 	}
 
 	/*
@@ -455,26 +452,9 @@ static int cluster_wait_check(const struct sd_node *joining,
 	 */
 	if (sys->cinfo.epoch > 0 &&
 	    enough_nodes_gathered(jm, joining, nodes, nr_nodes))
-		jm->cluster_status = SD_STATUS_OK;
-
-	return CJ_RES_SUCCESS;
-}
-
-static int cluster_running_check(struct join_message *jm)
-{
-	int ret;
-
-	/*
-	 * When the joining node is newly created and we are not waiting for
-	 * join we do not need to check anything.
-	 */
-	if (jm->cinfo.nr_nodes != 0) {
-		ret = cluster_ctime_check(jm);
-		if (ret != CJ_RES_SUCCESS)
-			return ret;
-	}
+		return SD_STATUS_OK;
 
-	return CJ_RES_SUCCESS;
+	return sys->status;
 }
 
 static int get_vdis_from(struct sd_node *node)
@@ -800,46 +780,28 @@ void sd_notify_handler(const struct sd_node *sender, void *data,
  *
  * Note that 'nodes' doesn't contain 'joining'.
  */
-enum cluster_join_result sd_check_join_cb(const struct sd_node *joining,
-					  const struct sd_node *nodes,
-					  size_t nr_nodes, void *opaque)
+void sd_check_join_cb(const struct sd_node *joining,
+		      const struct sd_node *nodes, size_t nr_nodes,
+		      void *opaque)
 {
 	struct join_message *jm = opaque;
 	char str[MAX_NODE_STR_LEN];
-	int ret;
 
 	sd_dprintf("check %s, %d", node_to_str(joining), sys->status);
 
-	if (jm->proto_ver != SD_SHEEP_PROTO_VER) {
-		sd_eprintf("invalid protocol version: %d", jm->proto_ver);
-		return CJ_RES_FAIL;
-	}
-
-	jm->cluster_status = sys->status;
+	jm->proto_ver = SD_SHEEP_PROTO_VER;
 
-	switch (sys->status) {
-	case SD_STATUS_SHUTDOWN:
-		ret = CJ_RES_FAIL;
-		break;
-	case SD_STATUS_WAIT:
-		ret = cluster_wait_check(joining, nodes, nr_nodes, jm);
-		break;
-	case SD_STATUS_OK:
-	case SD_STATUS_HALT:
-		ret = cluster_running_check(jm);
-		break;
-	default:
-		panic("invalid system status: 0x%x", sys->status);
-	}
+	if (sys->status == SD_STATUS_WAIT)
+		jm->cluster_status = cluster_wait_check(joining, nodes,
+							nr_nodes, jm);
+	else
+		jm->cluster_status = sys->status;
 
-	sd_dprintf("%s: ret = 0x%x, cluster_status = 0x%x",
+	sd_dprintf("%s: cluster_status = 0x%x",
 		   addr_to_str(str, sizeof(str), joining->nid.addr,
-			       joining->nid.port),
-		   ret, jm->cluster_status);
+			       joining->nid.port), jm->cluster_status);
 
 	jm->cinfo = sys->cinfo;
-
-	return ret;
 }
 
 static int send_join_request(struct sd_node *ent)
@@ -848,7 +810,6 @@ static int send_join_request(struct sd_node *ent)
 	int ret;
 
 	msg = xzalloc(sizeof(*msg));
-	msg->proto_ver = SD_SHEEP_PROTO_VER;
 	msg->cinfo = sys->cinfo;
 
 	ret = sys->cdrv->join(ent, msg, sizeof(*msg));
@@ -936,46 +897,53 @@ int sd_reconnect_handler(void)
 	return 0;
 }
 
+static bool cluster_join_check(const struct join_message *jm)
+{
+	if (jm->proto_ver != SD_SHEEP_PROTO_VER) {
+		sd_eprintf("invalid protocol version: %d, %d",
+			   jm->proto_ver, SD_SHEEP_PROTO_VER);
+		return false;
+	}
+
+	if (!cluster_ctime_check(jm))
+		return false;
+
+	if (jm->cinfo.epoch == sys->cinfo.epoch &&
+	    memcmp(jm->cinfo.nodes, sys->cinfo.nodes,
+		   sizeof(jm->cinfo.nodes[0]) * jm->cinfo.nr_nodes) != 0) {
+		sd_printf(SDOG_ALERT, "epoch log entries does not match");
+		return false;
+	}
+
+	return true;
+}
+
 void sd_join_handler(const struct sd_node *joined,
-		     const struct sd_node *members,
-		     size_t nr_members, enum cluster_join_result result,
+		     const struct sd_node *members, size_t nr_members,
 		     const void *opaque)
 {
 	int i;
 	const struct join_message *jm = opaque;
 
-	sys->cinfo = jm->cinfo;
-
-	if (node_is_local(joined)) {
-		if (result == CJ_RES_FAIL) {
-			sd_eprintf("Failed to join, exiting.");
-			sys->cdrv->leave();
-			exit(1);
-		}
+	if (!cluster_join_check(jm)) {
+		sd_eprintf("failed to join Sheepdog");
+		exit(1);
 	}
 
-	switch (result) {
-	case CJ_RES_SUCCESS:
-		sd_dprintf("join %s", node_to_str(joined));
-		for (i = 0; i < nr_members; i++)
-			sd_dprintf("[%x] %s", i, node_to_str(members + i));
+	sys->cinfo = jm->cinfo;
 
-		if (sys->status == SD_STATUS_SHUTDOWN)
-			break;
+	sd_dprintf("join %s", node_to_str(joined));
+	for (i = 0; i < nr_members; i++)
+		sd_dprintf("[%x] %s", i, node_to_str(members + i));
 
-		update_cluster_info(jm, joined, members, nr_members);
+	if (sys->status == SD_STATUS_SHUTDOWN)
+		return;
 
-		if (node_is_local(joined))
-			/* this output is used for testing */
-			sd_printf(SDOG_DEBUG, "join Sheepdog cluster");
-		break;
-	case CJ_RES_FAIL:
-		break;
-	default:
-		/* this means sd_check_join_cb() is buggy */
-		panic("unknown cluster join result: %d", result);
-		break;
-	}
+	update_cluster_info(jm, joined, members, nr_members);
+
+	if (node_is_local(joined))
+		/* this output is used for testing */
+		sd_printf(SDOG_DEBUG, "join Sheepdog cluster");
 }
 
 void sd_leave_handler(const struct sd_node *left, const struct sd_node *members,
diff --git a/shepherd/shepherd.c b/shepherd/shepherd.c
index 6e102b3..d294cb5 100644
--- a/shepherd/shepherd.c
+++ b/shepherd/shepherd.c
@@ -391,8 +391,6 @@ static void sph_handle_new_node_reply(struct sph_msg *msg, struct sheep *sheep)
 	struct sph_msg_join_reply *join_reply_body;
 	struct sph_msg_join_node_finish *join_node_finish;
 
-	enum cluster_join_result join_result;
-
 	if (nr_joined_sheep && sheep != master_sheep) {
 		sd_eprintf("sheep which is not a master replied "
 			"SPH_CLI_MSG_NEW_NODE_REPLY");
@@ -410,8 +408,6 @@ static void sph_handle_new_node_reply(struct sph_msg *msg, struct sheep *sheep)
 		goto purge_current_sheep;
 	}
 
-	join_result = join->res;
-
 	sd_dprintf("joining node is %s", node_to_str(&join->new_node));
 
 	joining_sheep = find_sheep_by_nid(&join->new_node.nid);
@@ -445,7 +441,6 @@ static void sph_handle_new_node_reply(struct sph_msg *msg, struct sheep *sheep)
 	join_reply_body->nodes[join_reply_body->nr_nodes++] =
 		joining_sheep->node;
 	memcpy(join_reply_body->opaque, opaque, opaque_len);
-	join_reply_body->res = join_result;
 
 	wbytes = writev2(joining_sheep->fd, &snd,
 			join_reply_body, snd.body_len);
@@ -468,7 +463,6 @@ static void sph_handle_new_node_reply(struct sph_msg *msg, struct sheep *sheep)
 	join_node_finish->nr_nodes = build_node_array(join_node_finish->nodes);
 	join_node_finish->nodes[join_node_finish->nr_nodes++] =
 		joining_sheep->node;
-	join_node_finish->res = join_result;
 
 	list_for_each_entry(s, &sheep_list_head, sheep_list) {
 		if (s->state != SHEEP_STATE_JOINED)
diff --git a/tests/unit/sheep/mock_group.c b/tests/unit/sheep/mock_group.c
index 7a47ca5..b2556a1 100644
--- a/tests/unit/sheep/mock_group.c
+++ b/tests/unit/sheep/mock_group.c
@@ -16,8 +16,7 @@
 #include "cluster.h"
 
 MOCK_VOID_METHOD(sd_join_handler, const struct sd_node *joined,
-		 const struct sd_node *members,
-		 size_t nr_members, enum cluster_join_result result,
+		 const struct sd_node *members, size_t nr_members,
 		 const void *opaque)
 MOCK_VOID_METHOD(sd_leave_handler, const struct sd_node *left,
 		 const struct sd_node *members, size_t nr_members)
@@ -25,8 +24,6 @@ MOCK_VOID_METHOD(sd_notify_handler, const struct sd_node *sender, void *msg,
 		 size_t msg_len)
 MOCK_METHOD(sd_block_handler, bool, true, const struct sd_node *sender)
 MOCK_METHOD(sd_reconnect_handler, int, 0)
-MOCK_METHOD(sd_check_join_cb, enum cluster_join_result, CJ_RES_SUCCESS,
-	    const struct sd_node *joining,
-	    const struct sd_node *nodes,
-	    size_t nr_nodes, void *opaque)
+MOCK_VOID_METHOD(sd_check_join_cb, const struct sd_node *joining,
+		 const struct sd_node *nodes, size_t nr_nodes, void *opaque)
 MOCK_VOID_METHOD(sd_update_node_handler, struct sd_node *node)
-- 
1.7.9.5




More information about the sheepdog mailing list