summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/cli-cmd-parser.c252
-rw-r--r--cli/src/cli-cmd-snapshot.c3
-rw-r--r--cli/src/cli-rpc-ops.c649
-rw-r--r--rpc/xdr/src/cli1-xdr.h3
4 files changed, 362 insertions, 545 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index 62c383c..2505bbc 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -2956,170 +2956,80 @@ cli_snap_create_parse (dict_t *dict, const char **words, int wordcount,
out :
return ret;
}
-
-/* snapshot list [<volnames> | <volname> -s <snapname> | -c <cgname>] [-d]
- * cmdi is command index which contains number of standard arguments in
- * command, here cmdi is 2 i.e "gluster snapshot list"
+/* snapshot info [(snapname | volume <volname>)]
+ * @arg-0, dict : Request Dictionary to be sent to server side.
+ * @arg-1, words : Contains individual words of CLI command.
+ * @arg-2, wordcount: Contains number of words present in the CLI command.
+ * @arg-3, cmdi : command index, here cmdi is "2" (gluster snapshot info)
+ *
+ * return value : -1 on failure
+ * 0 on success
*/
int
-cli_snap_list_parse (dict_t *dict, const char **words, int wordcount,
- unsigned int cmdi)
-{
- int ret = -1;
- int loop_ret = -1;
- int64_t actual_vol_count = 0;
- int64_t i = 0;
- int64_t vol_count = 0;
- int vol_start_index = -1;
- int8_t snap_details = 0;
- const char *snap_name = NULL;
- const char *cg_name = NULL;
- const char *vol_name = NULL;
- char key[256] = "";
+cli_snap_info_parse (dict_t *dict, const char **words, int wordcount,
+ unsigned int cmdi) {
+
+ int ret = -1;
- GF_ASSERT (dict);
GF_ASSERT (words);
- GF_ASSERT (wordcount >= cmdi);
- /* if command is "gluster snapshot list*/
+ GF_ASSERT (dict);
+
+ if (wordcount > 4 || wordcount < cmdi) {
+ gf_log ("", GF_LOG_ERROR, "Invalid syntax");
+ goto out;
+ }
+
if (wordcount == cmdi) {
- ret = dict_set_int8 (dict, "snap-details", snap_details);
+ ret = 0;
+ goto out;
+ }
+
+ /* If 3rd word is not "volume", then it must
+ * be snap-name.
+ */
+ if (strcmp (words[cmdi], "volume") != 0) {
+ ret = dict_set_str (dict, "snapname",
+ (char *)words[cmdi]);
if (ret) {
- gf_log("", GF_LOG_ERROR, "Failed to set snap-details");
+ gf_log ("cli", GF_LOG_ERROR, "Unable to save "
+ "snap-name %s", words[cmdi]);
+ goto out;
+ }
+
+ /* Once snap name is parsed, if we encounter any other
+ * word then fail it. Invalid Syntax.
+ * example : snapshot info <snap-name> word
+ */
+ if ((cmdi + 1) != wordcount) {
ret = -1;
+ gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
goto out;
}
+
ret = 0;
goto out;
+ /* No need to continue the parsing once we
+ * get the snap-name
+ */
}
- for (i = cmdi; i < wordcount; ++i) {
- if (strcmp (words[i], "-d") == 0) {
- if (snap_details == 1) {
- /* If option is already set */
- gf_log("", GF_LOG_ERROR,
- "snap_details already set");
- ret = -1;
- goto out;
- }
- snap_details = 1;
- } else if (strcmp (words[i], "-s") == 0) {
- if ((wordcount - 1) == i || (snap_name != NULL)
- || vol_count != 1 || strcmp (words[++i], "-d") == 0
- || strcmp (words[i], "-c") == 0) {
- /* if -s is not followed by a valid snap_name
- * or if snap_name is already parsed
- * or number of volname specified
- * is not equal to 1
- */
- gf_log("", GF_LOG_ERROR, "Invalid snap_name"
- " or snap_name already parsed"
- " or number of volumes greater than 1");
- ret = -1;
- goto out;
- }
- /* word followed by -s is snapname */
- snap_name = words[i];
- } else if (strcmp (words[i], "-c") == 0) {
- if ((wordcount - 1) == i || (cg_name != NULL)
- || strcmp (words[++i], "-d") == 0
- || strcmp (words[i], "-s") == 0) {
- /* if -c is not followed by a valid cg_name
- * or if cg_name is already parsed
- */
- gf_log("", GF_LOG_ERROR, "Invalid cg_name"
- " or cg_name already parsed");
- ret = -1;
- goto out;
- }
- cg_name = words[i];
- } else {
- if (vol_count != 0) {
- /* if vol names already set */
- gf_log("", GF_LOG_ERROR,
- "Vol Names already set");
- ret = -1;
- goto out;
- }
-
- vol_start_index = i;
- vol_count = 1;
-
- while (++i < wordcount) {
- if ((strcmp (words[i], "-d") == 0) ||
- (strcmp (words[i], "-s") == 0) ||
- (strcmp (words[i], "-c") == 0)) {
- /*if option -d, -s or -c is given after volname
- *then go back in index to parse this option
- *again
- */
- --i;
- break;
- }
- ++vol_count;
- }
- }
+ /* If 3rd word is "volume", then check if next word
+ * is present. As, "snapshot info volume" is an
+ * invalid command.
+ */
+ if ((cmdi + 1) == wordcount) {
+ ret = -1;
+ gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
}
- ret = dict_set_int8 (dict, "snap-details", snap_details);
+ ret = dict_set_str (dict, "volname", (char *)words[wordcount - 1]);
if (ret) {
- gf_log("", GF_LOG_ERROR, "Failed to set snap-details");
+ gf_log ("", GF_LOG_ERROR, "Count not save "
+ "volume name %s", words[wordcount - 1]);
goto out;
}
- /* if CG name is present in the command then fill it to dictionary */
- if (cg_name != NULL) {
- if (snap_name != NULL || vol_count != 0) {
- /* When -s option or volume name is given along
- * with -c option. Details of single snap belonging
- * to a CG is not supported.
- */
- gf_log("", GF_LOG_ERROR, "details of single snap"
- " belonging to a CG is not supported");
- ret = -1;
- goto out;
- }
- ret = dict_set_str(dict, "cgname", (char *)cg_name);
- if (ret) {
- gf_log("", GF_LOG_ERROR,
- "Failed to set CG name %s", cg_name);
- goto out;
- }
- } else {
- /* if snap name is present in the command
- * then fill it to dictionary
- */
- if (snap_name != NULL) {
- ret = dict_set_str (dict, "snapname",
- (char *)snap_name);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Failed to set snap name %s",
- snap_name);
- ret = -1;
- goto out;
- }
- }
-
- /* fill volume name in dictionary */
- for (i = 0; i < vol_count; ++i) {
- vol_name = (char*) words[vol_start_index + i];
- /* check if volume name is repeated */
- snprintf (key, sizeof (key), "vol%ld", actual_vol_count);
- ret = dict_set_str (dict, key, (char *)vol_name);
- if (ret) {
- gf_log("", GF_LOG_ERROR,
- "Failed to set Volume Name %s",
- vol_name);
- goto out;
- }
- actual_vol_count++;
- }
- ret = dict_set_int64 (dict, "vol-count", actual_vol_count);
- if (ret) {
- gf_log("", GF_LOG_ERROR, "Failed to set Volume Count");
- ret = -1;
- }
- }
-out:
+out :
return ret;
}
@@ -3471,10 +3381,9 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
gf1_cli_snapshot type = GF_SNAP_OPTION_TYPE_NONE;
unsigned int cmdi = 0;
char *w = NULL;
- int i = 0;
char *opwords[] = {"create", "delete", "restore",
"start", "stop", "list", "status",
- "config", NULL};
+ "config", "info", NULL};
GF_ASSERT (words);
GF_ASSERT (options);
@@ -3502,6 +3411,8 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
type = GF_SNAP_OPTION_TYPE_CREATE;
if (!strcmp (w, "list"))
type = GF_SNAP_OPTION_TYPE_LIST;
+ if (!strcmp (w, "info"))
+ type = GF_SNAP_OPTION_TYPE_INFO;
if (!strcmp (w, "delete"))
type = GF_SNAP_OPTION_TYPE_DELETE;
if (!strcmp (w, "config"))
@@ -3509,6 +3420,8 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
if (!strcmp (w, "restore"))
type = GF_SNAP_OPTION_TYPE_RESTORE;
+ cmdi = 2;
+
/* Check which op is intended */
switch (type) {
case GF_SNAP_OPTION_TYPE_CREATE:
@@ -3526,7 +3439,6 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
w = str_getunamb (words[2], opwords);
if (w)
goto out;
- cmdi = 2;
ret = cli_snap_create_parse (dict, words,
wordcount, cmdi);
@@ -3537,35 +3449,21 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
}
break;
}
- case GF_SNAP_OPTION_TYPE_LIST:
- {
- /* snapshot list [<volnames> | <volname> [-s <snapname>]
- * | -c <cgname>] [-d] */
- /* check if arguments contains any Keyword */
- cmdi = 2;
- for (i = cmdi ; i < wordcount ; i++) {
- w = str_getunamb (words[i], opwords);
- if (w) {
- /*Checks if the operation is a valid
- operation*/
- cli_out ("Usage of Keyword in wrong "
- "place");
- gf_log ("", GF_LOG_ERROR, "Opword "
- "Mismatch");
- goto out;
- }
- }
-
- ret = cli_snap_list_parse (dict, words,
- wordcount, cmdi);
+ case GF_SNAP_OPTION_TYPE_INFO:
+ {
+ /* Syntax :
+ * gluster snapshot info ([snap-name] | [vol <volname>])
+ */
+ ret = cli_snap_info_parse (dict, words, wordcount,
+ cmdi);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to parse "
+ "snapshot list command");
+ goto out;
+ }
+ break;
+ }
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "list command parsing failed.");
- goto out;
- }
- break;
- }
case GF_SNAP_OPTION_TYPE_DELETE:
{
/*syntax:
diff --git a/cli/src/cli-cmd-snapshot.c b/cli/src/cli-cmd-snapshot.c
index 44dbf8a..b5b4388 100644
--- a/cli/src/cli-cmd-snapshot.c
+++ b/cli/src/cli-cmd-snapshot.c
@@ -91,8 +91,7 @@ struct cli_cmd snapshot_cmds[] = {
cli_cmd_snapshot_cbk,
"Snapshot Restore."
},
- { "snapshot list [<volnames> | <volname> [-s <snapname>]"
- " | -c <cgname> ] [-d]",
+ { "snapshot info [(snap-name | volume <volname>)]",
cli_cmd_snapshot_cbk,
"Snapshot List."
},
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index e9c24fe..340752a 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -281,7 +281,7 @@ gf_cli_output_pool_list (dict_t *dict, int count)
else
connected_str = "Disconnected";
- cli_out ("%s\t%-8s\t%s ", uuid_buf, hostname_buf,
+ cli_out ("%s\t%-9s\t%s ", uuid_buf, hostname_buf,
connected_str);
i++;
}
@@ -7530,342 +7530,6 @@ out:
return ret;
}
-
-/*Function to list the snap "gluster snapshot list" */
-static int
-list_snap_of_volume (dict_t *dict_n, char *prefix_str) {
- uint64_t snapcount_total = 0 ;
- uint64_t snapcount = 0 ;
- char buffer[PATH_MAX] = "" ;
- char *get_buffer = NULL;
- int8_t detail = 0 ;
- uint64_t i = 0 ;
- int ret = -1 ;
- uint64_t snap_available = 0 ;
-
- GF_ASSERT (dict_n);
- GF_ASSERT (prefix_str);
-
- if (!dict_n) {
- ret = -1;
- goto out;
- }
-
- /* Check if volname is present.
- * if volume not present then display that volume doesnot exist
- * and try to fetch next volume mentioned
- */
-
- ret = snprintf (buffer, sizeof (buffer), "%s.err_str", prefix_str);
- if (ret < 0) {
- goto out;
- }
-
- ret = dict_get_str (dict_n, buffer, &get_buffer);
- if (ret == 0) {
- cli_out ("%s",get_buffer);
- ret = 0;
- goto out;
- }
-
- ret = snprintf (buffer, sizeof(buffer), "%s.volname", prefix_str);
- if (ret < 0) { /* Negative value is an error */
- goto out;
- }
-
- ret = dict_get_str (dict_n, buffer, &get_buffer);
- if (get_buffer == NULL){
- ret = 0;
- goto out;
- }
- cli_out ("\n%-28s %s %s", "Volume Name", ":", get_buffer);
- /* if Volume is present then get the snapcount.
- * string is "snaplist.vol{0..}.snap-count.
- */
- ret = snprintf (buffer, sizeof(buffer),
- "%s.snap-count", prefix_str);
- if (ret < 0) { /* Negative value is an error */
- goto out;
- }
-
- ret = dict_get_uint64 (dict_n, buffer, &snapcount);
- if (ret) {
- gf_log("", GF_LOG_ERROR, "Could not fetch snapcount");
- goto out;
- }
-
- /* To check if the user has given "-d" option */
- ret = dict_get_int8 (dict_n, "snap-details", &detail);
- if (ret) {
- gf_log ("",GF_LOG_ERROR, "could not get snap_details status");
- goto out;
- }
-
- /* "snap-count-total" holds number of snapshots taken
- * whereas "snap-count" holds number of snapshots to
- * be displayed
- * Ex : gluster snapshot list vol1 -s snap1
- * Here "snap-count-total" contains number of snapshots
- * of volume "vol1", whereas "snap-count" is 1 here,
- * as we are displaying details of only 1 snap "snap1"
- */
- ret = snprintf (buffer, sizeof (buffer),
- "%s.snap-count-total", prefix_str);
- if (ret < 0) {
- goto out;
- }
-
- ret = dict_get_uint64 (dict_n, buffer, &snapcount_total);
- if (!ret)
- cli_out ("%-28s %s %ld", "Number of snaps taken", ":",
- snapcount_total);
- else
- gf_log ("", GF_LOG_ERROR, "Failed to get snapcount total");
-
- ret = snprintf (buffer, sizeof (buffer),
- "%s.snap-available", prefix_str);
- if (ret < 0) {
- goto out;
- }
-
- ret = dict_get_uint64 (dict_n, buffer, &snap_available);
- if (!ret)
- cli_out ("%-28s %s %ld", "Number of snaps available",
- ":", snap_available);
- else
- gf_log ("", GF_LOG_ERROR, "Failed to get snap-available");
-
-
- for (i = 0 ; i < snapcount; i++) {
- /* get snapname "snaplist.vol-{0..}.snap-{0..}.snapname" */
- ret = snprintf (buffer, sizeof(buffer),
- "%s.snap-%ld.snapname", prefix_str,i);
- if (ret < 0) { /* Negative value is an error */
- goto out;
- }
-
- ret = dict_get_str (dict_n, buffer, &get_buffer);
- if (!ret)
- cli_out ("\n\t%-17s %s %s", "Snap Name", ":",
- get_buffer);
- else
- cli_out ("\n\t%-17s %s %s", "Snap Name", ":",
- "Does not exist");
-
- ret = snprintf (buffer, sizeof(buffer),
- "%s.snap-%ld.snap-time", prefix_str, i);
- if (ret < 0) { /* Negative value is an error */
- goto out;
- }
-
- ret = dict_get_str (dict_n, buffer, &get_buffer);
- if (!ret)
- cli_out ("\t%-17s %s %s", "Snap Time", ":",
- get_buffer);
- else
- cli_out ("\t%-17s %s %s", "Snap Time", ":",
- "Does not exist");
-
-
- ret = snprintf (buffer, sizeof(buffer), "%s.snap-%ld.snap-id"
- , prefix_str, i);
- if (ret < 0) { /* Negative value is an error */
- goto out;
- }
-
- ret = dict_get_str (dict_n, buffer, &get_buffer);
- if (!ret)
- cli_out("\t%-17s %s %s", "Snap UUID", ":",
- get_buffer);
- else
- cli_out("\t%-17s %s %s", "Snap UUID", ":",
- "Does not exist");
-
- if(detail == 0) {
- /* if snap_details is set to zero
- * then we can skip the additional information part
- */
- continue;
- }
- ret = snprintf (buffer, sizeof(buffer),
- "%s.snap-%ld.cg-name", prefix_str, i);
- if (ret < 0) { /* Negative value is an error */
- goto out;
- }
-
- ret = dict_get_str (dict_n, buffer, &get_buffer);
- if (!ret)
- cli_out("\t%-17s %s %s", "CG Name", ":",
- get_buffer);
- else
- cli_out("\t%-17s %s %s","CG Name", ":",
- "Does not exist");
-
- ret = snprintf (buffer, sizeof(buffer),
- "%s.snap-%ld.cg-id", prefix_str, i);
- if (ret < 0) { /* Negative value is an error */
- goto out;
- }
-
- ret = dict_get_str (dict_n, buffer, &get_buffer);
- if (!ret)
- cli_out("\t%-17s %s %s", "CG ID", ":",
- get_buffer);
- else
- cli_out("\t%-17s %s %s", "CG ID", ":",
- "Does not exist");
-
- ret = snprintf (buffer, sizeof(buffer),
- "%s.snap-%ld.snap-desc", prefix_str, i);
- if (ret < 0) { /* Negative value is an error */
- goto out;
- }
-
- ret = dict_get_str (dict_n, buffer, &get_buffer);
- if (!ret)
- cli_out ("\t%-17s %s %s", "Snap Description", ":",
- get_buffer);
- else
- cli_out ("\t%-17s %s %s", "Snap Description", ":",
- "Description not present");
-
- ret = snprintf (buffer, sizeof(buffer),
- "%s.snap-%ld.snap-status", prefix_str, i);
- if (ret < 0) { /* Negative value is an error */
- goto out;
- }
-
- ret = dict_get_str (dict_n, buffer, &get_buffer);
- if (!ret)
- cli_out ("\t%-17s %s %s", "Snap Status", ":",
- get_buffer);
- else
- cli_out ("\t%-17s %s %s", "Snap Status", ":",
- "Does not exist");
- ret = 0;
- }
-
-out :
- return ret;
-}
-
-/* Function to list snap present in CG */
-static int
-list_snap_of_cg (dict_t *dict) {
- int ret = -1 ;
- int8_t detail = 0 ;
- char *get_buffer = NULL;
- char cg_name_list[PATH_MAX] = "" ;
- int64_t cg_volcount = 0 ;
- uint64_t i = 0 ;
-
- GF_ASSERT(dict);
-
- /* As listing snaps of single CG is supported as of now
- * the string "snaplist.cg0" is directly included
- * or else we can keep that string in some variable
- * and use the same variable every where
- */
- ret = dict_get_int8 (dict, "snap-details", &detail);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "could not get snap_details status");
- goto out;
- }
-
- ret = dict_get_str (dict, "snaplist.cg-0.cg-name", &get_buffer);
- if (ret) {
- /* if cg_name is not present then exit, it is not necessary
- * to check other details if cg_name is not present
- */
- cli_out ("CG Name : %s","Does not exist");
- gf_log ("", GF_LOG_ERROR, "Could not get cg_name");
- goto out;
- }
- cli_out ("CG Name : %s", get_buffer);
-
- ret = dict_get_str (dict, "snaplist.cg-0.cg-id", &get_buffer);
- if (!ret)
- cli_out ("CG ID : %s",get_buffer);
- else
- cli_out ("CG ID : %s","Does not exist");
-
- if (detail == 1) {
- ret = dict_get_str (dict,
- "snaplist.cg-0.cg-desc", &get_buffer);
- if (!ret)
- cli_out ("CG Description : %s",
- get_buffer);
- else
- cli_out ("CG Description : %s",
- "Does not exist");
-
- ret = dict_get_str (dict, "snaplist.cg-0.cg-status",
- &get_buffer);
- if (!ret)
- cli_out ("CG Status : %s", get_buffer);
- else
- cli_out ("CG Status : %s",
- "Does not exist");
-
- }
-
- ret = dict_get_int64 (dict, "snaplist.cg-0.vol-count", &cg_volcount);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Could not fetch cg_volcount");
- goto out;
- }
- /* list the snaps of each volume present in a CG*/
- for (i = 0 ; i < cg_volcount ; i++){
- ret = snprintf (cg_name_list, sizeof(cg_name_list),
- "snaplist.cg-0.vol%ld",i);
- if (ret < 0) { /* Negative value is an error */
- goto out;
- }
- ret = list_snap_of_volume (dict, cg_name_list);
- if (ret) {
- gf_log("", GF_LOG_ERROR, "Failed to list the"
- " information of snaps of volume present in CG");
- }
- }
-out :
- return ret;
-}
-
-/* This function calls list_snap_of_volume */
-static int
-call_list_snap_of_volume(dict_t *dict){
- int ret = -1;
- int64_t volcount = 0;
- uint64_t i = 0;
- char vol_name_prefix[PATH_MAX] = "";
-
- ret = dict_get_int64 (dict, "snaplist.vol-count", &volcount);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Could not fetch volcount");
- goto out;
- }
- for (i = 0 ; i < volcount ; i++) {
- /* list the snap of each volume
- * vol_name_prefix = "snaplist.vol-{0..}"
- */
- ret = snprintf (vol_name_prefix, sizeof(vol_name_prefix),
- "snaplist.vol%ld", i);
- if (ret < 0) { /* Negative value is an error */
- goto out;
- }
- ret = list_snap_of_volume (dict, vol_name_prefix);
- if (ret) {
- gf_log("", GF_LOG_ERROR,
- "Failed to list information of snaps of volume");
- }
- /* If we fail to print information of one volume
- * then try to fetch information of next volume
- */
- }
-out :
- return ret;
-}
-
int32_t
cli_snapshot_remove_reply (gf_cli_rsp *rsp, dict_t *dict, call_frame_t *frame)
{
@@ -8053,6 +7717,274 @@ out:
return ret;
}
+/* This function is used to print the volume related information
+ * of a snap.
+ *
+ * arg - 0, dict : Response Dictionary.
+ * arg - 1, prefix str : snaplist.snap{0..}.vol{0..}.*
+ */
+int
+cli_get_each_volinfo_in_snap (dict_t *dict, char *keyprefix,
+ gf_boolean_t snap_driven) {
+ char key[PATH_MAX] = "";
+ char *get_buffer = NULL;
+ int value = 0;
+ int ret = -1;
+ char indent[5] = "\t";
+
+ GF_ASSERT (dict);
+ GF_ASSERT (keyprefix);
+
+ if (snap_driven) {
+ ret = snprintf (key, sizeof (key), "%s.volname", keyprefix);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, key, &get_buffer);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to get %s", key);
+ goto out;
+ }
+ cli_out ("%s%-12s %s", indent, "Volume Name:", get_buffer);
+
+ ret = snprintf (key, sizeof (key),
+ "%s.origin-volname", keyprefix);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, key, &get_buffer);
+ if (ret) {
+ gf_log ("cli", GF_LOG_WARNING, "Failed to get %s", key);
+ cli_out ("%-12s", "Origin:");
+ }
+ cli_out ("%s%-12s %s", indent, "Origin:", get_buffer);
+
+ ret = snprintf (key, sizeof (key),
+ "%s.snaps-available", keyprefix);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, key, &value);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to get %s", key);
+ goto out;
+ }
+ cli_out ("%s%-12s %d", indent, "Available:", value);
+ }
+
+ ret = snprintf (key, sizeof (key), "%s.vol-id", keyprefix);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, key, &get_buffer);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to get %s", key);
+ goto out;
+ }
+ cli_out ("%s%-12s %s", indent, "UUID:", get_buffer);
+out :
+ return ret;
+}
+
+/* This function is used to print snap related information
+ * arg - 0, dict : Response dictionary.
+ * arg - 1, prefix_str : snaplist.snap{0..}.*
+ */
+int
+cli_get_volinfo_in_snap (dict_t *dict, char *keyprefix) {
+
+ char key[PATH_MAX] = "";
+ int i = 0;
+ int volcount = 0;
+ int ret = -1;
+
+ GF_ASSERT (dict);
+ GF_ASSERT (keyprefix);
+
+ ret = snprintf (key, sizeof (key), "%s.vol-count", keyprefix);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, key, &volcount);
+ for (i = 1 ; i <= volcount ; i++) {
+ ret = snprintf (key, sizeof (key),
+ "%s.vol%d", keyprefix, i);
+ if (ret < 0) {
+ goto out;
+ }
+ ret = cli_get_each_volinfo_in_snap (dict, key, _gf_true);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Could not list "
+ "details of volume in a snap");
+ goto out;
+ }
+ cli_out (" ");
+ }
+
+out :
+ return ret;
+}
+
+int
+cli_get_each_snap_info (dict_t *dict, char *prefix_str,
+ gf_boolean_t snap_driven) {
+ char key_buffer[PATH_MAX] = "";
+ char *get_buffer = NULL;
+ int ret = -1;
+ char indent[5] = "";
+
+ GF_ASSERT (dict);
+ GF_ASSERT (prefix_str);
+
+ if (!snap_driven)
+ strcat (indent, "\t");
+
+ ret = snprintf (key_buffer, sizeof (key_buffer), "%s.snap-name",
+ prefix_str);
+ if (ret < 0 ) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, key_buffer, &get_buffer);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Unable to fetch snap-name %s ",
+ key_buffer);
+ goto out;
+ }
+ cli_out ("%s%-12s %s", indent, "Snapshot:", get_buffer);
+
+ ret = snprintf (key_buffer, sizeof (key_buffer), "%s.snap-desc",
+ prefix_str);
+ if (ret < 0 ) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, key_buffer, &get_buffer);
+ if (!ret) {
+ /* Ignore error for description */
+ cli_out ("%s%-12s %s", indent, "Desc:", get_buffer);
+ }
+
+ ret = snprintf (key_buffer, sizeof (key_buffer), "%s.snap-time",
+ prefix_str);
+ if (ret < 0 ) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, key_buffer, &get_buffer);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Unable to fetch snap-time %s ",
+ prefix_str);
+ goto out;
+ }
+ cli_out ("%s%-12s %s", indent, "Created:", get_buffer);
+
+ if (snap_driven) {
+ cli_out ("%-12s", "Volumes:");
+ ret = cli_get_volinfo_in_snap (dict, prefix_str);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Unable to list details "
+ "of the snaps");
+ goto out;
+ }
+ }
+out :
+ return ret;
+}
+
+/* This is a generic function to print snap related information.
+ * arg - 0, dict : Response Dictionary
+ */
+int
+cli_call_snapshot_info (dict_t *dict, gf_boolean_t bool_snap_driven) {
+ int snap_count = 0;
+ char key[PATH_MAX] = "";
+ int ret = -1;
+ int i = 0;
+
+ GF_ASSERT (dict);
+
+ ret = dict_get_int32 (dict, "snap-count", &snap_count);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Unable to get snap-count");
+ goto out;
+ }
+
+ for (i = 1 ; i <= snap_count ; i++) {
+ ret = snprintf (key, sizeof (key), "snap%d", i);
+ if (ret < 0) {
+ goto out;
+ }
+ ret = cli_get_each_snap_info (dict, key, bool_snap_driven);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Unable to print snap details");
+ goto out;
+ }
+ }
+out :
+ return ret;
+}
+
+int
+cli_get_snaps_in_volume (dict_t *dict) {
+ int ret = -1;
+ int i = 0;
+ int count = 0;
+ char key[PATH_MAX] = "";
+ char *get_buffer = NULL;
+
+ GF_ASSERT (dict);
+
+ ret = dict_get_str (dict, "origin-volname", &get_buffer);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Could not fetch origin-volname");
+ goto out;
+ }
+ cli_out ("%-12s %s", "Volume Name:", get_buffer);
+
+ ret = dict_get_int32 (dict, "snaps-available", &count);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Could not fetch snaps-available");
+ goto out;
+ }
+ cli_out ("%-12s %d", "Available:", count);
+
+ ret = dict_get_int32 (dict, "snap-count", &count);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Could not fetch snap-count");
+ goto out;
+ }
+ for (i = 1 ; i <= count ; i++) {
+ snprintf (key, sizeof (key), "snap%d", i);
+ ret = cli_get_each_snap_info (dict, key, _gf_false);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Unable to print snap details");
+ goto out;
+ }
+
+ ret = snprintf (key, sizeof (key), "snap%d.vol1", i);
+ if (ret < 0) {
+ goto out;
+ }
+ ret = cli_get_each_volinfo_in_snap (dict, key, _gf_false);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Could not get volume "
+ "related information");
+ goto out;
+ }
+
+ cli_out (" ");
+ }
+out :
+ return ret;
+}
int
gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
@@ -8065,6 +7997,7 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,
int32_t type = 0;
int64_t volcount = -1;
call_frame_t *frame = NULL;
+ gf_boolean_t snap_driven = _gf_false;
if (req->rpc_status == -1) {
ret = -1;
@@ -8166,7 +8099,7 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,
ret = 0;
break;
- case GF_SNAP_OPTION_TYPE_LIST:
+ case GF_SNAP_OPTION_TYPE_INFO:
if (rsp.op_ret) {
cli_err ("Snapshot list : failed: %s",
rsp.op_errstr ? rsp.op_errstr :
@@ -8175,40 +8108,26 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
- /* get the vol_count
- * if vol_count = 0, then there must be presence of CG
- */
- ret = dict_get_int64 (dict, "snaplist.vol-count", &volcount);
- if (ret){
- /* if "snaplist.vol-count" is not present then check
- * whether "snaplist.cg-0.vol-count" is present
- */
- ret = dict_get_int64 (dict, "snaplist.cg-0.vol-count",
- &volcount);
+ snap_driven = dict_get_str_boolean (dict, "snap-driven",
+ _gf_false);
+ if (snap_driven == _gf_true) {
+ ret = cli_call_snapshot_info (dict, snap_driven);
if (ret) {
- gf_log ("", GF_LOG_ERROR, "Could not fetch"
- " cg-volcount");
+ gf_log ("cli", GF_LOG_ERROR,
+ "Snapshot info failed");
goto out;
}
- ret = list_snap_of_cg (dict);
+ } else if (snap_driven == _gf_false) {
+ ret = cli_get_snaps_in_volume (dict);
if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Could not list snaps present in CG");
- }
- goto out;
- }
- if (volcount >= 1) {
- ret = call_list_snap_of_volume (dict);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Could not list snaps of volume");
+ gf_log ("cli", GF_LOG_ERROR,
+ "Snapshot info failed");
goto out;
}
}
- else {
- cli_out ("Snapshots not present");
- }
- break;
+ break;
+
+
case GF_SNAP_OPTION_TYPE_CONFIG:
ret = cli_snapshot_config_display (dict, &rsp);
diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h
index dfde3e2..598ddbd 100644
--- a/rpc/xdr/src/cli1-xdr.h
+++ b/rpc/xdr/src/cli1-xdr.h
@@ -179,13 +179,14 @@ enum gf1_cli_snapshot {
GF_SNAP_OPTION_TYPE_LIST = 6,
GF_SNAP_OPTION_TYPE_STATUS = 7,
GF_SNAP_OPTION_TYPE_CONFIG = 8,
+ GF_SNAP_OPTION_TYPE_INFO = 9,
};
typedef enum gf1_cli_snapshot gf1_cli_snapshot;
enum gf1_cli_snapshot_config {
GF_SNAP_CONFIG_TYPE_NONE = 0,
GF_SNAP_CONFIG_TYPE_SET = 0 + 1,
- GF_SNAP_CONFIG_DISPLAY = 0 + 2
+ GF_SNAP_CONFIG_DISPLAY = 0 + 2,
};
typedef enum gf1_cli_snapshot_config gf1_cli_snapshot_config;