summaryrefslogtreecommitdiffstats
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/src/cli-cmd-parser.c156
-rw-r--r--cli/src/cli-cmd-snapshot.c8
-rw-r--r--cli/src/cli-rpc-ops.c48
3 files changed, 205 insertions, 7 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index de0654a744b..e7f41fa7203 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -3297,6 +3297,102 @@ out:
return ret;
}
+/* snapshot activate <snapname> [force]
+ * @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.
+ *
+ * return value : -1 on failure
+ * 0 on success
+ */
+int
+cli_snap_activate_parse (dict_t *dict, const char **words, int wordcount)
+{
+
+ int ret = -1;
+ int flags = 0;
+
+ GF_ASSERT (words);
+ GF_ASSERT (dict);
+
+ if ((wordcount < 3) || (wordcount > 4)) {
+ gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
+
+ ret = dict_set_str (dict, "snapname", (char *)words[2]);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Unable to save snap-name %s",
+ words[2]);
+ goto out;
+ }
+
+ if (wordcount == 4) {
+ if (!strcmp("force", (char *)words[3])) {
+ flags = GF_CLI_FLAG_OP_FORCE;
+ } else {
+ gf_log ("cli", GF_LOG_ERROR, "Invalid option");
+ ret = -1;
+ goto out;
+ }
+ }
+ ret = dict_set_int32 (dict, "flags", flags);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Unable to save force option");
+ goto out;
+ }
+out:
+ return ret;
+}
+
+/* snapshot deactivate <snapname>
+ * @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.
+ *
+ * return value : -1 on failure
+ * 0 on success
+ * 1 if user cancelled the request
+ */
+int
+cli_snap_deactivate_parse (dict_t *dict, const char **words, int wordcount,
+ struct cli_state *state)
+{
+
+ int ret = -1;
+ gf_answer_t answer = GF_ANSWER_NO;
+ const char *question = "Deactivating snap will make its "
+ "data inaccessible. Do you want to "
+ "continue?";
+
+
+ GF_ASSERT (words);
+ GF_ASSERT (dict);
+
+ if ((wordcount != 3)) {
+ gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
+
+ ret = dict_set_str (dict, "snapname", (char *)words[2]);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Unable to save snap-name %s",
+ words[2]);
+ goto out;
+ }
+
+ answer = cli_cmd_get_confirmation (state, question);
+ if (GF_ANSWER_NO == answer) {
+ ret = 1;
+ gf_log ("cli", GF_LOG_DEBUG, "User cancelled "
+ "snapshot deactivate operation");
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
/* snapshot delete <snapname>
* @arg-0, dict : Request Dictionary to be sent to server side.
* @arg-1, words : Contains individual words of CLI command.
@@ -3648,9 +3744,9 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
dict_t *dict = NULL;
gf1_cli_snapshot type = GF_SNAP_OPTION_TYPE_NONE;
char *w = NULL;
- char *opwords[] = {"create", "delete", "restore", "start",
- "stop", "list", "status", "config",
- "info", NULL};
+ char *opwords[] = {"create", "delete", "restore",
+ "activate", "deactivate", "list",
+ "status", "config", "info", NULL};
char *invalid_snapnames[] = {"description", "force",
"volume", NULL};
@@ -3690,8 +3786,11 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
type = GF_SNAP_OPTION_TYPE_RESTORE;
} else if (!strcmp (w, "status")) {
type = GF_SNAP_OPTION_TYPE_STATUS;
+ } else if (!strcmp (w, "activate")) {
+ type = GF_SNAP_OPTION_TYPE_ACTIVATE;
+ } else if (!strcmp (w, "deactivate")) {
+ type = GF_SNAP_OPTION_TYPE_DEACTIVATE;
}
-
if (type != GF_SNAP_OPTION_TYPE_CONFIG) {
ret = dict_set_int32 (dict, "hold_snap_locks", _gf_true);
if (ret) {
@@ -3702,6 +3801,18 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
}
}
+ /* Following commands does not require volume locks */
+ if (type == GF_SNAP_OPTION_TYPE_STATUS ||
+ type == GF_SNAP_OPTION_TYPE_ACTIVATE ||
+ type == GF_SNAP_OPTION_TYPE_DEACTIVATE) {
+ ret = dict_set_int32 (dict, "hold_vol_locks", _gf_false);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Setting volume lock "
+ "flag failed");
+ goto out;
+ }
+ }
+
/* Check which op is intended */
switch (type) {
case GF_SNAP_OPTION_TYPE_CREATE:
@@ -3764,8 +3875,12 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
*/
ret = cli_snap_delete_parse (dict, words, wordcount, state);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to parse "
- "snapshot delete command");
+ /* A positive ret value means user cancelled
+ * the command */
+ if (ret < 0) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to parse "
+ "snapshot delete command");
+ }
goto out;
}
break;
@@ -3816,7 +3931,34 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
goto out;
}
break;
-
+ case GF_SNAP_OPTION_TYPE_ACTIVATE:
+ /* Syntax:
+ * snapshot activate <snapname> [force]
+ */
+ ret = cli_snap_activate_parse (dict, words, wordcount);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to parse "
+ "start command");
+ goto out;
+ }
+ break;
+ case GF_SNAP_OPTION_TYPE_DEACTIVATE:
+ /* Syntax:
+ * snapshot deactivate <snapname>
+ */
+ ret = cli_snap_deactivate_parse (dict, words, wordcount,
+ state);
+ if (ret) {
+ /* A positive ret value means user cancelled
+ * the command */
+ if (ret < 0) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Failed to parse deactivate "
+ "command");
+ }
+ goto out;
+ }
+ break;
default:
gf_log ("", GF_LOG_ERROR, "Opword Mismatch");
goto out;
diff --git a/cli/src/cli-cmd-snapshot.c b/cli/src/cli-cmd-snapshot.c
index 941dcbdd2a3..45fa5673f7a 100644
--- a/cli/src/cli-cmd-snapshot.c
+++ b/cli/src/cli-cmd-snapshot.c
@@ -110,6 +110,14 @@ struct cli_cmd snapshot_cmds[] = {
cli_cmd_snapshot_cbk,
"Snapshot Delete."
},
+ {"snapshot activate <snapname> [force]",
+ cli_cmd_snapshot_cbk,
+ "Activate snapshot volume."
+ },
+ {"snapshot deactivate <snapname>",
+ cli_cmd_snapshot_cbk,
+ "Deactivate snapshot volume."
+ },
{ NULL, NULL, NULL }
};
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index 47614323e3e..f174e27e46d 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -8544,7 +8544,55 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,
ret = 0;
break;
+ case GF_SNAP_OPTION_TYPE_ACTIVATE:
+ /* 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 activate: 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, "snapname", &snap_name);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Failed to get snap name");
+ goto out;
+ }
+
+ cli_out ("Snapshot activate: %s: Snap activated "
+ "successfully", snap_name);
+
+ ret = 0;
+ break;
+ case GF_SNAP_OPTION_TYPE_DEACTIVATE:
+ /* 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 deactivate: 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, "snapname", &snap_name);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Failed to get snap name");
+ goto out;
+ }
+
+ cli_out ("Snapshot deactivate: %s: Snap deactivated "
+ "successfully", snap_name);
+
+ ret = 0;
+ break;
case GF_SNAP_OPTION_TYPE_INFO:
if (rsp.op_ret) {
cli_err ("Snapshot info : failed: %s",