diff options
Diffstat (limited to 'cli/src')
-rw-r--r-- | cli/src/cli-cmd-parser.c | 110 | ||||
-rw-r--r-- | cli/src/cli-cmd-snapshot.c | 4 | ||||
-rw-r--r-- | cli/src/cli-rpc-ops.c | 281 |
3 files changed, 389 insertions, 6 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 2ad5d430c..c5d6fa009 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -3290,6 +3290,85 @@ out : return ret; } +/* snapshot status [(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 status) + * + * return value : -1 on failure + * 0 on success + */ +int +cli_snap_status_parse (dict_t *dict, const char **words, int wordcount, + unsigned int cmdi) { + + int ret = -1; + int32_t cmd = GF_SNAP_STATUS_TYPE_ALL; + + GF_ASSERT (words); + GF_ASSERT (dict); + + if (wordcount > 4 || wordcount < cmdi) { + gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax"); + goto out; + } + + if (wordcount == cmdi) { + ret = 0; + goto out; + } + + /* if 3rd word is not "volume", then it must be "snapname" + */ + if (strcmp (words[cmdi], "volume") != 0) { + ret = dict_set_str (dict, "snapname", + (char *)words[cmdi]); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Count not save " + "snap name %s", words[cmdi]); + goto out; + } + + if ((cmdi + 1) != wordcount) { + ret = -1; + gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax"); + goto out; + } + + ret = 0; + cmd = GF_SNAP_STATUS_TYPE_SNAP; + goto out; + } + + /* 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_str (dict, "volname", (char *)words [wordcount - 1]); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Count not save " + "volume name %s", words[wordcount - 1]); + goto out; + } + cmd = GF_SNAP_STATUS_TYPE_VOL; + +out : + if (ret == 0) { + ret = dict_set_int32 (dict, "cmd", cmd); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Could not save cmd " + "of snapshot status"); + } + } + return ret; +} + int32_t cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options, @@ -3326,18 +3405,21 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options, goto out; } - if (!strcmp (w, "create")) + if (!strcmp (w, "create")) { type = GF_SNAP_OPTION_TYPE_CREATE; - if (!strcmp (w, "list")) + } else if (!strcmp (w, "list")) { type = GF_SNAP_OPTION_TYPE_LIST; - if (!strcmp (w, "info")) + } else if (!strcmp (w, "info")) { type = GF_SNAP_OPTION_TYPE_INFO; - if (!strcmp (w, "delete")) + } else if (!strcmp (w, "delete")) { type = GF_SNAP_OPTION_TYPE_DELETE; - if (!strcmp (w, "config")) + } else if (!strcmp (w, "config")) { type = GF_SNAP_OPTION_TYPE_CONFIG; - if (!strcmp (w, "restore")) + } else if (!strcmp (w, "restore")) { type = GF_SNAP_OPTION_TYPE_RESTORE; + } else if (!strcmp (w, "status")) { + type = GF_SNAP_OPTION_TYPE_STATUS; + } if (type != GF_SNAP_OPTION_TYPE_CONFIG) { ret = dict_set_int32 (dict, "hold_snap_locks", _gf_true); @@ -3437,6 +3519,22 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options, } break; } + case GF_SNAP_OPTION_TYPE_STATUS: + { + /* Syntax : + * gluster snapshot status [(snapname | + * volume <volname>)] + */ + ret = cli_snap_status_parse (dict, words, wordcount, + cmdi); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to parse " + "snapshot status command"); + goto out; + } + break; + } + case GF_SNAP_OPTION_TYPE_RESTORE: { /* Syntax: diff --git a/cli/src/cli-cmd-snapshot.c b/cli/src/cli-cmd-snapshot.c index 2389252b3..bf954d61c 100644 --- a/cli/src/cli-cmd-snapshot.c +++ b/cli/src/cli-cmd-snapshot.c @@ -91,6 +91,10 @@ struct cli_cmd snapshot_cmds[] = { cli_cmd_snapshot_cbk, "Snapshot Restore." }, + { "snapshot status [(snapname | volume <volname>)]", + cli_cmd_snapshot_cbk, + "Snapshot Status." + }, { "snapshot info [(snapname | volume <volname>)]", cli_cmd_snapshot_cbk, "Snapshot Info." diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 42e41ce33..31096f67e 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -8033,6 +8033,278 @@ out : } int +cli_get_snap_volume_status (dict_t *dict, char *key_prefix) +{ + int ret = -1; + char key[PATH_MAX] = ""; + char *buffer = NULL; + int brickcount = 0; + int i = 0; + int pid = 0; + + GF_ASSERT (dict); + GF_ASSERT (key_prefix); + + ret = snprintf (key, sizeof (key), "%s.brickcount", key_prefix); + if (ret < 0) { + goto out; + } + ret = dict_get_int32 (dict, key, &brickcount); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to fetch brickcount"); + goto out; + } + + for ( i = 0 ; i < brickcount ; i++ ) { + ret = snprintf (key, sizeof (key), "%s.brick%d.path", + key_prefix, i); + if (ret < 0) { + goto out; + } + + ret = dict_get_str (dict, key, &buffer); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, + "Unable to get Brick Path"); + goto out; + } + cli_out ("\n\t%-17s %s %s", "Brick Path", ":", buffer); + + ret = snprintf (key, sizeof (key), "%s.brick%d.vgname", + key_prefix, i); + if (ret < 0) { + goto out; + } + + ret = dict_get_str (dict, key, &buffer); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, + "Unable to get Volume Group"); + goto out; + } + cli_out ("\t%-17s %s %s", "Volume Group", ":", buffer); + + ret = snprintf (key, sizeof (key), "%s.brick%d.status", + key_prefix, i); + if (ret < 0) { + goto out; + } + + ret = dict_get_str (dict, key, &buffer); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, + "Unable to get Brick Running"); + goto out; + } + cli_out ("\t%-17s %s %s", "Brick Running", ":", buffer); + + ret = snprintf (key, sizeof (key), "%s.brick%d.pid", + key_prefix, i); + if (ret < 0) { + goto out; + } + + ret = dict_get_int32 (dict, key, &pid); + if (!ret) { + cli_out ("\t%-17s %s %d", "Brick PID", ":", pid); + } + else { + cli_out ("\t%-17s %s %s", "Brick PID", ":", + "Brick Process is down"); + } + + ret = snprintf (key, sizeof (key), "%s.brick%d.data", + key_prefix, i); + if (ret < 0) { + goto out; + } + + ret = dict_get_str (dict, key, &buffer); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, + "Unable to get Data Percent"); + goto out; + } + cli_out ("\t%-17s %s %s", "Data Percentage", ":", buffer); + + ret = snprintf (key, sizeof (key), "%s.brick%d.lvsize", + key_prefix, i); + if (ret < 0) { + goto out; + } + ret = dict_get_str (dict, key, &buffer); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Unable to get LV Size"); + goto out; + } + cli_out ("\t%-17s %s %s", "LV Size", ":", buffer); + + } +out : + return ret; +} + + + +int +cli_get_single_snap_status (dict_t *dict, char *keyprefix) +{ + int ret = -1; + char key[PATH_MAX] = ""; + int i = 0; + int volcount = 0; + char *get_buffer = NULL; + + GF_ASSERT (dict); + GF_ASSERT (keyprefix); + + ret = snprintf (key, sizeof (key), "%s.snapname", keyprefix); + if (ret < 0) { + goto out; + } + + ret = dict_get_str (dict, key, &get_buffer); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Unable to get snapname"); + goto out; + } + cli_out ("\nSnap Name : %s", get_buffer); + + ret = snprintf (key, sizeof (key), "%s.uuid", keyprefix); + if (ret < 0) { + goto out; + } + + ret = dict_get_str (dict, key, &get_buffer); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Unable to get snap UUID"); + goto out; + } + cli_out ("Snap UUID : %s", get_buffer); + + ret = snprintf (key, sizeof (key), "%s.volcount", keyprefix); + if (ret < 0) { + goto out; + } + + ret = dict_get_int32 (dict, key, &volcount); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Unable to get volume count"); + goto out; + } + + for (i = 0 ; i < volcount ; i++) { + ret = snprintf (key, sizeof (key), "%s.vol%d", keyprefix, i); + if (ret < 0) { + goto out; + } + + ret = cli_get_snap_volume_status (dict, key); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, + "Could not get snap volume status"); + goto out; + } + } +out : + return ret; +} + +int +cli_snap_status_all (dict_t *dict) { + int ret = -1; + char key[PATH_MAX] = ""; + int snapcount = 0; + int i = 0; + + GF_ASSERT (dict); + + ret = dict_get_int32 (dict, "status.snapcount", &snapcount); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Could not get snapcount"); + goto out; + } + + for (i = 0 ; i < snapcount; i++) { + ret = snprintf (key, sizeof (key), "status.snap%d",i); + if (ret < 0) { + goto out; + } + ret = cli_get_single_snap_status (dict, key); + } +out: + return ret; +} + + +int +cli_snapshot_status_display (dict_t *dict, gf_cli_rsp *rsp) +{ + char key[PATH_MAX] = ""; + int ret = -1; + int status_cmd = -1; + + GF_ASSERT (dict); + GF_ASSERT (rsp); + + if (rsp->op_ret) { + cli_err ("Snapshot Status : failed: %s", + rsp->op_errstr ? rsp->op_errstr : + "Please check log file for details"); + ret = rsp->op_ret; + goto out; + } + + ret = dict_get_int32 (dict, "cmd", &status_cmd); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Could not fetch status type"); + goto out; + } + switch (status_cmd) { + case GF_SNAP_STATUS_TYPE_ALL : + { + ret = cli_snap_status_all (dict); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Could not fetch " + "status of all snap"); + goto out; + } + break; + } + + case GF_SNAP_STATUS_TYPE_SNAP : + { + ret = snprintf (key, sizeof (key), "status.snap0"); + if (ret < 0) { + goto out; + } + ret = cli_get_single_snap_status (dict, key); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Could not fetch " + "status of snap"); + goto out; + } + break; + } + + case GF_SNAP_STATUS_TYPE_VOL : + { + ret = cli_snap_status_all (dict); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Could not fetch " + "status of snap in a volume"); + goto out; + } + break; + } + default : + break; + } +out : + return ret; +} + +int gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { @@ -8184,6 +8456,15 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, } break; + case GF_SNAP_OPTION_TYPE_STATUS: + ret = cli_snapshot_status_display (dict, &rsp); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to display " + "snapshot status output."); + goto out; + } + break; + default: cli_err ("Unknown command executed"); ret = -1; |