summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVijaikumar M <vmallika@redhat.com>2014-02-20 17:12:29 +0530
committerRajesh Joseph <rjoseph@redhat.com>2014-03-06 01:36:13 -0800
commit1aea4bdc774950f2d313bc541aaccf6d313aac88 (patch)
tree7171287b7d878f8a42223a462f7d68f7740af870
parent40497ba922667abbc20dda635cb0ef0abe5f51eb (diff)
glusterd/snapshot: snapshot list and info changes
This changes includes snap-driven based list and info changes: Change-Id: Ie82a2a3c785baa36892ca0cd97a958a2ae819d4c Signed-off-by: Vijaikumar M <vmallika@redhat.com> Signed-off-by: Sachin Pandit <spandit@redhat.com> Reviewed-on: http://review.gluster.org/7139 Reviewed-by: Avra Sengupta <asengupt@redhat.com> Reviewed-by: Rajesh Joseph <rjoseph@redhat.com> Tested-by: Rajesh Joseph <rjoseph@redhat.com>
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c1199
1 files changed, 423 insertions, 776 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index e59aaa9..7bfede0 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -1339,43 +1339,165 @@ out:
return ret_1;
}
-/* This function will retrieve the details of a single snap
- * and then serialize them to dictionary (dict)
- * This function is called under snap lock
- *
- * @param dict dictionary where response should be serialized
- * @param keyprefix Prefix used for all the keys for rspdict dictionary
- * @param entry Snap object
- * @param detail if 1 then more details will be added for snap list
- *
- * @return -1 on failure and 0 on success.
- */
static int
-glusterd_snapshot_get_snapdetail_lk (dict_t *dict, char *keyprefix,
- glusterd_snap_t *entry,
- int8_t detail)
+glusterd_snapshot_get_snapvol_detail (dict_t *dict,
+ glusterd_volinfo_t *snap_vol,
+ char *keyprefix, int detail)
{
- int ret = -1; /* Failure */
- const int maxstrlen = 256;
- char *value = NULL;
- char *timestr = NULL;
- struct tm *tmptr = NULL;
- xlator_t *this = NULL;
- char key[maxstrlen];
+ int ret = -1;
+ int snap_limit = 0;
+ char key[PATH_MAX] = {0,};
+ char *value = NULL;
+ glusterd_volinfo_t *origin_vol = NULL;
+ glusterd_conf_t *conf = NULL;
+ xlator_t *this = NULL;
this = THIS;
+ conf = this->private;
+ GF_ASSERT (conf);
- /* General parameter validation */
- GF_ASSERT (this);
GF_ASSERT (dict);
+ GF_ASSERT (snap_vol);
GF_ASSERT (keyprefix);
- GF_ASSERT (entry);
- /* Snap Name */
- value = gf_strdup (entry->snapname);
+ /* Volume Name */
+ value = gf_strdup (snap_vol->volname);
+ if (!value)
+ goto out;
+
+ snprintf (key, sizeof (key), "%s.volname", keyprefix);
+ ret = dict_set_dynstr (dict, key, value);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set "
+ "volume name in dictionary: %s", key);
+ goto out;
+ }
+
+ /* Volume ID */
+ value = gf_strdup (uuid_utoa (snap_vol->volume_id));
if (NULL == value) {
+ ret = -1;
+ goto out;
+ }
+
+ snprintf (key, sizeof (key), "%s.vol-id", keyprefix);
+ ret = dict_set_dynstr (dict, key, value);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set "
+ "volume id in dictionary: %s", key);
+ goto out;
+ }
+
+ /* Ownership of value transferred to dict. Therefore we must initalize
+ * it to NULL */
+ value = NULL;
+
+ /* volume status */
+ snprintf (key, sizeof (key), "%s.vol-status", keyprefix);
+ switch (snap_vol->status) {
+ case GLUSTERD_STATUS_STARTED:
+ ret = dict_set_str (dict, key, "Started");
+ break;
+ case GLUSTERD_STATUS_STOPPED:
+ ret = dict_set_str (dict, key, "Stopped");
+ break;
+ case GD_SNAP_STATUS_NONE:
+ ret = dict_set_str (dict, key, "None");
+ break;
+ default:
+ gf_log (this->name, GF_LOG_ERROR, "Invalid volume "
+ "status");
+ ret = -1;
+ goto out;
+ }
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set volume status "
+ "in dictionary: %s", key);
+ goto out;
+ }
+
+ if (!detail)
+ goto out;
+
+ ret = glusterd_volinfo_find (snap_vol->parent_volname, &origin_vol);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to get the parent "
+ "volinfo for the volume %s", snap_vol->volname);
+ goto out;
+ }
+
+ /* Snaps available */
+ if (conf->snap_max_hard_limit < origin_vol->snap_max_hard_limit) {
+ snap_limit = conf->snap_max_hard_limit;
+ gf_log(this->name, GF_LOG_DEBUG, "system snap-max-hard-limit is"
+ " lesser than volume snap-max-hard-limit, "
+ "snap-max-hard-limit value is set to %d", snap_limit);
+ }
+ else {
+ snap_limit = origin_vol->snap_max_hard_limit ;
+ gf_log(this->name, GF_LOG_DEBUG, "volume snap-max-hard-limit is"
+ " lesser than system snap-max-hard-limit, "
+ "snap-max-hard-limit value is set to %d",snap_limit);
+ }
+
+ snprintf (key, sizeof (key), "%s.snaps-available", keyprefix);
+ if (snap_limit > origin_vol->snap_count)
+ ret = dict_set_int32 (dict, key,
+ snap_limit - origin_vol->snap_count);
+ else
+ ret = dict_set_int32 (dict, key, 0);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to set available snaps");
+ goto out;
+ }
+
+ /* Parent volume name */
+ value = gf_strdup (snap_vol->parent_volname);
+ if (!value)
+ goto out;
+
+ snprintf (key, sizeof (key), "%s.origin-volname", keyprefix);
+ ret = dict_set_dynstr (dict, key, value);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set parent "
+ "volume name in dictionary: %s", key);
goto out;
}
+ value = NULL;
+
+ ret = 0; /* Success */
+out:
+ if (value)
+ GF_FREE (value);
+
+ return ret;
+}
+
+static int
+glusterd_snapshot_get_snap_detail (dict_t *dict, glusterd_snap_t *snap,
+ char *keyprefix, glusterd_volinfo_t *volinfo)
+{
+ int ret = -1;
+ int volcount = 0;
+ char key[PATH_MAX] = {0,};
+ char *value = NULL;
+ char *timestr = NULL;
+ struct tm *tmptr = NULL;
+ glusterd_volinfo_t *snap_vol = NULL;
+ glusterd_volinfo_t *tmp_vol = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ GF_ASSERT (dict);
+ GF_ASSERT (snap);
+ GF_ASSERT (keyprefix);
+
+ /* Snap Name */
+ value = gf_strdup (snap->snapname);
+ if (!value)
+ goto out;
snprintf (key, sizeof (key), "%s.snapname", keyprefix);
ret = dict_set_dynstr (dict, key, value);
@@ -1386,17 +1508,13 @@ glusterd_snapshot_get_snapdetail_lk (dict_t *dict, char *keyprefix,
}
/* Snap ID */
- value = gf_strdup (uuid_utoa (entry->snap_id));
+ value = gf_strdup (uuid_utoa (snap->snap_id));
if (NULL == value) {
ret = -1;
goto out;
}
- ret = snprintf (key, sizeof (key), "%s.snap-id", keyprefix);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
-
+ snprintf (key, sizeof (key), "%s.snap-id", keyprefix);
ret = dict_set_dynstr (dict, key, value);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "Failed to set "
@@ -1409,9 +1527,8 @@ glusterd_snapshot_get_snapdetail_lk (dict_t *dict, char *keyprefix,
value = NULL;
/* Snap Timestamp */
-
/* convert time_t to tm struct. */
- tmptr = localtime (&(entry->time_stamp));
+ tmptr = localtime (&(snap->time_stamp));
if (NULL == tmptr) {
gf_log (this->name, GF_LOG_ERROR, "Failed to convert "
"time_t to *tm");
@@ -1419,14 +1536,14 @@ glusterd_snapshot_get_snapdetail_lk (dict_t *dict, char *keyprefix,
goto out;
}
- timestr = GF_CALLOC (1, maxstrlen, gf_gld_mt_char);
+ timestr = GF_CALLOC (1, PATH_MAX, gf_gld_mt_char);
if (NULL == timestr) {
ret = -1;
goto out;
}
/* Format time into string */
- ret = strftime (timestr, maxstrlen, "%Y-%m-%d %H:%M:%S", tmptr);
+ ret = strftime (timestr, PATH_MAX, "%Y-%m-%d %H:%M:%S", tmptr);
if (0 == ret) {
gf_log (this->name, GF_LOG_ERROR, "Failed to convert time_t "
"to string");
@@ -1434,11 +1551,7 @@ glusterd_snapshot_get_snapdetail_lk (dict_t *dict, char *keyprefix,
goto out;
}
- ret = snprintf (key, sizeof (key), "%s.snap-time", keyprefix);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
-
+ snprintf (key, sizeof (key), "%s.snap-time", keyprefix);
ret = dict_set_dynstr (dict, key, timestr);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "Failed to set "
@@ -1450,90 +1563,27 @@ glusterd_snapshot_get_snapdetail_lk (dict_t *dict, char *keyprefix,
* it to NULL */
timestr = NULL;
- if (!detail) {
- /* If detail is not needed then return from here */
- goto out;
- }
-
- /* Add detail */
-
- /* If CG name is set the add the details in the dictionary */
- if (0 != entry->cg_name[0] ) {
- /* CG name */
- value = gf_strdup (entry->cg_name);
- if (NULL == value) {
- ret = -1;
- goto out;
- }
-
- ret = snprintf (key, sizeof (key), "%s.cg-name", keyprefix);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
-
- ret = dict_set_dynstr (dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "snap name in dictionary");
- goto out;
- }
-
- /* CG ID */
- value = gf_strdup (uuid_utoa (entry->cg_id));
- if (NULL == value) {
- ret = -1;
- goto out;
- }
-
- ret = snprintf (key, sizeof (key), "%s.cg-id", keyprefix);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
-
- ret = dict_set_dynstr (dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "cg id in dictionary");
- goto out;
- }
-
- /* Ownership of value transferred to dict. Therefore we must initalize
- * it to NULL */
- value = NULL;
- }
-
/* If snap description is provided then add that into dictionary */
- if (NULL != entry->description) {
- /* Snap Description */
- value = gf_strdup (entry->description);
+ if (NULL != snap->description) {
+ value = gf_strdup (snap->description);
if (NULL == value) {
ret = -1;
goto out;
}
- ret = snprintf (key, sizeof (key), "%s.snap-desc", keyprefix);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
-
+ snprintf (key, sizeof (key), "%s.snap-desc", keyprefix);
ret = dict_set_dynstr (dict, key, value);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "Failed to set "
"snap description in dictionary");
goto out;
}
- /* Ownership of value transferred to dict. Therefore we must initalize
- * it to NULL */
value = NULL;
}
/* Snap status */
- ret = snprintf (key, sizeof (key), "%s.snap-status", keyprefix);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
-
- switch (entry->snap_status) {
+ snprintf (key, sizeof (key), "%s.snap-status", keyprefix);
+ switch (snap->snap_status) {
case GD_SNAP_STATUS_INIT:
ret = dict_set_str (dict, key, "Init");
break;
@@ -1555,838 +1605,429 @@ glusterd_snapshot_get_snapdetail_lk (dict_t *dict, char *keyprefix,
ret = -1;
goto out;
}
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set snap status "
+ "in dictionary");
+ goto out;
+ }
+
+ if (volinfo) {
+ volcount = 1;
+ snprintf (key, sizeof (key), "%s.vol%d", keyprefix, volcount);
+ ret = glusterd_snapshot_get_snapvol_detail (dict,
+ volinfo, key, 0);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to "
+ "get volume detail %s for snap %s",
+ snap_vol->volname, snap->snapname);
+ goto out;
+ }
+ goto done;
+ }
+
+ list_for_each_entry_safe (snap_vol, tmp_vol, &snap->volumes, vol_list) {
+ volcount++;
+ snprintf (key, sizeof (key), "%s.vol%d", keyprefix, volcount);
+ ret = glusterd_snapshot_get_snapvol_detail (dict,
+ snap_vol, key, 1);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to "
+ "get volume detail %s for snap %s",
+ snap_vol->volname, snap->snapname);
+ goto out;
+ }
+ }
+done:
+ snprintf (key, sizeof (key), "%s.vol-count", keyprefix);
+ ret = dict_set_int32 (dict, key, volcount);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "snap status in dictionary");
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set %s",
+ key);
goto out;
}
ret = 0; /* Success */
out:
- if (NULL != value) {
+ if (value)
GF_FREE (value);
- }
- if (NULL != timestr) {
+ if (timestr)
GF_FREE(timestr);
- }
+
return ret;
}
-/* This function will retrieve the details of a single snap
- * and then serialize them to dictionary (dict)
- *
- * @param dict dictionary where response should be serialized
- * @param keyprefix Prefix used for all the keys for rspdict dictionary
- * @param entry Snap object
- * @param detail if 1 then more details will be added for snap list
- *
- * @return -1 on failure and 0 on success.
- */
static int
-glusterd_snapshot_get_snapdetail (dict_t *dict, char *keyprefix,
- glusterd_snap_t *entry,
- int8_t detail)
+glusterd_snapshot_get_all_snap_info (dict_t *dict)
{
- int ret = -1;
- xlator_t *this = NULL;
+ int ret = -1;
+ int snapcount = 0;
+ char key[PATH_MAX] = {0,};
+ glusterd_snap_t *snap = NULL;
+ glusterd_snap_t *tmp_snap = NULL;
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
this = THIS;
- GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
/* General parameter validation */
- GF_ASSERT (this);
GF_ASSERT (dict);
- GF_ASSERT (keyprefix);
- GF_ASSERT (entry);
- /* Acquire snap lock */
- LOCK (&(entry->lock));
- {
- ret = glusterd_snapshot_get_snapdetail_lk (dict, keyprefix,
- entry, detail);
+ list_for_each_entry_safe (snap, tmp_snap, &priv->snapshots, snap_list) {
+ snapcount++;
+ snprintf (key, sizeof (key), "snap%d", snapcount);
+ ret = glusterd_snapshot_get_snap_detail (dict, snap, key, NULL);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to get "
+ "snapdetail for snap %s", snap->snapname);
+ goto out;
+ }
}
- UNLOCK (&(entry->lock));
+ ret = dict_set_int32 (dict, "snap-count", snapcount);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get snap detail");
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set snapcount");
+ goto out;
}
+ ret = 0; /* Success */
+out:
return ret;
}
-
-/* This function will retrieve snap list for the given volume
- * and then serialize them to dict.
- * This function is called under volinfo lock.
- *
- * @param dict dictionary where response should be serialized
- * @param keyprefix Prefix used for all the keys for rspdict dictionary
- * @param volinfo Volinfo object of the volume
- * @param snapname snap name. This field can be NULL
- * @param detail if 1 then more details will be added for snap list
- *
- * @return -1 on failure and 0 on success.
- */
-static int
-glusterd_snapshot_vol_get_snaplist_lk (dict_t *dict, char *keyprefix,
- glusterd_volinfo_t *volinfo,
- char *snapname, int8_t detail)
+int
+glusterd_snapshot_get_info_by_volume (dict_t *dict, char *volname)
{
- int ret = -1;
- uint64_t index = 0;
- glusterd_snap_t *entry = NULL;
- glusterd_snap_t *tmp = NULL;
- xlator_t *this = NULL;
- char *value = NULL;
- char key[256];
- glusterd_conf_t *conf = NULL;
- uint64_t snap_limit = 0;
- char err_str[PATH_MAX];
+ int ret = -1;
+ int snapcount = 0;
+ int snap_limit = 0;
+ char *value = NULL;
+ char key[PATH_MAX] = "";
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_volinfo_t *snap_vol = NULL;
+ glusterd_volinfo_t *tmp_vol = NULL;
+ glusterd_conf_t *conf = NULL;
+ xlator_t *this = NULL;
this = THIS;
-
- /* General parameter validation */
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (keyprefix);
- GF_ASSERT (volinfo);
-
conf = this->private;
GF_ASSERT (conf);
- value = gf_strdup (volinfo->volname);
- if (NULL == value) {
- goto out;
- }
-
- /* First set the volume name */
- ret = snprintf (key, sizeof (key), "%s.volname", keyprefix);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
-
- ret = dict_set_dynstr (dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set volume name");
- goto out;
- }
-
- ret = snprintf (key, sizeof (key), "%s.snap-count-total", keyprefix);
- if (ret < 0) {
- goto out;
- }
+ GF_ASSERT (dict);
+ GF_ASSERT (volname);
- ret = dict_set_int64 (dict, key, volinfo->snap_count);
+ ret = glusterd_volinfo_find (volname, &volinfo);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set total"
- " snap count");
- goto out;
- }
- ret = snprintf (key, sizeof (key), "%s.snap-available", keyprefix);
- if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to get the volinfo "
+ "for the volume %s", volname);
goto out;
}
+ /* Snaps available */
if (conf->snap_max_hard_limit < volinfo->snap_max_hard_limit) {
snap_limit = conf->snap_max_hard_limit;
gf_log(this->name, GF_LOG_DEBUG, "system snap-max-hard-limit is"
" lesser than volume snap-max-hard-limit, "
- "snap-max-hard-limit value is set to %ld", snap_limit);
+ "snap-max-hard-limit value is set to %d", snap_limit);
}
else {
snap_limit = volinfo->snap_max_hard_limit ;
gf_log(this->name, GF_LOG_DEBUG, "volume snap-max-hard-limit is"
" lesser than system snap-max-hard-limit, "
- "snap-max-hard-limit value is set to %ld",snap_limit);
+ "snap-max-hard-limit value is set to %d",snap_limit);
}
if (snap_limit > volinfo->snap_count)
- ret = dict_set_int64 (dict, key,
+ ret = dict_set_int32 (dict, "snaps-available",
snap_limit - volinfo->snap_count);
else
- ret = dict_set_int64 (dict, key, 0);
+ ret = dict_set_int32 (dict, "snaps-available", 0);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"Failed to set available snaps");
goto out;
}
- /* Ownership of value transferred to dict. Therefore we must initalize
- * it to NULL */
- value = NULL;
-
- /* snapshot taken first should be displayed first */
- list_for_each_entry_safe (entry, tmp, &conf->snapshots,
- snap_list) {
- ret = snprintf (key, sizeof (key), "%s.snap-%ld", keyprefix,
- index);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
- ++index;
- /* If snapname is NULL then get all the snaps
- * for the given volume */
- if (NULL == snapname) {
- ret = glusterd_snapshot_get_snapdetail (dict, key,
- entry, detail);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "get snap detail for %s snap",
- snapname);
- goto out; /* something wrong */
- }
- continue; /* Get the next entry */
- }
-
- /* If snapname is provided then get snap detail
- * for only that snap */
- if (strncmp (entry->snapname, snapname,
- sizeof (entry->snapname))) {
- /* Entry not yet found.*/
- ret = -1;
- continue; /* Check the next entry */
- }
- /* snap found */
- ret = snprintf (key, sizeof (key), "%s.snap-0", keyprefix);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
-
- ret = glusterd_snapshot_get_snapdetail (dict,
- key, entry, detail);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get snap "
- "detail for %s snap", snapname);
- goto out;
- }
+ /* Origin volume name */
+ value = gf_strdup (volinfo->volname);
+ if (!value)
+ goto out;
- /* Index is used to identify how many snap objects are
- * added to the dictionary. If snapshot name is passed
- * as argument then we would send only one snap object.
- * Therefore index should be reset to 0. */
- index = 1;
- break; /* Found the snap */
+ ret = dict_set_dynstr (dict, "origin-volname", value);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set parent "
+ "volume name in dictionary: %s", key);
+ goto out;
}
+ value = NULL;
- /* If all the snap is written into the dictionary then write the
- * snap count into the dictionary */
- if (0 == ret) {
- ret = snprintf (key, sizeof (key), "%s.snap-count", keyprefix);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
-
- ret = dict_set_int64 (dict, key, index);
+ list_for_each_entry_safe (snap_vol, tmp_vol, &volinfo->snap_volumes,
+ snapvol_list) {
+ snapcount++;
+ snprintf (key, sizeof (key), "snap%d", snapcount);
+ ret = glusterd_snapshot_get_snap_detail (dict,
+ snap_vol->snapshot,
+ key, snap_vol);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "snap count");
- goto out;
-
- }
- } else if (NULL != snapname) {
- gf_log (this->name, GF_LOG_ERROR, "Snap (%s) not found",
- snapname);
- ret = snprintf (key, sizeof (key), "%s.err_str",
- keyprefix);
- if (ret < 0) {
- goto out;
- }
- ret = snprintf (err_str, sizeof (err_str), "Snapshot %s"
- " not found", snapname);
- if (ret < 0) {
- goto out;
- }
- ret = dict_set_str (dict, key, err_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to"
- "set error string");
+ gf_log (this->name, GF_LOG_ERROR, "Failed to get "
+ "snapdetail for snap %s",
+ snap_vol->snapshot->snapname);
goto out;
}
}
-
-out:
- if (NULL != value) {
- GF_FREE (value);
- }
-
- return ret;
-}
-
-/* This function will retrieve snap list for the given volume
- * and then serialize them to dict.
- *
- * @param dict dictionary where response should be serialized
- * @param keyprefix Prefix used for all the keys for rspdict dictionary
- * @param volinfo Volinfo object of the volume
- * @param snapname snap name. This field can be NULL
- * @param detail if 1 then more details will be added for snap list
- *
- * @return -1 on failure and 0 on success.
- */
-static int
-glusterd_snapshot_vol_get_snaplist (dict_t *dict, char *keyprefix,
- glusterd_volinfo_t *volinfo,
- char *snapname, int8_t detail)
-{
- int ret = -1; /* Failure */
- xlator_t *this = NULL;
-
- this = THIS;
-
- /* General parameter validation */
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (keyprefix);
- GF_ASSERT (volinfo);
-
- /* Acquire the volinfo lock before proceeding */
- LOCK (&(volinfo->lock));
- {
- ret = glusterd_snapshot_vol_get_snaplist_lk (dict, keyprefix,
- volinfo, snapname, detail);
- }
- UNLOCK (&(volinfo->lock));
-
+ ret = dict_set_int32 (dict, "snap-count", snapcount);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get snap list for"
- " %s volume", volinfo->volname);
- }
-
- return ret;
-}
-
-
-/* This function will retrieve snap list for the given volume
- * and then serialize them to dict.
- *
- * @param dict dictionary where response should be serialized
- * @param keyprefix Prefix used for all the keys for rspdict dictionary
- * @param volname Volname whose snap list is requested
- * @param snapname snap name. This field can be NULL.
- * @param detail if 1 then more details will be added for snap list
- *
- * @return -1 on failure and 0 on success.
- */
-static int
-glusterd_snapshot_vol_get_snaplist_by_name (dict_t *dict, char *keyprefix,
- char *volname, char *snapname,
- int8_t detail)
-{
- int ret = -1;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
-
- /* General parameter validation */
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (keyprefix);
- GF_ASSERT (volname);
-
- /* Find te volinfo from the volname */
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get volinfo for "
- "%s volume", volname);
- goto out;
- }
-
- /* Now using the volinfo object get the snap list */
- ret = glusterd_snapshot_vol_get_snaplist (dict, keyprefix, volinfo,
- snapname, detail);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get snaplist for "
- "%s volume", volname);
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set snapcount");
goto out;
}
+ ret = 0;
out:
+ if (value)
+ GF_FREE (value);
+
return ret;
}
-
-
-/* This function will retrieve snap list for all the volumes
- * present in a given CG and then serialize them to dict.
- * This function is called under CG lock.
- *
- * @param dict dictionary where response should be serialized
- * @param cg CG object which need to be written into dictionary
- * @param keyprefix Prefix used for all the keys for rspdict dictionary
- * @param cgname CG name.
- * @param detail if 1 then more details will be added for snap list
+/* This function will be called from RPC handler routine.
+ * This function is responsible for getting the requested
+ * snapshot info into the dictionary.
*
- * @return -1 on failure and 0 on success.
+ * @param req RPC request object. Required for sending a response back.
+ * @param op glusterd operation. Required for sending a response back.
+ * @param dict pointer to dictionary which will contain both
+ * request and response key-pair values.
+ * @return -1 on error and 0 on success
*/
-static int
-glusterd_snapshot_cg_get_snaplist_lk (dict_t *dict, glusterd_snap_cg_t *cg,
- char *keyprefix, char *cgname,
- int8_t detail)
+int
+glusterd_handle_snapshot_info (rpcsvc_request_t *req, glusterd_op_t op,
+ dict_t *dict, char *err_str, size_t len)
{
- int ret = -1; /* Failure */
- glusterd_conf_t *conf = NULL;
- char *value = NULL;
- xlator_t *this = NULL;
- int64_t i = 0;
- char key[256]= {0,};
- glusterd_volinfo_t *volinfo = NULL;
+ int ret = -1;
+ int8_t snap_driven = 0;
+ char *volname = NULL;
+ char *snapname = NULL;
+ glusterd_snap_t *snap = NULL;
+ xlator_t *this = NULL;
this = THIS;
-
- /* General parameter validation */
GF_ASSERT (this);
- conf = this->private;
-
- GF_ASSERT (conf);
- GF_ASSERT (dict);
- GF_ASSERT (cg);
- GF_ASSERT (keyprefix);
- GF_ASSERT (cgname);
- /* CG Name */
- value = gf_strdup (cg->cg_name);
- if (NULL == value) {
- goto out;
- }
+ GF_VALIDATE_OR_GOTO (this->name, req, out);
+ GF_VALIDATE_OR_GOTO (this->name, dict, out);
- ret = snprintf (key, sizeof (key), "%s.cg-name", keyprefix);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
+ /* Get the request key-pair from the dictionary */
- ret = dict_set_dynstr (dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "cg name in dictionary");
- goto out;
- }
+ /* All these options are optonal. Therefore ignore
+ * error returned by following dictionary operations
+ */
+ ret = dict_get_str (dict, "snapname", &snapname);
+ ret = dict_get_str (dict, "volname", &volname);
- /* CG ID */
- value = gf_strdup (uuid_utoa (cg->cg_id));
- if (NULL == value) {
+ if (snapname && volname) {
+ gf_log (this->name, GF_LOG_ERROR, "Option volname and snapname "
+ "are mutually exclusive");
ret = -1;
goto out;
}
- ret = snprintf (key, sizeof (key), "%s.cg-id", keyprefix);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
-
- ret = dict_set_dynstr (dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "cg id in dictionary");
- goto out;
- }
-
- /* Ownership of value transferred to dict. Therefore we must initalize
- * it to NULL */
- value = NULL;
-
- /* Volume count */
- ret = snprintf (key, sizeof (key), "%s.vol-count", keyprefix);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
+ if (!volname)
+ snap_driven = 1;
- ret = dict_set_int64 (dict, key, cg->volume_count);
+ ret = dict_set_int8 (dict, "snap-driven", snap_driven);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "volume count in dictionary");
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set snap-driven");
goto out;
}
- /* Get snap list for all volumes present in the CG */
- for (i = 0; i < cg->volume_count; ++i) {
- volinfo = cg->volumes[i];
- ret = snprintf (key, sizeof (key), "%s.vol%ld", keyprefix, i);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
- ret = glusterd_snapshot_vol_get_snaplist (dict, key,
- volinfo, NULL,
- detail);
+ if (snapname) {
+ ret = dict_set_int32 (dict, "snap-count", 1);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "snaplist for %s volume", volinfo->volname);
- goto out;
- }
- }
-
- if (!detail) {
- /* If detail is not needed then return from here */
- goto out;
- }
-
- /* If CG description is provided then add that into dictionary */
- if (NULL != cg->description) {
- /* CG Description */
- value = gf_strdup (cg->description);
- if (NULL == value) {
- ret = -1;
- goto out;
- }
-
- ret = snprintf (key, sizeof (key), "%s.cg-desc", keyprefix);
- if (ret < 0) { /* Only negative value is error */
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to set snapcount");
goto out;
}
- ret = dict_set_dynstr (dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "cg description in dictionary");
+ snap = glusterd_find_snap_by_name (snapname);
+ if (!snap) {
+ gf_log (this->name, GF_LOG_ERROR, "Snap %s doen't "
+ "exist", snapname);
+ ret = -1;
goto out;
}
-
- /* Ownership of value transferred to dict. Therefore we must initalize
- * it to NULL */
- value = NULL;
+ ret = glusterd_snapshot_get_snap_detail (dict, snap, "snap1",
+ NULL);
+ } else if (volname) {
+ ret = glusterd_snapshot_get_info_by_volume (dict, volname);
+ } else {
+ ret = glusterd_snapshot_get_all_snap_info (dict);
}
-
- /* CG status */
- ret = snprintf (key, sizeof (key), "%s.cg-status", keyprefix);
- if (ret < 0) { /* Only negative value is error */
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to get snap info");
goto out;
}
- switch (cg->cg_status) {
- case GD_SNAP_STATUS_INIT:
- ret = dict_set_str (dict, key, "Init");
- break;
- case GD_SNAP_STATUS_IN_USE:
- ret = dict_set_str (dict, key, "In-use");
- break;
- case GD_SNAP_STATUS_DECOMMISSION:
- ret = dict_set_str (dict, key, "Decommisioned");
- break;
- case GD_SNAP_STATUS_RESTORED:
- ret = dict_set_str (dict, key, "Restored");
- break;
- case GD_SNAP_STATUS_NONE:
- ret = dict_set_str (dict, key, "None");
- break;
- default:
- gf_log (this->name, GF_LOG_ERROR, "Invalid snap "
- "status");
- ret = -1; /* Failure */
- goto out;
- }
-
+ /* If everything is successful then send the response back to cli.
+ * In case of failure the caller of this function will take of response.*/
+ ret = glusterd_op_send_cli_response (op, 0, 0, req, dict, err_str);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "snap status in dictionary");
+ gf_log (this->name, GF_LOG_ERROR, "Failed to send cli "
+ "response");
goto out;
}
- ret = 0;
-out:
- if (NULL != value) {
- GF_FREE (value);
- }
+ ret = 0; /* Success */
+out:
return ret;
}
-/* This function will retrieve snap list for all the volumes
- * present in a given CG and then serialize them to dict.
- *
- * @param dict dictionary where response should be serialized
- * @param keyprefix Prefix used for all the keys for rspdict dictionary
- * @param cgname CG name.
- * @param detail if 1 then more details will be added for snap list
- *
- * @return -1 on failure and 0 on success.
- */
-static int
-glusterd_snapshot_cg_get_snaplist (dict_t *dict, char *keyprefix,
- char *cgname, int8_t detail,
- char *err_str, size_t len)
+/* Function glusterd_snapshot_get_list1 sets all the snapshot names
+ in the dictionary */
+int
+glusterd_snapshot_get_list1 (dict_t *dict)
{
- int ret = -1; /* Failure */
- glusterd_conf_t *conf = NULL;
- glusterd_snap_cg_t *cg = NULL;
- xlator_t *this = NULL;
+ int ret = -1;
+ int snapcount = 0;
+ char *snapname = NULL;
+ char key[PATH_MAX] = {0,};
+ glusterd_snap_t *snap = NULL;
+ glusterd_snap_t *tmp_snap = NULL;
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
this = THIS;
-
- /* General parameter validation */
- GF_ASSERT (this);
- conf = this->private;
-
- GF_ASSERT (conf);
+ priv = this->private;
+ GF_ASSERT (priv);
GF_ASSERT (dict);
- GF_ASSERT (keyprefix);
- GF_ASSERT (cgname);
-
- /* Find the CG object from CG name */
- cg = glusterd_find_snap_cg_by_name (conf, cgname);
-
- if (NULL == cg) {
- snprintf (err_str, len, "CG %s not found", cgname);
- gf_log (this->name, GF_LOG_WARNING, "%s", err_str);
- ret = -1;
- goto out;
- }
- /* Got CG. Now serialize the CG content to dictionary */
-
- LOCK (&(cg->lock));
- {
- ret = glusterd_snapshot_cg_get_snaplist_lk (dict, cg, keyprefix,
- cgname, detail);
+ list_for_each_entry_safe (snap, tmp_snap, &priv->snapshots, snap_list) {
+ snapcount++;
+ snapname = gf_strdup (snap->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);
+ if (ret) {
+ GF_FREE (snapname);
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set %s",
+ key);
+ goto out;
+ }
}
- UNLOCK (&(cg->lock));
+ ret = dict_set_int32 (dict, "snap-count", snapcount);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get CG details");
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set snapcount");
+ goto out;
}
- ret = 0; /* Success */
+ ret = 0;
out:
+
return ret;
}
-
-/* This function will retrieve snap list for all the volumes
- * present in voldict dictionary. And then serialize them to
- * rspdict.
- *
- * @param voldict dictionary containing volumes
- * @param rspdict dictionary where response should be serialized
- * @param volcount Total volume count
- * @param keyprefix Prefix used for all the keys for rspdict dictionary
- * @param snapname snap name. This field can be NULL.
- * @param detail if 1 then more details will be added for snap list
- *
- * @return -1 on failure and 0 on success.
- */
-static int
-glusterd_snapshot_get_snaplist (dict_t *voldict, dict_t *rspdict,
- int64_t volcount, char* keyprefix,
- char *snapname, int8_t detail)
+/* Function glusterd_snapshot_get_list2 sets all the snapshot names
+ under a given volume in the dictionary */
+int
+glusterd_snapshot_get_list2 (dict_t *dict, glusterd_volinfo_t *volinfo)
{
- int ret = -1; /* Failure */
- int64_t i = 0;
- char *volname = NULL;
- xlator_t *this = NULL;
- char key[256] = {0,};
- gf_boolean_t exist = _gf_false;
- char *err_str = NULL;
- char err_prefix[PATH_MAX] = "";
+ int ret = -1;
+ int snapcount = 0;
+ char *snapname = NULL;
+ char key[PATH_MAX] = {0,};
+ glusterd_volinfo_t *snap_vol = NULL;
+ glusterd_volinfo_t *tmp_vol = NULL;
+ xlator_t *this = NULL;
this = THIS;
+ GF_ASSERT (dict);
+ GF_ASSERT (volinfo);
- /* General parameter validation */
- GF_ASSERT (this);
- GF_ASSERT (voldict);
- GF_ASSERT (rspdict);
- GF_ASSERT (keyprefix);
-
- /* Write the total volume count into the rspdict */
- ret = snprintf (key, sizeof (key), "%s.vol-count", keyprefix);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
-
- ret = dict_set_int64 (rspdict, key, volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "volume count in dictionary");
- goto out;
- }
-
- /* For each volume add all the snap list to rspdict dictionary */
- for (i = 0; i < volcount; ++i) {
- /* This key is used to get the volume name from voldict
- * dictionary. Therefore do not use keyprefix here
- */
- ret = snprintf (key, sizeof (key), "vol%ld", i);
- if (ret < 0) { /* Only negative value is error */
+ 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;
}
-
- ret = dict_get_str (voldict, key, &volname);
+ snprintf (key, sizeof (key), "snapname%d", snapcount);
+ ret = dict_set_dynstr (dict, key, snapname);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get"
- "volname for %s", key);
- goto out;
- }
-
- ret = snprintf (key, sizeof (key), "%s.vol%ld", keyprefix, i);
- if (ret < 0) { /* Only negative value is error */
+ gf_log (this->name, GF_LOG_ERROR, "Failed to "
+ "set %s", key);
+ GF_FREE (snapname);
goto out;
}
+ }
- exist = glusterd_check_volume_exists (volname);
- if (!exist) {
- err_str = (char *) GF_CALLOC(1, PATH_MAX, sizeof(char));
- gf_log ("", GF_LOG_ERROR,
- "Volume %s Does not exist", volname);
- ret = snprintf (err_str, PATH_MAX,
- "Volume %s Does not exist",volname);
- if (ret < 0) {
- goto out;
- }
- ret = snprintf (err_prefix, sizeof (err_prefix),
- "%s.err_str", key);
- if (ret < 0) {
- goto out;
- }
- ret = dict_set_str (rspdict, err_prefix, err_str);
- if (ret < 0 ) {
- gf_log ("", GF_LOG_ERROR, "Could not"
- "save the err_str");
- goto out;
- }
- continue;
- }
-
- /* Now for each volume get the snap list */
- ret = glusterd_snapshot_vol_get_snaplist_by_name (rspdict, key,
- volname, snapname, detail);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "snapshot list for %s volume", volname);
- goto out;
- }
+ ret = dict_set_int32 (dict, "snap-count", snapcount);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set snapcount");
+ goto out;
}
- ret = 0; /* Success */
+ ret = 0;
out:
+
return ret;
}
-
-
-/* This function will be called from RPC handler routine.
- * This function is responsible for getting the requested
- * snapshot list into the dictionary.
- *
- * @param req RPC request object. Required for sending a response back.
- * @param op glusterd operation. Required for sending a response back.
- * @param dict pointer to dictionary which will contain both
- * request and response key-pair values.
- * @return -1 on error and 0 on success
- */
int
glusterd_handle_snapshot_list (rpcsvc_request_t *req, glusterd_op_t op,
dict_t *dict, char *err_str, size_t len)
{
- int ret = -1;
- int64_t volcount = 0;
- int vol_count = 0;
- int8_t detail = 0;
- char *keyprefix = "snaplist";
- char *cgname = NULL;
- char *snapname = NULL;
- dict_t *voldict = NULL;
- xlator_t *this = NULL;
- char key[256] = {0,};
+ int ret = -1;
+ char *volname = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ xlator_t *this = NULL;
this = THIS;
- GF_ASSERT (this);
GF_VALIDATE_OR_GOTO (this->name, req, out);
GF_VALIDATE_OR_GOTO (this->name, dict, out);
- /* Get the request key-pair from the dictionary */
-
- /* All these options are optonal. Therefore ignore
- * error returned by following dictionary operations
- */
- ret = dict_get_str (dict, "snapname", &snapname);
- /* Ignore error */
- ret = dict_get_int8 (dict, "snap-details", &detail);
-
- ret = dict_get_int64 (dict, "vol-count", &volcount);
- if (ret) {
- /* Ignore error */
- ret = dict_get_str (dict, "cgname", &cgname);
- }
-
-
- /* If volume names are passed as argument then we should
- * get all the snapshots for the said volumes.
- */
- if (volcount > 0) {
- ret = glusterd_snapshot_get_snaplist (dict, dict, volcount,
- keyprefix, snapname,
- detail);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "snapshot list");
- goto out;
- }
- } else if (NULL != cgname) {
- /* If CG (Consistency Group) name is passed as argument then
- * we should get snapshots of all the volumes present in the
- * said CG
- */
-
- /* TODO: Handle multiple CG if needed */
- ret = snprintf (key, sizeof (key), "%s.cg-0", keyprefix);
- if (ret < 0) { /* Only negative value is error */
- goto out;
- }
+ /* Ignore error for getting volname as it is optional */
+ ret = dict_get_str (dict, "volname", &volname);
- ret = glusterd_snapshot_cg_get_snaplist (dict, key, cgname,
- detail, err_str, len);
+ if (NULL == volname) {
+ ret = glusterd_snapshot_get_list1 (dict);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "snapshot list for %s CG", cgname);
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to get snapshot list");
goto out;
}
} else {
- /* If no argument is provided then we should get snapshots of
- * all the volumes managed by this server
- */
-
- /* Create a dictionary to hold all the volumes retrieved from
- * glusterd
- */
- voldict = dict_new ();
- if (NULL == voldict) {
- ret = -1;
- goto out;
- }
-
- /* Get all the volumes from glusterd */
- ret = glusterd_get_all_volnames (voldict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get all "
- "volume names");
- goto out;
- }
-
- /* Get the volume count */
- ret = dict_get_int32 (voldict, "vol_count", &vol_count);
+ ret = glusterd_volinfo_find (volname, &volinfo);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get volume"
- " count");
+ gf_log (this->name, GF_LOG_ERROR,
+ "Volume %s doesn't exists", volname);
goto out;
}
- volcount = vol_count;
- /* Get snap list for all the volumes*/
- ret = glusterd_snapshot_get_snaplist (voldict, dict, volcount,
- keyprefix, NULL, detail);
+ ret = glusterd_snapshot_get_list2 (dict, volinfo);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "snapshot list");
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to get snapshot list for volume %s",
+ volname);
goto out;
}
}
/* If everything is successful then send the response back to cli.
- * In case of failure the caller of this function will take of response.*/
- ret = glusterd_op_send_cli_response (op, 0, 0,
- req, dict, err_str);
+ In case of failure the caller of this function will take of response.*/
+ 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");
@@ -2396,9 +2037,6 @@ glusterd_handle_snapshot_list (rpcsvc_request_t *req, glusterd_op_t op,
ret = 0; /* Success */
out:
- if (voldict) {
- dict_unref (voldict);
- }
return ret;
}
@@ -3450,6 +3088,7 @@ glusterd_handle_snapshot_remove (rpcsvc_request_t *req, glusterd_op_t op,
xlator_t *this = NULL;
this = THIS;
+
GF_ASSERT (req);
GF_ASSERT (dict);
GF_ASSERT (err_str);
@@ -4341,6 +3980,14 @@ glusterd_handle_snapshot_fn (rpcsvc_request_t *req)
}
break;
+ case GF_SNAP_OPTION_TYPE_INFO:
+ ret = glusterd_handle_snapshot_info (req, cli_op, dict,
+ err_str, sizeof (err_str));
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "Snapshot info "
+ "failed");
+ }
+ break;
case GF_SNAP_OPTION_TYPE_LIST:
ret = glusterd_handle_snapshot_list (req, cli_op, dict,
err_str, sizeof (err_str));