diff options
author | Sachin Pandit <spandit@redhat.com> | 2014-06-23 09:35:52 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2014-09-23 02:01:04 -0700 |
commit | c5aa277ec26cd7cf4109bc8854af50a254edbbd9 (patch) | |
tree | ecb9237e41389075052c5c36ca2f2c958e1092c8 /xlators/mgmt | |
parent | cde7cf45c49a59a688788abc0358c482e30f4018 (diff) |
feature/snapshot : Interface to delete all snapshots belonging to a system as-well-as to a particular volume
Problem :
With the current design we can only delete a single snapshot.
And the deletion of volume which contains snapshot is not allowed.
Because of that user might be forced to delete all the snapshots
manually before he is allowed to delete a volume.
Solution:
Following is the interface with which user can delete
all the snapshots of a system or belonging to a particular volume.
Syntax : gluster snapshot delete all
*To delete all the snapshots present in a system
Syntax : gluster snapshot delete volume <volname>
*To deletes all the snapshot present in a volume specified.
========================================================================
Sample Output:
Case 1 : Deleting a single snapshot.
[root@snapshot-24 glusterfs]# gluster snapshot delete snap1
Deleting snap will erase all the information about the snap. Do you still want to continue? (y/n) y
snapshot delete: snap1: snap removed successfully
-----------------------------------------------------------------
Case 2 : Deleting all the snapshots in a Volume.
[root@snapshot-24 glusterfs]# gluster snapshot delete volume vol1
Volume (vol1) contains 9 snapshot(s).
Do you still want to continue and delete them? (y/n) y
snapshot delete: snap2: snap removed successfully
snapshot delete: snap3: snap removed successfully
snapshot delete: snap4: snap removed successfully
snapshot delete: snap5: snap removed successfully
.
.
.
-----------------------------------------------------------------
Case 3 : Deleting all the snapshots in a system.
[root@snapshot-24 glusterfs]# gluster snapshot delete all
System contains 4 snapshot(s).
Do you still want to continue and delete them? (y/n) y
snapshot delete: snap7: snap removed successfully
snapshot delete: snap8: snap removed successfully
snapshot delete: snap9: snap removed successfully
snapshot delete: snap10: snap removed successfully
========================================================================
Change-Id: Ifec8e128ab2011cbbba208376b9c92cfbe7d8d71
BUG: 1145083
Signed-off-by: Sachin Pandit <spandit@redhat.com>
Reviewed-on: http://review.gluster.org/8162
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Avra Sengupta <asengupt@redhat.com>
Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com>
Reviewed-by: Kaushal M <kaushal@redhat.com>
Signed-off-by: Sachin Pandit <spandit@redhat.com>
Reviewed-on: http://review.gluster.org/8798
Reviewed-by: Vijaikumar Mallikarjuna <vmallika@redhat.com>
Diffstat (limited to 'xlators/mgmt')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-snapshot.c | 211 |
1 files changed, 186 insertions, 25 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c index f32b3140612..ae91f67fd2d 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c @@ -3123,15 +3123,10 @@ glusterd_snapshot_get_vol_snapnames (dict_t *dict, glusterd_volinfo_t *volinfo) list_for_each_entry_safe (snap_vol, tmp_vol, &volinfo->snap_volumes, snapvol_list) { snapcount++; - snapname = gf_strdup (snap_vol->snapshot->snapname); - if (!snapname) { - gf_log (this->name, GF_LOG_ERROR, - "strdup failed"); - ret = -1; - goto out; - } snprintf (key, sizeof (key), "snapname%d", snapcount); - ret = dict_set_dynstr (dict, key, snapname); + + ret = dict_set_dynstr_with_alloc (dict, key, + snap_vol->snapshot->snapname); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to " "set %s", key); @@ -4472,23 +4467,104 @@ out: return ret; } -/* This is a snapshot remove handler function. This function will be - * executed in the originator node. This function is responsible for - * calling mgmt v3 framework to do the actual remove on all the bricks - * - * @param req RPC request object - * @param op gluster operation - * @param dict dictionary containing snapshot remove request - * @param err_str In case of an err this string should be populated - * @param len length of err_str buffer - * - * @return Negative value on Failure and 0 in success - */ -int -glusterd_handle_snapshot_remove (rpcsvc_request_t *req, glusterd_op_t op, - dict_t *dict, char *err_str, size_t len) +int32_t +glusterd_handle_snapshot_delete_vol (dict_t *dict, char *err_str, int len) { - int ret = -1; + int32_t ret = -1; + int32_t i = 0; + glusterd_volinfo_t *snap_volinfo = NULL; + glusterd_volinfo_t *volinfo = NULL; + glusterd_volinfo_t *temp_volinfo = NULL; + char key[PATH_MAX] = ""; + xlator_t *this = NULL; + char *volname = NULL; + + this = THIS; + GF_ASSERT (this); + GF_ASSERT (dict); + + ret = dict_get_str (dict, "volname", &volname); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "volume name"); + goto out; + } + + ret = glusterd_volinfo_find (volname, &volinfo); + if (ret) { + snprintf (err_str, len, "Volume (%s) does not exist", volname); + gf_log (this->name, GF_LOG_ERROR, "Failed to get volinfo of " + "volume %s", volname); + goto out; + } + + ret = glusterd_snapshot_get_vol_snapnames (dict, volinfo); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to get snapshot list for volume %s", volname); + goto out; + } + + ret = 0; +out: + return ret; +} + +int32_t +glusterd_handle_snapshot_delete_all (dict_t *dict) +{ + int32_t ret = -1; + int32_t i = 0; + char key[PATH_MAX] = ""; + glusterd_conf_t *priv = NULL; + glusterd_snap_t *snap = NULL; + glusterd_snap_t *tmp_snap = NULL; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); + priv = this->private; + GF_ASSERT (priv); + + GF_ASSERT (dict); + + list_for_each_entry_safe (snap, tmp_snap, &priv->snapshots, snap_list) { + /* indexing from 1 to n, to keep it uniform with other code + * paths + */ + i++; + ret = snprintf (key, sizeof (key), "snapname%d", i); + if (ret < 0) { + goto out; + } + + ret = dict_set_dynstr_with_alloc (dict, key, snap->snapname); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Could not save " + "snap name"); + goto out; + } + } + + ret = dict_set_int32 (dict, "snapcount", i); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Could not save snapcount"); + goto out; + } + + ret = 0; + +out: + return ret; +} + +int32_t +glusterd_handle_snapshot_delete_type_snap (rpcsvc_request_t *req, + glusterd_op_t op, + dict_t *dict, char *err_str, + size_t len) +{ + int32_t ret = -1; int64_t volcount = 0; char *snapname = NULL; char *volname = NULL; @@ -4499,6 +4575,7 @@ glusterd_handle_snapshot_remove (rpcsvc_request_t *req, glusterd_op_t op, xlator_t *this = NULL; this = THIS; + GF_ASSERT (this); GF_ASSERT (req); GF_ASSERT (dict); @@ -4553,6 +4630,90 @@ glusterd_handle_snapshot_remove (rpcsvc_request_t *req, glusterd_op_t op, } ret = 0; + +out : + return ret; +} + +/* This is a snapshot remove handler function. This function will be + * executed in the originator node. This function is responsible for + * calling mgmt v3 framework to do the actual remove on all the bricks + * + * @param req RPC request object + * @param op gluster operation + * @param dict dictionary containing snapshot remove request + * @param err_str In case of an err this string should be populated + * @param len length of err_str buffer + * + * @return Negative value on Failure and 0 in success + */ +int +glusterd_handle_snapshot_delete (rpcsvc_request_t *req, glusterd_op_t op, + dict_t *dict, char *err_str, size_t len) +{ + int ret = -1; + xlator_t *this = NULL; + int32_t delete_cmd = -1; + + this = THIS; + + GF_ASSERT (this); + + GF_ASSERT (req); + GF_ASSERT (dict); + GF_ASSERT (err_str); + + ret = dict_get_int32 (dict, "delete-cmd", &delete_cmd); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get delete-cmd"); + goto out; + } + + switch (delete_cmd) { + case GF_SNAP_DELETE_TYPE_SNAP: + ret = glusterd_handle_snapshot_delete_type_snap (req, op, dict, + err_str, len); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to handle " + "snapshot delete for type SNAP"); + goto out; + } + break; + + case GF_SNAP_DELETE_TYPE_ALL: + ret = glusterd_handle_snapshot_delete_all (dict); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to handle " + "snapshot delete for type ALL"); + goto out; + } + break; + + case GF_SNAP_DELETE_TYPE_VOL: + ret = glusterd_handle_snapshot_delete_vol (dict, err_str, len); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to handle " + "snapshot delete for type VOL"); + goto out; + } + break; + + default: + gf_log (this->name, GF_LOG_ERROR, "Wrong snapshot delete type"); + break; + } + + if ( ret == 0 && (delete_cmd == GF_SNAP_DELETE_TYPE_ALL || + delete_cmd == GF_SNAP_DELETE_TYPE_VOL)) { + ret = glusterd_op_send_cli_response (op, 0, 0, req, dict, + err_str); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to send cli " + "response"); + goto out; + } + } + ret = 0; out: return ret; } @@ -7347,7 +7508,7 @@ glusterd_handle_snapshot_fn (rpcsvc_request_t *req) } break; case GF_SNAP_OPTION_TYPE_DELETE: - ret = glusterd_handle_snapshot_remove (req, cli_op, dict, + ret = glusterd_handle_snapshot_delete (req, cli_op, dict, err_str, sizeof (err_str)); if (ret) { |