diff options
Diffstat (limited to 'cli')
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 219 | ||||
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 64 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 118 | ||||
| -rw-r--r-- | cli/src/cli.h | 3 | 
4 files changed, 403 insertions, 1 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 83a9fbd7e7d..5520c9e46b1 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -4765,3 +4765,222 @@ out:          return ret;  } + +int +cli_cmd_validate_volume (char *volname) +{ +        int       i        =  0; +        int       ret      = -1; + + +        if (volname[0] == '-') +                return ret; + +        if (!strcmp (volname, "all")) { +                cli_err ("\"all\" cannot be the name of a volume."); +                return ret; +        } + +        if (strchr (volname, '/')) { +                cli_err ("Volume name should not contain \"/\" character."); +                return ret; +        } + +        if (strlen (volname) > GD_VOLUME_NAME_MAX) { +                cli_err ("Volname can not exceed %d characters.", +                        GD_VOLUME_NAME_MAX); +                return ret; +        } + +        for (i = 0; i < strlen (volname); i++) +                if (!isalnum (volname[i]) && (volname[i] != '_') && +                    (volname[i] != '-')) { +                        cli_err ("Volume name should not contain \"%c\"" +                                 " character.\nVolume names can only" +                                 "contain alphanumeric, '-' and '_' " +                                 "characters.", volname[i]); +                        return ret; +                } + +        ret = 0; + +        return ret; +} + +int32_t +cli_cmd_bitrot_parse (const char **words, int wordcount, dict_t **options) +{ +        int32_t            ret                    = -1; +        char               *w                     = NULL; +        char               *volname               = NULL; +        char               *opwords[]             = {"enable", "disable", +                                                     "scrub-throttle", +                                                     "scrub-frequency", +                                                     "scrub"}; +        char               *scrub_throt_values[]  = {"frozen", "lazy", "normal", +                                                     "aggressive"}; +        char               *scrub_freq_values[]   = {"daily", "weekly", +                                                     "biweekly", "monthly"}; +        char               *scrub_values[]        = {"pause", "resume"}; +        dict_t             *dict                  = NULL; +        gf_bitrot_type     type                   = GF_BITROT_OPTION_TYPE_NONE; + +        GF_ASSERT (words); +        GF_ASSERT (options); + +        dict = dict_new (); +        if (!dict) +                goto out; + +        if (wordcount < 4 || wordcount > 5) { +                gf_log ("", GF_LOG_ERROR, "Invalid syntax"); +                goto out; +        } + +        volname = (char *)words[2]; +        if (!volname) { +                ret = -1; +                goto out; +        } + +        ret = cli_cmd_validate_volume (volname); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Failed to validate volume name"); +                goto out; +        } + +        ret = dict_set_str (dict, "volname", volname); +        if (ret) { +                cli_out ("Failed to set volume name in dictionary "); +                goto out; +        } + +        w = str_getunamb (words[3], opwords); +        if (!w) { +                cli_out ("Invalid bit rot option : %s", words[3]); +                ret = -1; +                goto out; +        } + +        if (strcmp (w, "enable") == 0) { +                if (wordcount == 4) { +                        type = GF_BITROT_OPTION_TYPE_ENABLE; +                        ret = 0; +                        goto set_type; +                } else { +                        ret = -1; +                        goto out; +                } +        } + +        if (strcmp (w, "disable") == 0) { +                if (wordcount == 4) { +                        type = GF_BITROT_OPTION_TYPE_DISABLE; +                        ret = 0; +                        goto set_type; +                } else { +                        ret = -1; +                        goto out; +                } +        } + +        if (!strcmp (w, "scrub-throttle")) { +                if (!words[4]) { +                        cli_err ("Missing scrub-throttle value for bitrot " +                                 "option"); +                        ret = -1; +                        goto out; +                } else { +                        w = str_getunamb (words[4], scrub_throt_values); +                        if (!w) { +                                cli_err ("Invalid scrub-throttle option for " +                                         "bitrot"); +                                ret = -1; +                                goto out; +                        } else { +                                type = GF_BITROT_OPTION_TYPE_SCRUB_THROTTLE; +                                ret =  dict_set_str (dict, +                                                     "scrub-throttle-value", +                                                     (char *) words[4]); +                                if (ret) { +                                        cli_out ("Failed to set scrub-throttle " +                                                 "value in the dict"); +                                        goto out; +                                } +                                goto set_type; +                        } +                } +        } + +        if (!strcmp (words[3], "scrub-frequency")) { +                if (!words[4]) { +                        cli_err ("Missing scrub-frequency value"); +                        ret = -1; +                        goto out; +                } else { +                        w = str_getunamb (words[4], scrub_freq_values); +                        if (!w) { +                                cli_err ("Invalid frequency option for bitrot"); +                                ret = -1; +                                goto out; +                        } else { +                                type = GF_BITROT_OPTION_TYPE_SCRUB_FREQ; +                                ret = dict_set_str (dict, +                                                    "scrub-frequency-value", +                                                    (char *) words[4]); +                                if (ret) { +                                        cli_out ("Failed to set dict for " +                                                 "bitrot"); +                                        goto out; +                                } +                                goto set_type; +                        } +                } +        } + +        if (!strcmp (words[3], "scrub")) { +                if (!words[4]) { +                        cli_err ("Missing scrub value for bitrot option"); +                        ret = -1; +                        goto out; +                } else { +                        w = str_getunamb (words[4], scrub_values); +                        if (!w) { +                                cli_err ("Invalid scrub option for bitrot"); +                                ret = -1; +                                goto out; +                        } else { +                                type = GF_BITROT_OPTION_TYPE_SCRUB; +                                ret =  dict_set_str (dict, "scrub-value", +                                                    (char *) words[4]); +                                if (ret) { +                                        cli_out ("Failed to set dict for " +                                                 "bitrot"); +                                        goto out; +                                } +                                goto set_type; +                        } +                } +        } else { +                cli_err ("Invalid option %s for bitrot. Please enter valid " +                         "bitrot option", words[3]); +                ret = -1; +                goto out; +        } + +set_type: +        ret = dict_set_int32 (dict, "type", type); +        if (ret < 0) +                goto out; + +        *options = dict; + +out: +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Unable to parse bitrot command"); +                if (dict) +                        dict_destroy (dict); +        } + +        return ret; +} diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 5632a9798bb..6c950da4e97 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1300,6 +1300,58 @@ out:  }  int +cli_cmd_bitrot_cbk (struct cli_state *state, struct cli_cmd_word *word, +                    const char **words, int wordcount) +{ + +        int                     ret        = -1; +        int                     parse_err  = 0; +        call_frame_t            *frame     = NULL; +        dict_t                  *options   = NULL; +        cli_local_t             *local     = NULL; +        rpc_clnt_procedure_t    *proc      = NULL; +        int                     sent       = 0; + +        ret = cli_cmd_bitrot_parse (words, wordcount, &options); +        if (ret < 0) { +                cli_usage_out (word->pattern); +                parse_err = 1; +                goto out; +        } + +        frame = create_frame (THIS, THIS->ctx->pool); +        if (!frame) { +                ret = -1; +                goto out; +        } + +        proc = &cli_rpc_prog->proctable[GLUSTER_CLI_BITROT]; +        if (proc == NULL) { +                ret = -1; +                goto out; +        } + +        CLI_LOCAL_INIT (local, words, frame, options); + +        if (proc->fn) { +                ret = proc->fn (frame, THIS, options); +        } + +out: +        if (ret) { +                cli_cmd_sent_status_get (&sent); +                if ((sent == 0) && (parse_err == 0)) +                    cli_err ("Bit rot command failed. Please check the cli " +                             "logs for more details"); + +        } + +        CLI_STACK_DESTROY (frame); + +        return ret; +} + +int  cli_cmd_quota_cbk (struct cli_state *state, struct cli_cmd_word *word,                     const char **words, int wordcount)  { @@ -2492,7 +2544,17 @@ struct cli_cmd volume_cmds[] = {          },          {"volume get <VOLNAME> <key|all>",           cli_cmd_volume_getopt_cbk, -         "Get the value of the all options or given option for volume <VOLNAME>"}, +         "Get the value of the all options or given option for volume <VOLNAME>" +        }, +        { "volume bitrot <volname> {enable|disable} |\n" +          "volume bitrot <volname> {scrub-throttle frozen|lazy|normal" +          "|aggressive} |\n" +          "volume bitrot <volname> {scrub-frequency daily|weekly|biweekly" +          "|monthly} |\n" +          "volume bitrot <volname> {scrub pause|resume}", +          cli_cmd_bitrot_cbk, +          "Bitrot translator specific operations." +        },          { NULL, NULL, NULL }  }; diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 928df1e7082..6e66e377ed5 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -9804,6 +9804,123 @@ out:  } +int +gf_cli_bitrot_cbk (struct rpc_req *req, struct iovec *iov, +                   int count, void *myframe) +{ +        int                  ret                       = -1; +        gf_cli_rsp           rsp                       = {0, }; +        dict_t               *dict                     = NULL; +        call_frame_t         *frame                    = NULL; + +        if (req->rpc_status == -1) { +                ret = -1; +                goto out; +        } + +        frame = myframe; + +        ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp); +        if (ret < 0) { +                gf_log (frame->this->name, GF_LOG_ERROR, +                        "Failed to decode xdr response"); +                goto out; +        } + +        if (rsp.op_ret) { +                ret = -1; +                if (global_state->mode & GLUSTER_MODE_XML) +                        goto xml_output; + +                if (strcmp (rsp.op_errstr, "")) +                        cli_err ("Bitrot command failed : %s", rsp.op_errstr); +                else +                        cli_err ("Bitrot command : failed"); + +                goto out; +        } + +        if (rsp.dict.dict_len) { +                /* Unserialize the dictionary */ +                dict = dict_new (); + +                if (!dict) { +                        ret = -1; +                        goto out; +                } + +                ret = dict_unserialize (rsp.dict.dict_val, +                                        rsp.dict.dict_len, +                                        &dict); + +                if (ret) { +                        gf_log ("cli", GF_LOG_ERROR, "failed to unserialize " +                                "req-buffer to dictionary"); +                        goto out; +                } +        } + +        gf_log ("cli", GF_LOG_DEBUG, "Received resp to bit rot command"); + +xml_output: +        if (global_state->mode & GLUSTER_MODE_XML) { +                ret = cli_xml_output_vol_profile (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) +                cli_out ("volume bitrot: success"); + +        ret = rsp.op_ret; + +out: +        if (dict) +            dict_unref (dict); + +        free (rsp.dict.dict_val); +        free (rsp.op_errstr); + +        cli_cmd_broadcast_response (ret); + +        return ret; + +} + +int32_t +gf_cli_bitrot (call_frame_t *frame, xlator_t *this, void *data) +{ +        gf_cli_req        req           = { {0,} }; +        dict_t           *options       = NULL; +        int               ret           = -1; + +        if (!frame || !this || !data) +                goto out; + +        options = data; + +        ret = cli_to_glusterd (&req, frame, gf_cli_bitrot_cbk, +                               (xdrproc_t) xdr_gf_cli_req, options, +                               GLUSTER_CLI_BITROT, this, cli_rpc_prog, +                               NULL); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "cli_to_glusterd for " +                        "bitrot failed"); +                goto out; +        } + +out: +        gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); + +        GF_FREE (req.dict.dict_val); + +        return ret; +} +  struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {          [GLUSTER_CLI_NULL]             = {"NULL", NULL },          [GLUSTER_CLI_PROBE]            = {"PROBE_QUERY", gf_cli_probe}, @@ -9848,6 +9965,7 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {          [GLUSTER_CLI_BARRIER_VOLUME]   = {"BARRIER VOLUME", gf_cli_barrier_volume},          [GLUSTER_CLI_GANESHA]          = {"GANESHA", gf_cli_ganesha},          [GLUSTER_CLI_GET_VOL_OPT]      = {"GET_VOL_OPT", gf_cli_get_vol_opt}, +        [GLUSTER_CLI_BITROT]           = {"BITROT", gf_cli_bitrot}  };  struct rpc_clnt_program cli_prog = { diff --git a/cli/src/cli.h b/cli/src/cli.h index ad286ef5f85..ed2bc4aba8a 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -238,6 +238,9 @@ int32_t  cli_cmd_quota_parse (const char **words, int wordcount, dict_t **opt);  int32_t +cli_cmd_bitrot_parse (const char **words, int wordcount, dict_t **opt); + +int32_t  cli_cmd_volume_set_parse (const char **words, int wordcount,                            dict_t **options, char **op_errstr);  int32_t  | 
