From 3f99f6ef20a93645d57944087e89bee603053488 Mon Sep 17 00:00:00 2001 From: John Spray Date: Wed, 12 Jul 2017 17:58:19 -0400 Subject: [PATCH] common: enforce min/max/enum on config options Signed-off-by: John Spray --- src/common/config.cc | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/common/config.cc b/src/common/config.cc index 4b720f355bdf5..857fa4bd44f00 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; -- 2.39.5