From c36c95a79c2f73f35727c6f8cba0586714663fd9 Mon Sep 17 00:00:00 2001 From: Sachin Pandit Date: Mon, 17 Mar 2014 07:22:03 +0530 Subject: snapshot/config : snapshot config changes. Syntax : gluster snapshot config [volname] [snap-max-hard-limit ] [snap-max-soft-limit ] 1)If volume name is not specified, then the value is set system wide. 2)If volume name is specified, then the value is set to that particular volume. *NOTE : snap-max-soft-limit cannot be specified to individual volumes. case 1) When system limit is greater than volume limit. Sample output : Snapshot System Configuration: snap-max-hard-limit : 200 snap-max-soft-limit : 50% Snapshot Volume Configuration: Volume : vol2 snap-max-hard-limit : 100 Effective snap-max-hard-limit : 100 Effective snap-max-soft-limit : 50 (50%) Volume : vol1 snap-max-hard-limit : 150 Effective snap-max-hard-limit : 150 Effective snap-max-soft-limit : 75 (50%) case 2) When system limit is lesser than volume limit. Sample output : Snapshot System Configuration: snap-max-hard-limit : 50 snap-max-soft-limit : 50% Snapshot Volume Configuration: Volume : vol2 snap-max-hard-limit : 100 Effective snap-max-hard-limit : 50 Effective snap-max-soft-limit : 25 (50%) Volume : vol1 snap-max-hard-limit : 150 Effective snap-max-hard-limit : 50 Effective snap-max-soft-limit : 25 (50%) Change-Id: I97b5daefec7205bb9ab7b5b51d38f504cc5ee940 BUG: 1075034 Signed-off-by: Sachin Pandit Reviewed-on: http://review.gluster.org/7303 Reviewed-by: Rajesh Joseph Tested-by: Rajesh Joseph --- cli/src/cli-cmd-parser.c | 340 ++++++++++++++++---------- cli/src/cli-cmd-snapshot.c | 2 +- cli/src/cli-rpc-ops.c | 71 ++++-- rpc/xdr/src/cli1-xdr.h | 6 +- rpc/xdr/src/cli1-xdr.x | 5 +- xlators/mgmt/glusterd/src/glusterd-snapshot.c | 202 ++++++++------- xlators/mgmt/glusterd/src/glusterd-utils.c | 17 +- 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 [snap-max-hard-limit - * | snap-max-soft-limit ] */ - - 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 * @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 ] + * [snap-max-soft-limit ] + * + 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 [snap-max-hard-limit | - * snap-max-soft-limit ] */ + /* snapshot config [volname] [snap-max-hard-limit ] + * [snap-max-soft-limit ] */ 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 | snap-max-soft-limit ]", + {"snapshot config [volname] [snap-max-hard-limit ] [snap-max-soft-limit ]", 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, -- cgit