summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
Diffstat (limited to 'xlators')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c34
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.c6
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.h1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c127
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h8
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, &quota_version);
+ ret = dict_get_uint32(arg->peer_ver_data, key, &quota_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, &quota_cksum);
+ ret = dict_get_uint32(arg->peer_ver_data, key, &quota_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 {