diff options
Diffstat (limited to 'cli')
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 156 | ||||
| -rw-r--r-- | cli/src/cli-cmd-snapshot.c | 8 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 48 | 
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",  | 
