summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra Bhat <raghavendra@redhat.com>2013-10-24 18:55:27 +0530
committerRaghavendra Bhat <raghavendra@redhat.com>2013-10-29 18:27:04 +0530
commit07422ad21fd23db212f83777b1022350c5560876 (patch)
treee10ac187da02ef24b073f63a472909dcd00cd49c
parent5ce3051ca7bfb86e8ab1784c85d4064d5042c491 (diff)
mgmt/glusterd: changes to create consistency group out of volumes
* Also send the proper error back to cli incase of any failure * Before taking the snap check whether a snap with the requested name already exists. Change-Id: I0830b31b1f095dd1d3d968c4f8b3cf46dc32d259 Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com>
-rw-r--r--cli/src/cli-rpc-ops.c12
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c15
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-jarvis.c25
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c80
4 files changed, 105 insertions, 27 deletions
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index 58388344e..b50721df8 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -501,6 +501,9 @@ gf_cli_get_volume_cbk (struct rpc_req *req, struct iovec *iov,
char err_str[2048] = {0};
gf_cli_rsp rsp = {0};
int32_t backend = 0;
+ // snap_volume variable helps in showing whether a volume is a normal
+ //volume or a volume for the snapshot
+ int32_t snap_volume = 0;
if (-1 == req->rpc_status)
goto out;
@@ -622,6 +625,11 @@ xml_output:
if (ret)
goto out;
+ snprintf (key, sizeof (key), "volume%d.snap_volume", i);
+ ret = dict_get_int32 (dict, key, &snap_volume);
+ if (ret)
+ goto out;
+
snprintf (key, 256, "volume%d.brick_count", i);
ret = dict_get_int32 (dict, key, &brick_count);
if (ret)
@@ -665,6 +673,10 @@ xml_output:
cli_out ("Type: %s", cli_vol_type_str[vol_type]);
cli_out ("Volume ID: %s", volume_id_str);
cli_out ("Status: %s", cli_vol_status_str[status]);
+ if (snap_volume)
+ cli_out ("Snap Volume: %s", "yes");
+ else
+ cli_out ("Snap Volume: %s", "no");
if (backend)
goto next;
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index c56d16497..cacc6d562 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -363,6 +363,21 @@ glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,
if (ret)
goto out;
+ /* As of now, the snap volumes are also displayed as part of
+ volume info command. So this change is to display whether
+ the volume is original volume or the snap_volume. If
+ displaying of snap volumes in volume info o/p is not needed
+ this should be removed.
+ */
+ snprintf (key, 256, "volume%d.snap_volume", count);
+ ret = dict_set_int32 (volumes, key, volinfo->is_snap_volume);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "failed to set whether "
+ "the volume is a snap volume or actual volume (%s)",
+ volinfo->volname);
+ goto out;
+ }
+
snprintf (key, 256, "volume%d.brick_count", count);
ret = dict_set_int32 (volumes, key, volinfo->brick_count);
if (ret)
diff --git a/xlators/mgmt/glusterd/src/glusterd-jarvis.c b/xlators/mgmt/glusterd/src/glusterd-jarvis.c
index 40fb74c03..57512636d 100644
--- a/xlators/mgmt/glusterd/src/glusterd-jarvis.c
+++ b/xlators/mgmt/glusterd/src/glusterd-jarvis.c
@@ -1375,6 +1375,7 @@ glusterd_jarvis_initiate_snap_phases (rpcsvc_request_t *req, glusterd_op_t op,
gf_boolean_t is_acquired = _gf_false;
uuid_t *originator_uuid = NULL;
gf_boolean_t success = _gf_false;
+ char *tmp_errstr = NULL;
this = THIS;
GF_ASSERT (this);
@@ -1456,6 +1457,13 @@ glusterd_jarvis_initiate_snap_phases (rpcsvc_request_t *req, glusterd_op_t op,
&op_errstr, npeers);
if (ret) {
gf_log ("", GF_LOG_ERROR, "Commit Op Failed");
+ /* If the main op fails, we should save the error string.
+ Because, op_errstr will be used for unbarrier and
+ unlock ops also. We might lose the actual error that
+ caused the failure.
+ */
+ tmp_errstr = op_errstr;
+ op_errstr = NULL;
goto unbarrier;
}
@@ -1469,6 +1477,7 @@ unbarrier:
&op_errstr, npeers);
if (ret || (success == _gf_false)) {
gf_log ("", GF_LOG_ERROR, "Brick Ops Failed");
+ ret = -1;
goto out;
}
/* POST-COMMIT VALIDATE PHASE */
@@ -1486,6 +1495,22 @@ out:
(void) glusterd_jarvis_release_peer_locks (conf, op, dict, &op_errstr,
npeers, is_acquired);
+ /* If the commit op (snapshot taking) failed, then the error is stored
+ in tmp_errstr and unbarrier is called. Suppose, if unbarrier also
+ fails, then the error happened in unbarrier is logged and freed.
+ The error happened in commit op, which is stored in tmp_errstr
+ is sent to cli.
+ */
+ if (tmp_errstr) {
+ if (ret && op_errstr) {
+ gf_log (this->name, GF_LOG_ERROR, "unbarrier brick op"
+ "failed with the error %s", op_errstr);
+ GF_FREE (op_errstr);
+ op_errstr = NULL;
+ }
+ op_errstr = tmp_errstr;
+ }
+
/* SEND CLI RESPONSE */
glusterd_op_send_cli_response (op, ret, 0, req, dict, op_errstr);
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index f442085e3..6c365230b 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -490,7 +490,7 @@ glusterd_add_snap_cg (glusterd_conf_t *conf, glusterd_snap_cg_t *cg)
}
last = entry;
}
- list_add (&cg->cg_list, &last->cg_list);
+ list_add_tail (&cg->cg_list, &conf->snap_cg);
gf_log (THIS->name, GF_LOG_DEBUG, "Added CG %s (%s) @ %"PRIu64,
cg->cg_name, uuid_utoa(cg->cg_id), count);
ret = 0;
@@ -1927,8 +1927,8 @@ glusterd_snap_brick_create (char *device, glusterd_volinfo_t *snap_volinfo,
if (tmp[0] == '-')
tmp[0] = '/';
- snprintf (snap_brick_mount_path, sizeof (snap_brick_mount_path), "%s"
- "/%s%s-brick", GLUSTERD_DEFAULT_SNAPS_BRICK_DIR,
+ snprintf (snap_brick_mount_path, sizeof (snap_brick_mount_path),
+ "%s/%s%s-brick", GLUSTERD_DEFAULT_SNAPS_BRICK_DIR,
snap_volinfo->volname, tmp);
ret = glusterd_get_brick_root (original_brickinfo->path, &mnt_pt);
@@ -2012,18 +2012,29 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *name, dict_t *dict,
priv = this->private;
GF_ASSERT (priv);
- strcpy (snapname, name);
if (cg) {
- snprintf (tmp, sizeof (tmp), "%s-snap", volinfo->volname);
- strcat (snapname, tmp);
+ snprintf (tmp, sizeof (tmp), "%s_snap", volinfo->volname);
+ snprintf (snapname, sizeof (snapname), "%s_%s", name, tmp);
+ } else {
+ snprintf (snapname, sizeof (snapname), "%s", name);
}
ret = glusterd_volinfo_dup (volinfo, &snap_volume);
strcpy (snap_volume->volname, snapname);
+ snap_volume->is_snap_volume = _gf_true;
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (!glusterd_is_brick_started (brickinfo))
+ if (uuid_compare (brickinfo->uuid, MY_UUID)) {
continue;
+ }
+
+ if (!glusterd_is_brick_started (brickinfo)) {
+ gf_log (this->name, GF_LOG_WARNING, "brick %s:%s is not"
+ " started (volume: %s snap: %s)",
+ brickinfo->hostname, brickinfo->path,
+ volinfo->volname, snapname);
+ continue;
+ }
ret = glusterd_take_snapshot (brickinfo,
volinfo->volname,
@@ -2113,6 +2124,7 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *name, dict_t *dict,
}
}
+ snap_volume->status = GLUSTERD_STATUS_STARTED;
out:
if (ret)
glusterd_volinfo_delete (snap_volume);
@@ -2254,19 +2266,23 @@ int32_t
glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
dict_t *rsp_dict)
{
- char *name = NULL;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int64_t volume_count = 0;
- char volname_buf[PATH_MAX] = {0, };
- int i = 0;
- xlator_t *this = NULL;
- int ret = -1;
- glusterd_snap_cg_t *cg = NULL;
- gf_boolean_t is_cg = _gf_false;
- uuid_t cg_id;
- glusterd_conf_t *priv = NULL;
- char *tmp = NULL;
+ int ret = -1;
+ int i = 0;
+ int64_t volume_count = 0;
+ gf_boolean_t is_cg = _gf_false;
+ char *name = NULL;
+ char *volname = NULL;
+ char *tmp = NULL;
+ char volname_buf[PATH_MAX] = {0, };
+ xlator_t *this = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_snap_cg_t *cg = NULL;
+ glusterd_conf_t *priv = NULL;
+ uuid_t cg_id;
+ glusterd_snap_t *snap = NULL;
+ char err_str[PATH_MAX] = {0, };
+
+ this = THIS;
ret = dict_get_int64 (dict, "volcount", &volume_count);
if (ret) {
@@ -2327,20 +2343,30 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
goto out;
}
+ list_for_each_entry (snap, &volinfo->snaps, snap_list) {
+ if (!strcmp (snap->snap_name, tmp)) {
+ snprintf (err_str, sizeof (err_str), "snap "
+ "with name %s already exists", tmp);
+ gf_log (this->name, GF_LOG_ERROR, "%s",
+ err_str);
+ ret = -1;
+ *op_errstr = gf_strdup (err_str);
+ goto out;
+ }
+ }
+
/* TODO: Create a stub where the bricks are
added parallely by worker threads so that
the snap creating happens parallely.
*/
- ret = glusterd_do_snap (volinfo, tmp, dict,
- is_cg, cg_id);
+ ret = glusterd_do_snap (volinfo, tmp, dict, is_cg, cg_id);
if (ret) {
gf_log (this->name, GF_LOG_WARNING, "taking the "
- "snapshot of the volume %s failed",
- volname);
+ "snapshot of the volume %s failed", volname);
goto out;
}
-
}
+
if (volume_count > 1) {
cg = glusterd_new_snap_cg_object (volume_count);
if (!cg) {
@@ -2350,13 +2376,13 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
}
uuid_copy (cg->cg_id, cg_id);
+ strncpy (cg->cg_name, name, sizeof (cg->cg_name));
ret = glusterd_add_snap_cg (priv, cg);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "could not add the"
" consistency group %s to the glusterd list ",
name);
- cg = glusterd_remove_snap_cg_by_name (priv,
- name);
+ cg = glusterd_remove_snap_cg_by_name (priv, name);
if (!cg)
gf_log (this->name, GF_LOG_WARNING, "cannot "
"find the consistency group %s", name);