string who;
config_map.parse_key(key, &name, &who);
- const Option *opt = g_conf().find_option(name);
- if (!opt) {
- config_map.stray_options.push_back(
- std::unique_ptr<Option>(
- new Option(name, Option::TYPE_STR, Option::LEVEL_UNKNOWN)));
- opt = config_map.stray_options.back().get();
- }
-
- string err;
- int r = opt->pre_validate(&value, &err);
- if (r < 0) {
- dout(10) << __func__ << " pre-validate failed on '" << name << "' = '"
- << value << "' for " << name << dendl;
- }
-
- MaskedOption mopt(opt);
- mopt.raw_value = value;
- string section_name;
- if (who.size() &&
- !ConfigMap::parse_mask(who, §ion_name, &mopt.mask)) {
- derr << __func__ << " invalid mask for key " << key << dendl;
- } else if (opt->has_flag(Option::FLAG_NO_MON_UPDATE)) {
- dout(10) << __func__ << " NO_MON_UPDATE option '"
- << name << "' = '" << value << "' for " << name
- << dendl;
- } else {
- Section *section = &config_map.global;;
- if (section_name.size() && section_name != "global") {
- if (section_name.find('.') != std::string::npos) {
- section = &config_map.by_id[section_name];
- } else {
- section = &config_map.by_type[section_name];
- }
- }
- section->options.insert(make_pair(name, std::move(mopt)));
- }
+ config_map.add_option(
+ g_ceph_context, name, who, value,
+ [&](const std::string& name) {
+ return g_conf().find_option(name);
+ });
}
}
#include "crush/CrushWrapper.h"
#include "common/entity_name.h"
+#define dout_subsys ceph_subsys_mon
+#undef dout_prefix
+#include "common/dout.h"
+
using namespace std::literals;
using std::cerr;
}
}
+int ConfigMap::add_option(
+ CephContext *cct,
+ const std::string& name,
+ const std::string& who,
+ const std::string& orig_value,
+ std::function<const Option *(const std::string&)> get_opt)
+{
+ const Option *opt = get_opt(name);
+ if (!opt) {
+ ldout(cct, 10) << __func__ << " unrecognized option '" << name << "'" << dendl;
+ stray_options.push_back(
+ std::unique_ptr<Option>(
+ new Option(name, Option::TYPE_STR, Option::LEVEL_UNKNOWN)));
+ opt = stray_options.back().get();
+ }
+
+ string err;
+ string value = orig_value;
+ int r = opt->pre_validate(&value, &err);
+ if (r < 0) {
+ ldout(cct, 10) << __func__ << " pre-validate failed on '" << name << "' = '"
+ << value << "' for " << name << dendl;
+ }
+
+ int ret = 0;
+ MaskedOption mopt(opt);
+ mopt.raw_value = value;
+ mopt.localized_name = name;
+ string section_name;
+ if (who.size() &&
+ !ConfigMap::parse_mask(who, §ion_name, &mopt.mask)) {
+ lderr(cct) << __func__ << " invalid mask for option " << name << " mask " << who
+ << dendl;
+ ret = -EINVAL;
+ } else if (opt->has_flag(Option::FLAG_NO_MON_UPDATE)) {
+ ldout(cct, 10) << __func__ << " NO_MON_UPDATE option '"
+ << name << "' = '" << value << "' for " << name
+ << dendl;
+ ret = -EINVAL;
+ } else {
+ Section *section = &global;;
+ if (section_name.size() && section_name != "global") {
+ if (section_name.find('.') != std::string::npos) {
+ section = &by_id[section_name];
+ } else {
+ section = &by_type[section_name];
+ }
+ }
+ section->options.insert(make_pair(name, std::move(mopt)));
+ }
+ return ret;
+}
+
// --------------
const std::string& in,
std::string *section,
OptionMask *mask);
+
+ int add_option(
+ CephContext *cct,
+ const std::string& name,
+ const std::string& who,
+ const std::string& value,
+ std::function<const Option *(const std::string&)> get_opt);
};
unsigned num = 0;
KeyValueDB::Iterator it = mon.store->get_iterator(KV_PREFIX);
- it->lower_bound(KEY_PREFIX);
- while (it->valid() &&
- it->key().compare(0, KEY_PREFIX.size(), KEY_PREFIX) == 0) {
+ for (it->lower_bound(KEY_PREFIX);
+ it->valid() &&
+ it->key().compare(0, KEY_PREFIX.size(), KEY_PREFIX) == 0;
+ it->next(), ++num) {
string key = it->key().substr(KEY_PREFIX.size());
string value = it->value().to_str();
}
}
- const Option *opt = g_conf().find_option(name);
- if (!opt) {
- opt = mon.mgrmon()->find_module_option(name);
- }
- if (!opt) {
- dout(10) << __func__ << " unrecognized option '" << name << "'" << dendl;
- config_map.stray_options.push_back(
- std::unique_ptr<Option>(
- new Option(name, Option::TYPE_STR, Option::LEVEL_UNKNOWN)));
- opt = config_map.stray_options.back().get();
- }
-
- string err;
- int r = opt->pre_validate(&value, &err);
- if (r < 0) {
- dout(10) << __func__ << " pre-validate failed on '" << name << "' = '"
- << value << "' for " << name << dendl;
- }
-
- MaskedOption mopt(opt);
- mopt.raw_value = value;
- mopt.localized_name = name;
- string section_name;
- if (who.size() &&
- !ConfigMap::parse_mask(who, §ion_name, &mopt.mask)) {
- derr << __func__ << " invalid mask for key " << key << dendl;
- pending_cleanup[key].reset();
- } else if (opt->has_flag(Option::FLAG_NO_MON_UPDATE)) {
- dout(10) << __func__ << " NO_MON_UPDATE option '"
- << name << "' = '" << value << "' for " << name
- << dendl;
- pending_cleanup[key].reset();
- } else {
- if (section_name.empty()) {
- // we prefer global/$option instead of just $option
- derr << __func__ << " adding global/ prefix to key '" << key << "'"
- << dendl;
- pending_cleanup[key].reset();
- pending_cleanup["global/"s + key] = it->value();
- }
- Section *section = &config_map.global;;
- if (section_name.size() && section_name != "global") {
- if (section_name.find('.') != std::string::npos) {
- section = &config_map.by_id[section_name];
- } else {
- section = &config_map.by_type[section_name];
+ int r = config_map.add_option(
+ g_ceph_context, name, who, value,
+ [&](const std::string& name) {
+ const Option *opt = g_conf().find_option(name);
+ if (!opt) {
+ opt = mon.mgrmon()->find_module_option(name);
}
- }
- section->options.insert(make_pair(name, std::move(mopt)));
- ++num;
+ return opt;
+ });
+ if (r == -EINVAL) {
+ dout(10) << __func__ << " will clean up key " << key << dendl;
+ pending_cleanup[key].reset();
}
- it->next();
}
dout(10) << __func__ << " got " << num << " keys" << dendl;