diff options
Diffstat (limited to 'cli/src/cli-cmd-parser.c')
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 680 |
1 files changed, 396 insertions, 284 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index d9913f678a0..34620b4a31b 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -26,7 +26,7 @@ #define MAX_SNAP_DESCRIPTION_LEN 1024 -struct snap_config_opt_vals_ snap_confopt_vals[] = { +static struct snap_config_opt_vals_ snap_confopt_vals[] = { {.op_name = "snap-max-hard-limit", .question = "Changing snapshot-max-hard-limit " "will limit the creation of new snapshots " @@ -80,6 +80,95 @@ str_getunamb(const char *tok, char **opwords) } int32_t +cli_cmd_ta_brick_parse(const char **words, int wordcount, char **ta_brick) +{ + char *host_name = NULL; + char *tmp_host = NULL; + char *delimiter = NULL; + cli_brick_t *brick = NULL; + int ret = 0; + + GF_ASSERT(words); + GF_ASSERT(wordcount); + + if (validate_brick_name((char *)words[wordcount - 1])) { + cli_err( + "Wrong brick type: %s, use <HOSTNAME>:" + "<export-dir-abs-path>", + words[wordcount - 1]); + ret = -1; + goto out; + } else { + delimiter = strrchr(words[wordcount - 1], ':'); + ret = gf_canonicalize_path(delimiter + 1); + if (ret) + goto out; + } + + tmp_host = gf_strdup((char *)words[wordcount - 1]); + if (!tmp_host) { + gf_log("cli", GF_LOG_ERROR, "Out of memory"); + ret = -1; + goto out; + } + get_host_name(tmp_host, &host_name); + if (!host_name) { + ret = -1; + gf_log("cli", GF_LOG_ERROR, + "Unable to retrieve " + "hostname"); + goto out; + } + + if (!(strcmp(host_name, "localhost") && strcmp(host_name, "127.0.0.1") && + strncmp(host_name, "0.", 2))) { + cli_err( + "Please provide a valid hostname/ip other " + "than localhost, 127.0.0.1 or loopback " + "address (0.0.0.0 to 0.255.255.255)."); + ret = -1; + goto out; + } + if (!valid_internet_address(host_name, _gf_false, _gf_false)) { + cli_err( + "internet address '%s' does not conform to " + "standards", + host_name); + } + + brick = GF_MALLOC(sizeof(cli_brick_t), gf_common_list_node); + if (brick == NULL) { + ret = -1; + gf_log("cli", GF_LOG_ERROR, "Out of memory"); + goto out; + } + + brick->name = words[wordcount - 1]; + brick->len = strlen(words[wordcount - 1]); + *ta_brick = GF_MALLOC(brick->len + 3, gf_common_mt_char); + if (*ta_brick == NULL) { + ret = -1; + gf_log("cli", GF_LOG_ERROR, "Out of memory"); + goto out; + } + + strcat(*ta_brick, " "); + strcat(*ta_brick, brick->name); + strcat(*ta_brick, " "); +out: + if (tmp_host) { + GF_FREE(tmp_host); + tmp_host = NULL; + } + if (brick) { + GF_FREE(brick); + brick = NULL; + } + + return ret; +} + +int32_t cli_cmd_bricks_parse(const char **words, int wordcount, int brick_index, char **bricks, int *brick_count) { @@ -392,11 +481,6 @@ cli_validate_disperse_volume(char *word, gf1_cluster_type type, ret = 2; } break; - case GF_CLUSTER_TYPE_TIER: - cli_err( - "tier-dispersed volume is not " - "supported"); - goto out; case GF_CLUSTER_TYPE_REPLICATE: cli_err( "replicated-dispersed volume is not " @@ -481,14 +565,17 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, char *trans_type = NULL; int32_t index = 0; char *bricks = NULL; + char *ta_brick = NULL; int32_t brick_count = 0; - char *opwords[] = {"replica", "stripe", "transport", "disperse", - "redundancy", "disperse-data", "arbiter", NULL}; + static char *opwords[] = {"replica", "stripe", "transport", + "disperse", "redundancy", "disperse-data", + "arbiter", "thin-arbiter", NULL}; char *w = NULL; int op_count = 0; int32_t replica_count = 1; int32_t arbiter_count = 0; + int32_t thin_arbiter_count = 0; int32_t stripe_count = 1; int32_t disperse_count = -1; int32_t redundancy_count = -1; @@ -542,12 +629,6 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, case GF_CLUSTER_TYPE_STRIPE: cli_err("stripe option not supported"); goto out; - case GF_CLUSTER_TYPE_TIER: - cli_err( - "replicated-tiered volume is not " - "supported"); - goto out; - break; case GF_CLUSTER_TYPE_DISPERSE: cli_err( "replicated-dispersed volume is not " @@ -592,6 +673,26 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, if (ret) goto out; index += 2; + } else if (!strcmp(words[index], "thin-arbiter")) { + ret = gf_string2int(words[index + 1], &thin_arbiter_count); + if ((ret == -1) || (thin_arbiter_count != 1) || + (replica_count != 2)) { + cli_err( + "For thin-arbiter " + "configuration, " + "replica count must be" + " 2 and thin-arbiter count " + "must be 1. The 3rd " + "brick of the replica " + "will be the thin-arbiter brick"); + ret = -1; + goto out; + } + ret = dict_set_int32(dict, "thin-arbiter-count", + thin_arbiter_count); + if (ret) + goto out; + index += 2; } } @@ -600,7 +701,7 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, if ((arbiter_count == 1) && (replica_count == 2)) replica_count += arbiter_count; - if (replica_count == 2) { + if (replica_count == 2 && thin_arbiter_count == 0) { if (strcmp(words[wordcount - 1], "force")) { question = "Replica 2 volumes are prone" @@ -668,6 +769,12 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, "option."); ret = -1; goto out; + } else if ((strcmp(w, "thin-arbiter") == 0)) { + cli_err( + "thin-arbiter option must be preceded by replica " + "option."); + ret = -1; + goto out; } else { GF_ASSERT(!"opword mismatch"); ret = -1; @@ -691,7 +798,20 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, wc = wordcount - 1; } - ret = cli_cmd_bricks_parse(words, wc, brick_index, &bricks, &brick_count); + // Exclude the thin-arbiter-brick i.e. last brick in the bricks list + if (thin_arbiter_count == 1) { + ret = cli_cmd_bricks_parse(words, wc - 1, brick_index, &bricks, + &brick_count); + if (ret) + goto out; + + ret = cli_cmd_ta_brick_parse(words, wc, &ta_brick); + + } else { + ret = cli_cmd_bricks_parse(words, wc, brick_index, &bricks, + &brick_count); + } + if (ret) goto out; @@ -750,6 +870,12 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, if (ret) goto out; + if (thin_arbiter_count == 1) { + ret = dict_set_dynstr(dict, "ta-brick", ta_brick); + if (ret) + goto out; + } + ret = dict_set_int32(dict, "count", brick_count); if (ret) goto out; @@ -763,6 +889,7 @@ cli_cmd_volume_create_parse(struct cli_state *state, const char **words, out: if (ret) { GF_FREE(bricks); + GF_FREE(ta_brick); gf_log("cli", GF_LOG_ERROR, "Unable to parse create volume CLI"); if (dict) dict_unref(dict); @@ -1068,19 +1195,19 @@ cli_cmd_quota_parse(const char **words, int wordcount, dict_t **options) }; int64_t value = 0; gf_quota_type type = GF_QUOTA_OPTION_TYPE_NONE; - char *opwords[] = {"enable", - "disable", - "limit-usage", - "remove", - "list", - "alert-time", - "soft-timeout", - "hard-timeout", - "default-soft-limit", - "limit-objects", - "list-objects", - "remove-objects", - NULL}; + static char *opwords[] = {"enable", + "disable", + "limit-usage", + "remove", + "list", + "alert-time", + "soft-timeout", + "hard-timeout", + "default-soft-limit", + "limit-objects", + "list-objects", + "remove-objects", + NULL}; char *w = NULL; uint32_t time = 0; double percent = 0; @@ -1496,6 +1623,11 @@ cli_add_key_group(dict_t *dict, char *key, char *value, char **op_errstr) } goto out; } + + /* Treat line that start with "#" as comments */ + if ('#' == line[0]) + continue; + opt_count++; tok_key = strtok_r(line, "=", &saveptr); tok_val = strtok_r(NULL, "\r\n", &saveptr); @@ -1721,7 +1853,7 @@ cli_cmd_volume_add_brick_parse(struct cli_state *state, const char **words, int ret = -1; int brick_count = 0, brick_index = 0; char *bricks = NULL; - char *opwords_cl[] = {"replica", "stripe", NULL}; + static char *opwords_cl[] = {"replica", "stripe", NULL}; gf1_cluster_type type = GF_CLUSTER_TYPE_NONE; int count = 1; int arbiter_count = 0; @@ -1801,7 +1933,7 @@ cli_cmd_volume_add_brick_parse(struct cli_state *state, const char **words, question = "Replica 2 volumes are prone to " "split-brain. Use Arbiter or " - "Replica 3 to avaoid this. See: " + "Replica 3 to avoid this. See: " "http://docs.gluster.org/en/latest/Administrator%20Guide/" "Split%20brain%20and%20ways%20to%20deal%20with%20it/." "\nDo you still want to continue?\n"; @@ -1866,146 +1998,6 @@ out: } int32_t -cli_cmd_volume_tier_parse(const char **words, int wordcount, dict_t **options) -{ - dict_t *dict = NULL; - char *volname = NULL; - int ret = -1; - int32_t command = GF_DEFRAG_CMD_NONE; - int32_t is_force = 0; - - GF_ASSERT(words); - GF_ASSERT(options); - - dict = dict_new(); - - if (!dict) - goto out; - - if (!(wordcount == 4 || wordcount == 5)) { - gf_log("cli", GF_LOG_ERROR, "Invalid Syntax"); - ret = -1; - goto out; - } - - volname = (char *)words[2]; - - GF_ASSERT(volname); - - 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) - goto out; - - volname = (char *)words[2]; - if (wordcount == 4) { - if (!strcmp(words[3], "status")) - command = GF_DEFRAG_CMD_STATUS_TIER; - else if (!strcmp(words[3], "start")) - command = GF_DEFRAG_CMD_START_TIER; - else if (!strcmp(words[3], "stop")) - command = GF_DEFRAG_CMD_STOP_TIER; - else { - ret = -1; - goto out; - } - } else if (wordcount == 5) { - if ((!strcmp(words[3], "start")) && (!strcmp(words[4], "force"))) { - command = GF_DEFRAG_CMD_START_TIER; - is_force = 1; - ret = dict_set_int32(dict, "force", is_force); - if (ret) - goto out; - } else { - ret = -1; - goto out; - } - } - - ret = dict_set_int32(dict, "rebalance-command", command); - if (ret) - goto out; - - *options = dict; -out: - - if (ret) { - gf_log("cli", GF_LOG_ERROR, "Unable to parse tier CLI"); - if (dict) - dict_unref(dict); - } - - return ret; -} - -int32_t -cli_cmd_volume_detach_tier_parse(const char **words, int wordcount, - dict_t **options, int *question) -{ - int ret = -1; - char *word = NULL; - dict_t *dict = NULL; - int32_t command = GF_DEFRAG_CMD_NONE; - - dict = dict_new(); - if (!dict) - goto out; - - ret = dict_set_str(dict, "volname", (char *)words[2]); - if (ret) - goto out; - - if (wordcount == 3 && !strcmp((char *)words[2], "help")) { - return -1; - } - - if (wordcount != 4) { - ret = -1; - goto out; - } - - word = (char *)words[3]; - - ret = -1; - - if (!strcmp(word, "start")) { - command = GF_DEFRAG_CMD_DETACH_START; - } else if (!strcmp(word, "commit")) { - *question = 1; - command = GF_DEFRAG_CMD_DETACH_COMMIT; - } else if (!strcmp(word, "force")) { - *question = 1; - command = GF_DEFRAG_CMD_DETACH_COMMIT_FORCE; - } else if (!strcmp(word, "stop")) - command = GF_DEFRAG_CMD_DETACH_STOP; - else if (!strcmp(word, "status")) - command = GF_DEFRAG_CMD_DETACH_STATUS; - else - goto out; - - ret = dict_set_int32(dict, "command", command); - if (ret) - goto out; - - *options = dict; - ret = 0; -out: - if (ret) { - gf_log("cli", GF_LOG_ERROR, "Unable to parse detach tier CLI"); - if (dict) - dict_unref(dict); - } - - return ret; -} - -int32_t cli_cmd_volume_remove_brick_parse(struct cli_state *state, const char **words, int wordcount, dict_t **options, int *question, int *brick_count, @@ -2021,8 +2013,9 @@ cli_cmd_volume_remove_brick_parse(struct cli_state *state, const char **words, int32_t j = 0; char *tmp_brick = NULL; char *tmp_brick1 = NULL; - char *type_opword[] = {"replica", NULL}; - char *opwords[] = {"start", "commit", "stop", "status", "force", NULL}; + static char *type_opword[] = {"replica", NULL}; + static char *opwords[] = {"start", "commit", "stop", + "status", "force", NULL}; char *w = NULL; int32_t command = GF_OP_CMD_NONE; long count = 0; @@ -2068,7 +2061,7 @@ cli_cmd_volume_remove_brick_parse(struct cli_state *state, const char **words, ques = "Replica 2 volumes are prone to " "split-brain. Use Arbiter or Replica 3 " - "to avaoid this. See: " + "to avoid this. See: " "http://docs.gluster.org/en/latest/Administrator%20Guide/" "Split%20brain%20and%20ways%20to%20deal%20with%20it/." "\nDo you still want to continue?\n"; @@ -2593,8 +2586,6 @@ cli_cmd_log_rotate_parse(const char **words, int wordcount, dict_t **options) if (strcmp("rotate", words[3]) == 0) volname = (char *)words[2]; - else if (strcmp("rotate", words[2]) == 0) - volname = (char *)words[3]; GF_ASSERT(volname); ret = dict_set_str(dict, "volname", volname); @@ -2637,6 +2628,17 @@ gsyncd_url_check(const char *w) } static gf_boolean_t +valid_slave_gsyncd_url(const char *w) +{ + if (strstr(w, ":::")) + return _gf_false; + else if (strstr(w, "::")) + return _gf_true; + else + return _gf_false; +} + +static gf_boolean_t gsyncd_glob_check(const char *w) { return !!strpbrk(w, "*?["); @@ -2859,7 +2861,8 @@ out: } int32_t -cli_cmd_gsync_set_parse(const char **words, int wordcount, dict_t **options) +cli_cmd_gsync_set_parse(struct cli_state *state, const char **words, + int wordcount, dict_t **options, char **errstr) { int32_t ret = -1; dict_t *dict = NULL; @@ -2869,13 +2872,16 @@ cli_cmd_gsync_set_parse(const char **words, int wordcount, dict_t **options) unsigned slavei = 0; unsigned glob = 0; unsigned cmdi = 0; - char *opwords[] = {"create", "status", "start", "stop", "config", - "force", "delete", "ssh-port", "no-verify", "push-pem", - "detail", "pause", "resume", NULL}; + static char *opwords[] = {"create", "status", "start", "stop", + "config", "force", "delete", "ssh-port", + "no-verify", "push-pem", "detail", "pause", + "resume", NULL}; char *w = NULL; char *save_ptr = NULL; char *slave_temp = NULL; char *token = NULL; + gf_answer_t answer = GF_ANSWER_NO; + const char *question = NULL; GF_ASSERT(words); GF_ASSERT(options); @@ -2948,8 +2954,11 @@ cli_cmd_gsync_set_parse(const char **words, int wordcount, dict_t **options) if (masteri && gsyncd_url_check(words[masteri])) goto out; - if (slavei && !glob && !gsyncd_url_check(words[slavei])) + + if (slavei && !glob && !valid_slave_gsyncd_url(words[slavei])) { + gf_asprintf(errstr, "Invalid slave url: %s", words[slavei]); goto out; + } w = str_getunamb(words[cmdi], opwords); if (!w) @@ -3059,16 +3068,36 @@ cli_cmd_gsync_set_parse(const char **words, int wordcount, dict_t **options) } if (!ret) ret = dict_set_int32(dict, "type", type); - if (!ret && type == GF_GSYNC_OPTION_TYPE_CONFIG) + if (!ret && type == GF_GSYNC_OPTION_TYPE_CONFIG) { + if (!strcmp((char *)words[wordcount - 2], "ignore-deletes") && + !strcmp((char *)words[wordcount - 1], "true")) { + question = + "There exists ~15 seconds delay for the option to take" + " effect from stime of the corresponding brick. Please" + " check the log for the time, the option is effective." + " Proceed"; + + answer = cli_cmd_get_confirmation(state, question); + + if (GF_ANSWER_NO == answer) { + gf_log("cli", GF_LOG_INFO, + "Operation " + "cancelled, exiting"); + *errstr = gf_strdup("Aborted by user."); + ret = -1; + goto out; + } + } + ret = config_parse(words, wordcount, dict, cmdi, glob); + } out: if (slave_temp) GF_FREE(slave_temp); - if (ret) { - if (dict) - dict_unref(dict); - } else + if (ret && dict) + dict_unref(dict); + else *options = dict; return ret; @@ -3085,7 +3114,7 @@ cli_cmd_volume_profile_parse(const char **words, int wordcount, gf1_cli_info_op info_op = GF_CLI_INFO_NONE; gf_boolean_t is_peek = _gf_false; - char *opwords[] = {"start", "stop", "info", NULL}; + static char *opwords[] = {"start", "stop", "info", NULL}; char *w = NULL; GF_ASSERT(words); @@ -3186,8 +3215,9 @@ cli_cmd_volume_top_parse(const char **words, int wordcount, dict_t **options) int count = 0; gf_boolean_t nfs = _gf_false; char *delimiter = NULL; - char *opwords[] = {"open", "read", "write", "opendir", "readdir", - "read-perf", "write-perf", "clear", NULL}; + static char *opwords[] = {"open", "read", "write", + "opendir", "readdir", "read-perf", + "write-perf", "clear", NULL}; char *w = NULL; GF_ASSERT(words); @@ -3366,9 +3396,9 @@ cli_cmd_get_statusop(const char *arg) int i = 0; uint32_t ret = GF_CLI_STATUS_NONE; char *w = NULL; - char *opwords[] = {"detail", "mem", "clients", "fd", "inode", - "callpool", "tasks", "client-list", NULL}; - struct { + static char *opwords[] = {"detail", "mem", "clients", "fd", "inode", + "callpool", "tasks", "client-list", NULL}; + static struct { char *opname; uint32_t opcode; } optable[] = {{"detail", GF_CLI_STATUS_DETAIL}, @@ -3455,8 +3485,6 @@ cli_cmd_volume_status_parse(const char **words, int wordcount, dict_t **options) cmd |= GF_CLI_STATUS_QUOTAD; } else if (!strcmp(words[3], "snapd")) { cmd |= GF_CLI_STATUS_SNAPD; - } else if (!strcmp(words[3], "tierd")) { - cmd |= GF_CLI_STATUS_TIERD; } else if (!strcmp(words[3], "bitd")) { cmd |= GF_CLI_STATUS_BITD; } else if (!strcmp(words[3], "scrub")) { @@ -3532,16 +3560,6 @@ cli_cmd_volume_status_parse(const char **words, int wordcount, dict_t **options) goto out; } cmd |= GF_CLI_STATUS_SNAPD; - } else if (!strcmp(words[3], "tierd")) { - if (cmd == GF_CLI_STATUS_FD || cmd == GF_CLI_STATUS_CLIENTS || - cmd == GF_CLI_STATUS_DETAIL || cmd == GF_CLI_STATUS_INODE) { - cli_err( - "Detail/FD/Clients/Inode status not " - "available for tier daemon"); - ret = -1; - goto out; - } - cmd |= GF_CLI_STATUS_TIERD; } else { if (cmd == GF_CLI_STATUS_TASKS) { cli_err( @@ -3578,9 +3596,9 @@ out: gf_boolean_t cli_cmd_validate_dumpoption(const char *arg, char **option) { - char *opwords[] = {"all", "nfs", "mem", "iobuf", "callpool", - "priv", "fd", "inode", "history", "inodectx", - "fdctx", "quotad", NULL}; + static char *opwords[] = {"all", "nfs", "mem", "iobuf", "callpool", + "priv", "fd", "inode", "history", "inodectx", + "fdctx", "quotad", NULL}; char *w = NULL; w = str_getunamb(arg, opwords); @@ -3888,8 +3906,6 @@ heal_command_type_get(const char *command) [GF_SHD_OP_HEAL_INDEX] = NULL, [GF_SHD_OP_HEAL_FULL] = "full", [GF_SHD_OP_INDEX_SUMMARY] = "info", - [GF_SHD_OP_HEALED_FILES] = NULL, - [GF_SHD_OP_HEAL_FAILED_FILES] = NULL, [GF_SHD_OP_SPLIT_BRAIN_FILES] = NULL, [GF_SHD_OP_STATISTICS] = "statistics", [GF_SHD_OP_STATISTICS_HEAL_COUNT] = NULL, @@ -4067,55 +4083,6 @@ out: } int -cli_cmd_volume_old_tier_parse(const char **words, int wordcount, - dict_t **options) -{ - dict_t *dict = NULL; - int ret = -1; - char *volname = NULL; - gf_cli_defrag_type cmd = 0; - - GF_ASSERT(words); - GF_ASSERT(options); - - dict = dict_new(); - if (!dict) - goto out; - - if (wordcount != 4) - goto out; - - if ((strcmp(words[1], "tier") == 0) && (strcmp(words[3], "start") == 0)) { - cmd = GF_DEFRAG_CMD_START_TIER; - } else - goto out; - - volname = (char *)words[2]; - - ret = dict_set_str(dict, "volname", volname); - - if (ret) { - gf_log(THIS->name, GF_LOG_ERROR, "failed to set dict"); - goto out; - } - - ret = dict_set_int32(dict, "rebalance-command", (int32_t)cmd); - - if (ret) { - gf_log(THIS->name, GF_LOG_ERROR, "failed to set dict"); - goto out; - } - - *options = dict; - -out: - if (ret && dict) - dict_unref(dict); - - return ret; -} - -int cli_cmd_volume_defrag_parse(const char **words, int wordcount, dict_t **options) { dict_t *dict = NULL; @@ -5280,24 +5247,25 @@ 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", "activate", - "deactivate", "list", "status", "config", - "info", "clone", NULL}; - char *invalid_snapnames[] = {"description", "force", "volume", "all", NULL}; - char *invalid_volnames[] = {"volume", - "type", - "subvolumes", - "option", - "end-volume", - "all", - "volume_not_in_ring", - "description", - "force", - "snap-max-hard-limit", - "snap-max-soft-limit", - "auto-delete", - "activate-on-create", - NULL}; + static char *opwords[] = {"create", "delete", "restore", "activate", + "deactivate", "list", "status", "config", + "info", "clone", NULL}; + static char *invalid_snapnames[] = {"description", "force", "volume", "all", + NULL}; + static char *invalid_volnames[] = {"volume", + "type", + "subvolumes", + "option", + "end-volume", + "all", + "volume_not_in_ring", + "description", + "force", + "snap-max-hard-limit", + "snap-max-soft-limit", + "auto-delete", + "activate-on-create", + NULL}; GF_ASSERT(words); GF_ASSERT(options); @@ -5617,16 +5585,18 @@ 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", - "signing-time", NULL}; - char *scrub_throt_values[] = {"lazy", "normal", "aggressive", NULL}; - char *scrub_freq_values[] = {"hourly", "daily", "weekly", "biweekly", - "monthly", "minute", NULL}; - char *scrub_values[] = {"pause", "resume", "status", "ondemand", NULL}; + static char *opwords[] = {"enable", "disable", "scrub-throttle", + "scrub-frequency", "scrub", "signing-time", + "signer-threads", NULL}; + static char *scrub_throt_values[] = {"lazy", "normal", "aggressive", NULL}; + static char *scrub_freq_values[] = { + "hourly", "daily", "weekly", "biweekly", "monthly", "minute", NULL}; + static char *scrub_values[] = {"pause", "resume", "status", "ondemand", + NULL}; dict_t *dict = NULL; gf_bitrot_type type = GF_BITROT_OPTION_TYPE_NONE; int32_t expiry_time = 0; + int32_t signer_th_count = 0; GF_ASSERT(words); GF_ASSERT(options); @@ -5807,6 +5777,31 @@ cli_cmd_bitrot_parse(const char **words, int wordcount, dict_t **options) } goto set_type; } + } else if (!strcmp(words[3], "signer-threads")) { + if (!words[4]) { + cli_err( + "Missing signer-thread value for bitrot " + "option"); + ret = -1; + goto out; + } else { + type = GF_BITROT_OPTION_TYPE_SIGNER_THREADS; + + signer_th_count = strtol(words[4], NULL, 0); + if (signer_th_count < 1) { + cli_err("signer-thread count should not be less than 1"); + ret = -1; + goto out; + } + + ret = dict_set_uint32(dict, "signer-threads", + (unsigned int)signer_th_count); + 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 " @@ -5815,7 +5810,6 @@ cli_cmd_bitrot_parse(const char **words, int wordcount, dict_t **options) ret = -1; goto out; } - set_type: ret = dict_set_int32(dict, "type", type); if (ret < 0) @@ -5832,3 +5826,121 @@ out: return ret; } + +/* Parsing global option for NFS-Ganesha config + * gluster nfs-ganesha enable/disable */ + +int32_t +cli_cmd_ganesha_parse(struct cli_state *state, const char **words, + int wordcount, dict_t **options, char **op_errstr) +{ + dict_t *dict = NULL; + int ret = -1; + char *key = NULL; + char *value = NULL; + char *w = NULL; + static char *opwords[] = {"enable", "disable", NULL}; + const char *question = NULL; + gf_answer_t answer = GF_ANSWER_NO; + + GF_ASSERT(words); + GF_ASSERT(options); + + dict = dict_new(); + + if (!dict) + goto out; + + if (wordcount != 2) + goto out; + + key = (char *)words[0]; + value = (char *)words[1]; + + if (!key || !value) { + cli_out("Usage : nfs-ganesha <enable/disable>"); + ret = -1; + goto out; + } + + ret = gf_strip_whitespace(value, strlen(value)); + if (ret == -1) + goto out; + + if (strcmp(key, "nfs-ganesha")) { + gf_asprintf(op_errstr, + "Global option: error: ' %s '" + "is not a valid global option.", + key); + ret = -1; + goto out; + } + + w = str_getunamb(value, opwords); + if (!w) { + cli_out( + "Invalid global option \n" + "Usage : nfs-ganesha <enable/disable>"); + ret = -1; + goto out; + } + + if (strcmp(value, "enable") == 0) { + question = + "Enabling NFS-Ganesha requires Gluster-NFS to be " + "disabled across the trusted pool. Do you " + "still want to continue?\n"; + } else if (strcmp(value, "disable") == 0) { + question = + "Disabling NFS-Ganesha will tear down the entire " + "ganesha cluster across the trusted pool. Do you " + "still want to continue?\n"; + } else { + ret = -1; + goto out; + } + answer = cli_cmd_get_confirmation(state, question); + if (GF_ANSWER_NO == answer) { + gf_log("cli", GF_LOG_ERROR, + "Global operation " + "cancelled, exiting"); + ret = -1; + goto out; + } + cli_out("This will take a few minutes to complete. Please wait .."); + + ret = dict_set_str(dict, "key", key); + if (ret) { + gf_log(THIS->name, GF_LOG_ERROR, "dict set on key failed"); + goto out; + } + + ret = dict_set_str(dict, "value", value); + if (ret) { + gf_log(THIS->name, GF_LOG_ERROR, "dict set on value failed"); + goto out; + } + + ret = dict_set_str(dict, "globalname", "All"); + if (ret) { + gf_log(THIS->name, GF_LOG_ERROR, + "dict set on global" + " key failed."); + goto out; + } + + ret = dict_set_int32(dict, "hold_global_locks", _gf_true); + if (ret) { + gf_log(THIS->name, GF_LOG_ERROR, + "dict set on global key " + "failed."); + goto out; + } + + *options = dict; +out: + if (ret) + dict_unref(dict); + + return ret; +} |
