#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <errno.h>
#include <map>
#include <list>
static const char *_def_delim=" \t\n\r";
static const char *_eq_delim="= \t\n\r";
static const char *_eol_delim="\n\r";
-static const char *_pr_delim="[] \t\n\r";
+/* static const char *_pr_delim="[] \t\n\r"; */
static int is_delim(char c, const char *delim)
char *get_next_tok(char *str, const char *delim, int alloc, char **p)
{
- char *tok;
int i=0;
char *out;
- int is_str = 0;
while (*str && is_delim(*str, delim)) {
str++;
char *get_next_delim(char *str, const char *delim, int alloc, char **p)
{
- char *tok;
int i=0;
char *out;
static int _parse_section(char *str, ConfLine *parsed)
{
- char *open, *close;
char *name = NULL;
char *p;
int ret = 0;
if (*line)
parsed->set_section(line);
-out:
return ret;
}
{
char *dup=strdup(line);
char *p = NULL;
- char *tok;
- int i;
char *eq;
int ret = 0;
static int _str_cat(char *str1, int max, char *str2)
{
- int len;
+ int len = 0;
if (max)
len = snprintf(str1, max, "%s", str2);
delete sec;
}
+
+ if (fd >= 0)
+ close(fd);
}
int ConfLine::output(char *line, int max_len)
}
-void ConfFile::dump()
+void ConfFile::_dump(int fd)
{
SectionList::iterator sec_iter, sec_end;
ConfLine *cl;
sec_end=sections_list.end();
- printf("------ config starts here ------\n");
-
for (sec_iter=sections_list.begin(); sec_iter != sec_end; ++sec_iter) {
ConfList::iterator iter, end;
ConfSection *sec;
if (cl) {
line[0] = '\0';
cl->output(line, MAX_LINE);
- printf("%s\n", line);
+ ::write(fd, line, strlen(line));
+ ::write(fd, "\n", 1);
}
}
}
+}
+
+void ConfFile::dump()
+{
+ SectionList::iterator sec_iter, sec_end;
+
+ sec_end=sections_list.end();
+
+ printf("------ config starts here ------\n");
+ _dump(STDOUT_FILENO);
printf("------ config ends here ------\n");
}
return 1;
}
+int ConfFile::flush()
+{
+ int rc;
+
+ if (fd < 0) {
+ fd = open(filename, O_RDWR | O_CREAT);
+
+ if (fd < 0) {
+ printf("error opening file %s errno=%d\n", filename, errno);
+ return 0;
+ }
+ } else {
+ rc = lseek(fd, 0, SEEK_SET);
+ if (rc < 0) {
+ printf("error seeking file %s errno = %d\n", filename, errno);
+ return 0;
+ }
+ }
+
+ _dump(fd);
+ rc = fsync(fd);
+
+ if (rc < 0)
+ return 0;
+
+ return 1;
+}
+
ConfLine *ConfFile::_find_var(const char *section, const char* var)
{
SectionMap::iterator iter = sections.find(section);
memset(cl, 0, sizeof(ConfLine));
snprintf(buf, sizeof(buf), "[%s]", section);
cl->set_prefix(buf);
- cl->set_mid(" = ");
sec->conf_list.push_back(cl);
} else {
sec = iter->second;
*dst_val = def_val;
}
+template<char *>
static void _conf_copy(char **dst_val, char *def_val)
{
*dst_val = strdup(def_val);
if (*str_val == '"') {
str_val++;
- for (len-1; len > 0; len--) {
+ for (len = len-1; len > 0; len--) {
if (str_val[len] == '"')
break;
}
static void _conf_encode(char *dst_str, int len, float val)
{
- snprintf(dst_str, len, "%f", val);
+ snprintf(dst_str, len, "%g", val);
}
static void _conf_encode(char *dst_str, int len, bool val)
snprintf(dst_str, len, "%s", (val ? "true" : "false"));
}
-static void _conf_encode(char *dst_str, int len, char *val)
+static void _conf_encode(char *dst_str, int max_len, char *val)
{
int have_delim = 0;
int i;
- len = strlen(val);
+ int len = strlen(val);
for (i=0; i<len; i++) {
if (is_delim(val[i], _def_delim)) {
}
if (have_delim)
- snprintf(dst_str, len, """%s""", val);
+ snprintf(dst_str, max_len, "\"%s\"", val);
else
- snprintf(dst_str, len, "%s", val);
+ snprintf(dst_str, max_len, "%s", val);
return;
}
return 1;
notfound:
_conf_copy<T>(val, def_val);
+
+ if (auto_update)
+ _write<T>(section, var, def_val);
+
return 0;
}
return _read<bool>(section, var, val, def_val);
}
-int ConfFile::read(const char *section, const char *var, char **val, char *def_val)
+int ConfFile::read(const char *section, const char *var, char **val, const char *def_val)
{
- return _read<char *>(section, var, val, def_val);
+ return _read<char *>(section, var, val, (char *)def_val);
}
int ConfFile::read(const char *section, const char *var, float *val, float def_val)
{
return _write<char *>(section, var, val);
}
-
+#if 0
void parse_test(char *line)
{
ConfLine cl;
printf("val: '%s'\n", cl.get_val());
printf("suf: '%s'\n", cl.get_suffix());
printf("section: '%s'\n", cl.get_section());
-
}
int main(int argc, char *argv[])
{
ConfFile cf(argv[1]);
int val;
+ char *str_val;
+ float fval;
+ bool bval;
cf.parse();
cf.dump();
+
+ cf.set_auto_update(true);
+
cf.read("core", "repositoryformatversion", &val, 12);
- cf.write("core", "lola", 15);
- cf.write("zore", "lola", 15);
+ cf.read("foo", "lala1", &val, 10);
+ cf.read("foo", "lala2", &val, 11);
+ cf.read("foo", "lala3", &val, 12);
+ cf.read("foo2", "lala4", &val, 13);
+ cf.read("foo", "lala5", &val, 14);
+ cf.read("foo", "lala6", &fval, 14.2);
+ cf.read("foo", "lala7", &bval, false);
+
+ cf.read("foo", "str", &str_val, "hello world2");
+
+ printf("read str=%s\n", str_val);
+ printf("read bool=%d\n", bval);
+ printf("read float=%f\n", fval);
cf.dump();
+ cf.flush();
printf("read val=%d\n", val);
return 0;
}
+#endif
class ConfFile {
int fd;
char *filename;
+ bool auto_update;
SectionMap sections;
SectionList sections_list;
ConfLine *_add_var(const char *section, const char* var);
template<typename T>
- int _read(const char *section, const char *var, T *val, T def_val);
+ int _read(const char *section, const char *var, T *val, const T def_val);
template<typename T>
- int _write(const char *section, const char *var, T val);
+ int _write(const char *section, const char *var, const T val);
+
+ void _dump(int fd);
public:
- ConfFile(char *fname) : filename(strdup(fname)) {}
+ ConfFile(const char *fname) : fd(-1), filename(strdup(fname)), auto_update(false) {}
~ConfFile();
int parse();
int read(const char *section, const char *var, int *val, int 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, int size, char *def_val); */
- int read(const char *section, const char *var, char **val, char *def_val); /* allocates new val */
+ int read(const char *section, const char *var, char **val, const char *def_val);
int read(const char *section, const char *var, float *val, float def_val);
int write(const char *section, const char *var, int val);
int write(const char *section, const char *var, char *val);
void dump();
+ int flush();
+ void set_auto_update(bool update) { auto_update = update; }
};
#endif
dout_dir: "out", // if daemonize == true
dout_sym_dir: "out", // if daemonize == true
+
+ conf_file: "ceph.conf",
fake_clock: false,
fakemessenger_serialize: true,
}
-void parse_config_file(char *fname)
+#define CF_READ(section, var, inout) \
+ cf.read(section, var, &g_conf.inout, g_conf.inout)
+
+#define CF_READ_STR(section, var, inout) \
+ cf.read(section, var, (char **)&g_conf.inout, (char *)g_conf.inout)
+
+void parse_config_file(const char *fname)
{
ConfFile cf(fname);
+ cf.set_auto_update(true);
+
cf.parse();
-#define CF_READ(section, type, field, inout) \
- cf.read_##type((char *)section, (char *)#field, &inout, inout)
-
-#define CF_READ_STR(section, type, field, inout) \
- cf.read_##type((char *)section, (char *)#field, (char **)&inout, (char *)inout)
-
- CF_READ("global", int, num_mon, g_conf.num_mon);
- CF_READ("global", int, num_mon, g_conf.num_mds);
- CF_READ("global", int, num_mon, g_conf.num_osd);
- CF_READ("global", bool, mkfs, g_conf.mkfs);
- CF_READ("global", bool, daemonize, g_conf.daemonize);
- CF_READ("global", bool, file_logs, g_conf.file_logs);
- CF_READ("global", bool, log, g_conf.log);
- CF_READ("global", int, log_interval, g_conf.log_interval);
- CF_READ_STR("global", str_alloc, log_name, g_conf.log_name);
- CF_READ("global", bool, log_messages, g_conf.log_messages);
- CF_READ("global", bool, log_pins, g_conf.log_pins);
- CF_READ_STR("global", str_alloc, dout_dir, g_conf.dout_dir);
- CF_READ_STR("global", str_alloc, dout_sym_dir, g_conf.dout_sym_dir);
+ CF_READ("global", "num_mon", num_mon);
+ CF_READ("global", "num_mds", num_mds);
+ CF_READ("global", "num_osd", num_osd);
+ CF_READ("global", "mkfs", mkfs);
+ CF_READ("global", "daemonize", daemonize);
+ CF_READ_STR("global", "file_logs", file_logs);
+ CF_READ("global", "log", log);
+ CF_READ("global", "log_interval", log_interval);
+ CF_READ_STR("global", "str_alloc", log_name);
+ CF_READ("global", "log_messages", log_messages);
+ CF_READ("global", "log_pins", log_pins);
+ CF_READ_STR("global", "dout_dir", dout_dir);
+ CF_READ_STR("global", "dout_sym_dir", dout_sym_dir);
+
+ cf.flush();
}
void parse_config_options(std::vector<const char*>& args, bool open)
else if (//strcmp(args[i], "-o") == 0 ||
strcmp(args[i], "--dout_sym_dir") == 0)
g_conf.dout_sym_dir = args[++i];
+ else if (strcmp(args[i], "--conf_file") == 0)
+ g_conf.conf_file = args[++i];
else if (strcmp(args[i], "--lockdep") == 0)
g_lockdep = atoi(args[++i]);
}
}
+ parse_config_file(g_conf.conf_file);
+
// open log file?
if (open)
_dout_open_log();