map<string, bufferlist> caps;
const char *key_names[] = { "mon", "osd", "mds", NULL };
for (int i=0; key_names[i]; i++) {
- char *val;
+ std::string val;
cf->read("global", key_names[i], &val, NULL);
- if (val) {
+ if (!val.empty()) {
bufferlist bl;
::encode(val, bl);
string s(key_names[i]);
caps[s] = bl;
- free(val);
}
}
keyring.set_caps(ename, caps);
static int lookup(const deque<const char *> §ions,
const char *key, bool resolve_search)
{
- char *val = NULL;
if (!g_conf.cf)
return 2;
- conf_read_key(NULL, key, OPT_STR, (char **)&val, NULL);
- if (val) {
- print_val(val, resolve_search);
- free(val);
+
+ std::string val;
+ std::string my_default("");
+ if (conf_read_key(NULL, key, OPT_STR, &val, (void*)&my_default)) {
+ print_val(val.c_str(), resolve_search);
return 0;
}
- for (unsigned int i=0; i<sections.size(); i++) {
- g_conf.cf->read(sections[i], key, (char **)&val, NULL);
- if (val) {
- print_val(val, resolve_search);
- free(val);
- return 0;
- }
+ // Search the sections.
+ for (deque<const char*>::const_iterator s = sections.begin();
+ s != sections.end(); ++s) {
+ if (!g_conf.cf->_find_var(*s, key))
+ continue;
+ g_conf.cf->read(*s, key, (std::string *)&val, "");
+ print_val(val.c_str(), resolve_search);
+ return 0;
}
+ // Not found
return 1;
}
entity_addr_t ipaddr = monmap.get_addr(g_conf.name->get_id());
entity_addr_t conf_addr;
- char *mon_addr_str;
+ std::string mon_addr_str;
- if (conf_read_key(NULL, "mon addr", OPT_STR, &mon_addr_str, NULL) &&
- conf_addr.parse(mon_addr_str) &&
- ipaddr != conf_addr)
+ std::string my_default("");
+ if (conf_read_key(NULL, "mon addr", OPT_STR, &mon_addr_str, (void*)&my_default) &&
+ 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
<< " continuing with monmap configuration" << std::endl;
+ }
// bind
SimpleMessenger *messenger = new SimpleMessenger();
return cl;
}
-template<typename T>
-static void _conf_copy(T *dst_val, T def_val)
+static void _conf_decode(int *dst_val, const std::string &str_val)
{
- *dst_val = def_val;
+ *dst_val = atoi(str_val.c_str());
}
-template<>
-void _conf_copy<char *>(char **dst_val, char *def_val)
+static void _conf_decode(unsigned int *dst_val, const std::string &str_val)
{
- if (def_val)
- *dst_val = strdup(def_val);
- else
- *dst_val = NULL;
+ *dst_val = strtoul(str_val.c_str(), NULL, 0);
}
-static void _conf_decode(int *dst_val, char *str_val)
+static void _conf_decode(unsigned long long *dst_val, const std::string &str_val)
{
- *dst_val = atoi(str_val);
+ *dst_val = strtoull(str_val.c_str(), NULL, 0);
}
-
-static void _conf_decode(unsigned int *dst_val, char *str_val)
+static void _conf_decode(long long *dst_val, const std::string &str_val)
{
- *dst_val = strtoul(str_val, NULL, 0);
+ *dst_val = strtoll(str_val.c_str(), NULL, 0);
}
-static void _conf_decode(unsigned long long *dst_val, char *str_val)
-{
- *dst_val = strtoull(str_val, NULL, 0);
-}
-static void _conf_decode(long long *dst_val, char *str_val)
+static void _conf_decode(bool *dst_val, const std::string &str_val)
{
- *dst_val = strtoll(str_val, NULL, 0);
-}
-
-static void _conf_decode(bool *dst_val, char *str_val)
-{
- if (strcasecmp(str_val, "true")==0) {
+ if (strcasecmp(str_val.c_str(), "true")==0) {
*dst_val = true;
- } else if (strcasecmp(str_val, "false")==0) {
+ } else if (strcasecmp(str_val.c_str(), "false")==0) {
*dst_val = false;
} else {
- *dst_val = atoi(str_val);
+ *dst_val = atoi(str_val.c_str());
}
}
-static void _conf_decode(char **dst_val, char *str_val)
+static void _conf_decode(std::string *dst_val, const std::string &str_val)
{
int len;
- len = strlen(str_val);
+ len = str_val.size();
+ const char *s = str_val.c_str();
- if (*str_val == '"') {
- str_val++;
+ if (*s == '"') {
+ s++;
for (len = len-1; len > 0; len--) {
- if (str_val[len] == '"')
+ if (s[len] == '"')
break;
}
}
- *dst_val = (char *)malloc(len + 1);
- strncpy(*dst_val, str_val, len);
- (*dst_val)[len] = '\0';
+ *dst_val = std::string(s, len);
}
-static int _conf_decode(float *dst_val, char *str_val)
+static int _conf_decode(float *dst_val, const std::string &str_val)
{
- *dst_val = atof(str_val);
+ *dst_val = atof(str_val.c_str());
return 1;
}
-static int _conf_decode(double *dst_val, char *str_val)
+static int _conf_decode(double *dst_val, const std::string &str_val)
{
- *dst_val = atof(str_val);
+ *dst_val = atof(str_val.c_str());
return 1;
}
template<typename T>
int ConfFile::_read(const char *section, const char *var, T *val, T def_val)
{
- ConfLine *cl;
- char *str_val;
- bool should_free = false;
-
- cl = _find_var(section, var);
- if (!cl || !cl->get_val())
- goto notfound;
+ ConfLine *cl = _find_var(section, var);
+ if (!cl || !cl->get_val()) {
+ *val = def_val;
+ return 0;
+ }
- str_val = cl->get_val();
+ std::string str_val(cl->get_val());
if (post_process_func) {
- str_val = post_process_func(str_val);
- should_free = true;
+ post_process_func(str_val);
}
_conf_decode(val, str_val);
- if (should_free)
- free(str_val);
return 1;
-notfound:
- _conf_copy<T>(val, def_val);
-
- return 0;
}
template<typename T>
return _read<bool>(section, var, val, def_val);
}
-int ConfFile::read(const char *section, const char *var, char **val, const char *def_val)
+int ConfFile::read(const char *section, const char *var, std::string *val, const std::string &def_val)
{
- return _read<char *>(section, var, val, (char *)def_val);
+ return _read<std::string>(section, var, val, def_val);
}
int ConfFile::read(const char *section, const char *var, float *val, float def_val)
Mutex parse_lock;
bool default_global;
- char *(*post_process_func)(const char *);
+ void (*post_process_func)(std::string &);
SectionMap sections;
SectionList sections_list;
ConfList global_list;
- ConfLine *_find_var(const char *section, const char* var);
ConfLine *_add_var(const char *section, const char* var);
template<typename T>
const SectionList& get_section_list() { return sections_list; }
const char *get_filename() { return filename; }
+ ConfLine *_find_var(const char *section, const char* var);
+
int parse();
int read(const char *section, const char *var, int *val, int def_val);
int read(const char *section, const char *var, unsigned int *val, unsigned int def_val);
int read(const char *section, const char *var, long long *val, long long def_val);
int read(const char *section, const char *var, unsigned long long *val, unsigned long long def_val);
int read(const char *section, const char *var, bool *val, bool def_val);
- int read(const char *section, const char *var, char **val, const char *def_val);
+ int read(const char *section, const char *var, std::string *val, const std::string &def_val);
int read(const char *section, const char *var, float *val, float def_val);
int read(const char *section, const char *var, double *val, double def_val);
void dump();
int flush();
- void set_post_process_func(char *(*func)(const char *)) {post_process_func = func; };
+ void set_post_process_func(void (*func)(std::string &)) {post_process_func = func; };
void set_global(bool global) { default_global = global; }
};
opt->conf_name = (const char *)newconf;
}
-static bool get_var(const char *str, int pos, char *var_name, int len, int *new_pos)
-{
- int bracket = (str[pos] == '{');
- int out_pos = 0;
-
- if (bracket) {
- pos++;
- }
-
- while (str[pos] &&
- ((bracket && str[pos] != '}') ||
- isalnum(str[pos]) ||
- str[pos] == '_')) {
- var_name[out_pos] = str[pos];
-
- out_pos ++;
- if (out_pos == len)
- return false;
- pos++;
- }
-
- var_name[out_pos] = '\0';
-
-
- if (bracket && (str[pos] == '}'))
- pos++;
-
- *new_pos = pos;
-
- return true;
-}
-
-static const char *var_val(char *var_name)
-{
- const char *val;
-
- if (strcmp(var_name, "type")==0)
- return g_conf.name->get_type_name();
- if (strcmp(var_name, "id")==0)
- return g_conf.name->get_id().c_str();
- if (strcmp(var_name, "num")==0)
- return g_conf.name->get_id().c_str();
- if (strcmp(var_name, "name")==0)
- return g_conf.name->to_cstr();
- if (strcmp(var_name, "host")==0)
- return g_conf.host;
-
- val = getenv(var_name);
- if (!val)
- val = "";
-
- return val;
-}
+static const char *CONF_METAVARIABLES[] =
+ { "type", "name", "host", "num", "id" };
+static const int NUM_CONF_METAVARIABLES =
+ (sizeof(CONF_METAVARIABLES) / sizeof(CONF_METAVARIABLES[0]));
-#define MAX_LINE 256
-#define MAX_VAR_LEN 32
-
-char *conf_post_process_val(const char *val)
+void conf_post_process_val(std::string &val)
{
- char var_name[MAX_VAR_LEN];
- char *buf;
- int i=0;
- size_t out_pos = 0;
- size_t max_line = MAX_LINE;
-
- buf = (char *)malloc(max_line);
- *buf = 0;
-
- while (val[i]) {
- if (val[i] == '$') {
- if (get_var(val, i+1, var_name, MAX_VAR_LEN, &i)) {
- out_pos = dyn_snprintf(&buf, &max_line, 2, "%s%s", buf, var_val(var_name));
- } else {
- ++i;
- }
- } else {
- if (out_pos == max_line - 1) {
- max_line *= 2;
- buf = (char *)realloc(buf, max_line);
- }
- buf[out_pos] = val[i];
- buf[out_pos + 1] = '\0';
- ++out_pos;
- ++i;
+ 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) {
+ size_t clen = strlen(CONF_METAVARIABLES[i]);
+ if (rem < clen)
+ continue;
+ if (strncmp(val.c_str() + s + 1, CONF_METAVARIABLES[i], clen))
+ continue;
+ if (strcmp(CONF_METAVARIABLES[i], "type")==0)
+ out += g_conf.name->get_type_name();
+ else if (strcmp(CONF_METAVARIABLES[i], "name")==0)
+ out += g_conf.name->to_cstr();
+ else if (strcmp(CONF_METAVARIABLES[i], "host")==0)
+ out += g_conf.host;
+ else if (strcmp(CONF_METAVARIABLES[i], "num")==0)
+ out += g_conf.name->get_id().c_str();
+ else if (strcmp(CONF_METAVARIABLES[i], "id")==0)
+ out += g_conf.name->get_id().c_str();
+ else
+ assert(0); // unreachable
+ break;
}
+ if (i == NUM_CONF_METAVARIABLES)
+ out += val[s++];
+ else
+ s += strlen(CONF_METAVARIABLES[i]) + 1;
}
-
- buf[out_pos] = '\0';
-
- return buf;
+ val = out;
}
#define OPT_READ_TYPE(ret, section, var, type, out, def) \
const char *alt_section, const char *key, opt_type_t type, void *out, void *def,
bool free_old_val)
{
- int s;
int ret;
- char *tmp = 0;
- for (s=0; s<5; s++) {
+ for (int s=0; s<5; s++) {
const char *section;
switch (s) {
}
switch (type) {
- case OPT_STR:
- if (free_old_val)
- tmp = *(char **)out;
- OPT_READ_TYPE(ret, section, key, char *, out, def);
- if (free_old_val &&
- *(char **)out != tmp)
- free(tmp);
+ case OPT_STR: {
+ std::string str;
+ std::string my_default(*(char**)def);
+ ret = g_conf.cf->read(section, key, &str, my_default);
+ *(char**)out = strdup(str.c_str());
break;
+ }
case OPT_BOOL:
OPT_READ_TYPE(ret, section, key, bool, out, def);
break;
case OPT_DOUBLE:
OPT_READ_TYPE(ret, section, key, double, out, def);
break;
- case OPT_ADDR:
- ret = g_conf.cf->read(section, key, &tmp, (char *)def);
- if (*tmp == *((char *)def)) {
- ret = 0;
+ case OPT_ADDR: {
+ std::string str;
+ if (!g_conf.cf->_find_var(section, key)) {
+ ret = 0;
}
else {
- ret = 1;
- }
- if ((1 == ret) &&!(((entity_addr_t*)out)->parse(tmp))) {
- cerr << "Addr " << tmp << " failed to parse! Shutting down" << std::endl;
- exit(1);
+ std::string my_default("");
+ ret = g_conf.cf->read(section, key, &str, my_default);
+ if (((entity_addr_t*)out)->parse(str.c_str()) == 0) {
+ cerr << "Addr " << str << " failed to parse! Shutting down" << std::endl;
+ exit(1);
+ }
+ ret = 1;
}
break;
+ }
case OPT_U32:
OPT_READ_TYPE(ret, section, key, uint32_t, out, def);
break;
default:
- ret = 0;
+ ret = 0;
break;
}
if (ret)
- break;
+ return ret;
}
-
- return ret;
}
int conf_read_key(const char *alt_section, const char *key, opt_type_t type, void *out, void *def, bool free_old_val)
for (int i = 0; i<opt_len; i++) {
config_option *opt = &config_optionsp[i];
if (opt->type == OPT_STR && opt->val_ptr) {
- if (*(char**)opt->val_ptr) {
- *(char **)opt->val_ptr = conf_post_process_val(*(char **)opt->val_ptr);
+ char *s = *(char**)opt->val_ptr;
+ if (s) {
+ // this is going away soon...
+ std::string str(s);
+ conf_post_process_val(str);
+ free(s);
+ *(char **)opt->val_ptr = strdup(str.c_str());
}
}
}
const char *name = section + 3;
if (name[0] == '.')
name++;
- char *val = 0;
- g_conf.cf->read(section, "mon addr", &val, 0);
- if (!val || !val[0]) {
- delete val;
+ std::string val;
+ g_conf.cf->read(section, "mon addr", &val, "");
+ if (val.empty())
continue;
- }
entity_addr_t addr;
- if (!addr.parse(val)) {
+ if (!addr.parse(val.c_str())) {
cerr << "unable to parse mon addr for " << section << " (" << val << ")" << std::endl;
- delete val;
continue;
}
monmap.add(name, addr);
int basedir_fd;
struct btrfs_ioctl_vol_args volargs;
- if (g_conf.filestore_dev) {
+ if (g_conf.filestore_dev && g_conf.filestore_dev[0]) {
dout(0) << "mounting" << dendl;
ret = run_cmd("mount", g_conf.filestore_dev, (char*)NULL);
if (ret) {
if (ret)
goto close_basedir_fd;
- if (g_conf.filestore_dev) {
+ if (g_conf.filestore_dev && g_conf.filestore_dev[0]) {
dout(0) << "umounting" << dendl;
snprintf(buf, sizeof(buf), "umount %s", g_conf.filestore_dev);
//system(cmd);
char buf[PATH_MAX];
uint64_t initial_op_seq;
- if (g_conf.filestore_dev) {
+ if (g_conf.filestore_dev && g_conf.filestore_dev[0]) {
dout(0) << "mounting" << dendl;
//run_cmd("mount", g_conf.filestore_dev, (char*)NULL);
}
basedir_fd = -1;
}
- if (g_conf.filestore_dev) {
+ if (g_conf.filestore_dev && g_conf.filestore_dev[0]) {
dout(0) << "umounting" << dendl;
//run_cmd("umount", g_conf.filestore_dev, (char*)NULL);
}