[Sheepdog] [PATCH 2/6] sheep: refactor get_cluster_status()
Liu Yuan
namei.unix at gmail.com
Tue Oct 18 08:46:48 CEST 2011
From: Liu Yuan <tailai.ly at taobao.com>
And add a helper func to do the sanity check for cluster status.
Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
sheep/group.c | 136 +++++++++++++++++++++++++++++----------------------------
1 files changed, 69 insertions(+), 67 deletions(-)
diff --git a/sheep/group.c b/sheep/group.c
index 8ad54a3..615b365 100644
--- a/sheep/group.c
+++ b/sheep/group.c
@@ -525,100 +525,96 @@ err:
return ret;
}
+static int cluster_sanity_check(struct sheepdog_node_list_entry *entries,
+ int nr_entries, uint64_t ctime, uint32_t epoch)
+{
+ int ret = SD_RES_SUCCESS, nr_local_entries;
+ struct sheepdog_node_list_entry local_entries[SD_MAX_NODES];
+ uint32_t lepoch;
+
+ if (sys->status == SD_STATUS_WAIT_FOR_FORMAT ||
+ sys->status == SD_STATUS_SHUTDOWN)
+ goto out;
+ /* When the joinning node is newly created, we need to check nothing. */
+ if (nr_entries == 0)
+ goto out;
+
+ if (ctime != get_cluster_ctime()) {
+ ret = SD_RES_INVALID_CTIME;
+ goto out;
+ }
+
+ lepoch = get_latest_epoch();
+ if (epoch > lepoch) {
+ ret = SD_RES_OLD_NODE_VER;
+ goto out;
+ }
+
+ if (sys->status == SD_STATUS_OK)
+ goto out;
+
+ if (epoch < lepoch) {
+ ret = SD_RES_NEW_NODE_VER;
+ goto out;
+ }
+
+ nr_local_entries = epoch_log_read_nr(epoch, (char *)local_entries,
+ sizeof(local_entries));
+
+ if (nr_entries != nr_local_entries ||
+ memcmp(entries, local_entries, sizeof(entries[0]) * nr_entries) != 0) {
+ ret = SD_RES_INVALID_EPOCH;
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
static int get_cluster_status(struct sheepdog_node_list_entry *from,
struct sheepdog_node_list_entry *entries,
int nr_entries, uint64_t ctime, uint32_t epoch,
uint32_t *status, uint8_t *inc_epoch)
{
- int i;
- int nr_local_entries, nr_leave_entries;
+ int i, ret = SD_RES_SUCCESS;
+ int nr, nr_local_entries, nr_leave_entries;
struct sheepdog_node_list_entry local_entries[SD_MAX_NODES];
struct node *node;
- uint32_t local_epoch;
char str[256];
*status = sys->status;
if (inc_epoch)
*inc_epoch = 0;
+ ret = cluster_sanity_check(entries, nr_entries, ctime, epoch);
+ if (ret)
+ goto out;
+
switch (sys->status) {
case SD_STATUS_OK:
if (inc_epoch)
*inc_epoch = 1;
-
- if (nr_entries == 0)
- break;
-
- if (ctime != get_cluster_ctime()) {
- eprintf("joining node has invalid ctime, %s\n",
- addr_to_str(str, sizeof(str), from->addr, from->port));
- return SD_RES_INVALID_CTIME;
- }
-
- local_epoch = get_latest_epoch();
- if (epoch > local_epoch) {
- eprintf("sheepdog is running with older epoch, %"PRIu32" %"PRIu32" %s\n",
- epoch, local_epoch,
- addr_to_str(str, sizeof(str), from->addr, from->port));
- return SD_RES_OLD_NODE_VER;
- }
break;
case SD_STATUS_WAIT_FOR_FORMAT:
- if (nr_entries != 0) {
- eprintf("joining node is not clean, %s\n",
- addr_to_str(str, sizeof(str), from->addr, from->port));
- return SD_RES_NOT_FORMATTED;
- }
+ if (nr_entries != 0)
+ ret = SD_RES_NOT_FORMATTED;
break;
case SD_STATUS_WAIT_FOR_JOIN:
- if (ctime != get_cluster_ctime()) {
- eprintf("joining node has invalid ctime, %s\n",
- addr_to_str(str, sizeof(str), from->addr, from->port));
- return SD_RES_INVALID_CTIME;
- }
-
- local_epoch = get_latest_epoch();
- if (epoch > local_epoch) {
- eprintf("sheepdog is waiting with older epoch, %"PRIu32" %"PRIu32" %s\n",
- epoch, local_epoch,
- addr_to_str(str, sizeof(str), from->addr, from->port));
- return SD_RES_OLD_NODE_VER;
- } else if (epoch < local_epoch) {
- eprintf("sheepdog is waiting with newer epoch, %"PRIu32" %"PRIu32" %s\n",
- epoch, local_epoch,
- addr_to_str(str, sizeof(str), from->addr, from->port));
- return SD_RES_NEW_NODE_VER;
- }
-
+ nr = get_nodes_nr_from(&sys->sd_node_list) + 1;
nr_local_entries = epoch_log_read_nr(epoch, (char *)local_entries,
sizeof(local_entries));
- if (nr_entries != nr_local_entries) {
- eprintf("joining node has invalid epoch, %"PRIu32" %s\n",
- epoch,
- addr_to_str(str, sizeof(str), from->addr, from->port));
- return SD_RES_INVALID_EPOCH;
- }
-
- if (memcmp(entries, local_entries, sizeof(entries[0]) * nr_entries) != 0) {
- eprintf("joining node has invalid epoch, %s\n",
- addr_to_str(str, sizeof(str), from->addr, from->port));
- return SD_RES_INVALID_EPOCH;
- }
-
- nr_entries = get_nodes_nr_from(&sys->sd_node_list) + 1;
-
- if (nr_entries != nr_local_entries) {
+ if (nr != nr_local_entries) {
nr_leave_entries = get_nodes_nr_from(&sys->leave_list);
- if (nr_local_entries == nr_entries + nr_leave_entries) {
+ if (nr_local_entries == nr + nr_leave_entries) {
/* Even though some nodes leave, we can make do with it.
* Order cluster to do recovery right now.
*/
- *inc_epoch = 1;
+ if (inc_epoch)
+ *inc_epoch = 1;
*status = SD_STATUS_OK;
- return SD_RES_SUCCESS;
}
- return SD_RES_SUCCESS;
+ break;
}
for (i = 0; i < nr_local_entries; i++) {
@@ -628,7 +624,7 @@ static int get_cluster_status(struct sheepdog_node_list_entry *from,
if (node_cmp(local_entries + i, &node->ent) == 0)
goto next;
}
- return SD_RES_SUCCESS;
+ break;
next:
;
}
@@ -636,11 +632,17 @@ static int get_cluster_status(struct sheepdog_node_list_entry *from,
*status = SD_STATUS_OK;
break;
case SD_STATUS_SHUTDOWN:
- return SD_RES_SHUTDOWN;
+ ret = SD_RES_SHUTDOWN;
+ break;
default:
break;
}
- return SD_RES_SUCCESS;
+out:
+ if (ret)
+ eprintf("%x, %s\n", ret,
+ addr_to_str(str, sizeof(str), from->addr, from->port));
+
+ return ret;
}
static void join(struct join_message *msg)
--
1.7.6.1
More information about the sheepdog
mailing list