diff options
Diffstat (limited to 'cli')
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 55 | ||||
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 70 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 72 | ||||
| -rw-r--r-- | cli/src/cli.h | 4 | 
4 files changed, 200 insertions, 1 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 6d984680e..d3cb1240f 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -1731,3 +1731,58 @@ cli_cmd_volume_status_parse (const char **words, int wordcount,          return ret;  } + +gf_boolean_t +cli_cmd_validate_dumpoption (const char *option) +{ +        char    *opwords[] = {"all", "mem", "iobuf", "callpool", "priv", "fd", +                              "inode", NULL}; +        char    *w = NULL; + +        w = str_getunamb (option, opwords); +        if (!w) { +                gf_log ("cli", GF_LOG_DEBUG, "Unknown statedump option  %s", +                        option); +                return _gf_false; +        } +        return _gf_true; +} + +int +cli_cmd_volume_statedump_options_parse (const char **words, int wordcount, +                                        dict_t **options) +{ +        int     ret = 0; +        int     i = 0; +        dict_t  *dict = NULL; +        int     option_cnt = 0; +        char    option_str[100] = {0,}; + +        for (i = 3; i < wordcount; i++, option_cnt++) { +                if (!cli_cmd_validate_dumpoption (words[i])) { +                        ret = -1; +                        goto out; +                } +                strncat (option_str, words[i], sizeof (words [i])); +                strncat (option_str, " ", 1); +        } +        dict = dict_new (); +        if (!dict) +                goto out; + +        ret = dict_set_str (dict, "options", gf_strdup (option_str)); +        if (ret) +                goto out; + +        ret = dict_set_int32 (dict, "option-cnt", option_cnt); +        if (ret) +                goto out; + +        *options = dict; +out: +        if (ret && dict) +                dict_destroy (dict); +        if (ret) +                gf_log ("cli", GF_LOG_ERROR, "Error parsing dumpoptions"); +        return ret; +} diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 000772532..9b85bf819 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1510,6 +1510,72 @@ out:          return ret;  } +int +cli_cmd_volume_statedump_cbk (struct cli_state *state, struct cli_cmd_word *word, +                              const char **words, int wordcount) +{ +        int                             ret = -1; +        rpc_clnt_procedure_t            *proc = NULL; +        call_frame_t                    *frame = NULL; +        dict_t                          *options = NULL; +        int                             sent = 0; +        int                             parse_error = 0; + +        frame = create_frame (THIS, THIS->ctx->pool); +        if (!frame) +                goto out; + +        if (wordcount < 3) { +                cli_usage_out (word->pattern); +                parse_error = 1; +                goto out; +        } + +        if (wordcount > 3) { +               ret = cli_cmd_volume_statedump_options_parse (words, wordcount, +                                                              &options); +               if (ret) { +                       parse_error = 1; +                       gf_log ("cli", GF_LOG_ERROR, "Error parsing " +                               "statedump options"); +                       cli_out ("Error parsing options"); +                       cli_usage_out (word->pattern); +               } +        } else { +                options = dict_new (); +                if (!options) { +                        ret = -1; +                        gf_log ("cli", GF_LOG_ERROR, "Could not create dict"); +                        goto out; +                } +                ret = dict_set_str (options, "options",""); +                if (ret) +                        goto out; +                ret = dict_set_int32 (options, "option-cnt", 0); +                if (ret) +                        goto out; +        } + +        ret = dict_set_str (options, "volname", (char *)words[2]); +        if (ret) +                goto out; + +        proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STATEDUMP_VOLUME]; +        if (proc->fn) { +                ret = proc->fn (frame, THIS, options); +        } + +out: +        if (ret) { +                cli_cmd_sent_status_get (&sent); +                if ((sent == 0) && (parse_error = 0)) +                        cli_out ("Volume statedump failed"); +        } + +        return ret; +} + +  struct cli_cmd volume_cmds[] = {          { "volume info [all|<VOLNAME>]",            cli_cmd_volume_info_cbk, @@ -1616,6 +1682,10 @@ struct cli_cmd volume_cmds[] = {            cli_cmd_volume_heal_cbk,            "Start healing of volume specified by <VOLNAME>"}, +        {"volume statedump <VOLNAME> [all|mem|iobuf|callpool|priv|fd|inode]...", +         cli_cmd_volume_statedump_cbk, +         "perform statedump on bricks"}, +          { NULL, NULL, NULL }  }; diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index b58e03173..1e77ae0ab 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -4000,7 +4000,76 @@ out:          return ret;  } +int32_t +gf_cli3_1_statedump_volume_cbk (struct rpc_req *req, struct iovec *iov, +                                int count, void *myframe) +{ +        gf1_cli_statedump_vol_rsp       rsp = {0,}; +        int                             ret = -1; + +        if (-1 == req->rpc_status) +                goto out; +        ret = xdr_to_generic (*iov, &rsp, +                              (xdrproc_t)xdr_gf1_cli_statedump_vol_rsp); +        if (ret < 0) { +                gf_log (THIS->name, GF_LOG_ERROR, "XDR decoding failed"); +                goto out; +        } +        gf_log ("cli", GF_LOG_DEBUG, "Recieved response to statedump"); +        if (rsp.op_ret) +                cli_out ("%s", rsp.op_errstr); +        else +                cli_out ("Volume statedump sucessful"); + +        ret = rsp.op_ret; + +out: +        cli_cmd_broadcast_response (ret); +        return ret; +} + +int32_t +gf_cli3_1_statedump_volume (call_frame_t *frame, xlator_t *this, +                            void *data) +{ +        gf1_cli_statedump_vol_req       req = {0,}; +        dict_t                          *options = NULL; +        char                            *volname = NULL; +        char                            *option_str = NULL; +        int                             option_cnt = 0; +        int                             ret = -1; + +        if (!frame || !this || !data) +                goto out; + +        options = data; + +        ret = dict_get_str (options, "volname", &volname); +        if (ret) +                goto out; +        req.volname = volname; + +        ret = dict_get_str (options, "options", &option_str); +        if (ret) +                goto out; +        req.options = option_str; + +        ret = dict_get_int32 (options, "option-cnt", &option_cnt); +        if (ret) +                goto out; +        req.option_cnt = option_cnt; +        ret = cli_cmd_submit (&req, frame, cli_rpc_prog, +                              GLUSTER_CLI_STATEDUMP_VOLUME, NULL, +                              this, gf_cli3_1_statedump_volume_cbk, +                              (xdrproc_t)xdr_gf1_cli_statedump_vol_req); + +out: +        if (options) +                dict_destroy (options); +        gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +}  struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {          [GLUSTER_CLI_NULL]             = {"NULL", NULL }, @@ -4036,7 +4105,8 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {          [GLUSTER_CLI_STATUS_VOLUME]    = {"STATUS_VOLUME", gf_cli3_1_status_volume},          [GLUSTER_CLI_MOUNT]            = {"MOUNT", gf_cli3_1_mount},          [GLUSTER_CLI_UMOUNT]           = {"UMOUNT", gf_cli3_1_umount}, -        [GLUSTER_CLI_HEAL_VOLUME]      = {"HEAL_VOLUME", gf_cli3_1_heal_volume} +        [GLUSTER_CLI_HEAL_VOLUME]      = {"HEAL_VOLUME", gf_cli3_1_heal_volume}, +        [GLUSTER_CLI_STATEDUMP_VOLUME] = {"STATEDUMP_VOLUME", gf_cli3_1_statedump_volume},  };  struct rpc_clnt_program cli_prog = { diff --git a/cli/src/cli.h b/cli/src/cli.h index 4ef1dbe06..0a2fdb54b 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -230,6 +230,10 @@ cli_cmd_log_locate_parse (const char **words, int wordcount, dict_t **options);  int32_t  cli_cmd_log_filename_parse (const char **words, int wordcount, dict_t **options); +int32_t +cli_cmd_volume_statedump_options_parse (const char **words, int wordcount, +                                        dict_t **options); +  cli_local_t * cli_local_get ();  void  | 
