diff options
Diffstat (limited to 'cli/src')
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 73 | ||||
| -rw-r--r-- | cli/src/cli-cmd-snapshot.c | 2 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 216 | 
3 files changed, 268 insertions, 23 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index b4dc3fe49bd..4811293dbb8 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -3422,7 +3422,7 @@ cli_snap_info_parse (dict_t *dict, const char **words, int wordcount)          GF_ASSERT (dict);          if (wordcount > 4 || wordcount < cmdi) { -                gf_log ("", GF_LOG_ERROR, "Invalid syntax"); +                gf_log ("cli", GF_LOG_ERROR, "Invalid syntax");                  goto out;          } @@ -3473,7 +3473,7 @@ cli_snap_info_parse (dict_t *dict, const char **words, int wordcount)          ret = dict_set_str (dict, "volname", (char *)words[wordcount - 1]);          if (ret) { -                gf_log ("", GF_LOG_ERROR, "Count not save " +                gf_log ("cli", GF_LOG_ERROR, "Could not save "                          "volume name %s", words[wordcount - 1]);                  goto out;          } @@ -3634,34 +3634,71 @@ cli_snap_delete_parse (dict_t *dict, const char **words, int wordcount,          int             ret             =       -1;          const char      *question       =       NULL; +        int32_t         cmd             =       -1; +        unsigned int    cmdi            =       2;          gf_answer_t     answer          =       GF_ANSWER_NO; -        question = "Deleting snap will erase all the information about " -                   "the snap. Do you still want to continue?"; -          GF_ASSERT (words);          GF_ASSERT (dict); -        if (wordcount != 3) { +        if (wordcount > 4 || wordcount <= cmdi) {                  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 snapname %s", -                        words[2]); -                goto out; +        question = "Deleting snap will erase all the information about " +                   "the snap. Do you still want to continue?"; + +        if (strcmp (words [cmdi], "all") == 0) { +                ret = 0; +                cmd = GF_SNAP_DELETE_TYPE_ALL; +        } else if (strcmp (words [cmdi], "volume") == 0) { +                if (++cmdi == wordcount) { +                        ret = -1; +                        gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax"); +                        goto out; +                } + +                ret = dict_set_str (dict, "volname", +                                    (char *)words[cmdi]); +                if (ret) { +                        gf_log ("cli", GF_LOG_ERROR, "Could not save " +                                "volume name %s", words[wordcount - 1]); +                        goto out; +                } +                cmd = GF_SNAP_DELETE_TYPE_VOL; +        } else { +                ret = dict_set_str (dict, "snapname", (char *)words[cmdi]); +                if (ret) { +                        gf_log ("cli", GF_LOG_ERROR, "Unable to save " +                                "snapname %s", words[2]); +                        goto out; +                } +                cmd = GF_SNAP_DELETE_TYPE_SNAP;          } -        answer = cli_cmd_get_confirmation (state, question); -        if (GF_ANSWER_NO == answer) { -                ret = 1; -                gf_log ("cli", GF_LOG_DEBUG, "User cancelled " -                        "snapshot delete operation for snap %s", -                        (char *)words[2]); +        if ((cmdi + 1) != wordcount) { +                ret = -1; +                gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");                  goto out;          } + +        if (cmd == GF_SNAP_DELETE_TYPE_SNAP) { +                answer = cli_cmd_get_confirmation (state, question); +                if (GF_ANSWER_NO == answer) { +                        ret = 1; +                        gf_log ("cli", GF_LOG_DEBUG, "User cancelled " +                                "snapshot delete operation for snap %s", +                                (char *)words[2]); +                        goto out; +                } +        } + +        ret = dict_set_int32 (dict, "delete-cmd", cmd); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Could not save " +                        "type of snapshot delete"); +        }  out:          return ret;  } @@ -4000,7 +4037,7 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,                                          "activate", "deactivate", "list",                                          "status", "config", "info", NULL};          char               *invalid_snapnames[] = {"description", "force", -                                                  "volume", NULL}; +                                                  "volume", "all", NULL};          GF_ASSERT (words);          GF_ASSERT (options); diff --git a/cli/src/cli-cmd-snapshot.c b/cli/src/cli-cmd-snapshot.c index 1fb4e5e634c..07d04595b06 100644 --- a/cli/src/cli-cmd-snapshot.c +++ b/cli/src/cli-cmd-snapshot.c @@ -108,7 +108,7 @@ struct cli_cmd snapshot_cmds[] = {            cli_cmd_snapshot_cbk,            "Snapshot Config."          }, -        {"snapshot delete <snapname>", +        {"snapshot delete (all | snapname | volume <volname>)",            cli_cmd_snapshot_cbk,            "Snapshot Delete."          }, diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index a240f376f7f..268f5434a75 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -7721,11 +7721,14 @@ out:  }  int32_t -cli_snapshot_remove_reply (gf_cli_rsp *rsp, dict_t *dict) +cli_snapshot_remove_reply (gf_cli_rsp *rsp, dict_t *dict, call_frame_t *frame)  { -        int32_t       ret        = -1; -        char         *snap_name  = NULL; +        int32_t         ret             = -1; +        char            *snap_name      = NULL; +        int32_t         delete_cmd      = -1; +        cli_local_t     *local          = NULL; +        GF_ASSERT (frame);          GF_ASSERT (rsp);          GF_ASSERT (dict); @@ -7737,6 +7740,31 @@ cli_snapshot_remove_reply (gf_cli_rsp *rsp, dict_t *dict)                  goto out;          } +        ret = dict_get_int32 (dict, "delete-cmd", &delete_cmd); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Could not get delete-cmd"); +                goto out; +        } + +        if (delete_cmd == GF_SNAP_DELETE_TYPE_ALL || +            delete_cmd == GF_SNAP_DELETE_TYPE_VOL) { +                local = ((call_frame_t *) frame) -> local; +                if (!local) { +                        ret = -1; +                        gf_log ("cli", GF_LOG_ERROR, "frame->local is NULL"); +                        goto out; +                } + +                /* During first call back of snapshot delete of type +                 * ALL and VOL, We will get the snapcount and snapnames. +                 * Hence to make the subsequent rpc calls for individual +                 * snapshot delete, We need to save it in local dictionary. +                 */ +                dict_copy (dict, local->dict); +                ret = 0; +                goto out; +        } +          ret = dict_get_str (dict, "snapname", &snap_name);          if (ret) {                  gf_log ("cli", GF_LOG_ERROR, "Failed to get snapname"); @@ -8455,6 +8483,60 @@ out:          return ret;  } +int32_t +cli_populate_req_dict_for_delete (dict_t *snap_dict, dict_t *dict, size_t index) +{ +        int32_t         ret             = -1; +        char            key[PATH_MAX]   = ""; +        char            *buffer         = NULL; +        int             type            = 0; +        int             snapcount       = 0; + +        GF_ASSERT (snap_dict); +        GF_ASSERT (dict); + +        ret = dict_set_int32 (snap_dict, "delete-cmd", +                              GF_SNAP_DELETE_TYPE_SNAP); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Could not save command " +                        "type in snap dictionary"); +                goto out; +        } + +        ret = snprintf (key, sizeof (key), "snapname%lu", index); +        if (ret < 0) { +                goto out; +        } + +        ret = dict_get_str (dict, key, &buffer); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Failed to get snapname"); +                goto out; +        } + +        ret = dict_set_dynstr_with_alloc (snap_dict, "snapname", buffer); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Failed to save snapname"); +                goto out; +        } + +        ret = dict_set_int32 (snap_dict, "type", GF_SNAP_OPTION_TYPE_DELETE); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Failed to save command type"); +                goto out; +        } + +        ret = dict_set_dynstr_with_alloc (snap_dict, "cmd-str", +                                       "snapshot delete"); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, +                        "Could not save command string as delete"); +                goto out; +        } +out: +        return ret; +} +  int  cli_populate_req_dict_for_status (dict_t *snap_dict, dict_t *dict, int index) {          int             ret             =       -1; @@ -8820,7 +8902,7 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,                  break;          case GF_SNAP_OPTION_TYPE_DELETE: -                ret = cli_snapshot_remove_reply (&rsp, dict); +                ret = cli_snapshot_remove_reply (&rsp, dict, frame);                  if (ret) {                          gf_log ("cli", GF_LOG_ERROR,                                  "Failed to delete snap"); @@ -8854,6 +8936,123 @@ out:  }  int32_t +gf_cli_snapshot_for_delete (call_frame_t *frame, xlator_t *this, +                            void *data) +{ +        gf_cli_req      req                     = {{0,}}; +        dict_t          *options                = NULL; +        int32_t         ret                     = -1; +        int32_t         cmd                     = -1; +        cli_local_t     *local                  = NULL; +        dict_t          *snap_dict              = NULL; +        int32_t         snapcount               = 0; +        int             i                       = 0; +        char            question[PATH_MAX]      = ""; +        char            *volname                = NULL; +        gf_answer_t     answer                  = GF_ANSWER_NO; + +        GF_VALIDATE_OR_GOTO ("cli", frame,  out); +        GF_VALIDATE_OR_GOTO ("cli", frame->local, out); +        GF_VALIDATE_OR_GOTO ("cli", this, out); +        GF_VALIDATE_OR_GOTO ("cli", data, out); + +        local = frame->local; + +        options = data; + +        ret = dict_get_int32 (local->dict, "delete-cmd", &cmd); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Failed to get " +                        "delete-cmd"); +                goto out; +        } + +        /* No need multiple RPCs for individual snapshot delete*/ +        if (cmd == GF_SNAP_DELETE_TYPE_SNAP) { +                ret = 0; +                goto out; +        } + +        ret = dict_get_int32 (local->dict, "snapcount", +                              &snapcount); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Could not get " +                        "snapcount"); +                goto out; +        } + +        if (snapcount == 0) { +                cli_out ("No snapshots present"); +                goto out; +        } + +        if (cmd == GF_SNAP_DELETE_TYPE_ALL) { +                snprintf (question, sizeof (question), "System contains %d " +                          "snapshot(s).\nDo you still " +                          "want to continue and delete them? ", +                           snapcount); +        } else { +                ret = dict_get_str (local->dict, "volname", &volname); +                if (ret) { +                        gf_log ("cli", GF_LOG_ERROR, "Failed to fetch " +                                "volname from local dictionary"); +                        goto out; +                } + +                snprintf (question, sizeof (question), "Volume (%s) contains " +                          "%d snapshot(s).\nDo you still want to " +                           "continue and delete them? ", volname, +                           snapcount); +        } + +        answer = cli_cmd_get_confirmation (global_state, question); +        if (GF_ANSWER_NO == answer) { +                ret = 0; +                gf_log ("cli", GF_LOG_DEBUG, "User cancelled " +                        "snapshot delete operation for snap delete"); +                goto out; +        } + +        for (i = 1 ; i <= snapcount ; i++) { +                ret = -1; + +                snap_dict = dict_new(); +                if (!snap_dict) +                        goto out; + +                ret = cli_populate_req_dict_for_delete (snap_dict, +                                                       local->dict, i); +                if (ret) { +                        gf_log ("cli", GF_LOG_ERROR, "Could not " +                                "populate snap request dictionary"); +                        goto out; +                } + +                ret = cli_to_glusterd (&req, frame, +                                gf_cli_snapshot_cbk, +                                (xdrproc_t) xdr_gf_cli_req, snap_dict, +                                GLUSTER_CLI_SNAP, this, cli_rpc_prog, +                                NULL); +                if (ret) { +                        /* Fail the operation if deleting one of the +                         * snapshots is failed +                         */ +                        gf_log ("cli", GF_LOG_ERROR, "cli_to_glusterd " +                                "for snapshot delete failed"); +                        goto out; +                } +                dict_unref (snap_dict); +                snap_dict = NULL; +        } + +out: +        if (snap_dict) +                dict_unref (snap_dict); + +        return ret; +} + +int32_t  gf_cli_snapshot_for_status (call_frame_t *frame, xlator_t *this,                              void *data)  { @@ -9007,6 +9206,15 @@ gf_cli_snapshot (call_frame_t *frame, xlator_t *this,                  }          } +        if (GF_SNAP_OPTION_TYPE_DELETE == type) { +                ret = gf_cli_snapshot_for_delete (frame, this, data); +                if (ret) { +                        gf_log ("cli", GF_LOG_ERROR, "cli to glusterd " +                                "for snapshot delete command failed"); +                        goto out; +                } +        } +          ret = 0;  out:  | 
