From f846e54b8844decbc8bd73840e7d35b2dcaed2e0 Mon Sep 17 00:00:00 2001 From: Avra Sengupta Date: Wed, 23 Apr 2014 04:26:24 +0000 Subject: glusterd: Fetch brick mount_dirs during brick create. Fetch the mount directory path for a brick, during volume create, add-brick, and replace-brick. When a snap-create is missed, use this mount directory information to create the brick path for the missed snap brick. Change-Id: Iad3eec96a32cf340f26bdf3f28e2f529e4b77e31 BUG: 1061685 Signed-off-by: Avra Sengupta Reviewed-on: http://review.gluster.org/7550 Reviewed-by: Rajesh Joseph Tested-by: Gluster Build System Reviewed-by: Krishnan Parthasarathi Tested-by: Krishnan Parthasarathi --- libglusterfs/src/dict.c | 2 +- xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 50 ++++++- xlators/mgmt/glusterd/src/glusterd-op-sm.c | 26 +++- xlators/mgmt/glusterd/src/glusterd-replace-brick.c | 44 +++++- xlators/mgmt/glusterd/src/glusterd-snapshot.c | 115 +++++----------- xlators/mgmt/glusterd/src/glusterd-store.c | 12 ++ xlators/mgmt/glusterd/src/glusterd-store.h | 1 + xlators/mgmt/glusterd/src/glusterd-syncop.c | 38 ++++- xlators/mgmt/glusterd/src/glusterd-utils.c | 153 +++++++++++++++++++-- xlators/mgmt/glusterd/src/glusterd-utils.h | 7 + xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 122 ++++++++++++++-- xlators/mgmt/glusterd/src/glusterd.h | 10 +- 12 files changed, 462 insertions(+), 118 deletions(-) diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c index b5ebe6cea3d..cf4a3ce644c 100644 --- a/libglusterfs/src/dict.c +++ b/libglusterfs/src/dict.c @@ -2101,7 +2101,7 @@ dict_set_dynstr_with_alloc (dict_t *this, char *key, const char *str) return -1; ret = dict_set_dynstr (this, key, alloc_str); - if (ret) + if (ret == -EINVAL) GF_FREE (alloc_str); return ret; diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c index e2e01672893..b14d3606d81 100644 --- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c @@ -996,7 +996,12 @@ glusterd_op_perform_add_bricks (glusterd_volinfo_t *volinfo, int32_t count, char msg[1024] __attribute__((unused)) = {0, }; int caps = 0; int brickid = 0; + char key[PATH_MAX] = ""; + char *brick_mount_dir = NULL; + xlator_t *this = NULL; + this = THIS; + GF_ASSERT (this); GF_ASSERT (volinfo); if (bricks) { @@ -1034,6 +1039,18 @@ glusterd_op_perform_add_bricks (glusterd_volinfo_t *volinfo, int32_t count, GLUSTERD_ASSIGN_BRICKID_TO_BRICKINFO (brickinfo, volinfo, brickid++); + brick_mount_dir = NULL; + + snprintf (key, sizeof(key), "brick%d.mount_dir", i); + ret = dict_get_str (dict, key, &brick_mount_dir); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "%s not present", key); + goto out; + } + strncpy (brickinfo->mount_dir, brick_mount_dir, + sizeof(brickinfo->mount_dir)); + ret = glusterd_resolve_brick (brickinfo); if (ret) goto out; @@ -1049,7 +1066,6 @@ glusterd_op_perform_add_bricks (glusterd_volinfo_t *volinfo, int32_t count, } - /* Gets changed only if the options are given in add-brick cli */ if (type) volinfo->type = type; @@ -1202,13 +1218,14 @@ out: } int -glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr) +glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr, dict_t *rsp_dict) { int ret = 0; char *volname = NULL; int count = 0; int replica_count = 0; int i = 0; + int32_t local_brick_count = 0; char *bricks = NULL; char *brick_list = NULL; char *saveptr = NULL; @@ -1218,6 +1235,7 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr) glusterd_volinfo_t *volinfo = NULL; xlator_t *this = NULL; char msg[2048] = {0,}; + char key[PATH_MAX] = ""; gf_boolean_t brick_alloc = _gf_false; char *all_bricks = NULL; char *str_ret = NULL; @@ -1349,6 +1367,26 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr) op_errstr, is_force); if (ret) goto out; + + ret = glusterd_get_brick_mount_dir + (brickinfo->path, + brickinfo->hostname, + brickinfo->mount_dir); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to get brick mount_dir"); + goto out; + } + + snprintf (key, sizeof(key), "brick%d.mount_dir", i + 1); + ret = dict_set_dynstr_with_alloc (rsp_dict, key, + brickinfo->mount_dir); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set %s", key); + goto out; + } + local_brick_count = i + 1; } glusterd_brickinfo_delete (brickinfo); @@ -1358,6 +1396,14 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr) i++; } + ret = dict_set_int32 (rsp_dict, "brick_count", + local_brick_count); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set local_brick_count"); + goto out; + } + out: GF_FREE (free_ptr); if (brick_alloc && brickinfo) diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 30658459ba7..d6d72516c67 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -3373,6 +3373,7 @@ glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx) xlator_t *this = NULL; glusterd_peerinfo_t *peerinfo = NULL; dict_t *dict = NULL; + dict_t *rsp_dict = NULL; char *op_errstr = NULL; glusterd_op_t op = GD_OP_NONE; uint32_t pending_count = 0; @@ -3384,6 +3385,13 @@ glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx) op = glusterd_op_get_op (); + rsp_dict = dict_new(); + if (!rsp_dict) { + gf_log (this->name, GF_LOG_ERROR, "Failed to create rsp_dict"); + ret = -1; + goto out; + } + ret = glusterd_op_build_payload (&dict, &op_errstr, NULL); if (ret) { gf_log (this->name, GF_LOG_ERROR, LOGSTR_BUILD_PAYLOAD, @@ -3401,8 +3409,7 @@ glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx) goto out; } - /* rsp_dict NULL from source */ - ret = glusterd_op_stage_validate (op, dict, &op_errstr, NULL); + ret = glusterd_op_stage_validate (op, dict, &op_errstr, rsp_dict); if (ret) { gf_log (this->name, GF_LOG_ERROR, LOGSTR_STAGE_FAIL, gd_op_list[op], "localhost", @@ -3414,6 +3421,9 @@ glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx) goto out; } + if (op == GD_OP_REPLACE_BRICK) + glusterd_rb_use_rsp_dict (NULL, rsp_dict); + list_for_each_entry (peerinfo, &priv->peers, uuid_list) { GF_ASSERT (peerinfo); @@ -3447,6 +3457,9 @@ glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx) opinfo.pending_count = pending_count; out: + if (rsp_dict) + dict_unref (rsp_dict); + if (dict) dict_unref (dict); if (ret) { @@ -4586,11 +4599,13 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr, switch (op) { case GD_OP_CREATE_VOLUME: - ret = glusterd_op_stage_create_volume (dict, op_errstr); + ret = glusterd_op_stage_create_volume (dict, op_errstr, + rsp_dict); break; case GD_OP_START_VOLUME: - ret = glusterd_op_stage_start_volume (dict, op_errstr); + ret = glusterd_op_stage_start_volume (dict, op_errstr, + rsp_dict); break; case GD_OP_STOP_VOLUME: @@ -4602,7 +4617,8 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr, break; case GD_OP_ADD_BRICK: - ret = glusterd_op_stage_add_brick (dict, op_errstr); + ret = glusterd_op_stage_add_brick (dict, op_errstr, + rsp_dict); break; case GD_OP_REPLACE_BRICK: diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c index ed6d7fd57d5..929c86b718c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c +++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c @@ -544,6 +544,30 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr, ret = -1; goto out; } + } else { + ret = glusterd_get_brick_mount_dir (dst_brickinfo->path, + dst_brickinfo->hostname, + dst_brickinfo->mount_dir); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to get brick mount_dir"); + goto out; + } + + ret = dict_set_dynstr_with_alloc (rsp_dict, "brick1.mount_dir", + dst_brickinfo->mount_dir); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set brick1.mount_dir"); + goto out; + } + + ret = dict_set_int32 (rsp_dict, "brick_count", 1); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set local_brick_count"); + goto out; + } } if (replace_op == GF_REPLACE_OP_START && @@ -1493,12 +1517,18 @@ out: static int glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo, - char *old_brick, char *new_brick) + char *old_brick, char *new_brick, + dict_t *dict) { + char *brick_mount_dir = NULL; glusterd_brickinfo_t *old_brickinfo = NULL; glusterd_brickinfo_t *new_brickinfo = NULL; int32_t ret = -1; + xlator_t *this = NULL; + this = THIS; + GF_ASSERT (this); + GF_ASSERT (dict); GF_ASSERT (volinfo); ret = glusterd_brickinfo_new_from_brick (new_brick, @@ -1519,6 +1549,15 @@ glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo, strncpy (new_brickinfo->brick_id, old_brickinfo->brick_id, sizeof (new_brickinfo->brick_id)); + ret = dict_get_str (dict, "brick1.mount_dir", &brick_mount_dir); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "brick1.mount_dir not present"); + goto out; + } + strncpy (new_brickinfo->mount_dir, brick_mount_dir, + sizeof(new_brickinfo->mount_dir)); + list_add_tail (&new_brickinfo->brick_list, &old_brickinfo->brick_list); @@ -1629,7 +1668,6 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict) if (ret) goto out; - if ((GF_REPLACE_OP_START != replace_op)) { /* Set task-id, if available, in op_ctx dict for operations @@ -1753,7 +1791,7 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict) } ret = glusterd_op_perform_replace_brick (volinfo, src_brick, - dst_brick); + dst_brick, dict); if (ret) { gf_log (this->name, GF_LOG_CRITICAL, "Unable to add " "dst-brick: %s to volume: %s", dst_brick, diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c index 54b61ee66cd..327155fee31 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c @@ -1042,7 +1042,6 @@ glusterd_snap_create_pre_val_use_rsp_dict (dict_t *dst, dict_t *src) { char *snap_brick_dir = NULL; char *snap_device = NULL; - char *tmpstr = NULL; char key[PATH_MAX] = ""; char snapbrckcnt[PATH_MAX] = ""; char snapbrckord[PATH_MAX] = ""; @@ -1081,7 +1080,6 @@ glusterd_snap_create_pre_val_use_rsp_dict (dict_t *dst, dict_t *src) /* Fetching data from source dict */ snprintf (key, sizeof(key) - 1, "vol%"PRId64".brickdir%"PRId64, i+1, j); - ret = dict_get_ptr (src, key, (void **)&snap_brick_dir); if (ret) { @@ -1090,20 +1088,9 @@ glusterd_snap_create_pre_val_use_rsp_dict (dict_t *dst, dict_t *src) continue; } - snprintf (key, sizeof(key) - 1, - "vol%"PRId64".brick_snapdevice%"PRId64, i+1, j); - - ret = dict_get_ptr (src, key, - (void **)&snap_device); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Unable to fetch snap_device"); - goto out; - } - + /* Fetching brick order from source dict */ snprintf (snapbrckord, sizeof(snapbrckord) - 1, "vol%"PRId64".brick%"PRId64".order", i+1, j); - ret = dict_get_int64 (src, snapbrckord, &brick_order); if (ret) { gf_log (this->name, GF_LOG_ERROR, @@ -1111,39 +1098,36 @@ glusterd_snap_create_pre_val_use_rsp_dict (dict_t *dst, dict_t *src) goto out; } - /* Adding the data in the dst dict */ snprintf (key, sizeof(key) - 1, - "vol%"PRId64".brickdir%"PRId64, i+1, brick_order); - - tmpstr = gf_strdup (snap_brick_dir); - if (!tmpstr) { + "vol%"PRId64".brickdir%"PRId64, i+1, + brick_order); + ret = dict_set_dynstr_with_alloc (dst, key, + snap_brick_dir); + if (ret) { gf_log (this->name, GF_LOG_ERROR, - "Out Of Memory"); - ret = -1; + "Failed to set %s", key); goto out; } - ret = dict_set_dynstr (dst, key, tmpstr); + + snprintf (key, sizeof(key) - 1, + "vol%"PRId64".brick_snapdevice%"PRId64, + i+1, j); + ret = dict_get_ptr (src, key, + (void **)&snap_device); if (ret) { gf_log (this->name, GF_LOG_ERROR, - "Failed to set %s", key); - GF_FREE (tmpstr); + "Unable to fetch snap_device"); goto out; } snprintf (key, sizeof(key) - 1, "vol%"PRId64".brick_snapdevice%"PRId64, i+1, brick_order); - - tmpstr = gf_strdup (snap_device); - if (!tmpstr) { - ret = -1; - goto out; - } - ret = dict_set_dynstr (dst, key, tmpstr); + ret = dict_set_dynstr_with_alloc (dst, key, + snap_device); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to set %s", key); - GF_FREE (tmpstr); goto out; } } @@ -1205,12 +1189,7 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr, char *volname = NULL; char *snapname = NULL; char *device = NULL; - char *tmpstr = NULL; - char *brick_dir = NULL; - char snap_brick_dir[PATH_MAX] = ""; - char *mnt_pt = NULL; char key[PATH_MAX] = ""; - char snap_mount[PATH_MAX] = ""; char snap_volname[64] = ""; char err_str[PATH_MAX] = ""; int ret = -1; @@ -1394,44 +1373,17 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr, GF_FREE (device); goto out; } + device = NULL; - ret = glusterd_get_brick_root (brickinfo->path, - &mnt_pt); - if (ret) { - snprintf (err_str, sizeof (err_str), - "could not get the root of the brick path %s", - brickinfo->path); - loglevel = GF_LOG_WARNING; - goto out; - } - if (strncmp (brickinfo->path, mnt_pt, strlen(mnt_pt))) { - snprintf (err_str, sizeof (err_str), - "brick: %s brick mount: %s", - brickinfo->path, mnt_pt); - loglevel = GF_LOG_WARNING; - goto out; - } - - brick_dir = &brickinfo->path[strlen (mnt_pt)]; - brick_dir++; - - snprintf (snap_brick_dir, sizeof (snap_brick_dir), - "/%s", brick_dir); - - tmpstr = gf_strdup (snap_brick_dir); - if (!tmpstr) { - ret = -1; - goto out; - } snprintf (key, sizeof(key), "vol%"PRId64".brickdir%"PRId64, i, brick_count); - ret = dict_set_dynstr (rsp_dict, key, tmpstr); + ret = dict_set_dynstr_with_alloc (rsp_dict, key, + brickinfo->mount_dir); if (ret) { gf_log (this->name, GF_LOG_ERROR, - "Failed to set %s", snap_mount); + "Failed to set %s", key); goto out; } - tmpstr = NULL; snprintf (key, sizeof(key) - 1, "vol%"PRId64".brick%"PRId64".order", i, brick_count); @@ -1462,8 +1414,8 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr, ret = 0; out: - if (ret) - GF_FREE (tmpstr); + if (device) + GF_FREE (device); if (ret && err_str[0] != '\0') { gf_log (this->name, loglevel, "%s", err_str); @@ -3536,23 +3488,16 @@ glusterd_add_bricks_to_snap_volume (dict_t *dict, dict_t *rsp_dict, * will help in mapping while recreating the missed snapshot */ gf_log (this->name, GF_LOG_WARNING, "Unable to fetch " - "snap mount path (%s). Using original brickinfo", key); + "snap mount path(%s). Adding to missed_snap_list", key); snap_brickinfo->snap_status = -1; - strcpy (snap_brick_path, original_brickinfo->path); + + *snap_brick_dir = original_brickinfo->mount_dir; /* In origiator node add snaps missed * from different nodes to the dict */ if (is_origin_glusterd (dict) == _gf_true) add_missed_snap = _gf_true; - } else { - /* Create brick-path in the format /var/run/gluster/snaps/ * - * //snap-brick-dir * - */ - snprintf (snap_brick_path, sizeof(snap_brick_path), - "%s/%s/brick%d%s", snap_mount_folder, - snap_vol->volname, brick_count+1, - *snap_brick_dir); } if ((snap_brickinfo->snap_status != -1) && @@ -3566,7 +3511,6 @@ glusterd_add_bricks_to_snap_volume (dict_t *dict, dict_t *rsp_dict, snap_vol->snapshot->snapname); snap_brickinfo->snap_status = -1; - strcpy (snap_brick_path, original_brickinfo->path); add_missed_snap = _gf_true; } @@ -3585,6 +3529,14 @@ glusterd_add_bricks_to_snap_volume (dict_t *dict, dict_t *rsp_dict, } } + /* Create brick-path in the format /var/run/gluster/snaps/ * + * //snap-brick-dir * + */ + snprintf (snap_brick_path, sizeof(snap_brick_path), + "%s/%s/brick%d%s", snap_mount_folder, + snap_vol->volname, brick_count+1, + *snap_brick_dir); + snprintf (key, sizeof(key), "vol%"PRId64".brick_snapdevice%d", volcount, brick_count); ret = dict_get_ptr (dict, key, (void **)&snap_device); @@ -3606,6 +3558,7 @@ glusterd_add_bricks_to_snap_volume (dict_t *dict, dict_t *rsp_dict, strcpy (snap_brickinfo->hostname, original_brickinfo->hostname); strcpy (snap_brickinfo->path, snap_brick_path); + strcpy (snap_brickinfo->mount_dir, original_brickinfo->mount_dir); uuid_copy (snap_brickinfo->uuid, original_brickinfo->uuid); /* AFR changelog names are based on brick_id and hence the snap * volume's bricks must retain the same ID */ diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index eda176d1b6b..5b1d80e84aa 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -294,6 +294,14 @@ glusterd_store_brickinfo_write (int fd, glusterd_brickinfo_t *brickinfo) goto out; } + if (strlen(brickinfo->mount_dir) > 0) { + snprintf (value, sizeof(value), "%s", brickinfo->mount_dir); + ret = gf_store_save_value (fd, + GLUSTERD_STORE_KEY_BRICK_MOUNT_DIR, value); + if (ret) + goto out; + } + snprintf (value, sizeof(value), "%d", brickinfo->snap_status); ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_BRICK_SNAP_STATUS, value); @@ -2073,6 +2081,10 @@ glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo) strlen (GLUSTERD_STORE_KEY_BRICK_DEVICE_PATH))) { strncpy (brickinfo->device_path, value, sizeof (brickinfo->device_path)); + } else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_MOUNT_DIR, + strlen (GLUSTERD_STORE_KEY_BRICK_MOUNT_DIR))) { + strncpy (brickinfo->mount_dir, value, + sizeof (brickinfo->mount_dir)); } else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_SNAP_STATUS, strlen (GLUSTERD_STORE_KEY_BRICK_SNAP_STATUS))) { gf_string2int (value, &brickinfo->snap_status); diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h index 7fc643ebe8d..01973bb7ae6 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.h +++ b/xlators/mgmt/glusterd/src/glusterd-store.h @@ -77,6 +77,7 @@ typedef enum glusterd_store_ver_ac_{ #define GLUSTERD_STORE_KEY_BRICK_DECOMMISSIONED "decommissioned" #define GLUSTERD_STORE_KEY_BRICK_VGNAME "vg" #define GLUSTERD_STORE_KEY_BRICK_DEVICE_PATH "device_path" +#define GLUSTERD_STORE_KEY_BRICK_MOUNT_DIR "mount_dir" #define GLUSTERD_STORE_KEY_BRICK_SNAP_STATUS "snap-status" #define GLUSTERD_STORE_KEY_BRICK_ID "brick-id" diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c index d385cf9eede..998af71b524 100644 --- a/xlators/mgmt/glusterd/src/glusterd-syncop.c +++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c @@ -271,9 +271,24 @@ extern struct rpc_clnt_program gd_mgmt_v3_prog; int glusterd_syncop_aggr_rsp_dict (glusterd_op_t op, dict_t *aggr, dict_t *rsp) { - int ret = 0; + int ret = 0; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); switch (op) { + case GD_OP_CREATE_VOLUME: + case GD_OP_ADD_BRICK: + case GD_OP_START_VOLUME: + ret = glusterd_aggr_brick_mount_dirs (aggr, rsp); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "aggregate brick mount dirs"); + goto out; + } + break; + case GD_OP_REPLACE_BRICK: ret = glusterd_rb_use_rsp_dict (aggr, rsp); if (ret) @@ -723,7 +738,9 @@ _gd_syncop_stage_op_cbk (struct rpc_req *req, struct iovec *iov, } uuid_copy (args->uuid, rsp.uuid); - if (rsp.op == GD_OP_REPLACE_BRICK || rsp.op == GD_OP_QUOTA) { + if (rsp.op == GD_OP_REPLACE_BRICK || rsp.op == GD_OP_QUOTA || + rsp.op == GD_OP_CREATE_VOLUME || rsp.op == GD_OP_ADD_BRICK || + rsp.op == GD_OP_START_VOLUME) { pthread_mutex_lock (&args->lock_dict); { ret = glusterd_syncop_aggr_rsp_dict (rsp.op, args->dict, @@ -1148,20 +1165,29 @@ gd_stage_op_phase (struct list_head *peers, glusterd_op_t op, dict_t *op_ctx, uuid_t tmp_uuid = {0}; char *errstr = NULL; struct syncargs args = {0}; + dict_t *aggr_dict = NULL; this = THIS; rsp_dict = dict_new (); if (!rsp_dict) goto out; + if ((op == GD_OP_CREATE_VOLUME) || (op == GD_OP_ADD_BRICK) || + (op == GD_OP_START_VOLUME)) + aggr_dict = req_dict; + else + aggr_dict = op_ctx; + ret = glusterd_op_stage_validate (op, req_dict, op_errstr, rsp_dict); if (ret) { hostname = "localhost"; goto stage_done; } - if ((op == GD_OP_REPLACE_BRICK || op == GD_OP_QUOTA)) { - ret = glusterd_syncop_aggr_rsp_dict (op, op_ctx, rsp_dict); + if ((op == GD_OP_REPLACE_BRICK || op == GD_OP_QUOTA || + op == GD_OP_CREATE_VOLUME || op == GD_OP_ADD_BRICK || + op == GD_OP_START_VOLUME)) { + ret = glusterd_syncop_aggr_rsp_dict (op, aggr_dict, rsp_dict); if (ret) { gf_log (this->name, GF_LOG_ERROR, "%s", "Failed to aggregate response from node/brick"); @@ -1186,7 +1212,7 @@ stage_done: goto out; } - gd_syncargs_init (&args, op_ctx); + gd_syncargs_init (&args, aggr_dict); synctask_barrier_init((&args)); peer_cnt = 0; list_for_each_entry (peerinfo, peers, op_peers_list) { @@ -1203,7 +1229,7 @@ stage_done: if (args.errstr) *op_errstr = gf_strdup (args.errstr); - else if (dict_get_str (op_ctx, "errstr", &errstr) == 0) + else if (dict_get_str (aggr_dict, "errstr", &errstr) == 0) *op_errstr = gf_strdup (errstr); ret = args.op_ret; diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index eb5cb33bb0e..d508e74f510 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -628,6 +628,7 @@ glusterd_brickinfo_dup (glusterd_brickinfo_t *brickinfo, } } strcpy (dup_brickinfo->brick_id, brickinfo->brick_id); + strcpy (dup_brickinfo->mount_dir, brickinfo->mount_dir); dup_brickinfo->status = brickinfo->status; dup_brickinfo->snap_status = brickinfo->snap_status; out: @@ -933,18 +934,72 @@ glusterd_resolve_brick (glusterd_brickinfo_t *brickinfo) return ret; } +int32_t +glusterd_get_brick_mount_dir (char *brickpath, char *hostname, char *mount_dir) +{ + char *mnt_pt = NULL; + char *brick_dir = NULL; + int32_t ret = -1; + uuid_t brick_uuid = {0, }; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); + GF_ASSERT (brickpath); + GF_ASSERT (hostname); + GF_ASSERT (mount_dir); + + ret = glusterd_hostname_to_uuid (hostname, brick_uuid); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to convert hostname %s to uuid", + hostname); + goto out; + } + + if (!uuid_compare (brick_uuid, MY_UUID)) { + ret = glusterd_get_brick_root (brickpath, &mnt_pt); + if (ret) { + gf_log (this->name, GF_LOG_WARNING, + "Could not get the root of the brick path %s", + brickpath); + goto out; + } + + if (strncmp (brickpath, mnt_pt, strlen(mnt_pt))) { + gf_log (this->name, GF_LOG_WARNING, + "brick: %s brick mount: %s", + brickpath, mnt_pt); + ret = -1; + goto out; + } + + brick_dir = &brickpath[strlen (mnt_pt)]; + brick_dir++; + + snprintf (mount_dir, PATH_MAX, "/%s", brick_dir); + } + +out: + gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret); + return ret; +} + int32_t glusterd_brickinfo_new_from_brick (char *brick, glusterd_brickinfo_t **brickinfo) { - int32_t ret = -1; - glusterd_brickinfo_t *new_brickinfo = NULL; - char *hostname = NULL; - char *path = NULL; - char *tmp_host = NULL; - char *tmp_path = NULL; - char *vg = NULL; + char *hostname = NULL; + char *path = NULL; + char *tmp_host = NULL; + char *tmp_path = NULL; + char *vg = NULL; + int32_t ret = -1; + glusterd_brickinfo_t *new_brickinfo = NULL; + xlator_t *this = NULL; + this = THIS; + GF_ASSERT (this); GF_ASSERT (brick); GF_ASSERT (brickinfo); @@ -987,7 +1042,8 @@ out: GF_FREE (tmp_host); if (tmp_host) GF_FREE (tmp_path); - gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret); + + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } @@ -2565,6 +2621,17 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo, goto out; } + snprintf (key, sizeof (key), "%s%d.brick%d.mount_dir", + prefix, count, i); + ret = dict_set_str (dict, key, brickinfo->mount_dir); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set mount_dir for %s:%s", + brickinfo->hostname, + brickinfo->path); + goto out; + } + i++; } @@ -3485,13 +3552,17 @@ glusterd_import_new_brick (dict_t *peer_data, int32_t vol_count, int ret = -1; int32_t snap_status = 0; char *snap_device = NULL; + char *mount_dir = NULL; char *hostname = NULL; char *path = NULL; char *brick_id = NULL; int decommissioned = 0; glusterd_brickinfo_t *new_brickinfo = NULL; char msg[2048] = {0}; + xlator_t *this = NULL; + this = THIS; + GF_ASSERT (this); GF_ASSERT (peer_data); GF_ASSERT (vol_count >= 0); GF_ASSERT (brickinfo); @@ -3545,6 +3616,14 @@ glusterd_import_new_brick (dict_t *peer_data, int32_t vol_count, goto out; } + snprintf (key, sizeof (key), "%s%d.brick%d.mount_dir", + prefix, vol_count, brick_count); + ret = dict_get_str (peer_data, key, &mount_dir); + if (ret) { + snprintf (msg, sizeof (msg), "%s missing in payload", key); + goto out; + } + ret = glusterd_brickinfo_new (&new_brickinfo); if (ret) goto out; @@ -3552,6 +3631,7 @@ glusterd_import_new_brick (dict_t *peer_data, int32_t vol_count, strcpy (new_brickinfo->path, path); strcpy (new_brickinfo->hostname, hostname); strcpy (new_brickinfo->device_path, snap_device); + strcpy (new_brickinfo->mount_dir, mount_dir); new_brickinfo->snap_status = snap_status; new_brickinfo->decommissioned = decommissioned; if (brick_id) @@ -9234,6 +9314,54 @@ glusterd_append_status_dicts (dict_t *dst, dict_t *src) } +int32_t +glusterd_aggr_brick_mount_dirs (dict_t *aggr, dict_t *rsp_dict) +{ + char key[PATH_MAX] = ""; + char *brick_mount_dir = NULL; + int32_t brick_count = -1; + int32_t ret = -1; + int32_t i = -1; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); + GF_ASSERT (aggr); + GF_ASSERT (rsp_dict); + + ret = dict_get_int32 (rsp_dict, "brick_count", &brick_count); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, "No brick_count present"); + ret = 0; + goto out; + } + + for (i = 1; i <= brick_count; i++) { + brick_mount_dir = NULL; + snprintf (key, sizeof(key), "brick%d.mount_dir", i); + ret = dict_get_str (rsp_dict, key, &brick_mount_dir); + if (ret) { + /* Coz the info will come from a different node */ + gf_log (this->name, GF_LOG_DEBUG, + "%s not present", key); + continue; + } + + ret = dict_set_dynstr_with_alloc (aggr, key, + brick_mount_dir); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set %s", key); + goto out; + } + } + + ret = 0; +out: + gf_log (this->name, GF_LOG_TRACE, "Returning %d ", ret); + return ret; +} + int32_t glusterd_gsync_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict, char *op_errstr) { @@ -9293,7 +9421,10 @@ glusterd_rb_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict) int32_t dst_port = 0; int ret = 0; dict_t *ctx = NULL; + xlator_t *this = NULL; + this = THIS; + GF_ASSERT (this); if (aggr) { ctx = aggr; @@ -9320,6 +9451,12 @@ glusterd_rb_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict) "dst-brick-port=%d found", dst_port); } + ret = glusterd_aggr_brick_mount_dirs (ctx, rsp_dict); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "aggregate brick mount dirs"); + goto out; + } } if (src_port) { diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index e4d41af64c0..2cf328f91ab 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -780,4 +780,11 @@ glusterd_copy_quota_files (glusterd_volinfo_t *src_vol, int glusterd_recursive_rmdir (const char *delete_path); + +int32_t +glusterd_get_brick_mount_dir (char *brickpath, char *hostname, char *mount_dir); + +int32_t +glusterd_aggr_brick_mount_dirs (dict_t *aggr, dict_t *rsp_dict); + #endif diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index 8d126c5cc1a..25b87b661e0 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -714,7 +714,8 @@ out: /* op-sm */ int -glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr) +glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr, + dict_t *rsp_dict) { int ret = 0; char *volname = NULL; @@ -722,8 +723,10 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr) char *bricks = NULL; char *brick_list = NULL; char *free_ptr = NULL; + char key[PATH_MAX] = ""; glusterd_brickinfo_t *brick_info = NULL; int32_t brick_count = 0; + int32_t local_brick_count = 0; int32_t i = 0; char *brick = NULL; char *tmpptr = NULL; @@ -738,6 +741,7 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr) GF_ASSERT (this); priv = this->private; GF_ASSERT (priv); + GF_ASSERT (rsp_dict); ret = dict_get_str (dict, "volname", &volname); if (ret) { @@ -844,11 +848,40 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr) is_force); if (ret) goto out; + + ret = glusterd_get_brick_mount_dir + (brick_info->path, + brick_info->hostname, + brick_info->mount_dir); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to get brick mount_dir"); + goto out; + } + + snprintf (key, sizeof(key), "brick%d.mount_dir", i); + ret = dict_set_dynstr_with_alloc + (rsp_dict, key, + brick_info->mount_dir); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set %s", key); + goto out; + } + local_brick_count = i; + brick_list = tmpptr; } glusterd_brickinfo_delete (brick_info); brick_info = NULL; } + + ret = dict_set_int32 (rsp_dict, "brick_count", local_brick_count); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set local_brick_count"); + goto out; + } out: GF_FREE (free_ptr); if (brick_info) @@ -922,11 +955,15 @@ out: } int -glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr) +glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr, + dict_t *rsp_dict) { int ret = 0; char *volname = NULL; + char key[PATH_MAX] = ""; int flags = 0; + int32_t brick_count = 0; + int32_t local_brick_count = 0; gf_boolean_t exists = _gf_false; glusterd_volinfo_t *volinfo = NULL; glusterd_brickinfo_t *brickinfo = NULL; @@ -942,6 +979,7 @@ glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr) GF_ASSERT (this); priv = this->private; GF_ASSERT (priv); + GF_ASSERT (rsp_dict); ret = glusterd_op_start_volume_args_get (dict, &volname, &flags); if (ret) @@ -976,6 +1014,7 @@ glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr) } list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + brick_count++; ret = glusterd_resolve_brick (brickinfo); if (ret) { gf_log (this->name, GF_LOG_ERROR, FMTSTR_RESOLVE_BRICK, @@ -983,7 +1022,8 @@ glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr) goto out; } - if (uuid_compare (brickinfo->uuid, MY_UUID)) + if ((uuid_compare (brickinfo->uuid, MY_UUID)) || + (brickinfo->snap_status == -1)) continue; ret = gf_lstat_dir (brickinfo->path, NULL); @@ -1030,6 +1070,30 @@ glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr) ret = -1; goto out; } + + if (strlen(brickinfo->mount_dir) < 1) { + ret = glusterd_get_brick_mount_dir + (brickinfo->path, + brickinfo->hostname, + brickinfo->mount_dir); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to get brick mount_dir"); + goto out; + } + + snprintf (key, sizeof(key), "brick%d.mount_dir", + brick_count); + ret = dict_set_dynstr_with_alloc + (rsp_dict, key, + brickinfo->mount_dir); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set %s", key); + goto out; + } + local_brick_count = brick_count; + } #ifdef HAVE_BD_XLATOR if (brickinfo->vg[0]) caps = CAPS_BD | CAPS_THIN | @@ -1047,6 +1111,13 @@ glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr) #endif } + ret = dict_set_int32 (rsp_dict, "brick_count", local_brick_count); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set local_brick_count"); + goto out; + } + volinfo->caps = caps; ret = 0; out: @@ -1507,6 +1578,8 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) int caps = 0; int brickid = 0; char msg[1024] __attribute__((unused)) = {0, }; + char *brick_mount_dir = NULL; + char key[PATH_MAX] = ""; this = THIS; GF_ASSERT (this); @@ -1689,6 +1762,17 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) goto out; } + brick_mount_dir = NULL; + snprintf (key, sizeof(key), "brick%d.mount_dir", i); + ret = dict_get_str (dict, key, &brick_mount_dir); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "%s not present", key); + goto out; + } + strncpy (brickinfo->mount_dir, brick_mount_dir, + sizeof(brickinfo->mount_dir)); + #ifdef HAVE_BD_XLATOR if (!uuid_compare (brickinfo->uuid, MY_UUID)) { if (brickinfo->vg[0]) { @@ -1792,11 +1876,15 @@ out: int glusterd_op_start_volume (dict_t *dict, char **op_errstr) { - int ret = 0; - char *volname = NULL; - int flags = 0; - glusterd_volinfo_t *volinfo = NULL; - xlator_t *this = NULL; + int ret = 0; + int32_t brick_count = 0; + char *brick_mount_dir = NULL; + char key[PATH_MAX] = ""; + char *volname = NULL; + int flags = 0; + glusterd_volinfo_t *volinfo = NULL; + glusterd_brickinfo_t *brickinfo = NULL; + xlator_t *this = NULL; this = THIS; GF_ASSERT (this); @@ -1812,8 +1900,24 @@ glusterd_op_start_volume (dict_t *dict, char **op_errstr) goto out; } - ret = glusterd_start_volume (volinfo, flags); + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + brick_count++; + if (strlen(brickinfo->mount_dir) < 1) { + brick_mount_dir = NULL; + snprintf (key, sizeof(key), "brick%d.mount_dir", + brick_count); + ret = dict_get_str (dict, key, &brick_mount_dir); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "%s not present", key); + goto out; + } + strncpy (brickinfo->mount_dir, brick_mount_dir, + sizeof(brickinfo->mount_dir)); + } + } + ret = glusterd_start_volume (volinfo, flags); if (ret) goto out; diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 2f63d07aac4..fc2ae12cbfa 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -191,6 +191,7 @@ struct glusterd_brickinfo { char hostname[1024]; char path[PATH_MAX]; char device_path[PATH_MAX]; + char mount_dir[PATH_MAX]; char brick_id[1024];/*Client xlator name, AFR changelog name*/ struct list_head brick_list; uuid_t uuid; @@ -903,8 +904,10 @@ int glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr, int glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict); int glusterd_op_log_rotate (dict_t *dict); int glusterd_op_stage_log_rotate (dict_t *dict, char **op_errstr); -int glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr); -int glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr); +int glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr, + dict_t *rsp_dict); +int glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr, + dict_t *rsp_dict); int glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr); int glusterd_op_stage_delete_volume (dict_t *dict, char **op_errstr); int glusterd_op_create_volume (dict_t *dict, char **op_errstr); @@ -914,7 +917,8 @@ int glusterd_op_delete_volume (dict_t *dict); int glusterd_op_add_brick (dict_t *dict, char **op_errstr); int glusterd_op_remove_brick (dict_t *dict, char **op_errstr); -int glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr); +int glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr, + dict_t *rsp_dict); int glusterd_op_stage_remove_brick (dict_t *dict, char **op_errstr); int glusterd_op_stage_rebalance (dict_t *dict, char **op_errstr); -- cgit