summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/cli-cmd-parser.c340
-rw-r--r--cli/src/cli-cmd-snapshot.c2
-rw-r--r--cli/src/cli-rpc-ops.c71
-rw-r--r--rpc/xdr/src/cli1-xdr.h6
-rw-r--r--rpc/xdr/src/cli1-xdr.x5
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c202
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c17
7 files changed, 389 insertions, 254 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:
diff --git a/cli/src/cli-cmd-snapshot.c b/cli/src/cli-cmd-snapshot.c
index bf954d61c..de492d683 100644
--- a/cli/src/cli-cmd-snapshot.c
+++ b/cli/src/cli-cmd-snapshot.c
@@ -103,7 +103,7 @@ struct cli_cmd snapshot_cmds[] = {
cli_cmd_snapshot_cbk,
"Snapshot List."
},
- {"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>]",
cli_cmd_snapshot_cbk,
"Snapshot Config."
},
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index 677431127..6e0f24d5f 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -7569,10 +7569,10 @@ cli_snapshot_config_display (dict_t *dict, gf_cli_rsp *rsp)
{
char buf[PATH_MAX] = "";
char *volname = NULL;
- char *key = NULL;
int ret = -1;
int config_command = 0;
uint64_t value = 0;
+ uint64_t hard_limit = 0;
uint64_t soft_limit = 0;
uint64_t i = 0;
uint64_t voldisplaycount = 0;
@@ -7590,23 +7590,24 @@ cli_snapshot_config_display (dict_t *dict, gf_cli_rsp *rsp)
ret = dict_get_int32 (dict, "config-command", &config_command);
if (ret) {
- gf_log("", GF_LOG_ERROR, "Could not fetch config type");
+ gf_log ("cli", GF_LOG_ERROR, "Could not fetch config type");
goto out;
}
ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log("", GF_LOG_ERROR, "Could not fetch "
- "volname");
- goto out;
- }
+ /* Ignore the error, as volname is optional */
- if (!strcmp (volname, "all")) {
+ if (!volname) {
volname = "System";
}
- ret = dict_get_str (dict, "config-key", &key);
- if (ret && config_command != GF_SNAP_CONFIG_DISPLAY) {
+ ret = dict_get_uint64 (dict, "snap-max-hard-limit", &hard_limit);
+ /* Ignore the error, as the key specified is optional */
+ ret = dict_get_uint64 (dict, "snap-max-soft-limit", &soft_limit);
+
+ if (!hard_limit && !soft_limit
+ && config_command != GF_SNAP_CONFIG_DISPLAY) {
+ ret = -1;
gf_log(THIS->name, GF_LOG_ERROR,
"Could not fetch config-key");
goto out;
@@ -7614,8 +7615,19 @@ cli_snapshot_config_display (dict_t *dict, gf_cli_rsp *rsp)
switch (config_command) {
case GF_SNAP_CONFIG_TYPE_SET:
- cli_out ("snapshot config: %s "
- "for %s set successfully", key, volname);
+ if (hard_limit && soft_limit) {
+ cli_out ("snapshot config: snap-max-hard-limit "
+ "& snap-max-soft-limit for system set "
+ "successfully");
+ } else if (hard_limit){
+ cli_out ("snapshot config: %s "
+ "for snap-max-hard-limit set successfully",
+ volname);
+ } else if (soft_limit) {
+ cli_out ("snapshot config: %s "
+ "for snap-max-soft-limit set successfully",
+ volname);
+ }
break;
case GF_SNAP_CONFIG_DISPLAY :
@@ -7623,7 +7635,7 @@ cli_snapshot_config_display (dict_t *dict, gf_cli_rsp *rsp)
ret = dict_get_uint64 (dict, "snap-max-hard-limit",
&value);
if (ret) {
- gf_log("", GF_LOG_ERROR, "Could not fetch "
+ gf_log ("cli", GF_LOG_ERROR, "Could not fetch "
"snap_max_hard_limit for %s", volname);
ret = -1;
goto out;
@@ -7633,19 +7645,21 @@ cli_snapshot_config_display (dict_t *dict, gf_cli_rsp *rsp)
ret = dict_get_uint64 (dict, "snap-max-soft-limit",
&soft_limit);
if (ret) {
- gf_log("", GF_LOG_ERROR, "Could not fetch "
+ gf_log ("cli", GF_LOG_ERROR, "Could not fetch "
"snap-max-soft-limit for %s", volname);
ret = -1;
goto out;
}
- cli_out ("snap-max-soft-limit : %"PRIu64"%%\n", soft_limit);
+ cli_out ("snap-max-soft-limit : %"PRIu64"%%\n",
+ soft_limit);
cli_out ("Snapshot Volume Configuration:");
ret = dict_get_uint64 (dict, "voldisplaycount",
&voldisplaycount);
if (ret) {
- gf_log("", GF_LOG_ERROR, "Could not fetch voldisplaycount");
+ gf_log ("cli", GF_LOG_ERROR,
+ "Could not fetch voldisplaycount");
ret = -1;
goto out;
}
@@ -7654,7 +7668,7 @@ cli_snapshot_config_display (dict_t *dict, gf_cli_rsp *rsp)
snprintf (buf, sizeof(buf), "volume%ld-volname", i);
ret = dict_get_str (dict, buf, &volname);
if (ret) {
- gf_log("", GF_LOG_ERROR, "Could not fetch "
+ gf_log ("cli", GF_LOG_ERROR, "Could not fetch "
" %s", buf);
ret = -1;
goto out;
@@ -7665,7 +7679,7 @@ cli_snapshot_config_display (dict_t *dict, gf_cli_rsp *rsp)
"volume%ld-snap-max-hard-limit", i);
ret = dict_get_uint64 (dict, buf, &value);
if (ret) {
- gf_log("", GF_LOG_ERROR, "Could not fetch "
+ gf_log ("cli", GF_LOG_ERROR, "Could not fetch "
" %s", buf);
ret = -1;
goto out;
@@ -7673,16 +7687,29 @@ cli_snapshot_config_display (dict_t *dict, gf_cli_rsp *rsp)
cli_out ("snap-max-hard-limit : %"PRIu64, value);
snprintf (buf, sizeof(buf),
- "volume%ld-snap-max-soft-limit-value", i);
+ "volume%ld-active-hard-limit", i);
ret = dict_get_uint64 (dict, buf, &value);
if (ret) {
- gf_log("", GF_LOG_ERROR, "Could not fetch "
+ gf_log ("cli", GF_LOG_ERROR, "Could not fetch"
+ " effective snap_max_hard_limit for "
+ "%s", volname);
+ ret = -1;
+ goto out;
+ }
+ cli_out ("Effective snap-max-hard-limit : %"PRIu64,
+ value);
+
+ snprintf (buf, sizeof(buf),
+ "volume%ld-snap-max-soft-limit", i);
+ ret = dict_get_uint64 (dict, buf, &value);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Could not fetch "
" %s", buf);
ret = -1;
goto out;
}
- cli_out ("snap-max-soft-limit : %"PRIu64" (%"PRIu64"%%)",
- value, soft_limit);
+ cli_out ("Effective snap-max-soft-limit : %"PRIu64" "
+ "(%"PRIu64"%%)", value, soft_limit);
}
break;
default :
diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h
index b4b717e4c..5e8c29fbb 100644
--- a/rpc/xdr/src/cli1-xdr.h
+++ b/rpc/xdr/src/cli1-xdr.h
@@ -191,9 +191,9 @@ enum gf1_cli_snapshot_info {
typedef enum gf1_cli_snapshot_info gf1_cli_snapshot_info;
enum gf1_cli_snapshot_config {
- GF_SNAP_CONFIG_TYPE_NONE = 0,
- GF_SNAP_CONFIG_TYPE_SET = 0 + 1,
- GF_SNAP_CONFIG_DISPLAY = 0 + 2,
+ GF_SNAP_CONFIG_TYPE_NONE = 0,
+ GF_SNAP_CONFIG_TYPE_SET = 1,
+ GF_SNAP_CONFIG_DISPLAY = 2,
};
typedef enum gf1_cli_snapshot_config gf1_cli_snapshot_config;
diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x
index 8167abbf9..f9d29b7e1 100644
--- a/rpc/xdr/src/cli1-xdr.x
+++ b/rpc/xdr/src/cli1-xdr.x
@@ -137,10 +137,9 @@ enum gf1_cli_snapshot {
enum gf1_cli_snapshot_config {
GF_SNAP_CONFIG_TYPE_NONE = 0,
- GF_SNAP_CONFIG_SYS_MAX,
- GF_SNAP_CONFIG_VOL_MAX,
+ GF_SNAP_CONFIG_TYPE_SET,
GF_SNAP_CONFIG_DISPLAY,
- GF_SNAP_CONFIG_CG_MAX
+
};
struct gf_cli_req {
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index 7434b7abd..7068a04bb 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -244,7 +244,7 @@ out:
}
int
-snap_max_limits_validate (dict_t *dict, char *volname, char *key,
+snap_max_hard_limits_validate (dict_t *dict, char *volname,
uint64_t value, char **op_errstr)
{
char err_str[PATH_MAX] = "";
@@ -258,47 +258,37 @@ snap_max_limits_validate (dict_t *dict, char *volname, char *key,
GF_ASSERT (this);
GF_ASSERT (dict);
- GF_ASSERT (volname);
- GF_ASSERT (key);
GF_ASSERT (op_errstr);
conf = this->private;
GF_ASSERT (conf);
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (!ret) {
- if (volinfo->is_snap_volume) {
- ret = -1;
- snprintf (err_str, PATH_MAX,"%s is a snap volume. "
- "Configuring %s for a snap volume is "
- "prohibited.", volname, key);
- goto out;
+ if (volname) {
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (!ret) {
+ if (volinfo->is_snap_volume) {
+ ret = -1;
+ snprintf (err_str, PATH_MAX,
+ "%s is a snap volume. Configuring "
+ "snap-max-hard-limit for a snap "
+ "volume is prohibited.", volname);
+ goto out;
+ }
}
}
- if (!strcmp (key, "snap-max-hard-limit")) {
+ if (value) {
max_limit = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
- if ((max_limit > conf->snap_max_hard_limit) &&
- (strncmp (volname, "all", strlen(volname))))
+ if ((max_limit > conf->snap_max_hard_limit) && volname)
max_limit = conf->snap_max_hard_limit;
- } else {
- max_limit = GLUSTERD_SNAPS_MAX_SOFT_LIMIT_PERCENT;
- if (strncmp (volname, "all", strlen(volname))) {
- ret = -1;
- snprintf (err_str, PATH_MAX, "%s is not configurable "
- "for individual volumes. Configure %s for "
- "system.", key, key);
- goto out;
- }
}
- if ((value < 0) ||
- (value > max_limit)) {
+ if ((value < 0) || (value > max_limit)) {
ret = -1;
- snprintf (err_str, PATH_MAX, "Invalid %s "
+ snprintf (err_str, PATH_MAX, "Invalid snap-max-hard-limit"
"%"PRIu64 ". Expected range 0 - %"PRIu64,
- key, value, max_limit);
+ value, max_limit);
goto out;
}
@@ -315,7 +305,6 @@ int
glusterd_snapshot_config_prevalidate (dict_t *dict, char **op_errstr)
{
char *volname = NULL;
- char *key = NULL;
glusterd_volinfo_t *volinfo = NULL;
xlator_t *this = NULL;
int ret = -1;
@@ -323,7 +312,10 @@ glusterd_snapshot_config_prevalidate (dict_t *dict, char **op_errstr)
char err_str[PATH_MAX] = {0,};
glusterd_conf_t *conf = NULL;
uint64_t value = 0;
+ uint64_t hard_limit = 0;
+ uint64_t soft_limit = 0;
gf_loglevel_t loglevel = GF_LOG_ERROR;
+ uint64_t max_limit = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
this = THIS;
@@ -342,25 +334,13 @@ glusterd_snapshot_config_prevalidate (dict_t *dict, char **op_errstr)
goto out;
}
- ret = dict_get_str (dict, "config-key", &key);
- if (!ret) {
- ret = dict_get_uint64 (dict, key, &value);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Failed to get the"
- " value for %s", key);
+ ret = dict_get_uint64 (dict, "snap-max-hard-limit", &hard_limit);
- goto out;
- }
- }
+ ret = dict_get_uint64 (dict, "snap-max-soft-limit", &soft_limit);
ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Failed to get the"
- " volume name");
- goto out;
- }
- if (strncmp (volname, "all", strlen(volname))) {
+ if (volname) {
ret = glusterd_volinfo_find (volname, &volinfo);
if (ret) {
snprintf (err_str, sizeof (err_str),
@@ -371,22 +351,35 @@ glusterd_snapshot_config_prevalidate (dict_t *dict, char **op_errstr)
switch (config_command) {
case GF_SNAP_CONFIG_TYPE_SET:
- if ((!strncmp (key, "snap-max-hard-limit", strlen(key))) ||
- (!strncmp (key, "snap-max-soft-limit", strlen(key)))) {
- /* Validations for snap-max-limits */
- ret = snap_max_limits_validate (dict, volname,
- key, value, op_errstr);
+ if (hard_limit) {
+ /* Validations for snap-max-hard-limits */
+ ret = snap_max_hard_limits_validate (dict, volname,
+ hard_limit, op_errstr);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
- "%s validation failed.", key);
+ "snap-max-hard-limit validation "
+ "failed.");
goto out;
}
}
- break;
+ if (soft_limit) {
+ max_limit = GLUSTERD_SNAPS_MAX_SOFT_LIMIT_PERCENT;
+ if ((soft_limit < 0) || (soft_limit > max_limit)) {
+ ret = -1;
+ snprintf (err_str, PATH_MAX, "Invalid "
+ "snap-max-soft-limit ""%"
+ PRIu64 ". Expected range 0 - %"PRIu64,
+ value, max_limit);
+ goto out;
+ }
+ break;
+ }
default:
break;
}
+
+ ret = 0; /* Success */
out:
if (ret && err_str[0] != '\0') {
@@ -3386,7 +3379,7 @@ out:
}
int
-snap_max_hard_limit_set_commit (dict_t *dict, char *key, uint64_t value,
+snap_max_hard_limit_set_commit (dict_t *dict, uint64_t value,
char *volname, char **op_errstr)
{
char err_str[PATH_MAX] = "";
@@ -3399,7 +3392,6 @@ snap_max_hard_limit_set_commit (dict_t *dict, char *key, uint64_t value,
GF_ASSERT (this);
GF_ASSERT (dict);
- GF_ASSERT (key);
GF_ASSERT (volname);
GF_ASSERT (op_errstr);
@@ -3408,14 +3400,14 @@ snap_max_hard_limit_set_commit (dict_t *dict, char *key, uint64_t value,
GF_ASSERT (conf);
/* TODO: Initiate auto deletion when there is a limit change */
- if (!strncmp (volname, "all", strlen(volname))) {
+ if (!volname) {
/* For system limit */
conf->snap_max_hard_limit = value;
ret = glusterd_store_global_info (this);
if (ret) {
- snprintf (err_str, PATH_MAX,"Failed to store %s "
- "for system", key);
+ snprintf (err_str, PATH_MAX,"Failed to store "
+ "snap-max-hard-limit for system");
goto out;
}
} else {
@@ -3432,8 +3424,8 @@ snap_max_hard_limit_set_commit (dict_t *dict, char *key, uint64_t value,
ret = glusterd_store_volinfo (volinfo,
GLUSTERD_VOLINFO_VER_AC_INCREMENT);
if (ret) {
- snprintf (err_str, PATH_MAX,"Failed to store %s "
- "for volume %s", key, volname);
+ snprintf (err_str, PATH_MAX,"Failed to store "
+ "snap-max-hard-limit for volume %s", volname);
goto out;
}
}
@@ -3473,7 +3465,7 @@ snap_max_limits_display_commit (dict_t *rsp_dict, char *volname,
GF_ASSERT (conf);
- if (!strncmp (volname, "all", strlen(volname))) {
+ if (!volname) {
/* For system limit */
list_for_each_entry (volinfo, &conf->volumes, vol_list) {
if (volinfo->is_snap_volume == _gf_true)
@@ -3504,7 +3496,16 @@ snap_max_limits_display_commit (dict_t *rsp_dict, char *volname,
}
snprintf (buf, sizeof(buf),
- "volume%ld-snap-max-soft-limit-value", count);
+ "volume%ld-active-hard-limit", count);
+ ret = dict_set_uint64 (rsp_dict, buf, active_hard_limit);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,
+ "Failed to set %s", buf);
+ goto out;
+ }
+
+ snprintf (buf, sizeof(buf),
+ "volume%ld-snap-max-soft-limit", count);
ret = dict_set_uint64 (rsp_dict, buf, soft_limit_value);
if (ret) {
snprintf (err_str, PATH_MAX,
@@ -3530,7 +3531,12 @@ snap_max_limits_display_commit (dict_t *rsp_dict, char *volname,
}
snap_max_limit = volinfo->snap_max_hard_limit;
- soft_limit_value = (volinfo->snap_max_hard_limit *
+ if (snap_max_limit > conf->snap_max_hard_limit)
+ active_hard_limit = conf->snap_max_hard_limit;
+ else
+ active_hard_limit = snap_max_limit;
+
+ soft_limit_value = (active_hard_limit *
conf->snap_max_soft_limit) / 100;
snprintf (buf, sizeof(buf), "volume%ld-volname", count);
@@ -3551,13 +3557,23 @@ snap_max_limits_display_commit (dict_t *rsp_dict, char *volname,
}
snprintf (buf, sizeof(buf),
- "volume%ld-snap-max-soft-limit-value", count);
+ "volume%ld-active-hard-limit", count);
+ ret = dict_set_uint64 (rsp_dict, buf, active_hard_limit);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,
+ "Failed to set %s", buf);
+ goto out;
+ }
+
+ snprintf (buf, sizeof(buf),
+ "volume%ld-snap-max-soft-limit", count);
ret = dict_set_uint64 (rsp_dict, buf, soft_limit_value);
if (ret) {
snprintf (err_str, PATH_MAX,
"Failed to set %s", buf);
goto out;
}
+
count++;
ret = dict_set_uint64 (rsp_dict, "voldisplaycount", count);
@@ -3599,13 +3615,13 @@ glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr,
dict_t *rsp_dict)
{
char *volname = NULL;
- char *key = NULL;
xlator_t *this = NULL;
int ret = -1;
char err_str[PATH_MAX] = {0,};
glusterd_conf_t *conf = NULL;
int config_command = 0;
- uint64_t value = 0;
+ uint64_t hard_limit = 0;
+ uint64_t soft_limit = 0;
this = THIS;
@@ -3624,46 +3640,37 @@ glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr,
goto out;
}
+ /* Ignore the return value of the following dict_get,
+ * as they are optional
+ */
ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- snprintf (err_str, PATH_MAX,"Failed to get the"
- " volume name");
- *op_errstr = gf_strdup (err_str);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- ret = dict_get_str (dict, "config-key", &key);
- if (!ret) {
- ret = dict_get_uint64 (dict, key, &value);
- if (ret) {
- snprintf (err_str, PATH_MAX,"Failed to get the"
- " value for %s", key);
- *op_errstr = gf_strdup (err_str);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- }
+ ret = dict_get_uint64 (dict, "snap-max-hard-limit", &hard_limit);
+
+ ret = dict_get_uint64 (dict, "snap-max-soft-limit", &soft_limit);
switch (config_command) {
case GF_SNAP_CONFIG_TYPE_SET:
- if (!strncmp (key, "snap-max-hard-limit", strlen(key))) {
+ if (hard_limit) {
/* Commit ops for snap-max-hard-limit */
- ret = snap_max_hard_limit_set_commit (dict, key, value,
+ ret = snap_max_hard_limit_set_commit (dict, hard_limit,
volname, op_errstr);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
- "%s set commit failed.", key);
+ "snap-max-hard-limit set "
+ "commit failed.");
goto out;
}
- } else if (!strncmp (key, "snap-max-soft-limit", strlen(key))) {
+ }
+
+ if (soft_limit) {
/* For system limit */
- conf->snap_max_soft_limit = value;
+ conf->snap_max_soft_limit = soft_limit;
ret = glusterd_store_global_info (this);
if (ret) {
- snprintf (err_str, PATH_MAX,"Failed to store %s "
- "for system", key);
+ snprintf (err_str, PATH_MAX,"Failed to store "
+ "snap-max-soft-limit for system");
*op_errstr = gf_strdup (err_str);
gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
goto out;
@@ -3678,7 +3685,8 @@ glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr,
break;
}
- ret = snap_max_limits_display_commit (rsp_dict, volname, op_errstr);
+ ret = snap_max_limits_display_commit (rsp_dict, volname,
+ op_errstr);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"snap-max-limit "
@@ -4612,6 +4620,7 @@ glusterd_handle_snapshot_fn (rpcsvc_request_t *req)
char *host_uuid = NULL;
char err_str[2048] = {0,};
xlator_t *this = NULL;
+ char *volname = NULL;
GF_ASSERT (req);
@@ -4707,6 +4716,21 @@ glusterd_handle_snapshot_fn (rpcsvc_request_t *req)
}
break;
case GF_SNAP_OPTION_TYPE_CONFIG:
+ /* TODO : Type of lock to be taken when we are setting
+ * limits system wide
+ */
+ ret = dict_get_str (dict, "volname", &volname);
+ if (!volname) {
+ ret = dict_set_int32 (dict, "hold_vol_locks",
+ _gf_false);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Unable to set hold_vol_locks value "
+ "as _gf_false");
+ goto out;
+ }
+
+ }
ret = glusterd_mgmt_v3_initiate_all_phases (req, cli_op, dict);
break;
case GF_SNAP_OPTION_TYPE_DELETE:
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index a398058d5..7f1f49461 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -7758,7 +7758,22 @@ glusterd_snap_config_use_rsp_dict (dict_t *dst, dict_t *src)
}
snprintf (buf, sizeof(buf),
- "volume%ld-snap-max-soft-limit-value", i);
+ "volume%ld-active-hard-limit", i);
+ ret = dict_get_uint64 (src, buf, &value);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "Unable to get %s", buf);
+ goto out;
+ }
+ ret = dict_set_uint64 (dst, buf, value);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "Unable to set %s", buf);
+ goto out;
+ }
+
+ snprintf (buf, sizeof(buf),
+ "volume%ld-snap-max-soft-limit", i);
ret = dict_get_uint64 (src, buf, &value);
if (ret) {
gf_log ("", GF_LOG_ERROR,