diff options
author | Raghavendra Bhat <raghavendra@redhat.com> | 2013-10-24 18:55:27 +0530 |
---|---|---|
committer | Raghavendra Bhat <raghavendra@redhat.com> | 2013-10-29 18:27:04 +0530 |
commit | 07422ad21fd23db212f83777b1022350c5560876 (patch) | |
tree | e10ac187da02ef24b073f63a472909dcd00cd49c | |
parent | 5ce3051ca7bfb86e8ab1784c85d4064d5042c491 (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.c | 12 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 15 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-jarvis.c | 25 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-snapshot.c | 80 |
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); |