From: John Spray Date: Wed, 12 Jul 2017 21:58:19 +0000 (-0400) Subject: common: enforce min/max/enum on config options X-Git-Tag: v12.1.2~192^2~16 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=3f99f6ef20a93645d57944087e89bee603053488;p=ceph-ci.git common: enforce min/max/enum on config options Signed-off-by: John Spray --- diff --git a/src/common/config.cc b/src/common/config.cc index 4b720f355bd..857fa4bd44f 100644 --- a/src/common/config.cc +++ b/src/common/config.cc @@ -865,7 +865,7 @@ int md_config_t::_get_val(const std::string &key, std::string *value) const { if (bool *flag = boost::get(&config_value)) { oss << (*flag ? "true" : "false"); } else if (double *dp = boost::get(&config_value)) { - oss << std::fixed << *dp ; + oss << std::fixed << *dp; } else { oss << config_value; } @@ -995,6 +995,8 @@ int md_config_t::set_val_impl(const std::string &raw_val, const Option &opt, assert(lock.is_locked()); std::string val = raw_val; + + // Special validator callback? if (opt.validator) { int r = opt.validator(&val, error_message); if (r < 0) { @@ -1052,6 +1054,41 @@ int md_config_t::set_val_impl(const std::string &raw_val, const Option &opt, ceph_abort(); } + // Generic validation: min + if (!boost::get(&(opt.min))) { + if (new_value < opt.min) { + std::ostringstream oss; + oss << "Value '" << new_value << "' is below minimum " << opt.min; + *error_message = oss.str(); + return -EINVAL; + } + } + + // Generic validation: max + if (!boost::get(&(opt.max))) { + if (new_value > opt.max) { + std::ostringstream oss; + oss << "Value '" << new_value << "' exceeds maximum " << opt.max; + *error_message = oss.str(); + return -EINVAL; + } + } + + // Generic validation: enum + if (!opt.enum_allowed.empty() && opt.type == Option::TYPE_STR) { + auto found = std::find(opt.enum_allowed.begin(), opt.enum_allowed.end(), + boost::get(new_value)); + if (found == opt.enum_allowed.end()) { + std::ostringstream oss; + oss << "'" << new_value << "' is not one of the permitted " + "values: " << joinify(opt.enum_allowed.begin(), + opt.enum_allowed.end(), + std::string(", ")); + *error_message = oss.str(); + return -EINVAL; + } + } + // Apply the value to its entry in the `values` map values[opt.name] = new_value;