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.c340
1 files changed, 205 insertions, 135 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index d25bf45a3..6232f6301 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -31,20 +31,33 @@
struct snap_config_opt_vals_ snap_confopt_vals[] = {
{.op_name = "snap-max-hard-limit",
.question = "Changing snapshot-max-hard-limit "
- "will lead deletion of snapshots "
+ "will lead to deletion of snapshots "
"if they exceed the new limit.\n"
"Do you want to continue?"
},
{.op_name = "snap-max-soft-limit",
.question = "Changing snapshot-max-soft-limit "
- "will lead deletion of snapshots "
+ "will lead to deletion of snapshots "
"if they exceed the new limit.\n"
"Do you want to continue?"
},
+ {.op_name = "both",
+ .question = "Changing snapshot-max-hard-limit & "
+ "snapshot-max-soft-limit will lead to "
+ "deletion of snapshots if they exceed "
+ "the new limit.\nDo you want to continue?"
+ },
{.op_name = NULL,
}
};
+enum cli_snap_config_set_types {
+ GF_SNAP_CONFIG_SET_HARD = 0,
+ GF_SNAP_CONFIG_SET_SOFT = 1,
+ GF_SNAP_CONFIG_SET_BOTH = 2,
+};
+typedef enum cli_snap_config_set_types cli_snap_config_set_types;
+
static const char *
id_sel (void *wcon)
{
@@ -182,7 +195,8 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options
char *invalid_volnames[] = {"volume", "type", "subvolumes", "option",
"end-volume", "all", "volume_not_in_ring",
- "description", NULL};
+ "description", "force", "snap-max-hard-limit",
+ "snap-max-soft-limit", NULL};
char *w = NULL;
int op_count = 0;
int32_t replica_count = 1;
@@ -3097,135 +3111,7 @@ out :
return ret;
}
-/* function cli_snap_config_parse
- return value: -1 on failure
- 1 if user cancels the operation
- 0 on success
-*/
-int32_t
-cli_snap_config_parse (const char **words, int wordcount, dict_t *options,
- struct cli_state *state)
-{
- char *volname = NULL;
- int ret = -1;
- int i = -1;
- char *key = NULL;
- char *value = NULL;
- uint64_t limit = 0;
- gf1_cli_snapshot type = GF_SNAP_OPTION_TYPE_NONE;
- gf_answer_t answer = GF_ANSWER_NO;
- struct snap_config_opt_vals_ *conf_vals = NULL;
- gf_boolean_t op_match = _gf_true;
-
- GF_ASSERT (words);
- GF_ASSERT (options);
- GF_ASSERT (state);
-
- if ((wordcount != 3) && (wordcount != 5)) {
- gf_log ("", GF_LOG_ERROR,
- "Invalid wordcount(%d)", wordcount);
- goto out;
- }
-
- volname = (char *)words[2];
-
- GF_ASSERT (volname);
-
- type = GF_SNAP_OPTION_TYPE_CONFIG;
- ret = dict_set_int32 (options, "type", type);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Failed to set type.");
- goto out;
- }
-
- ret = dict_set_str (options, "volname", volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Failed to set volname.");
- goto out;
- }
-
- /* snapshot config <volname | all> [snap-max-hard-limit <count>
- * | snap-max-soft-limit <percent>] */
-
- if (wordcount > 3) {
- key = (char *) words[3];
- value = (char *) words[4];
- } else {
- ret = dict_set_int32 (options, "config-command",
- GF_SNAP_CONFIG_DISPLAY);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to set config-command");
- ret = -1;
- goto out;
- }
- }
-
- if (key) {
- /* Check options in snap_confopt_vals for invalid keys */
- for (conf_vals = snap_confopt_vals; conf_vals->op_name;
- conf_vals++) {
- op_match = _gf_true;
- for (i = 0; conf_vals->op_name[i] && key[i]; i++) {
- if (conf_vals->op_name[i] == key[i] ||
- (conf_vals->op_name[i] == '-' &&
- key[i] == '_'))
- continue;
- op_match = _gf_false;
- break;
- }
-
- if (op_match)
- break;
- }
-
- if (!op_match) {
- gf_log ("", GF_LOG_ERROR, "Invalid key");
- ret = -1;
- goto out;
- }
-
- ret = dict_set_str (options, "config-key", conf_vals->op_name);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to set config-key");
- goto out;
- }
- }
-
- if (value) {
- ret = dict_set_int32 (options, "config-command",
- GF_SNAP_CONFIG_TYPE_SET);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to set config-command");
- ret = -1;
- goto out;
- }
-
- limit = (uint64_t) atoll (value);
- ret = dict_set_uint64 (options, conf_vals->op_name, limit);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Failed to set %s.", key);
- goto out;
- }
-
- /* Ask question only for a set op */
- if (conf_vals->question) {
- answer = cli_cmd_get_confirmation (state,
- conf_vals->question);
- if (GF_ANSWER_NO == answer) {
- ret = 1;
- gf_log ("", GF_LOG_DEBUG, "User cancelled "
- "snapshot config operation");
- goto out;
- }
- }
- }
-out:
- return ret;
-}
/* snapshot restore <snapname>
* @arg-0, dict : Request Dictionary to be sent to server side.
@@ -3386,6 +3272,181 @@ out :
return ret;
}
+
+int32_t
+cli_snap_config_limit_parse (const char **words, dict_t *dict,
+ unsigned int wordcount, unsigned int index,
+ char *key)
+{
+ int ret = -1;
+ int limit = 0;
+
+ GF_ASSERT (words);
+ GF_ASSERT (dict);
+ GF_ASSERT (key);
+
+ if (index >= wordcount) {
+ ret = -1;
+ cli_err ("Please provide a value for %s.",key);
+ gf_log ("cli", GF_LOG_ERROR, "Value not provided for %s", key);
+ goto out;
+ }
+
+ limit = strtol (words[index], NULL, 0);
+ if (limit <= 0) {
+ ret = -1;
+ cli_err ("%s should be greater than 0.", key);
+ goto out;
+ }
+
+ ret = dict_set_int32 (dict, key, limit);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Could not set "
+ "%s in dictionary", key);
+ goto out;
+ }
+
+out :
+ return ret;
+}
+
+/* function cli_snap_config_parse
+ * Config Syntax : gluster snapshot config [volname]
+ * [snap-max-hard-limit <count>]
+ * [snap-max-soft-limit <count>]
+ *
+ return value: <0 on failure
+ 1 if user cancels the operation
+ 0 on success
+
+ NOTE : snap-max-soft-limit can only be set for system.
+*/
+int32_t
+cli_snap_config_parse (const char **words, int wordcount, dict_t *dict,
+ unsigned int cmdi, struct cli_state *state)
+{
+ int ret = -1;
+ gf_answer_t answer = GF_ANSWER_NO;
+ gf_boolean_t vol_presence = _gf_false;
+ struct snap_config_opt_vals_ *conf_vals = NULL;
+ int8_t hard_limit = 0;
+ int8_t soft_limit = 0;
+ int8_t config_type = -1;
+ const char *question = NULL;
+
+ GF_ASSERT (words);
+ GF_ASSERT (dict);
+ GF_ASSERT (state);
+
+ if ((wordcount < 2) || (wordcount > 7)) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Invalid wordcount(%d)", wordcount);
+ goto out;
+ }
+
+ if (wordcount == 2) {
+ config_type = GF_SNAP_CONFIG_DISPLAY;
+ ret = 0;
+ goto set;
+ }
+
+ /* Check whether the 3rd word is volname */
+ if (strcmp (words[cmdi], "snap-max-hard-limit") != 0
+ && strcmp (words[cmdi], "snap-max-soft-limit") != 0) {
+ ret = dict_set_str (dict, "volname", (char *)words[cmdi]);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to set volname");
+ goto out;
+ }
+ cmdi++;
+ vol_presence = _gf_true;
+
+ if (cmdi == wordcount) {
+ config_type = GF_SNAP_CONFIG_DISPLAY;
+ ret = 0;
+ goto set;
+ }
+ }
+
+ config_type = GF_SNAP_CONFIG_TYPE_SET;
+
+ if (strcmp (words[cmdi], "snap-max-hard-limit") == 0) {
+ ret = cli_snap_config_limit_parse (words, dict, wordcount,
+ ++cmdi, "snap-max-hard-limit");
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to parse snap "
+ "config hard limit");
+ goto out;
+ }
+ hard_limit = 1;
+
+ if (++cmdi == wordcount) {
+ ret = 0;
+ goto set;
+ }
+ }
+
+ if (strcmp (words[cmdi], "snap-max-soft-limit") == 0) {
+ if (vol_presence == 1) {
+ ret = -1;
+ cli_err ("Soft limit cannot be set to individual "
+ "volumes.");
+ gf_log ("cli", GF_LOG_ERROR, "Soft limit cannot be "
+ "set to volumes");
+ goto out;
+ }
+
+ ret = cli_snap_config_limit_parse (words, dict, wordcount,
+ ++cmdi, "snap-max-soft-limit");
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to parse snap "
+ "config soft limit");
+ goto out;
+ }
+
+ if (++cmdi != wordcount) {
+ ret = -1;
+ gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
+ soft_limit = 1;
+ } else {
+ ret = -1;
+ gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
+ ret = 0; /* Success */
+
+set:
+ ret = dict_set_int32 (dict, "config-command", config_type);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Unable to set "
+ "config-command");
+ goto out;
+ }
+
+ if (config_type == GF_SNAP_CONFIG_TYPE_SET) {
+ conf_vals = snap_confopt_vals;
+ if (hard_limit && soft_limit) {
+ question = conf_vals[GF_SNAP_CONFIG_SET_BOTH].question;
+ } else if (soft_limit) {
+ question = conf_vals[GF_SNAP_CONFIG_SET_SOFT].question;
+ } else if (hard_limit) {
+ question = conf_vals[GF_SNAP_CONFIG_SET_HARD].question;
+ }
+
+ answer = cli_cmd_get_confirmation (state, question);
+ if (GF_ANSWER_NO == answer) {
+ ret = 1;
+ gf_log ("cli", GF_LOG_DEBUG, "User cancelled "
+ "snapshot config operation");
+ }
+ }
+
+out:
+ return ret;
+}
+
int
validate_snapname (const char *snapname, char **opwords) {
int ret = -1;
@@ -3461,7 +3522,7 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
if (type != GF_SNAP_OPTION_TYPE_CONFIG) {
ret = dict_set_int32 (dict, "hold_snap_locks", _gf_true);
if (ret) {
- gf_log ("", GF_LOG_ERROR,
+ gf_log ("cli", GF_LOG_ERROR,
"Unable to set hold-snap-locks value as _gf_true");
goto out;
}
@@ -3552,16 +3613,25 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
case GF_SNAP_OPTION_TYPE_CONFIG:
{
- /* snapshot config <volname | all> [snap-max-hard-limit <count> |
- * snap-max-soft-limit <percent>] */
+ /* snapshot config [volname] [snap-max-hard-limit <count>]
+ * [snap-max-soft-limit <percent>] */
ret = cli_snap_config_parse (words, wordcount, dict,
- state);
+ cmdi, state);
if (ret) {
if (ret < 0)
gf_log ("cli", GF_LOG_ERROR,
"config command parsing failed.");
goto out;
}
+
+ ret = dict_set_int32 (dict, "type",
+ GF_SNAP_OPTION_TYPE_CONFIG);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Unable to set "
+ "config type");
+ ret = -1;
+ goto out;
+ }
break;
}
case GF_SNAP_OPTION_TYPE_STATUS: