static void join(struct sd_node *joining, struct join_message *msg) { if (msg->proto_ver != SD_SHEEP_PROTO_VER) { eprintf("joining node sent a message with the wrong protocol version\n"); msg->result = SD_RES_VER_MISMATCH; return; } msg->result = get_cluster_status(joining, msg->nodes, msg->nr_nodes, msg->ctime, msg->epoch, &msg->cluster_status, &msg->inc_epoch); msg->nr_copies = sys->nr_copies; msg->cluster_flags = sys->flags; msg->ctime = get_cluster_ctime(); if (sd_store) strcpy((char *)msg->store, sd_store->name); }
static int cluster_sanity_check(struct sd_node *entries, int nr_entries, uint64_t ctime, uint32_t epoch) { int ret = SD_RES_SUCCESS, nr_local_entries; struct sd_node local_entries[SD_MAX_NODES]; uint32_t lepoch; if (sys_stat_wait_format() || sys_stat_shutdown()) goto out; /* When the joining node is newly created, we need not check anything. */ 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_can_recover()) 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 cluster_sanity_check(struct join_message *jm) { uint64_t local_ctime = get_cluster_ctime(); uint32_t local_epoch = get_latest_epoch(); uint8_t local_nr_copies; if (get_cluster_copies(&local_nr_copies)) { eprintf("failed to get nr_copies\n"); return CJ_RES_FAIL; } if (jm->ctime != local_ctime) { eprintf("joining node ctime doesn't match: %" PRIu64 " vs %" PRIu64 "\n", jm->ctime, local_ctime); return CJ_RES_FAIL; } if (jm->epoch > local_epoch) { eprintf("joining node epoch too large: %" PRIu32 " vs %" PRIu32 "\n", jm->epoch, local_epoch); return CJ_RES_FAIL; } if (jm->nr_copies != local_nr_copies) { eprintf("joining node nr_copies doesn't match: %u vs %u\n", jm->nr_copies, local_nr_copies); return CJ_RES_FAIL; } if (jm->cluster_flags != sys->flags) { eprintf("joining node cluster_flags don't match: %u vs %u\n", jm->cluster_flags, sys->flags); return CJ_RES_FAIL; } return CJ_RES_SUCCESS; }