summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c32
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c19
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.c16
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.h1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c16
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.h1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c488
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h12
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h14
-rw-r--r--xlators/mgmt/glusterd/src/glusterd3_1-mops.c18
10 files changed, 600 insertions, 17 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index 7e9a82e306a..00162e913ea 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -119,7 +119,8 @@ glusterd_friend_find_by_uuid (uuid_t uuid,
}
static int
-glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid, char *hostname, int port)
+glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid,
+ char *hostname, int port, dict_t *dict)
{
int ret = -1;
glusterd_peerinfo_t *peerinfo = NULL;
@@ -159,6 +160,7 @@ glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid, char *hostname,
if (hostname)
ctx->hostname = gf_strdup (hostname);
ctx->req = req;
+ ctx->vols = dict;
event->ctx = ctx;
@@ -176,6 +178,8 @@ out:
if (0 != ret) {
if (ctx && ctx->hostname)
GF_FREE (ctx->hostname);
+ if (ctx && ctx->vols)
+ dict_destroy (ctx->vols);
if (ctx)
GF_FREE (ctx);
}
@@ -742,7 +746,7 @@ out:
defrag->mount);
snprintf (cmd_str, 1024, "umount %s", defrag->mount);
- system (cmd_str);
+ ret = system (cmd_str);
volinfo->defrag = NULL;
LOCK_DESTROY (&defrag->lock);
GF_FREE (defrag);
@@ -1291,7 +1295,8 @@ glusterd_handle_incoming_friend_req (rpcsvc_request_t *req)
{
int32_t ret = -1;
gd1_mgmt_friend_req friend_req = {{0},};
- char str[50];
+ char str[50] = {0,};
+ dict_t *dict = NULL;
GF_ASSERT (req);
if (!gd_xdr_to_mgmt_friend_req (req->msg[0], &friend_req)) {
@@ -1304,8 +1309,22 @@ glusterd_handle_incoming_friend_req (rpcsvc_request_t *req)
gf_log ("glusterd", GF_LOG_NORMAL,
"Received probe from uuid: %s", str);
+ dict = dict_new ();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_unserialize (friend_req.vols.vols_val,
+ friend_req.vols.vols_len,
+ &dict);
+
+ if (ret)
+ goto out;
+
ret = glusterd_handle_friend_req (req, friend_req.uuid,
- friend_req.hostname, friend_req.port);
+ friend_req.hostname, friend_req.port,
+ dict);
out:
@@ -1728,7 +1747,8 @@ glusterd_xfer_friend_remove_resp (rpcsvc_request_t *req, char *hostname, int por
}
int
-glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *hostname, int port)
+glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *hostname, int port,
+ int32_t op_ret)
{
gd1_mgmt_friend_rsp rsp = {{0}, };
int32_t ret = -1;
@@ -1737,7 +1757,7 @@ glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *hostname, int port)
GF_ASSERT (hostname);
- rsp.op_ret = 0;
+ rsp.op_ret = op_ret;
this = THIS;
GF_ASSERT (this);
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index b243e78951b..3b4b390d144 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -253,7 +253,7 @@ out:
return ret;
}
-static int
+int
glusterd_volume_create_generate_volfiles (glusterd_volinfo_t *volinfo)
{
int32_t ret = -1;
@@ -800,6 +800,7 @@ glusterd_op_create_volume (gd1_mgmt_stage_op_req *req)
i++;
}
list_add_tail (&volinfo->vol_list, &priv->volumes);
+ volinfo->version++;
ret = glusterd_store_create_volume (volinfo);
@@ -811,6 +812,10 @@ glusterd_op_create_volume (gd1_mgmt_stage_op_req *req)
goto out;
+ ret = glusterd_volume_compute_cksum (volinfo);
+ if (ret)
+ goto out;
+
out:
return ret;
}
@@ -942,6 +947,12 @@ glusterd_op_add_brick (gd1_mgmt_stage_op_req *req)
goto out;
}
+ volinfo->version++;
+
+ ret = glusterd_volume_compute_cksum (volinfo);
+ if (ret)
+ goto out;
+
ret = glusterd_store_update_volume (volinfo);
if (ret)
@@ -1879,6 +1890,12 @@ glusterd_op_remove_brick (gd1_mgmt_stage_op_req *req)
goto out;
}
+ volinfo->version++;
+
+ ret = glusterd_volume_compute_cksum (volinfo);
+ if (ret)
+ goto out;
+
ret = glusterd_store_update_volume (volinfo);
if (ret)
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c
index 18b0b1aa5eb..c12a11a8fb2 100644
--- a/xlators/mgmt/glusterd/src/glusterd-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-sm.c
@@ -306,6 +306,7 @@ glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx)
glusterd_friend_sm_event_t *new_event = NULL;
glusterd_friend_sm_event_type_t event_type = GD_FRIEND_EVENT_NONE;
int status = 0;
+ int32_t op_ret = -1;
GF_ASSERT (ctx);
ev_ctx = ctx;
@@ -315,11 +316,18 @@ glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx)
uuid_copy (peerinfo->uuid, ev_ctx->uuid);
//Build comparison logic here.
+ ret = glusterd_compare_friend_data (ev_ctx->vols, &status);
+ if (ret)
+ goto out;
- if (!status)
+ if (GLUSTERD_VOL_COMP_RJT != status) {
event_type = GD_FRIEND_EVENT_LOCAL_ACC;
- else
+ op_ret = 0;
+ }
+ else {
event_type = GD_FRIEND_EVENT_LOCAL_RJT;
+ op_ret = -1;
+ }
ret = glusterd_friend_sm_new_event (event_type, &new_event);
@@ -344,7 +352,7 @@ glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx)
glusterd_friend_sm_inject_event (new_event);
ret = glusterd_xfer_friend_add_resp (ev_ctx->req, ev_ctx->hostname,
- ev_ctx->port);
+ ev_ctx->port, op_ret);
out:
gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
@@ -408,7 +416,7 @@ glusterd_sm_t glusterd_state_req_rcvd [] = {
{GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_RCVD_ACC
{GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_RCVD_LOCAL_ACC
{GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_RCVD_RJT
- {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
+ {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
{GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_RCV_FRIEND_REQ
{GD_FRIEND_STATE_DEFAULT, glusterd_ac_send_friend_remove_req}, //EVENT_INIT_REMOVE_FRIEND,
{GD_FRIEND_STATE_DEFAULT, glusterd_ac_handle_friend_remove_req}, //EVENT_RCVD_REMOVE_FRIEND
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.h b/xlators/mgmt/glusterd/src/glusterd-sm.h
index 65cf6dc8905..6490f3d526d 100644
--- a/xlators/mgmt/glusterd/src/glusterd-sm.h
+++ b/xlators/mgmt/glusterd/src/glusterd-sm.h
@@ -124,6 +124,7 @@ typedef struct glusterd_friend_req_ctx_ {
char *hostname;
rpcsvc_request_t *req;
int port;
+ dict_t *vols;
} glusterd_friend_req_ctx_t;
typedef glusterd_friend_req_ctx_t glusterd_friend_update_ctx_t;
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
index 2cee89516db..ee47696da96 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
+++ b/xlators/mgmt/glusterd/src/glusterd-store.c
@@ -134,9 +134,9 @@ glusterd_store_create_brick (glusterd_volinfo_t *volinfo,
snprintf (buf, sizeof(buf), "hostname=%s\n", brickinfo->hostname);
- write (fd, buf, strlen(buf));
+ ret = write (fd, buf, strlen(buf));
snprintf (buf, sizeof(buf), "path=%s\n", brickinfo->path);
- write (fd, buf, strlen(buf));
+ ret = write (fd, buf, strlen(buf));
ret = 0;
@@ -293,18 +293,24 @@ glusterd_store_create_volume (glusterd_volinfo_t *volinfo)
if (ret)
goto out;
- snprintf (buf, sizeof (buf), "%d", volinfo->status);
+/* snprintf (buf, sizeof (buf), "%d", volinfo->port);
ret = glusterd_store_save_value (volinfo->shandle,
GLUSTERD_STORE_KEY_VOL_PORT, buf);
if (ret)
goto out;
-
+*/
snprintf (buf, sizeof (buf), "%d", volinfo->sub_count);
ret = glusterd_store_save_value (volinfo->shandle,
GLUSTERD_STORE_KEY_VOL_SUB_COUNT, buf);
if (ret)
goto out;
+ snprintf (buf, sizeof (buf), "%d", volinfo->version);
+ ret = glusterd_store_save_value (volinfo->shandle,
+ GLUSTERD_STORE_KEY_VOL_VERSION, buf);
+ if (ret)
+ goto out;
+
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
ret = glusterd_store_create_brick (volinfo, brickinfo);
if (ret)
@@ -328,7 +334,7 @@ int32_t
glusterd_store_delete_volume (glusterd_volinfo_t *volinfo)
{
char pathname[PATH_MAX] = {0,};
- int32_t ret = -1;
+ int32_t ret = 0;
glusterd_conf_t *priv = NULL;
DIR *dir = NULL;
struct dirent *entry = NULL;
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h
index 1889e5f58bd..10fb4a3af01 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.h
+++ b/xlators/mgmt/glusterd/src/glusterd-store.h
@@ -46,6 +46,7 @@
#define GLUSTERD_STORE_KEY_VOL_PORT "port"
#define GLUSTERD_STORE_KEY_VOL_SUB_COUNT "sub_count"
#define GLUSTERD_STORE_KEY_VOL_BRICK "brick"
+#define GLUSTERD_STORE_KEY_VOL_VERSION "version"
#define GLUSTERD_STORE_KEY_BRICK_HOSTNAME "hostname"
#define GLUSTERD_STORE_KEY_BRICK_PATH "path"
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 35dfa3dfba3..f0115c05b19 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -927,3 +927,491 @@ glusterd_is_cli_op_req (int32_t op)
return _gf_false;
}
+
+
+int
+glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo)
+{
+ int32_t ret = -1;
+ glusterd_conf_t *priv = NULL;
+ char path[PATH_MAX] = {0,};
+ char cksum_path[PATH_MAX] = {0,};
+ char filepath[PATH_MAX] = {0,};
+ DIR *dir = NULL;
+ struct dirent *entry = NULL;
+ int fd = -1;
+ uint32_t cksum = 0;
+ char buf[4096] = {0,};
+
+ GF_ASSERT (volinfo);
+
+ priv = THIS->private;
+ GF_ASSERT (priv);
+
+ GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
+
+ snprintf (cksum_path, sizeof (cksum_path), "%s/%s",
+ path, GLUSTERD_CKSUM_FILE);
+
+ fd = open (cksum_path, O_RDWR | O_APPEND | O_CREAT, 0644);
+
+ if (-1 == fd) {
+ gf_log ("", GF_LOG_ERROR, "Unable to open %s, errno: %d",
+ cksum_path, errno);
+ ret = -1;
+ goto out;
+ }
+
+
+ dir = opendir (path);
+
+ glusterd_for_each_entry (entry, dir);
+
+/* while (entry) {
+
+ snprintf (filepath, sizeof (filepath), "%s/%s", path,
+ entry->d_name);
+
+ if (!strcmp (entry->d_name, "bricks") ||
+ !strcmp (entry->d_name, "run")) {
+ glusterd_for_each_entry (entry, dir);
+ continue;
+ }
+
+ ret = get_checksum_for_path (filepath, &cksum);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get checksum"
+ " for path: %s", filepath);
+ goto out;
+ }
+
+ snprintf (buf, sizeof (buf), "%s=%u\n", entry->d_name, cksum);
+ ret = write (fd, buf, strlen (buf));
+
+ if (ret <= 0) {
+ ret = -1;
+ goto out;
+ }
+
+ glusterd_for_each_entry (entry, dir);
+ }
+*/
+
+ snprintf (filepath, sizeof (filepath), "%s/%s", path,
+ GLUSTERD_VOLUME_INFO_FILE);
+
+ ret = get_checksum_for_path (filepath, &cksum);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get checksum"
+ " for path: %s", filepath);
+ goto out;
+ }
+
+ snprintf (buf, sizeof (buf), "%s=%u\n", "info", cksum);
+ ret = write (fd, buf, strlen (buf));
+
+ if (ret <= 0) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = get_checksum_for_file (fd, &cksum);
+
+ if (ret)
+ goto out;
+
+ volinfo->cksum = cksum;
+
+out:
+ if (fd > 0)
+ close (fd);
+
+ if (dir)
+ closedir (dir);
+
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
+
+ return ret;
+}
+
+int32_t
+glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
+ dict_t *dict, int32_t count)
+{
+ int32_t ret = -1;
+ char key[512] = {0,};
+ glusterd_brickinfo_t *brickinfo = NULL;
+ int32_t i = 1;
+
+ GF_ASSERT (dict);
+ GF_ASSERT (volinfo);
+
+ snprintf (key, sizeof (key), "volume%d.name", count);
+ ret = dict_set_str (dict, key, volinfo->volname);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.type", count);
+ ret = dict_set_int32 (dict, key, volinfo->type);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick_count", count);
+ ret = dict_set_int32 (dict, key, volinfo->brick_count);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.version", count);
+ ret = dict_set_int32 (dict, key, volinfo->version);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.status", count);
+ ret = dict_set_int32 (dict, key, volinfo->status);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.sub_count", count);
+ ret = dict_set_int32 (dict, key, volinfo->sub_count);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.ckusm", count);
+ ret = dict_set_int64 (dict, key, volinfo->cksum);
+ if (ret)
+ goto out;
+
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick%d.hostname",
+ count, i);
+ ret = dict_set_str (dict, key, brickinfo->hostname);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick%d.path",
+ count, i);
+ ret = dict_set_str (dict, key, brickinfo->path);
+ if (ret)
+ goto out;
+
+ i++;
+ }
+
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
+
+ return ret;
+}
+
+int32_t
+glusterd_build_volume_dict (dict_t **vols)
+{
+ int32_t ret = -1;
+ dict_t *dict = NULL;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ int32_t count = 0;
+
+ priv = THIS->private;
+
+ dict = dict_new ();
+
+ if (!dict)
+ goto out;
+
+ list_for_each_entry (volinfo, &priv->volumes, vol_list) {
+ count++;
+ ret = glusterd_add_volume_to_dict (volinfo, dict, count);
+ if (ret)
+ goto out;
+ }
+
+
+ ret = dict_set_int32 (dict, "count", count);
+ if (ret)
+ goto out;
+
+ *vols = dict;
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
+ if (ret)
+ dict_destroy (dict);
+
+ return ret;
+}
+
+int32_t
+glusterd_compare_friend_volume (dict_t *vols, int32_t count, int32_t *status)
+{
+
+ int32_t ret = -1;
+ char key[512] = {0,};
+ glusterd_volinfo_t *volinfo = NULL;
+ char *volname = NULL;
+ uint32_t cksum = 0;
+ int32_t version = 0;
+
+ GF_ASSERT (vols);
+ GF_ASSERT (status);
+
+ snprintf (key, sizeof (key), "volume%d.name", count);
+ ret = dict_get_str (vols, key, &volname);
+ if (ret)
+ goto out;
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+
+ if (ret) {
+ *status = GLUSTERD_VOL_COMP_UPDATE_REQ;
+ ret = 0;
+ goto out;
+ }
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.version", count);
+ ret = dict_get_int32 (vols, key, &version);
+ if (ret)
+ goto out;
+
+ if (version != volinfo->version) {
+ //Mismatch detected
+ ret = 0;
+ gf_log ("", GF_LOG_ERROR, "Version of volume %s differ."
+ "local version = %d, remote version = %d",
+ volinfo->volname, volinfo->version, version);
+ *status = GLUSTERD_VOL_COMP_UPDATE_REQ;
+ goto out;
+ }
+
+ //Now, versions are same, compare cksums.
+ //
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.ckusm", count);
+ ret = dict_get_uint32 (vols, key, &cksum);
+ if (ret)
+ goto out;
+
+ if (cksum != volinfo->cksum) {
+ ret = 0;
+ gf_log ("", GF_LOG_ERROR, "Cksums of volume %s differ."
+ " local cksum = %d, remote cksum = %d",
+ volinfo->volname, volinfo->cksum, cksum);
+ *status = GLUSTERD_VOL_COMP_RJT;
+ goto out;
+ }
+
+ *status = GLUSTERD_VOL_COMP_SCS;
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with ret: %d, status: %d",
+ ret, *status);
+ return ret;
+}
+
+int32_t
+glusterd_import_friend_volume (dict_t *vols, int count)
+{
+
+ int32_t ret = -1;
+ glusterd_conf_t *priv = NULL;
+ char key[512] = {0,};
+ glusterd_volinfo_t *volinfo = NULL;
+ char *volname = NULL;
+ char *hostname = NULL;
+ char *path = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ glusterd_brickinfo_t *tmp = NULL;
+ int new_volinfo = 0;
+ int i = 1;
+
+ GF_ASSERT (vols);
+
+ snprintf (key, sizeof (key), "volume%d.name", count);
+ ret = dict_get_str (vols, key, &volname);
+ if (ret)
+ goto out;
+
+ priv = THIS->private;
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+
+ if (ret) {
+ ret = glusterd_volinfo_new (&volinfo);
+ if (ret)
+ goto out;
+ strncpy (volinfo->volname, volname, sizeof (volinfo->volname));
+ new_volinfo = 1;
+ }
+
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.type", count);
+ ret = dict_get_int32 (vols, key, &volinfo->type);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick_count", count);
+ ret = dict_get_int32 (vols, key, &volinfo->brick_count);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.version", count);
+ ret = dict_get_int32 (vols, key, &volinfo->version);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.status", count);
+ ret = dict_get_int32 (vols, key, (int32_t *)&volinfo->status);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.sub_count", count);
+ ret = dict_get_int32 (vols, key, &volinfo->sub_count);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.ckusm", count);
+ ret = dict_get_uint32 (vols, key, &volinfo->cksum);
+ if (ret)
+ goto out;
+
+ list_for_each_entry_safe (brickinfo, tmp, &volinfo->bricks,
+ brick_list) {
+ ret = glusterd_brickinfo_delete (brickinfo);
+ if (ret)
+ goto out;
+ }
+
+ while (i <= volinfo->brick_count) {
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick%d.hostname",
+ count, i);
+ ret = dict_get_str (vols, key, &hostname);
+ if (ret)
+ goto out;
+
+ memset (&key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick%d.path",
+ count, i);
+ ret = dict_get_str (vols, key, &path);
+ if (ret)
+ goto out;
+
+ ret = glusterd_brickinfo_new (&brickinfo);
+ if (ret)
+ goto out;
+
+ strcpy (brickinfo->path, path);
+ strcpy (brickinfo->hostname, hostname);
+
+ list_add_tail (&brickinfo->brick_list, &volinfo->bricks);
+
+ i++;
+ }
+
+ if (new_volinfo) {
+ list_add_tail (&volinfo->vol_list, &priv->volumes);
+ ret = glusterd_store_create_volume (volinfo);
+ } else {
+ ret = glusterd_store_update_volume (volinfo);
+ }
+
+ ret = glusterd_volume_create_generate_volfiles (volinfo);
+ if (ret)
+ goto out;
+
+ //volinfo->version++;
+
+ ret = glusterd_volume_compute_cksum (volinfo);
+ if (ret)
+ goto out;
+
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with ret: %d", ret);
+ return ret;
+}
+
+
+int32_t
+glusterd_import_friend_volumes (dict_t *vols)
+{
+ int32_t ret = -1;
+ int32_t count = 0;
+ int i = 1;
+
+ GF_ASSERT (vols);
+
+ ret = dict_get_int32 (vols, "count", &count);
+ if (ret)
+ goto out;
+
+ while (i <= count) {
+ ret = glusterd_import_friend_volume (vols, i);
+ if (ret)
+ goto out;
+
+ i++;
+ }
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
+ return ret;
+}
+
+int32_t
+glusterd_compare_friend_data (dict_t *vols, int32_t *status)
+{
+ int32_t ret = -1;
+ int32_t count = 0;
+ int i = 1;
+
+ GF_ASSERT (vols);
+ GF_ASSERT (status);
+
+ ret = dict_get_int32 (vols, "count", &count);
+ if (ret)
+ goto out;
+
+ while (i <= count) {
+ ret = glusterd_compare_friend_volume (vols, i, status);
+ if (ret)
+ goto out;
+
+ if (GLUSTERD_VOL_COMP_RJT == *status) {
+ ret = 0;
+ goto out;
+ }
+
+ i++;
+ }
+
+ if (GLUSTERD_VOL_COMP_UPDATE_REQ == *status) {
+ ret = glusterd_import_friend_volumes (vols);
+ if (ret)
+ goto out;
+ }
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with ret: %d, status: %d",
+ ret, *status);
+
+ return ret;
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index 892533c40a6..1e9469ce0fd 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -117,4 +117,16 @@ glusterd_brickinfo_get (char *brick, glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t **brickinfo);
int32_t
glusterd_is_local_addr (char *hostname);
+
+int32_t
+glusterd_build_volume_dict (dict_t **vols);
+
+int32_t
+glusterd_compare_friend_data (dict_t *vols, int32_t *status);
+
+int
+glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo);
+
+int
+glusterd_volume_create_generate_volfiles (glusterd_volinfo_t *volinfo);
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index cc1fb7786bd..4465ee316dd 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -127,6 +127,9 @@ struct glusterd_volinfo_ {
uint64_t rebalance_data;
uint64_t lookedup_files;
glusterd_defrag_info_t *defrag;
+
+ int version;
+ uint32_t cksum;
};
typedef struct glusterd_volinfo_ glusterd_volinfo_t;
@@ -135,6 +138,13 @@ enum glusterd_op_ret {
GLUSTERD_CONNECTION_AWAITED = 100,
};
+enum glusterd_vol_comp_status_ {
+ GLUSTERD_VOL_COMP_NONE = 0,
+ GLUSTERD_VOL_COMP_SCS = 1,
+ GLUSTERD_VOL_COMP_UPDATE_REQ,
+ GLUSTERD_VOL_COMP_RJT,
+};
+
#define GLUSTERD_DEFAULT_WORKDIR "/etc/glusterd"
#define GLUSTERD_DEFAULT_PORT 6969
#define GLUSTERD_INFO_FILE "glusterd.info"
@@ -142,6 +152,7 @@ enum glusterd_op_ret {
#define GLUSTERD_PEER_DIR_PREFIX "peers"
#define GLUSTERD_VOLUME_INFO_FILE "info"
#define GLUSTERD_BRICK_INFO_DIR "bricks"
+#define GLUSTERD_CKSUM_FILE "cksum"
/*All definitions related to replace brick */
#define RB_PUMP_START_CMD "trusted.glusterfs.pump.start"
@@ -173,7 +184,8 @@ int
glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr, int port);
int
-glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *hostname, int port);
+glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *hostname,
+ int port, int32_t op_ret);
int
glusterd_friend_find (uuid_t uuid, char *hostname,
diff --git a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
index 2c5cb8f33ab..5196055b3e1 100644
--- a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
+++ b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
@@ -639,6 +639,7 @@ glusterd3_1_friend_add (call_frame_t *frame, xlator_t *this,
glusterd_conf_t *priv = NULL;
glusterd_friend_sm_event_t *event = NULL;
glusterd_friend_req_ctx_t *ctx = NULL;
+ dict_t *vols = NULL;
if (!frame || !this || !data) {
@@ -655,15 +656,32 @@ glusterd3_1_friend_add (call_frame_t *frame, xlator_t *this,
peerinfo = event->peerinfo;
+ ret = glusterd_build_volume_dict (&vols);
+ if (ret)
+ goto out;
+
uuid_copy (req.uuid, priv->uuid);
req.hostname = gf_strdup (peerinfo->hostname);
req.port = peerinfo->port;
+
+ ret = dict_allocate_and_serialize (vols, &req.vols.vols_val,
+ (size_t *)&req.vols.vols_len);
+ if (ret)
+ goto out;
+
ret = glusterd_submit_request (peerinfo, &req, frame, priv->mgmt,
GD_MGMT_FRIEND_ADD,
NULL, gd_xdr_from_mgmt_friend_req,
this, glusterd3_1_friend_add_cbk);
+
out:
+ if (req.vols.vols_val)
+ GF_FREE (req.vols.vols_val);
+
+ if (vols)
+ dict_destroy (vols);
+
gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}