diff options
Diffstat (limited to 'cli')
| -rw-r--r-- | cli/src/Makefile.am | 3 | ||||
| -rw-r--r-- | cli/src/cli-cmd-misc.c | 7 | ||||
| -rw-r--r-- | cli/src/cli-cmd-volume-bdevice.c | 225 | ||||
| -rw-r--r-- | cli/src/cli-cmd.c | 5 | ||||
| -rw-r--r-- | cli/src/cli-cmd.h | 4 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 131 | ||||
| -rw-r--r-- | cli/src/cli.h | 13 | 
7 files changed, 387 insertions, 1 deletions
diff --git a/cli/src/Makefile.am b/cli/src/Makefile.am index 39307768..7054f112 100644 --- a/cli/src/Makefile.am +++ b/cli/src/Makefile.am @@ -3,6 +3,9 @@ sbin_PROGRAMS = gluster  gluster_SOURCES = cli.c registry.c input.c cli-cmd.c cli-rl.c \  	 cli-cmd-volume.c cli-cmd-peer.c cli-rpc-ops.c cli-cmd-parser.c\  	 cli-cmd-system.c cli-cmd-misc.c cli-xml-output.c +if ENABLE_BD_XLATOR +gluster_SOURCES += cli-cmd-volume-bdevice.c +endif  gluster_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la $(GF_LDADD)\  		$(RLLIBS) $(top_builddir)/rpc/xdr/src/libgfxdr.la \ diff --git a/cli/src/cli-cmd-misc.c b/cli/src/cli-cmd-misc.c index f3ef1214..5f3a77ca 100644 --- a/cli/src/cli-cmd-misc.c +++ b/cli/src/cli-cmd-misc.c @@ -31,6 +31,7 @@ extern struct cli_cmd volume_cmds[];  extern struct cli_cmd cli_probe_cmds[];  extern struct cli_cmd cli_log_cmds[];  extern struct cli_cmd cli_system_cmds[]; +extern struct cli_cmd cli_bd_cmds[];  struct cli_cmd cli_misc_cmds[];  int @@ -45,7 +46,11 @@ cli_cmd_display_help (struct cli_state *state, struct cli_cmd_word *in_word,                        const char **words, int wordcount)  {          struct cli_cmd        *cmd[] = {volume_cmds, cli_probe_cmds, -                                       cli_misc_cmds, NULL}; +                                       cli_misc_cmds, +#ifdef HAVE_BD_XLATOR +                                       cli_bd_cmds, +#endif +                                       NULL};          struct cli_cmd        *cmd_ind = NULL;          int                   i = 0; diff --git a/cli/src/cli-cmd-volume-bdevice.c b/cli/src/cli-cmd-volume-bdevice.c new file mode 100644 index 00000000..ea7edab6 --- /dev/null +++ b/cli/src/cli-cmd-volume-bdevice.c @@ -0,0 +1,225 @@ +/* +  CLI for BD translator + +  Copyright IBM, Corp. 2012 + +  This file is part of GlusterFS. + +  Author: +  M. Mohan Kumar <mohan@in.ibm.com> + +  This file is licensed to you under your choice of the GNU Lesser +  General Public License, version 3 or any later version (LGPLv3 or +  later), or the GNU General Public License, version 2 (GPLv2), in all +  cases as published by the Free Software Foundation. +*/ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "cli.h" +#include "cli-cmd.h" +#include <string.h> + +extern rpc_clnt_prog_t *cli_rpc_prog; + +int +cli_cmd_bd_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word, +                      const char **words, int wordcount); + +int32_t +cli_cmd_bd_parse (dict_t *dict, const char **words) +{ +        char          *volname  = NULL; +        char          *buff     = NULL; +        char          *buffp    = NULL; +        int            ret      = -1; +        char          *save     = NULL; +        char          *path     = NULL; +        char          *size     = NULL; +        char          *eptr     = NULL; +        gf_xl_bd_op_t  bd_op    = GF_BD_OP_INVALID; + +        /* volname:/path */ +        if (!strchr (words[2], ':') || !strchr (words[2], '/')) { +                cli_out ("invalid parameter %s, needs <volname:/path>", +                                words[2]); +                return -1; +        } +        buff = buffp = gf_strdup (words[2]); +        volname = strtok_r (buff, ":", &save); +        path = strtok_r (NULL, ":", &save); + +        ret = dict_set_dynstr (dict, "volname", gf_strdup (volname)); +        if (ret) +                goto out; + +        ret = dict_set_dynstr (dict, "path", gf_strdup (path)); +        if (ret) +                goto out; + +        if (!strcasecmp (words[1], "create")) +                bd_op = GF_BD_OP_NEW_BD; +        else if (!strcasecmp (words[1], "delete")) +                bd_op = GF_BD_OP_DELETE_BD; +        else +                return -1; + +        ret = dict_set_int32 (dict, "bd-op", bd_op); +        if (ret) +                goto out; + +        if (bd_op == GF_BD_OP_NEW_BD) { +                /* If no suffix given we will treat it as MB */ +                strtoull (words[3], &eptr, 0); +                /* no suffix */ +                if (!eptr[0]) +                        gf_asprintf (&size, "%sMB", words[3]); +                else +                        size = gf_strdup (words[3]); + +                ret = dict_set_dynstr (dict, "size", size); +                if (ret) +                        goto out; +        } + +        ret = 0; +out: +        GF_FREE (buffp); +        return ret; +} + +/* + * bd create <volname>:/path <size> + * bd delete <volname>:/path + */ +int32_t +cli_cmd_bd_validate (const char **words, int wordcount, dict_t **options) +{ +        dict_t  *dict = NULL; +        int     ret   = -1; +        char    *op[] = { "create", "delete", NULL }; +        int     index = 0; + +        for (index = 0; op[index]; index++) +                if (!strcasecmp (words[1], op[index])) +                        break; + +        if (!op[index]) +                return -1; + +        dict = dict_new (); +        if (!dict) +                goto out; + +        if (!strcasecmp (words[1], "create")) { +                if (wordcount != 4) +                        goto out; +        } else if (!strcasecmp (words[1], "delete")) { +                if (wordcount != 3) +                        goto out; +        } else { +                ret = -1; +                goto out; +        } + +        ret = cli_cmd_bd_parse (dict, words); +        if (ret < 0) +                goto out; + +        *options = dict; +        ret = 0; +out: +        if (ret) +                dict_unref (dict); +        return ret; +} + +int +cli_cmd_bd_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; +        int                     sent        = 0; +        int                     parse_error = 0; +        dict_t                  *options    = NULL; +        cli_local_t             *local = NULL; + +        proc = &cli_rpc_prog->proctable[GLUSTER_CLI_BD_OP]; + +        frame = create_frame (THIS, THIS->ctx->pool); +        if (!frame) +                goto out; + +        ret = cli_cmd_bd_validate (words, wordcount, &options); +        if (ret) { +                cli_usage_out (word->pattern); +                parse_error = 1; +                goto out; +        } + +        CLI_LOCAL_INIT (local, words, frame, options); +        if (proc->fn) { +                ret = proc->fn (frame, THIS, options); +        } + +out: +        if (options) +                dict_unref (options); + +        if (ret) { +                cli_cmd_sent_status_get (&sent); +                if ((sent == 0) && (parse_error == 0)) +                        cli_out ("BD op failed!"); +        } + +        CLI_STACK_DESTROY (frame); + +        return ret; +} + +struct cli_cmd cli_bd_cmds[] = { +        { "bd help", +           cli_cmd_bd_help_cbk, +           "display help for bd command"}, +        { "bd create <volname>:<bd> <size>", +          cli_cmd_bd_cbk, +          "\n\tcreate a block device where size can be " +          "suffixed with KB, MB etc. Default size is in MB"}, +        { "bd delete <volname>:<bd>", +          cli_cmd_bd_cbk, +          "Delete a block device"}, +        { NULL, NULL, NULL } +}; + +int +cli_cmd_bd_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word, +                      const char **words, int wordcount) +{ +        struct cli_cmd *cmd = NULL; + +        for (cmd = cli_bd_cmds; cmd->pattern; cmd++) +                if (_gf_false == cmd->disable) +                        cli_out ("%s - %s", cmd->pattern, cmd->desc); + +        return 0; +} + +int +cli_cmd_bd_register (struct cli_state *state) +{ +        int  ret = 0; +        struct cli_cmd *cmd = NULL; + +        for (cmd = cli_bd_cmds; cmd->pattern; cmd++) { +                ret = cli_cmd_register (&state->tree, cmd); +                if (ret) +                        goto out; +        } +out: +        return ret; +} diff --git a/cli/src/cli-cmd.c b/cli/src/cli-cmd.c index 64aba5d9..7a697603 100644 --- a/cli/src/cli-cmd.c +++ b/cli/src/cli-cmd.c @@ -231,6 +231,11 @@ cli_cmds_register (struct cli_state *state)          if (ret)                  goto out; +#ifdef HAVE_BD_XLATOR +        ret = cli_cmd_bd_register (state); +        if (ret) +                goto out; +#endif  out:          return ret;  } diff --git a/cli/src/cli-cmd.h b/cli/src/cli-cmd.h index a30a6cfe..0ad37d49 100644 --- a/cli/src/cli-cmd.h +++ b/cli/src/cli-cmd.h @@ -118,4 +118,8 @@ cli_cmd_submit (void *req, call_frame_t *frame,  gf_answer_t  cli_cmd_get_confirmation (struct cli_state *state, const char *question);  int cli_cmd_sent_status_get (int *status); + +#ifdef HAVE_BD_XLATOR +int cli_cmd_bd_register (struct cli_state *state); +#endif  #endif /* __CLI_CMD_H__ */ diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 77e15ee2..9e4e03d0 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -2601,6 +2601,134 @@ out:          return ret;  } +#ifdef HAVE_BD_XLATOR +int +gf_cli_bd_op_cbk (struct rpc_req *req, struct iovec *iov, +                             int count, void *myframe) +{ +        gf_cli_rsp              rsp         = {0,}; +        int                     ret         = -1; +        cli_local_t             *local      = NULL; +        dict_t                  *dict       = NULL; +        dict_t                  *input_dict = NULL; +        gf_xl_bd_op_t           bd_op       = GF_BD_OP_INVALID; +        char                    *operation  = NULL; +        call_frame_t            *frame      = NULL; + +        if (-1 == req->rpc_status) +                goto out; + +        ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp); +        if (ret < 0) { +                gf_log ("", GF_LOG_ERROR, "error"); +                goto out; +        } + +        dict = dict_new (); +        if (!dict) { +                ret = -1; +                goto out; +        } + +        frame = myframe; +        if (frame) +                local = frame->local; + +        if (local) { +                input_dict = local->dict; +                ret = dict_get_int32 (input_dict, "bd-op", +                                      (int32_t *)&bd_op); +        } + +        switch (bd_op) { +        case GF_BD_OP_NEW_BD: +                operation = gf_strdup ("create"); +                break; +        case GF_BD_OP_DELETE_BD: +                operation = gf_strdup ("delete"); +                break; +        default: +                break; +        } + +        ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict); +        if (ret) +                goto out; + +        gf_log ("cli", GF_LOG_INFO, "Received resp to %s bd op", operation); + +        if (global_state->mode & GLUSTER_MODE_XML) { +                ret = cli_xml_output_dict ("BdOp", dict, rsp.op_ret, +                                           rsp.op_errno, rsp.op_errstr); +                if (ret) +                        gf_log ("cli", GF_LOG_ERROR, +                                "Error outputting to xml"); +                goto out; +        } + +        if (rsp.op_ret && strcmp (rsp.op_errstr, "")) +                cli_err ("%s", rsp.op_errstr); +        else +                cli_out ("BD %s has been %s", operation, +                                (rsp.op_ret) ? "unsuccessful": +                                "successful."); +        ret = rsp.op_ret; + +out: +        cli_cmd_broadcast_response (ret); + +        if (dict) +                dict_unref (dict); + +        if (operation) +                GF_FREE (operation); + +        if (rsp.dict.dict_val) +                free (rsp.dict.dict_val); +        if (rsp.op_errstr) +                free (rsp.op_errstr); +        return ret; +} + +int32_t +gf_cli_bd_op (call_frame_t *frame, xlator_t *this, +                      void *data) +{ +        gf_cli_req      req    = { {0,} }; +        int             ret    = 0; +        dict_t          *dict  = NULL; + +        if (!frame || !this || !data) { +                ret = -1; +                goto out; +        } + +        dict = dict_ref ((dict_t *)data); +        if (!dict) +                goto out; + +        ret = dict_allocate_and_serialize (dict, +                                           &req.dict.dict_val, +                                           &req.dict.dict_len); + + +        ret = cli_cmd_submit (&req, frame, cli_rpc_prog, +                              GLUSTER_CLI_BD_OP, NULL, +                              this, gf_cli_bd_op_cbk, +                              (xdrproc_t) xdr_gf_cli_req); + +out: +        if (dict) +                dict_unref (dict); + +        if (req.dict.dict_val) +                GF_FREE (req.dict.dict_val); + +        gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} +#endif +  int32_t  gf_cli_create_volume (call_frame_t *frame, xlator_t *this,                           void *data) @@ -6227,6 +6355,9 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {          [GLUSTER_CLI_STATEDUMP_VOLUME] = {"STATEDUMP_VOLUME", gf_cli_statedump_volume},          [GLUSTER_CLI_LIST_VOLUME]      = {"LIST_VOLUME", gf_cli_list_volume},          [GLUSTER_CLI_CLRLOCKS_VOLUME]  = {"CLEARLOCKS_VOLUME", gf_cli_clearlocks_volume}, +#ifdef HAVE_BD_XLATOR +        [GLUSTER_CLI_BD_OP]            = {"BD_OP", gf_cli_bd_op}, +#endif  };  struct rpc_clnt_program cli_prog = { diff --git a/cli/src/cli.h b/cli/src/cli.h index a5f85ec8..6e05e099 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -37,6 +37,19 @@  #define CLI_TAB_LENGTH                         8  #define CLI_BRICK_STATUS_LINE_LEN             78 +#define CLI_LOCAL_INIT(local, words, frame, dictionary) \ +        do {                                                 \ +                local = cli_local_get ();                    \ +                                                             \ +                if (local) {                                 \ +                        local->words = words;                \ +                        if (dictionary)                      \ +                                local->dict = dictionary;    \ +                        if (frame)                           \ +                                frame->local = local;        \ +                }                                            \ +        } while (0) +  enum argp_option_keys {  	ARGP_DEBUG_KEY = 133,  	ARGP_PORT_KEY = 'p',  | 
