config: expand metavariables when needed

md_config_t::get_val_from_config_file now has an option that causes it
to expand metavariables. This is necessary because many callers want
metavariables to be expanded in the results they get back.

md_config_t::set_val should expand metavariables.

Remove some unecessary typecasts from
md_config_t::get_val_from_config_file()

Signed-off-by: Colin McCabe <colin.mccabe@dreamhost.com>
This commit is contained in:
Colin Patrick McCabe 2011-04-04 13:35:11 -07:00
parent 94fade29af
commit b6084cf916
5 changed files with 50 additions and 46 deletions

View File

@ -77,18 +77,6 @@ static int list_sections(const char *prefix)
return 0;
}
static void print_val(const char *val, bool resolve_search)
{
if (!resolve_search) {
puts(val);
} else {
string search_path(val);
string result;
if (ceph_resolve_file_search(search_path, result))
puts(result.c_str());
}
}
static int lookup(const deque<const char *> &sections,
const char *key, bool resolve_search)
{
@ -98,11 +86,18 @@ static int lookup(const deque<const char *> &sections,
}
g_conf.get_my_sections(my_sections);
std::string val;
int ret = g_conf.get_val_from_conf_file(my_sections, key, val);
int ret = g_conf.get_val_from_conf_file(my_sections, key, val, true);
if (ret == -ENOENT)
return 1;
else if (ret == 0) {
print_val(val.c_str(), resolve_search);
if (resolve_search) {
string result;
if (ceph_resolve_file_search(val, result))
puts(result.c_str());
}
else {
puts(val.c_str());
}
return 0;
}
else {
@ -118,9 +113,7 @@ int main(int argc, const char **argv)
deque<const char *> sections;
DEFINE_CONF_VARS(usage);
bool resolve_search = false;
bool do_help = false;
bool do_list = false;
bool do_lookup = false;
std::string action("lookup");
argv_to_vec(argc, argv, args);
env_to_vec(args);
@ -132,11 +125,11 @@ int main(int argc, const char **argv)
} else if (CEPH_ARGPARSE_EQ("resolve-search", 'r')) {
CEPH_ARGPARSE_SET_ARG_VAL(&resolve_search, OPT_BOOL);
} else if (CEPH_ARGPARSE_EQ("help", 'h')) {
CEPH_ARGPARSE_SET_ARG_VAL(&do_help, OPT_BOOL);
action = "help";
} else if (CEPH_ARGPARSE_EQ("list-sections", 'l')) {
CEPH_ARGPARSE_SET_ARG_VAL(&do_list, OPT_BOOL);
action = "list-sections";
} else if (CEPH_ARGPARSE_EQ("lookup", '\0')) {
CEPH_ARGPARSE_SET_ARG_VAL(&do_lookup, OPT_BOOL);
action = "lookup";
}
else {
nargs.push_back(args[i]);
@ -145,27 +138,27 @@ int main(int argc, const char **argv)
common_init(nargs, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
if (do_help) {
if (action == "help") {
usage();
exit(0);
}
if (!do_lookup && !do_list)
do_lookup = true;
if (do_list) {
else if (action == "list-sections") {
if (nargs.size() != 1)
usage();
return list_sections(nargs[0]);
} else if (do_lookup) {
}
else if (action == "lookup") {
if (nargs.size() != 1) {
cerr << "lookup: expected exactly one argument" << std::endl;
usage();
}
return lookup(sections, nargs[0], resolve_search);
} else if ((nargs.size() >= 1) && (nargs[0][0] == '-')) {
}
else if ((nargs.size() >= 1) && (nargs[0][0] == '-')) {
cerr << "Parse error at argument: " << nargs[0] << std::endl;
usage();
} else {
}
else {
if (nargs.size() != 1) {
cerr << "lookup: expected exactly one argument" << std::endl;
usage();

View File

@ -231,7 +231,9 @@ int main(int argc, const char **argv)
std::vector <std::string> my_sections;
g_conf.get_my_sections(my_sections);
std::string mon_addr_str;
if (g_conf.get_val_from_conf_file(my_sections, "mon addr", mon_addr_str) == 0) {
if (g_conf.get_val_from_conf_file(my_sections, "mon addr",
mon_addr_str, true) == 0)
{
if (conf_addr.parse(mon_addr_str.c_str()) && (ipaddr != conf_addr)) {
cerr << "WARNING: 'mon addr' config option " << conf_addr
<< " does not match monmap file" << std::endl

View File

@ -537,7 +537,7 @@ parse_config_files(const std::list<std::string> &conf_files,
for (int i = 0; i < NUM_CONFIG_OPTIONS; i++) {
config_option *opt = &config_optionsp[i];
std::string val;
int ret = get_val_from_conf_file(my_sections, opt->conf_name, val);
int ret = get_val_from_conf_file(my_sections, opt->conf_name, val, false);
if (ret == 0) {
set_val_impl(val.c_str(), opt);
}
@ -546,7 +546,7 @@ parse_config_files(const std::list<std::string> &conf_files,
// FIXME: This bit of global fiddling needs to go somewhere else eventually.
std::string val;
g_lockdep =
((get_val_from_conf_file(my_sections, "lockdep", val) == 0) &&
((get_val_from_conf_file(my_sections, "lockdep", val, true) == 0) &&
((strcasecmp(val.c_str(), "true") == 0) || (atoi(val.c_str()) != 0)));
return 0;
}
@ -639,10 +639,12 @@ set_val(const char *key, const char *val)
return -EINVAL;
if (!val)
return -EINVAL;
std::string v(val);
expand_meta(v);
for (int i = 0; i < NUM_CONFIG_OPTIONS; ++i) {
config_option *opt = &config_optionsp[i];
if (strcmp(opt->conf_name, key) == 0)
return set_val_impl(val, opt);
return set_val_impl(v.c_str(), opt);
}
// couldn't find a configuration option with key 'key'
@ -743,7 +745,7 @@ have_conf_file() const
int md_config_t::
get_val_from_conf_file(const std::vector <std::string> &sections,
const char *key, std::string &out) const
const char *key, std::string &out, bool emeta) const
{
if (!cf)
return -EDOM;
@ -751,8 +753,11 @@ get_val_from_conf_file(const std::vector <std::string> &sections,
std::vector <std::string>::const_iterator s_end = sections.end();
for (; s != s_end; ++s) {
int ret = cf->read(s->c_str(), key, out);
if (ret == 0)
if (ret == 0) {
if (emeta)
expand_meta(out);
return 0;
}
else if (ret != -ENOENT)
return ret;
}
@ -862,7 +867,7 @@ set_val_impl(const char *val, const config_option *opt)
*(bool*)opt->val_ptr = true;
else {
std::string err;
int b = strict_strtol((const char*)val, 10, &err);
int b = strict_strtol(val, 10, &err);
if (!err.empty())
return -EINVAL;
*(bool*)opt->val_ptr = !!b;
@ -870,7 +875,7 @@ set_val_impl(const char *val, const config_option *opt)
return 0;
case OPT_U32: {
std::string err;
int f = strict_strtol((const char*)val, 10, &err);
int f = strict_strtol(val, 10, &err);
if (!err.empty())
return -EINVAL;
*(uint32_t*)opt->val_ptr = f;
@ -878,7 +883,7 @@ set_val_impl(const char *val, const config_option *opt)
}
case OPT_U64: {
std::string err;
long long f = strict_strtoll((const char*)val, 10, &err);
long long f = strict_strtoll(val, 10, &err);
if (!err.empty())
return -EINVAL;
*(uint64_t*)opt->val_ptr = f;

View File

@ -61,10 +61,12 @@ public:
void parse_argv_part2(std::vector<const char*>& args);
void parse_argv(std::vector<const char*>& args);
// Set a configuration value
// Set a configuration value.
// Metavariables will be expanded.
int set_val(const char *key, const char *val);
// Get a configuration value
// Get a configuration value.
// No metavariables will be returned (they will have already been expanded)
int get_val(const char *key, char **buf, int len) const;
// Return a list of all the sections that the current entity is a member of.
@ -75,22 +77,24 @@ public:
bool have_conf_file() const;
// Get a value from the configuration file we read
// Get a value from the configuration file that we read earlier.
// Metavariables will be expanded if emeta is true.
int get_val_from_conf_file(const std::vector <std::string> &sections,
const char *key, std::string &out) const;
const char *key, std::string &out, bool emeta) const;
// Do all metavariable substitutions
// Perform metavariable expansion on all the data members of md_config_t.
void expand_all_meta();
// Expand metavariables in the provided string.
// Returns true if any metavariables were found and expanded.
bool expand_meta(std::string &val) const;
private:
// Private function for setting a default for a config option
void set_val_from_default(const config_option *opt);
int set_val_impl(const char *val, const config_option *opt);
// Do metavariable expansions
bool expand_meta(std::string &val) const;
// The configuration file we read, or NULL if we haven't read one.
ConfFile *cf;

View File

@ -150,7 +150,7 @@ int MonClient::build_initial_monmap()
sections.push_back("mon");
sections.push_back("global");
std::string val;
int res = g_conf.get_val_from_conf_file(sections, "mon addr", val);
int res = g_conf.get_val_from_conf_file(sections, "mon addr", val, true);
if (res) {
cerr << "failed to get an address for mon." << *m << ": error "
<< res << std::endl;