From: Sage Weil Date: Fri, 8 Jun 2012 19:45:30 +0000 (-0700) Subject: config: expand any config variable in config X-Git-Tag: v0.48argonaut~74^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d422bf159d59345eb96483169de80bd5dc9996fc;p=ceph.git config: expand any config variable in config This is currently broken wrt 'foo' vs 'foo_bar', but otherwise works. Signed-off-by: Sage Weil --- diff --git a/src/common/config.cc b/src/common/config.cc index 778433889221..fcbf61a53bf4 100644 --- a/src/common/config.cc +++ b/src/common/config.cc @@ -875,21 +875,30 @@ void md_config_t::expand_all_meta() } } -bool md_config_t::expand_meta(std::string &val) const +bool md_config_t::expand_meta(std::string &origval) const { assert(lock.is_locked()); bool found_meta = false; + + set resolved; + + string::size_type sz; + string val = origval; + + restart: + sz = val.size(); string out; - string::size_type sz = val.size(); out.reserve(sz); + for (string::size_type s = 0; s < sz; ) { if (val[s] != '$') { out += val[s++]; continue; } string::size_type rem = sz - (s + 1); - int i; - for (i = 0; i < NUM_CONF_METAVARIABLES; ++i) { + + // special metavariable? + for (int i = 0; i < NUM_CONF_METAVARIABLES; ++i) { size_t clen = strlen(CONF_METAVARIABLES[i]); if (rem < clen) continue; @@ -910,14 +919,43 @@ bool md_config_t::expand_meta(std::string &val) const else assert(0); // unreachable found_meta = true; - break; - } - if (i == NUM_CONF_METAVARIABLES) - out += val[s++]; - else s += strlen(CONF_METAVARIABLES[i]) + 1; - } - val = out; + out += val.substr(s); + val = out; + goto restart; + } + + // config option? + for (int i = 0; i < NUM_CONFIG_OPTIONS; i++) { + config_option *opt = &config_optionsp[i]; + size_t clen = strlen(opt->name); + if (rem < clen) + continue; + if (strncmp(val.c_str() + s + 1, opt->name, clen)) + continue; + + // avoid loops + if (resolved.count(opt->name)) + continue; // loop; skip + resolved.insert(opt->name); + + found_meta = true; + char *vv = NULL; + _get_val(opt->name, &vv, -1); + out += vv; + s += strlen(opt->name) + 1; + out += val.substr(s); + //cout << "val '" << val << "' s " << s << " out '" << out << "' after sub " << opt->name << " -> " << vv << std::endl; + val = out; + free(vv); + goto restart; + } + + // pass it thru + out += val[s++]; + } + //cout << "done '" << origval << "' -> '" << out << "'" << std::endl; + origval = out; return found_meta; } diff --git a/src/test/daemon_config.cc b/src/test/daemon_config.cc index e85de9485d90..9eaf6614bcbb 100644 --- a/src/test/daemon_config.cc +++ b/src/test/daemon_config.cc @@ -38,6 +38,42 @@ TEST(DaemonConfig, SimpleSet) { ASSERT_EQ(string("21"), string(buf)); } +TEST(DaemonConfig, Substitution) { + int ret; + ret = g_ceph_context->_conf->set_val("internal_safe_to_start_threads", "false"); + ret = g_ceph_context->_conf->set_val("host", "foo"); + ASSERT_EQ(ret, 0); + ret = g_ceph_context->_conf->set_val("public_network", "bar$hostbaz", false); + ASSERT_EQ(ret, 0); + g_ceph_context->_conf->apply_changes(NULL); + char buf[128]; + memset(buf, 0, sizeof(buf)); + char *tmp = buf; + ret = g_ceph_context->_conf->get_val("public_network", &tmp, sizeof(buf)); + ASSERT_EQ(ret, 0); + ASSERT_EQ(string("barfoobaz"), string(buf)); +} + +TEST(DaemonConfig, SubstitutionLoop) { + int ret; + ret = g_ceph_context->_conf->set_val("internal_safe_to_start_threads", "false"); + ret = g_ceph_context->_conf->set_val("host", "foo$public_network", false); + ASSERT_EQ(ret, 0); + ret = g_ceph_context->_conf->set_val("public_network", "bar$host", false); + ASSERT_EQ(ret, 0); + g_ceph_context->_conf->apply_changes(NULL); + char buf[128], buf2[128]; + memset(buf, 0, sizeof(buf)); + memset(buf2, 0, sizeof(buf2)); + char *tmp = buf; + char *tmp2 = buf; + ret = g_ceph_context->_conf->get_val("host", &tmp, sizeof(buf)); + ASSERT_EQ(ret, 0); + ret = g_ceph_context->_conf->get_val("public_network", &tmp2, sizeof(buf)); + ASSERT_EQ(ret, 0); + ASSERT_TRUE(strchr(buf, '$') || strchr(buf2, '$')); +} + TEST(DaemonConfig, ArgV) { ASSERT_EQ(0, g_ceph_context->_conf->set_val("internal_safe_to_start_threads", "false"));