For a sheep that is restarted we can trust the local nr_copies and cluster
flags stored in the config file, so read it from there if is present and
only pick up the values from the join message if the sheep does not
have a configuration yet.

Also change the type of the nr_copes value in struct cluster_info so
that get_cluster_copies can be used on it without warnings.

Signed-off-by: Christoph Hellwig <hch@lst.de>

---
 sheep/group.c      |   33 +++++++++++++++++++--------------
 sheep/sheep_priv.h |    2 +-
 2 files changed, 20 insertions(+), 15 deletions(-)

Index: sheepdog/sheep/group.c
===================================================================
--- sheepdog.orig/sheep/group.c	2012-07-18 12:02:03.390147718 +0200
+++ sheepdog/sheep/group.c	2012-07-18 12:02:19.463481298 +0200
@@ -242,7 +242,7 @@ int local_get_node_list(const struct sd_
  */
 int get_nr_copies(struct vnode_info *vnode_info)
 {
-	return min(vnode_info->nr_zones, sys->nr_copies);
+	return min(vnode_info->nr_zones, (int)sys->nr_copies);
 }
 
 /*
@@ -722,7 +722,6 @@ static void finish_join(struct join_mess
 		struct sd_node *nodes, size_t nr_nodes)
 {
 	sys->join_finished = 1;
-	sys->nr_copies = msg->nr_copies;
 	sys->epoch = msg->epoch;
 
 	if (msg->cluster_status != SD_STATUS_OK)
@@ -770,8 +769,11 @@ static void update_cluster_info(struct j
 			uatomic_inc(&sys->epoch);
 			log_current_epoch();
 		}
+
 		/* Fresh node */
-		if (!sys_stat_ok() && !sys_stat_halt()) {
+		if (sys->status == SD_STATUS_WAIT_FOR_FORMAT) {
+			sys->nr_copies = msg->nr_copies;
+
 			set_cluster_copies(sys->nr_copies);
 			set_cluster_flags(sys->flags);
 			set_cluster_ctime(msg->ctime);
@@ -950,15 +952,11 @@ static int send_join_request(struct sd_n
 	struct join_message *msg;
 	int ret;
 
-	msg = zalloc(sizeof(*msg) + SD_MAX_NODES * sizeof(msg->nodes[0]));
-	if (!msg)
-		panic("failed to allocate memory\n");
+	msg = xzalloc(sizeof(*msg) + SD_MAX_NODES * sizeof(msg->nodes[0]));
 	msg->proto_ver = SD_SHEEP_PROTO_VER;
-
-	get_cluster_copies(&msg->nr_copies);
-	get_cluster_flags(&msg->cluster_flags);
-
-	msg->epoch = get_latest_epoch();
+	msg->nr_copies = sys->nr_copies;
+	msg->cluster_flags = sys->flags;
+	msg->epoch = sys->epoch;
 	msg->ctime = get_cluster_ctime();
 
 	if (msg->epoch) {
@@ -1133,10 +1131,17 @@ int create_cluster(int port, int64_t zon
 		sys->this_node.zone = zone;
 	dprintf("zone id = %u\n", sys->this_node.zone);
 
-	if (get_latest_epoch() == 0)
-		sys_stat_set(SD_STATUS_WAIT_FOR_FORMAT);
-	else
+	if (get_latest_epoch() > 0) {
 		sys_stat_set(SD_STATUS_WAIT_FOR_JOIN);
+
+		get_cluster_copies(&sys->nr_copies);
+		get_cluster_flags(&sys->flags);
+
+		sys->epoch = get_latest_epoch();
+	} else {
+		sys_stat_set(SD_STATUS_WAIT_FOR_FORMAT);
+	}
+
 	INIT_LIST_HEAD(&sys->pending_list);
 	INIT_LIST_HEAD(&sys->failed_nodes);
 	INIT_LIST_HEAD(&sys->delayed_nodes);
Index: sheepdog/sheep/sheep_priv.h
===================================================================
--- sheepdog.orig/sheep/sheep_priv.h	2012-07-18 12:00:40.176813114 +0200
+++ sheepdog/sheep/sheep_priv.h	2012-07-18 12:02:04.513481068 +0200
@@ -107,7 +107,7 @@ struct cluster_info {
 
 	struct list_head blocking_conn_list;
 
-	int nr_copies;
+	uint8_t nr_copies;
 	int req_efd;
 
 	pthread_mutex_t wait_req_lock;


