summaryrefslogtreecommitdiffstats
path: root/cli/src/cli-cmd-parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'cli/src/cli-cmd-parser.c')
-rw-r--r--cli/src/cli-cmd-parser.c680
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;
+}