summaryrefslogtreecommitdiffstats
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/src/cli-cmd-parser.c159
-rw-r--r--cli/src/cli-cmd-snapshot.c8
-rw-r--r--cli/src/cli-rpc-ops.c32
3 files changed, 181 insertions, 18 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index 352a2cc9b..44c497977 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2010-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
This file is licensed to you under your choice of the GNU Lesser
@@ -2797,7 +2797,7 @@ out:
int32_t
cli_snap_create_parse (dict_t *dict, const char **words, int wordcount,
- int32_t cmdi)
+ unsigned int cmdi)
{
int32_t volcount = -1;
int32_t no_of_wrds_in_desc = -1;
@@ -3239,16 +3239,116 @@ out:
}
+/* Syntax:
+ * snapshot restore (-v <volname> <snap-name> | -c <cg-name> )
+ */
+int
+cli_snap_restore_parse (dict_t *dict, const char **words, int wordcount,
+ unsigned int cmdi)
+{
+ int ret = -1; /* Failure */
+ const char* vol_name = NULL;
+ const char* snap_name = NULL;
+ const char* cg_name = NULL;
+
+ GF_ASSERT (dict);
+ GF_ASSERT (words);
+
+ /* At least CG_INDEX argument should be there for a valid command */
+ if (wordcount <= cmdi) {
+ gf_log ("cli", GF_LOG_ERROR, "Invalid command: Not enough "
+ "arguments");
+ goto out;
+ }
+ if (0 == strcmp (words[cmdi], "-v")) {
+ /* snapshot restore -v <volname> <snap-name>
+ *
+ * cmdi points to -v, therefore wordcount should be exactly
+ * equal to (cmdi + 2) + 1. +1 is added to convert index to
+ * count
+ */
+ if ((cmdi + 3) != wordcount) {
+ gf_log ("cli", GF_LOG_ERROR, "Invalid argument count");
+ goto out;
+ }
+
+ vol_name = words[++cmdi];
+ snap_name = words[++cmdi];
+
+ if ((NULL == vol_name) || (NULL == snap_name)) {
+ gf_log ("cli", GF_LOG_ERROR, "Volume or snap "
+ "name missing");
+ goto out;
+ }
+
+ /* Single volume should be represented by volcount 1
+ * and a volname in dictionary
+ */
+ ret = dict_set_int64 (dict, "volcount", 1);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to set "
+ "vol count");
+ goto out;
+ }
+
+ /* TODO: Change the index to 0 once Jarvis code is fixed */
+ ret = dict_set_str (dict, "volname1", (char *)vol_name);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to set "
+ "volume name");
+ goto out;
+ }
+
+ ret = dict_set_str (dict, "snapname", (char *)snap_name);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to set "
+ "snap name");
+ goto out;
+ }
+ } else if (0 == strcmp (words[cmdi], "-c")) {
+ /* If -c option is provided then command should look like
+ * snapshot restore -c <cg-name>
+ *
+ * cmdi points to -c, therefore wordcount should be exactly
+ * equal to (cmdi + 1) + 1. +1 is added to convert index to
+ * count
+ */
+ if ((cmdi + 2) != wordcount) {
+ gf_log ("cli", GF_LOG_ERROR, "Invalid argument count");
+ goto out;
+ }
+ cg_name = words[++cmdi];
+
+ ret = dict_set_str (dict, "cgname", (char *)cg_name);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to set "
+ "CG name");
+ goto out;
+ }
+ } else {
+ gf_log ("cli", GF_LOG_ERROR, "Invalid (%s) option",
+ words[cmdi]);
+ goto out;
+ }
+
+ ret = 0; /* Success */
+out:
+ return ret;
+}
+
+
int32_t
cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options)
{
int32_t ret = -1;
dict_t *dict = NULL;
gf1_cli_snapshot type = GF_SNAP_OPTION_TYPE_NONE;
- int32_t cmdi = 0;
- char *opwords[] = {"create", "list", "config", NULL};
+ unsigned int cmdi = 0;
char *w = NULL;
int i = 0;
+ char *opwords[] = {"create", "delete", "restore",
+ "start", "stop", "list", "status",
+ "config", NULL};
GF_ASSERT (words);
GF_ASSERT (options);
@@ -3257,7 +3357,6 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options)
if (!dict)
goto out;
-
/* Lowest wordcount possible */
if (wordcount < 2) {
gf_log ("", GF_LOG_ERROR,
@@ -3274,29 +3373,54 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options)
/* Check which op is intended */
if (strcmp (w, "create") == 0) {
- /*syntax:
- *snapshot create <volnames> [-n <snap-name/cg-name>] [-d <description>]
- */
+ /*syntax:
+ * snapshot create <volnames> [-n <snap-name/cg-name>]
+ * [-d <description>]
+ */
- /* In cases where the vol-name is not given
- * parsing fails. volname cannot be an opword.
- * and that is what this check verifies */
+ /* In cases where the vol-name is not given
+ * parsing fails. volname cannot be an opword.
+ * and that is what this check verifies */
w = str_getunamb (words[2], opwords);
if (w)
goto out;
+
type = GF_SNAP_OPTION_TYPE_CREATE;
cmdi = 1;
- ret = cli_snap_create_parse (dict, words,
- wordcount, cmdi);
+ ret = cli_snap_create_parse (dict, words, wordcount, cmdi);
if (ret) {
gf_log ("", GF_LOG_ERROR,
"create command parsing failed.");
goto out;
}
+ } else if (strcmp (w, "delete") == 0) {
+ gf_log ("", GF_LOG_ERROR, "Operation Not supported");
+ goto out;
+ } else if (strcmp (w, "restore") == 0) {
+ /* Syntax:
+ * snapshot restore (-v <volname> <snap-name> | -c <cg-name> )
+ */
+ type = GF_SNAP_OPTION_TYPE_RESTORE;
+
+ /* Start parsing from the first option after "restore" */
+ cmdi = 2;
+
+ ret = cli_snap_restore_parse (dict, words, wordcount, cmdi);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to parse "
+ "restore command");
+ goto out;
+ }
+ } else if (strcmp (w, "start") == 0) {
+ gf_log ("", GF_LOG_ERROR, "Operation Not supported");
+ goto out;
+ } else if (strcmp (w, "stop") == 0) {
+ gf_log ("", GF_LOG_ERROR, "Operation Not supported");
+ goto out;
} else if (strcmp (w, "list") == 0) {
- /* snapshot list [<volnames> | <volname> [-s <snapname>]
- * | -c <cgname>] [-d] */
+ /* snapshot list [<volnames> | <volname> [-s <snapname>]
+ * | -c <cgname>] [-d] */
/* check if arguments contains any Keyword */
cmdi = 2;
for (i = cmdi ; i < wordcount ; i++) {
@@ -3319,7 +3443,10 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options)
"list command parsing failed.");
goto out;
}
- } else if (strcmp (w, "config") == 0){
+ } else if (strcmp (w, "status") == 0) {
+ gf_log ("", GF_LOG_ERROR, "Operation Not supported");
+ goto out;
+ } else if (strcmp (w, "config") == 0) {
/* snapshot config <volname | all> [snap_max_limit <count>] */
type = GF_SNAP_OPTION_TYPE_CONFIG;
diff --git a/cli/src/cli-cmd-snapshot.c b/cli/src/cli-cmd-snapshot.c
index 6c2b3d5e5..9f52ab01b 100644
--- a/cli/src/cli-cmd-snapshot.c
+++ b/cli/src/cli-cmd-snapshot.c
@@ -77,11 +77,15 @@ struct cli_cmd snapshot_cmds[] = {
cli_cmd_snapshot_help_cbk,
"display help for snapshot commands"
},
- {"snapshot create <volnames> [-n <snap-name|cg-name>] [-d <description>]",
+ { "snapshot create <volnames> [-n <snap-name|cg-name>] [-d <description>]",
cli_cmd_snapshot_cbk,
"Snapshot Create."
},
- {"snapshot list [<volnames> | <volname> [-s <snapname>]"
+ { "snapshot restore (-v <volname> <snap-name> | -c <cg-name>)",
+ cli_cmd_snapshot_cbk,
+ "Snapshot Restore."
+ },
+ { "snapshot list [<volnames> | <volname> [-s <snapname>]"
" | -c <cgname> ] [-d]",
cli_cmd_snapshot_cbk,
"Snapshot List."
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index fdac00384..870588e9a 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -7889,6 +7889,38 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,
snap_name);
}
break;
+ case GF_SNAP_OPTION_TYPE_RESTORE:
+ /* TODO: Check if rsp.op_ret needs to be checked here. Or is
+ * it ok to check this in the start of the function where we
+ * get rsp.*/
+ if (rsp.op_ret) {
+ cli_err("snapshot restore: failed: %s",
+ rsp.op_errstr ? rsp.op_errstr :
+ "Please check log file for details");
+ ret = rsp.op_ret;
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "cg-name", &cg_name);
+ if (ret) {
+ ret = dict_get_str (dict, "snap-name", &snap_name);
+ if (ret) {
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "Failed to get CG name or snap name");
+ goto out;
+ }
+ }
+
+ if (NULL != snap_name) {
+ cli_out ("Snapshot restore: %s: Snap restored "
+ "successfully", snap_name);
+ } else {
+ cli_out ("Snapshot restore: %s: Consistency group "
+ "restored successfully", cg_name);
+ }
+
+ ret = 0;
+ break;
case GF_SNAP_OPTION_TYPE_LIST:
if (rsp.op_ret) {