diff options
Diffstat (limited to 'xlators/mgmt')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 34 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-sm.c | 6 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-sm.h | 1 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 127 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 2 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 8 |
6 files changed, 100 insertions, 78 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index fada93bc0b..7f49c06ff7 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -82,6 +82,9 @@ glusterd_big_locked_handler(rpcsvc_request_t *req, rpcsvc_actor actor_fn) return ret; } +static char *specific_key_suffix[] = {".quota-cksum", ".ckusm", ".version", + ".quota-version", ".name"}; + static int glusterd_handle_friend_req(rpcsvc_request_t *req, uuid_t uuid, char *hostname, int port, gd1_mgmt_friend_req *friend_req) @@ -92,6 +95,8 @@ glusterd_handle_friend_req(rpcsvc_request_t *req, uuid_t uuid, char *hostname, glusterd_friend_req_ctx_t *ctx = NULL; char rhost[UNIX_PATH_MAX + 1] = {0}; dict_t *dict = NULL; + dict_t *peer_ver = NULL; + int totcount = sizeof(specific_key_suffix) / sizeof(specific_key_suffix[0]); if (!port) port = GF_DEFAULT_BASE_PORT; @@ -100,9 +105,17 @@ glusterd_handle_friend_req(rpcsvc_request_t *req, uuid_t uuid, char *hostname, ctx = GF_CALLOC(1, sizeof(*ctx), gf_gld_mt_friend_req_ctx_t); dict = dict_new(); + peer_ver = dict_new(); RCU_READ_LOCK; + if (!ctx || !dict || !peer_ver) { + gf_msg("glusterd", GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY, + "Unable to allocate memory"); + ret = -1; + goto out; + } + peerinfo = glusterd_peerinfo_find(uuid, rhost); if (peerinfo == NULL) { @@ -127,26 +140,14 @@ glusterd_handle_friend_req(rpcsvc_request_t *req, uuid_t uuid, char *hostname, event->peername = gf_strdup(peerinfo->hostname); gf_uuid_copy(event->peerid, peerinfo->uuid); - if (!ctx) { - gf_msg("glusterd", GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY, - "Unable to allocate memory"); - ret = -1; - goto out; - } - gf_uuid_copy(ctx->uuid, uuid); if (hostname) ctx->hostname = gf_strdup(hostname); ctx->req = req; - if (!dict) { - gf_smsg("glusterd", GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL, NULL); - ret = -1; - goto out; - } - - ret = dict_unserialize(friend_req->vols.vols_val, friend_req->vols.vols_len, - &dict); + ret = dict_unserialize_specific_keys( + friend_req->vols.vols_val, friend_req->vols.vols_len, &dict, + specific_key_suffix, &peer_ver, totcount); if (ret) { gf_smsg("glusterd", GF_LOG_ERROR, 0, GD_MSG_DICT_UNSERIALIZE_FAIL, @@ -156,6 +157,7 @@ glusterd_handle_friend_req(rpcsvc_request_t *req, uuid_t uuid, char *hostname, dict->extra_stdfree = friend_req->vols.vols_val; ctx->vols = dict; + ctx->peer_ver = peer_ver; event->ctx = ctx; ret = glusterd_friend_sm_inject_event(event); @@ -185,6 +187,8 @@ out: } else { free(friend_req->vols.vols_val); } + if (peer_ver) + dict_unref(peer_ver); if (event) GF_FREE(event->peername); GF_FREE(event); diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c index bf2d81b644..83aa65abc5 100644 --- a/xlators/mgmt/glusterd/src/glusterd-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-sm.c @@ -106,6 +106,8 @@ glusterd_destroy_friend_req_ctx(glusterd_friend_req_ctx_t *ctx) if (ctx->vols) dict_unref(ctx->vols); + if (ctx->peer_ver) + dict_unref(ctx->peer_ver); GF_FREE(ctx->hostname); GF_FREE(ctx); } @@ -995,8 +997,8 @@ glusterd_ac_handle_friend_add_req(glusterd_friend_sm_event_t *event, void *ctx) // Build comparison logic here. pthread_mutex_lock(&conf->import_volumes); { - ret = glusterd_compare_friend_data(ev_ctx->vols, &status, - event->peername); + ret = glusterd_compare_friend_data(ev_ctx->vols, ev_ctx->peer_ver, + &status, event->peername); if (ret) { pthread_mutex_unlock(&conf->import_volumes); goto out; diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.h b/xlators/mgmt/glusterd/src/glusterd-sm.h index 11cbd85b3e..b0aa2485f3 100644 --- a/xlators/mgmt/glusterd/src/glusterd-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-sm.h @@ -171,6 +171,7 @@ typedef struct glusterd_friend_req_ctx_ { rpcsvc_request_t *req; int port; dict_t *vols; + dict_t *peer_ver; // Dictionary to save peer ver data } glusterd_friend_req_ctx_t; typedef struct glusterd_friend_update_ctx_ { diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 2a34613ff5..b0b8d598f8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -3759,8 +3759,9 @@ out: } static int32_t -glusterd_compare_friend_volume(dict_t *peer_data, int32_t count, - int32_t *status, char *hostname) +glusterd_compare_friend_volume(dict_t *peer_data, + glusterd_friend_synctask_args_t *arg, + int32_t count, int32_t *status, char *hostname) { int32_t ret = -1; char key[64] = ""; @@ -3776,6 +3777,7 @@ glusterd_compare_friend_volume(dict_t *peer_data, int32_t count, xlator_t *this = NULL; GF_ASSERT(peer_data); + GF_ASSERT(arg); GF_ASSERT(status); this = THIS; @@ -3783,10 +3785,10 @@ glusterd_compare_friend_volume(dict_t *peer_data, int32_t count, snprintf(key_prefix, sizeof(key_prefix), "volume%d", count); keylen = snprintf(key, sizeof(key), "%s.name", key_prefix); - ret = dict_get_strn(peer_data, key, keylen, &volname); + ret = dict_get_strn(arg->peer_ver_data, key, keylen, &volname); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_GET_FAILED, - "Key=%s", key, NULL); + "Key=%s is NULL in peer_ver_data", key, NULL); goto out; } @@ -3804,10 +3806,10 @@ glusterd_compare_friend_volume(dict_t *peer_data, int32_t count, } keylen = snprintf(key, sizeof(key), "%s.version", key_prefix); - ret = dict_get_int32n(peer_data, key, keylen, &version); + ret = dict_get_int32n(arg->peer_ver_data, key, keylen, &version); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_GET_FAILED, - "Key=%s", key, NULL); + "Key=%s is NULL in peer_ver_data", key, NULL); goto out; } @@ -3828,10 +3830,10 @@ glusterd_compare_friend_volume(dict_t *peer_data, int32_t count, // Now, versions are same, compare cksums. // snprintf(key, sizeof(key), "%s.ckusm", key_prefix); - ret = dict_get_uint32(peer_data, key, &cksum); + ret = dict_get_uint32(arg->peer_ver_data, key, &cksum); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_GET_FAILED, - "Key=%s", key, NULL); + "Key=%s is NULL in peer_ver_data", key, NULL); goto out; } @@ -3848,7 +3850,7 @@ glusterd_compare_friend_volume(dict_t *peer_data, int32_t count, goto skip_quota; snprintf(key, sizeof(key), "%s.quota-version", key_prefix); - ret = dict_get_uint32(peer_data, key, "a_version); + ret = dict_get_uint32(arg->peer_ver_data, key, "a_version); if (ret) { gf_msg_debug(this->name, 0, "quota-version key absent for" @@ -3864,6 +3866,7 @@ glusterd_compare_friend_volume(dict_t *peer_data, int32_t count, "%d on peer %s", volinfo->volname, volinfo->quota_conf_version, quota_version, hostname); + GF_ATOMIC_INIT(volinfo->volpeerupdate, 1); *status = GLUSTERD_VOL_COMP_UPDATE_REQ; goto out; } else if (quota_version < volinfo->quota_conf_version) { @@ -3875,7 +3878,7 @@ glusterd_compare_friend_volume(dict_t *peer_data, int32_t count, // Now, versions are same, compare cksums. // snprintf(key, sizeof(key), "%s.quota-cksum", key_prefix); - ret = dict_get_uint32(peer_data, key, "a_cksum); + ret = dict_get_uint32(arg->peer_ver_data, key, "a_cksum); if (ret) { gf_msg_debug(this->name, 0, "quota checksum absent for " @@ -3899,13 +3902,12 @@ skip_quota: *status = GLUSTERD_VOL_COMP_SCS; out: - keylen = snprintf(key, sizeof(key), "%s.update", key_prefix); - if (*status == GLUSTERD_VOL_COMP_UPDATE_REQ) { - ret = dict_set_int32n(peer_data, key, keylen, 1); - } else { - ret = dict_set_int32n(peer_data, key, keylen, 0); + /*Set the status to ensure volume is updated on the peer + */ + arg->status_arr[(count / 64)] ^= 1UL << (count % 64); } + if (*status == GLUSTERD_VOL_COMP_RJT) { gf_event(EVENT_COMPARE_FRIEND_VOLUME_FAILED, "volume=%s", volinfo->volname); @@ -5101,7 +5103,8 @@ out: } static int32_t -glusterd_import_friend_volume(dict_t *peer_data, int count) +glusterd_import_friend_volume(dict_t *peer_data, int count, + glusterd_friend_synctask_args_t *arg) { int32_t ret = -1; glusterd_conf_t *priv = NULL; @@ -5119,17 +5122,27 @@ glusterd_import_friend_volume(dict_t *peer_data, int count) priv = this->private; GF_ASSERT(priv); - ret = snprintf(key, sizeof(key), "volume%d.update", count); - ret = dict_get_int32n(peer_data, key, ret, &update); - if (ret) { - gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_GET_FAILED, - "Key=%s", key, NULL); - goto out; + if (arg) { + /*Check if the volume options are updated on the other peers + */ + update = (1UL & (arg->status_arr[(count / 64)] >> (count % 64))); + } else { + ret = snprintf(key, sizeof(key), "volume%d.update", count); + ret = dict_get_int32n(peer_data, key, ret, &update); + if (ret) { + gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_GET_FAILED, + "Key=%s", key, NULL); + goto out; + } } if (!update) { /* if update is 0 that means the volume is not imported */ - gf_smsg(this->name, GF_LOG_INFO, 0, GD_MSG_VOLUME_NOT_IMPORTED, NULL); + gf_log(this->name, GF_LOG_DEBUG, + "The volume%d does" + " not have any peer change", + count); + ret = 0; goto out; } @@ -5221,6 +5234,8 @@ glusterd_import_friend_volumes_synctask(void *opaque) glusterd_conf_t *conf = NULL; dict_t *peer_data = NULL; glusterd_friend_synctask_args_t *arg = NULL; + uint64_t bm = 0; + uint64_t mask = 0; this = THIS; GF_ASSERT(this); @@ -5232,20 +5247,7 @@ glusterd_import_friend_volumes_synctask(void *opaque) if (!arg) goto out; - peer_data = dict_new(); - if (!peer_data) { - gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_CREATE_FAIL, NULL); - goto out; - } - - ret = dict_unserialize(arg->dict_buf, arg->dictlen, &peer_data); - if (ret) { - gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_UNSERIALIZE_FAIL, - NULL); - errno = ENOMEM; - goto out; - } - + peer_data = arg->peer_data; ret = dict_get_int32n(peer_data, "count", SLEN("count"), &count); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_GET_FAILED, @@ -5265,11 +5267,18 @@ glusterd_import_friend_volumes_synctask(void *opaque) conf->restart_bricks = _gf_true; while (i <= count) { - ret = glusterd_import_friend_volume(peer_data, i); - if (ret) { - break; + bm = arg->status_arr[i / 64]; + while (bm != 0) { + /* mask will contain the lowest bit set from bm. */ + mask = bm & (-bm); + bm ^= mask; + ret = glusterd_import_friend_volume(peer_data, i + ffsll(mask) - 2, + arg); + if (ret < 0) { + break; + } } - i++; + i += 64; } if (i > count) { glusterd_svcs_manager(NULL); @@ -5277,11 +5286,9 @@ glusterd_import_friend_volumes_synctask(void *opaque) conf->restart_bricks = _gf_false; synccond_broadcast(&conf->cond_restart_bricks); out: - if (peer_data) - dict_unref(peer_data); if (arg) { - if (arg->dict_buf) - GF_FREE(arg->dict_buf); + dict_unref(arg->peer_data); + dict_unref(arg->peer_ver_data); GF_FREE(arg); } @@ -5306,7 +5313,7 @@ glusterd_import_friend_volumes(dict_t *peer_data) } while (i <= count) { - ret = glusterd_import_friend_volume(peer_data, i); + ret = glusterd_import_friend_volume(peer_data, i, NULL); if (ret) goto out; i++; @@ -5459,7 +5466,8 @@ out: } int32_t -glusterd_compare_friend_data(dict_t *peer_data, int32_t *status, char *hostname) +glusterd_compare_friend_data(dict_t *peer_data, dict_t *cmp, int32_t *status, + char *hostname) { int32_t ret = -1; int32_t count = 0; @@ -5491,8 +5499,19 @@ glusterd_compare_friend_data(dict_t *peer_data, int32_t *status, char *hostname) goto out; } + arg = GF_CALLOC(1, sizeof(*arg) + sizeof(uint64_t) * (count / 64), + gf_common_mt_char); + if (!arg) { + ret = -1; + gf_msg("glusterd", GF_LOG_ERROR, ENOMEM, GD_MSG_NO_MEMORY, + "Out Of Memory"); + goto out; + } + arg->peer_data = dict_ref(peer_data); + arg->peer_ver_data = dict_ref(cmp); while (i <= count) { - ret = glusterd_compare_friend_volume(peer_data, i, status, hostname); + ret = glusterd_compare_friend_volume(peer_data, arg, i, status, + hostname); if (ret) goto out; @@ -5512,21 +5531,13 @@ glusterd_compare_friend_data(dict_t *peer_data, int32_t *status, char *hostname) * first brick to come up before attaching the subsequent bricks * in case brick multiplexing is enabled */ - arg = GF_CALLOC(1, sizeof(*arg), gf_common_mt_char); - ret = dict_allocate_and_serialize(peer_data, &arg->dict_buf, - &arg->dictlen); - if (ret < 0) { - gf_log(this->name, GF_LOG_ERROR, - "dict_serialize failed while handling " - " import friend volume request"); - goto out; - } - glusterd_launch_synctask(glusterd_import_friend_volumes_synctask, arg); } out: if (ret && arg) { + dict_unref(arg->peer_data); + dict_unref(arg->peer_ver_data); GF_FREE(arg); } gf_msg_debug(this->name, 0, "Returning with ret: %d, status: %d", ret, diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 2149fc6a98..852b3fad19 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -241,7 +241,7 @@ glusterd_add_volumes_to_export_dict(dict_t *peer_data, char **buf, u_int *length); int32_t -glusterd_compare_friend_data(dict_t *peer_data, int32_t *status, +glusterd_compare_friend_data(dict_t *peer_data, dict_t *cmp, int32_t *status, char *hostname); int diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 7ff93d7f8a..a0f17c20dd 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -247,8 +247,12 @@ typedef struct glusterd_add_dict_args { } glusterd_add_dict_args_t; typedef struct glusterd_friend_synctask_args { - char *dict_buf; - u_int dictlen; + dict_t *peer_data; + dict_t *peer_ver_data; // Dictionary to save peer version data + /* This status_arr[1] is not a real size, real size of the array + is dynamically allocated + */ + uint64_t status_arr[1]; } glusterd_friend_synctask_args_t; typedef enum gf_brick_status { |