From 5906be31845f6a63ff9d5cd15ad0c13af51b81ea Mon Sep 17 00:00:00 2001 From: Sachin Pandit Date: Wed, 4 Jun 2014 03:41:35 +0530 Subject: glusterd/snapshot : Store the global snapshot config limit in options. Problem : Initially we used to save the global config limit in glusterd.info, The problem with that approach was glusterd.info is local to a particular glusterd and hence is not synced during the handshake of glusterds. Solution : Store the global snapshot config in options, which is synced during handshake. Change-Id: I4c688bb4052a57df28aadba8581b14e2ddb510ef BUG: 1104642 Signed-off-by: Sachin Pandit Reviewed-on: http://review.gluster.org/7971 Reviewed-by: Rajesh Joseph Tested-by: Gluster Build System Reviewed-by: Atin Mukherjee Reviewed-by: Krishnan Parthasarathi Tested-by: Krishnan Parthasarathi --- xlators/mgmt/glusterd/src/glusterd-snapshot.c | 218 +++++++++++++++++++++----- xlators/mgmt/glusterd/src/glusterd-store.c | 40 ----- xlators/mgmt/glusterd/src/glusterd-utils.c | 52 ++++++ xlators/mgmt/glusterd/src/glusterd-utils.h | 3 + xlators/mgmt/glusterd/src/glusterd.c | 18 ++- xlators/mgmt/glusterd/src/glusterd.h | 2 - 6 files changed, 245 insertions(+), 88 deletions(-) diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c index e024544d34d..4769b794cd1 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c @@ -215,6 +215,8 @@ snap_max_limits_display_commit (dict_t *rsp_dict, char *volname, uint64_t soft_limit_value = -1; uint64_t count = 0; xlator_t *this = NULL; + uint64_t opt_hard_max = 0; + uint64_t opt_soft_max = 0; this = THIS; @@ -226,18 +228,40 @@ snap_max_limits_display_commit (dict_t *rsp_dict, char *volname, GF_ASSERT (conf); + ret = dict_get_uint64 (conf->opts, + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT, + &opt_hard_max); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "%s from opts dictionary", + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT); + goto out; + } + + ret = dict_get_uint64 (conf->opts, + GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT, + &opt_soft_max); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "%s from options", + GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT); + goto out; + } + if (!volname) { /* For system limit */ list_for_each_entry (volinfo, &conf->volumes, vol_list) { if (volinfo->is_snap_volume == _gf_true) continue; + snap_max_limit = volinfo->snap_max_hard_limit; - if (snap_max_limit > conf->snap_max_hard_limit) - active_hard_limit = conf->snap_max_hard_limit; + if (snap_max_limit > opt_hard_max) + active_hard_limit = opt_hard_max; else active_hard_limit = snap_max_limit; - soft_limit_value = (active_hard_limit * - conf->snap_max_soft_limit) / 100; + + soft_limit_value = (opt_soft_max * + active_hard_limit) / 100; snprintf (buf, sizeof(buf), "volume%"PRId64"-volname", count); @@ -294,13 +318,13 @@ snap_max_limits_display_commit (dict_t *rsp_dict, char *volname, } snap_max_limit = volinfo->snap_max_hard_limit; - if (snap_max_limit > conf->snap_max_hard_limit) - active_hard_limit = conf->snap_max_hard_limit; + if (snap_max_limit > opt_hard_max) + active_hard_limit = opt_hard_max; else active_hard_limit = snap_max_limit; - soft_limit_value = (active_hard_limit * - conf->snap_max_soft_limit) / 100; + soft_limit_value = (opt_soft_max * + active_hard_limit) / 100; snprintf (buf, sizeof(buf), "volume%"PRId64"-volname", count); ret = dict_set_str (rsp_dict, buf, volinfo->volname); @@ -348,19 +372,23 @@ snap_max_limits_display_commit (dict_t *rsp_dict, char *volname, } - ret = dict_set_uint64 (rsp_dict, "snap-max-hard-limit", - conf->snap_max_hard_limit); + ret = dict_set_uint64 (rsp_dict, + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT, + opt_hard_max); if (ret) { snprintf (err_str, PATH_MAX, - "Failed to set sys-snap-max-hard-limit "); + "Failed to set %s in reponse dictionary", + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT); goto out; } - ret = dict_set_uint64 (rsp_dict, "snap-max-soft-limit", - conf->snap_max_soft_limit); + ret = dict_set_uint64 (rsp_dict, + GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT, + opt_soft_max); if (ret) { snprintf (err_str, PATH_MAX, - "Failed to set sys-snap-max-hard-limit "); + "Failed to set %s in response dictionary", + GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT); goto out; } @@ -952,6 +980,7 @@ snap_max_hard_limits_validate (dict_t *dict, char *volname, int ret = -1; uint64_t max_limit = GLUSTERD_SNAPS_MAX_HARD_LIMIT; xlator_t *this = NULL; + uint64_t opt_hard_max = 0; this = THIS; @@ -977,15 +1006,23 @@ snap_max_hard_limits_validate (dict_t *dict, char *volname, } } - if (value) { - /* Max limit for the system is GLUSTERD_SNAPS_MAX_HARD_LIMIT - * but max limit for a volume is conf->snap_max_hard_limit. - */ - if (volname) { - max_limit = conf->snap_max_hard_limit; - } else { - max_limit = GLUSTERD_SNAPS_MAX_HARD_LIMIT; - } + ret = dict_get_uint64 (conf->opts, + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT, + &opt_hard_max); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "%s from opts dictionary", + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT); + goto out; + } + + /* volume snap-max-hard-limit cannot exceed system snap-max-hard-limit. + * Hence during prevalidate following checks are made to ensure the + * snap-max-hard-limit set on one particular volume does not + * exceed snap-max-hard-limit set globally (system limit). + */ + if (value && volname) { + max_limit = opt_hard_max; } if ((value < 0) || (value > max_limit)) { @@ -1508,6 +1545,7 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr, glusterd_conf_t *conf = NULL; int64_t effective_max_limit = 0; int flags = 0; + uint64_t opt_hard_max = 0; this = THIS; GF_ASSERT (op_errstr); @@ -1584,10 +1622,20 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr, goto out; } - if (volinfo->snap_max_hard_limit < conf->snap_max_hard_limit) + ret = dict_get_uint64 (conf->opts, + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT, + &opt_hard_max); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "%s from opts dictionary", + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT); + goto out; + } + + if (volinfo->snap_max_hard_limit < opt_hard_max) effective_max_limit = volinfo->snap_max_hard_limit; else - effective_max_limit = conf->snap_max_hard_limit; + effective_max_limit = opt_hard_max; if (volinfo->snap_count >= effective_max_limit) { snprintf (err_str, sizeof (err_str), @@ -2269,6 +2317,7 @@ glusterd_snapshot_get_snapvol_detail (dict_t *dict, glusterd_volinfo_t *origin_vol = NULL; glusterd_conf_t *conf = NULL; xlator_t *this = NULL; + uint64_t opt_hard_max = 0; this = THIS; conf = this->private; @@ -2339,8 +2388,19 @@ glusterd_snapshot_get_snapvol_detail (dict_t *dict, } /* Snaps available */ - if (conf->snap_max_hard_limit < origin_vol->snap_max_hard_limit) { - snap_limit = conf->snap_max_hard_limit; + + ret = dict_get_uint64 (conf->opts, + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT, + &opt_hard_max); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "%s from opts dictionary", + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT); + goto out; + } + + if (opt_hard_max < origin_vol->snap_max_hard_limit) { + snap_limit = opt_hard_max; gf_log(this->name, GF_LOG_DEBUG, "system snap-max-hard-limit is" " lesser than volume snap-max-hard-limit, " "snap-max-hard-limit value is set to %d", snap_limit); @@ -2622,6 +2682,7 @@ glusterd_snapshot_get_info_by_volume (dict_t *dict, char *volname, glusterd_volinfo_t *tmp_vol = NULL; glusterd_conf_t *conf = NULL; xlator_t *this = NULL; + uint64_t opt_hard_max = 0; this = THIS; conf = this->private; @@ -2638,8 +2699,18 @@ glusterd_snapshot_get_info_by_volume (dict_t *dict, char *volname, } /* Snaps available */ - if (conf->snap_max_hard_limit < volinfo->snap_max_hard_limit) { - snap_limit = conf->snap_max_hard_limit; + ret = dict_get_uint64 (conf->opts, + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT, + &opt_hard_max); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "%s from opts dictionary", + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT); + goto out; + } + + if (opt_hard_max < volinfo->snap_max_hard_limit) { + snap_limit = opt_hard_max; gf_log(this->name, GF_LOG_DEBUG, "system snap-max-hard-limit is" " lesser than volume snap-max-hard-limit, " "snap-max-hard-limit value is set to %d", snap_limit); @@ -4918,6 +4989,7 @@ snap_max_hard_limit_set_commit (dict_t *dict, uint64_t value, glusterd_volinfo_t *volinfo = NULL; int ret = -1; xlator_t *this = NULL; + char *next_version = NULL; this = THIS; @@ -4932,12 +5004,31 @@ snap_max_hard_limit_set_commit (dict_t *dict, uint64_t value, /* TODO: Initiate auto deletion when there is a limit change */ if (!volname) { /* For system limit */ - conf->snap_max_hard_limit = value; + ret = dict_set_uint64 (conf->opts, + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT, + value); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to store " + "%s in the options", + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT); + goto out; + } + + + ret = glusterd_get_next_global_opt_version_str (conf->opts, + &next_version); + if (ret) + goto out; + + ret = dict_set_str (conf->opts, GLUSTERD_GLOBAL_OPT_VERSION, + next_version); + if (ret) + goto out; - ret = glusterd_store_global_info (this); + ret = glusterd_store_options (this, conf->opts); if (ret) { - snprintf (err_str, PATH_MAX, "Failed to store " - "snap-max-hard-limit for system"); + gf_log (this->name, GF_LOG_ERROR, "Failed to store " + "options"); goto out; } } else { @@ -4981,6 +5072,7 @@ glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr, int config_command = 0; uint64_t hard_limit = 0; uint64_t soft_limit = 0; + char *next_version = NULL; this = THIS; @@ -5025,15 +5117,33 @@ glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr, if (soft_limit) { /* For system limit */ - conf->snap_max_soft_limit = soft_limit; - ret = glusterd_store_global_info (this); + ret = dict_set_uint64 (conf->opts, + GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT, + soft_limit); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "save %s in the dictionary", + GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT); + goto out; + } + + ret = glusterd_get_next_global_opt_version_str + (conf->opts, + &next_version); + if (ret) + goto out; + + ret = dict_set_str (conf->opts, + GLUSTERD_GLOBAL_OPT_VERSION, + next_version); + if (ret) + goto out; + + ret = glusterd_store_options (this, conf->opts); if (ret) { - 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); + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "store options"); goto out; } } @@ -5741,6 +5851,8 @@ glusterd_handle_snap_limit (dict_t *dict, dict_t *rsp_dict) glusterd_snap_t *snap = NULL; glusterd_volinfo_t *tmp_volinfo = NULL; glusterd_volinfo_t *other_volinfo = NULL; + uint64_t opt_max_hard = 0; + uint64_t opt_max_soft = 0; this = THIS; GF_ASSERT (this); @@ -5775,12 +5887,32 @@ glusterd_handle_snap_limit (dict_t *dict, dict_t *rsp_dict) /* The minimum of the 2 limits i.e system wide limit and volume wide limit will be considered */ - if (volinfo->snap_max_hard_limit < priv->snap_max_hard_limit) + + ret = dict_get_uint64 (priv->opts, + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT, + &opt_max_hard); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "%s", GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT); + goto out; + } + + if (volinfo->snap_max_hard_limit < opt_max_hard) effective_max_limit = volinfo->snap_max_hard_limit; else - effective_max_limit = priv->snap_max_hard_limit; + effective_max_limit = opt_max_hard; + + ret = dict_get_uint64 (priv->opts, + GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT, + &opt_max_soft); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "%s from opts dictionary", + GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT); + goto out; + } - limit = (priv->snap_max_soft_limit * effective_max_limit)/100; + limit = (opt_max_soft * effective_max_limit)/100; count = volinfo->snap_count - limit; if (count <= 0) diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index 7efa9fb6d17..a243a1365d3 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -1784,24 +1784,6 @@ glusterd_store_global_info (xlator_t *this) goto out; } - snprintf (buf, sizeof (buf), "%"PRIu64, conf->snap_max_hard_limit); - ret = gf_store_save_value (handle->fd, - GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT, buf); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Storing snap-max-hard-limit failed ret = %d", ret); - goto out; - } - - snprintf (buf, sizeof (buf), "%"PRIu64, conf->snap_max_soft_limit); - ret = gf_store_save_value (handle->fd, - GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT, buf); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Storing snap-max-soft-limit failed ret = %d", ret); - goto out; - } - ret = gf_store_rename_tmppath (handle); out: if (handle) { @@ -1940,28 +1922,6 @@ glusterd_restore_op_version (xlator_t *this) conf = this->private; - ret = glusterd_retrieve_sys_snap_max_limit (this, - &conf->snap_max_hard_limit, - GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT); - if (ret) { - gf_log (this->name, GF_LOG_WARNING, - "Unable to retrieve system snap-max-hard-limit, " - "setting it to default value(%d)", - GLUSTERD_SNAPS_MAX_HARD_LIMIT); - conf->snap_max_hard_limit = GLUSTERD_SNAPS_MAX_HARD_LIMIT; - } - - ret = glusterd_retrieve_sys_snap_max_limit (this, - &conf->snap_max_soft_limit, - GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT); - if (ret) { - gf_log (this->name, GF_LOG_WARNING, - "Unable to retrieve system snap-max-soft-limit, " - "setting it to default value(%d)", - GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT); - conf->snap_max_soft_limit = GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT; - } - ret = glusterd_retrieve_op_version (this, &op_version); if (!ret) { if ((op_version < GD_OP_VERSION_MIN) || diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 07ff79f6e53..3db49d79a23 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -13429,3 +13429,55 @@ glusterd_handle_snapd_option (glusterd_volinfo_t *volinfo) out: return ret; } + +int32_t +glusterd_check_and_set_config_limit (glusterd_conf_t *priv) +{ + int32_t ret = -1; + xlator_t *this = NULL; + uint64_t hard_limit = 0; + uint64_t soft_limit = 0; + + GF_ASSERT (priv); + this = THIS; + GF_ASSERT (this); + + + ret = dict_get_uint64 (priv->opts, + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT, + &hard_limit); + if (ret) { + ret = dict_set_uint64 (priv->opts, + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT, + GLUSTERD_SNAPS_MAX_HARD_LIMIT); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "store %s during glusterd init", + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT); + goto out; + } + } + + ret = dict_get_uint64 (priv->opts, + GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT, + &soft_limit); + if (ret) { + ret = dict_set_uint64 (priv->opts, + GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT, + GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "store %s during glusterd init", + GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT); + goto out; + } + } + ret = glusterd_store_options (this, priv->opts); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Unable to store version"); + return ret; + } +out: + return ret; +} diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 834d4a52156..dc37cf232cd 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -890,5 +890,8 @@ glusterd_snapd_set_online_status (glusterd_volinfo_t *volinfo, int glusterd_restart_snapds (glusterd_conf_t *priv); + +int32_t +glusterd_check_and_set_config_limit (glusterd_conf_t *priv); /* End snapd functions */ #endif diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c index 255c1db5de9..c2e6fe8b251 100644 --- a/xlators/mgmt/glusterd/src/glusterd.c +++ b/xlators/mgmt/glusterd/src/glusterd.c @@ -199,20 +199,32 @@ glusterd_options_init (xlator_t *this) goto out; ret = glusterd_store_retrieve_options (this); - if (ret == 0) - goto out; + if (ret == 0) { + goto set; + } ret = dict_set_str (priv->opts, GLUSTERD_GLOBAL_OPT_VERSION, initial_version); if (ret) goto out; + ret = glusterd_store_options (this, priv->opts); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Unable to store version"); return ret; } -out: +set: + if (priv->op_version >= GD_OP_VERSION_3_6_0) { + ret = glusterd_check_and_set_config_limit (priv); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed " + "to set config limit in options"); + return ret; + } + } + +out: return 0; } int diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 57a5862a368..1dd823a588f 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -173,8 +173,6 @@ typedef struct { gf_boolean_t restart_done; rpcsvc_t *uds_rpc; /* RPCSVC for the unix domain socket */ uint32_t base_port; - uint64_t snap_max_hard_limit; - uint64_t snap_max_soft_limit; char *snap_bricks_directory; gf_store_handle_t *missed_snaps_list_shandle; struct list_head missed_snaps_list; -- cgit