diff options
author | Colin Patrick McCabe <cmccabe@alumni.cmu.edu> | 2011-02-20 09:18:03 -0800 |
---|---|---|
committer | Colin Patrick McCabe <cmccabe@alumni.cmu.edu> | 2011-02-20 10:17:11 -0800 |
commit | 2a59b2132fae02b2b136b0bab0d3cacdfe288217 (patch) | |
tree | ae7ad07c8ce59aa71d148592044f13f837524031 /src | |
parent | 349cb128597f84b80a5177de57013bdfee48ff22 (diff) | |
download | ceph-2a59b2132fae02b2b136b0bab0d3cacdfe288217.tar.gz |
common: Split argument parsing into ceph_argparse
Signed-off-by: Colin McCabe <colin.mccabe@dreamhost.com>
Diffstat (limited to 'src')
37 files changed, 493 insertions, 383 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 8b89a8d48d7..a6ac02feec5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -523,6 +523,7 @@ libcommon_files = \ osd/OSDMap.cc \ mds/MDSMap.cc \ common/common_init.cc \ + common/ceph_argparse.cc \ common/buffer.cc \ common/signal.cc \ common/Thread.cc \ diff --git a/src/cauthtool.cc b/src/cauthtool.cc index 8d8e6a55687..d0c27b33104 100644 --- a/src/cauthtool.cc +++ b/src/cauthtool.cc @@ -17,6 +17,7 @@ using namespace std; #include "config.h" #include "common/ConfUtils.h" +#include "common/ceph_argparse.h" #include "common/common_init.h" #include "auth/Crypto.h" #include "auth/Auth.h" diff --git a/src/cconf.cc b/src/cconf.cc index 182a9ee1326..47f4385b2f7 100644 --- a/src/cconf.cc +++ b/src/cconf.cc @@ -21,6 +21,7 @@ #include "mon/AuthMonitor.h" #include "common/ConfUtils.h" #include "common/common_init.h" +#include "common/ceph_argparse.h" #include "config.h" #include "include/str_list.h" @@ -71,12 +72,11 @@ void error_exit() static int list_sections(const char *s) { - ConfFile *cf = conf_get_conf_file(); - if (!cf) + if (!g_conf.cf) return 2; for (std::list<ConfSection*>::const_iterator p = - cf->get_section_list().begin(); - p != cf->get_section_list().end(); ++p) + g_conf.cf->get_section_list().begin(); + p != g_conf.cf->get_section_list().end(); ++p) { if (strncmp(s, (*p)->get_name().c_str(), strlen(s)) == 0) cout << (*p)->get_name() << std::endl; @@ -101,8 +101,7 @@ static int lookup_impl(const deque<const char *> §ions, bool resolve_search) { char *val = NULL; - ConfFile *cf = conf_get_conf_file(); - if (!cf) + if (!g_conf.cf) return 2; conf_read_key(NULL, key, OPT_STR, (char **)&val, NULL); if (val) { @@ -112,7 +111,7 @@ static int lookup_impl(const deque<const char *> §ions, } for (unsigned int i=0; i<sections.size(); i++) { - cf->read(sections[i], key, (char **)&val, NULL); + g_conf.cf->read(sections[i], key, (char **)&val, NULL); if (val) { print_val(val, resolve_search); free(val); @@ -132,8 +131,9 @@ static int lookup_impl(const deque<const char *> §ions, { // TODO: document exactly what we are doing here? std::vector<const char *> empty_args; + bool force_fg_logging = false; parse_startup_config_options(empty_args, type, - STARTUP_FLAG_FORCE_FG_LOGGING); + STARTUP_FLAG_FORCE_FG_LOGGING, &force_fg_logging); char buf[1024]; memset(buf, 0, sizeof(buf)); if (ceph_def_conf_by_name(key, buf, sizeof(buf))) { diff --git a/src/cfuse.cc b/src/cfuse.cc index e8ff5694f5a..a883e227470 100644 --- a/src/cfuse.cc +++ b/src/cfuse.cc @@ -27,6 +27,7 @@ using namespace std; #include "mon/MonClient.h" #include "common/Timer.h" +#include "common/ceph_argparse.h" #include "common/common_init.h" #include "common/errno.h" #include "common/safe_io.h" diff --git a/src/cmds.cc b/src/cmds.cc index f23e61ecd08..7dba179b77c 100644 --- a/src/cmds.cc +++ b/src/cmds.cc @@ -32,6 +32,7 @@ using namespace std; #include "common/Timer.h" #include "common/common_init.h" +#include "common/ceph_argparse.h" #include "mon/MonClient.h" diff --git a/src/cmon.cc b/src/cmon.cc index 591b856970b..8fe95e41d7f 100644 --- a/src/cmon.cc +++ b/src/cmon.cc @@ -31,6 +31,7 @@ using namespace std; #include "include/CompatSet.h" +#include "common/ceph_argparse.h" #include "common/Timer.h" #include "common/common_init.h" diff --git a/src/common/ceph_argparse.cc b/src/common/ceph_argparse.cc new file mode 100644 index 00000000000..af714581081 --- /dev/null +++ b/src/common/ceph_argparse.cc @@ -0,0 +1,334 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "auth/Auth.h" +#include "common/ceph_argparse.h" +#include "common/common_init.h" +#include "common/ConfUtils.h" +#include "common/version.h" +#include "config.h" +#include "include/intarith.h" +#include "include/str_list.h" +#include "msg/msg_types.h" + +#include <deque> +#include <stdlib.h> +#include <string> +#include <string.h> +#include <vector> + +/* + * Ceph argument parsing library + * + * We probably should eventually replace this with something standard like popt. + * Until we do that, though, this file is the place for argv parsing + * stuff to live. + */ + +#undef dout +#undef pdout +#undef derr +#undef generic_dout +#undef dendl + +static void env_override(char **ceph_var, const char * const env_var) +{ + char *e = getenv(env_var); + if (!e) + return; + if (*ceph_var) + free(*ceph_var); + *ceph_var = strdup(e); +} + +void env_to_vec(std::vector<const char*>& args) +{ + char *p = getenv("CEPH_ARGS"); + if (!p) return; + + static char buf[1000]; + int len = MIN(strlen(p), sizeof(buf)-1); // bleh. + memcpy(buf, p, len); + buf[len] = 0; + //cout << "CEPH_ARGS='" << p << ";" << endl; + + p = buf; + while (*p && p < buf + len) { + char *e = p; + while (*e && *e != ' ') + e++; + *e = 0; + args.push_back(p); + //cout << "arg " << p << std::endl; + p = e+1; + } +} + +void env_to_deq(std::deque<const char*>& args) +{ + char *p = getenv("CEPH_ARGS"); + if (!p) return; + + static char buf[1000]; + int len = MIN(strlen(p), sizeof(buf)-1); // bleh. + memcpy(buf, p, len); + buf[len] = 0; + + p = buf; + while (*p && p < buf + len) { + char *e = p; + while (*e && *e != ' ') + e++; + *e = 0; + args.push_back(p); + p = e+1; + } +} + +void argv_to_vec(int argc, const char **argv, + std::vector<const char*>& args) +{ + for (int i=1; i<argc; i++) + args.push_back(argv[i]); +} + +void argv_to_deq(int argc, const char **argv, + std::deque<const char*>& args) +{ + for (int i=1; i<argc; i++) + args.push_back(argv[i]); +} + +void vec_to_argv(std::vector<const char*>& args, + int& argc, const char **&argv) +{ + const char *myname = "asdf"; + if (argc && argv) + myname = argv[0]; + argv = (const char**)malloc(sizeof(char*) * argc); + argc = 1; + argv[0] = myname; + + for (unsigned i=0; i<args.size(); i++) + argv[argc++] = args[i]; +} + +bool parse_ip_port_vec(const char *s, vector<entity_addr_t>& vec) +{ + const char *p = s; + const char *end = p + strlen(p); + while (p < end) { + entity_addr_t a; + //cout << " parse at '" << p << "'" << std::endl; + if (!a.parse(p, &p)) { + //dout(0) << " failed to parse address '" << p << "'" << dendl; + return false; + } + //cout << " got " << a << ", rest is '" << p << "'" << std::endl; + vec.push_back(a); + while (*p == ',' || *p == ' ') + p++; + } + return true; +} + +void parse_config_option_string(std::string& s) +{ + char b[s.length()+1]; + strcpy(b, s.c_str()); + std::vector<const char*> nargs; + char *p = b; + while (*p) { + nargs.push_back(p); + while (*p && *p != ' ') p++; + if (!*p) + break; + *p++ = 0; + while (*p && *p == ' ') p++; + } + parse_config_options(nargs); +} + +void parse_startup_config_options(std::vector<const char*>& args, + const char *module_type, int flags, + bool *force_fg_logging) +{ + bool show_config = false; + DEFINE_CONF_VARS(NULL); + std::vector<const char *> nargs; + bool conf_specified = false; + *force_fg_logging = ((flags & STARTUP_FLAG_FORCE_FG_LOGGING) != 0); + + if (!g_conf.type) + g_conf.type = (char *)""; + + bool isdaemon = g_conf.daemonize; + + FOR_EACH_ARG(args) { + if (CONF_ARG_EQ("version", 'v')) { + cout << ceph_version_to_string() << std::endl; + _exit(0); + } else if (CONF_ARG_EQ("conf", 'c')) { + CONF_SAFE_SET_ARG_VAL(&g_conf.conf, OPT_STR); + conf_specified = true; + } else if (CONF_ARG_EQ("monmap", 'M')) { + CONF_SAFE_SET_ARG_VAL(&g_conf.monmap, OPT_STR); + } else if (CONF_ARG_EQ("show_conf", 'S')) { + show_config = true; + } else if (isdaemon && CONF_ARG_EQ("bind", 0)) { + g_conf.public_addr.parse(args[++i]); + } else if (CONF_ARG_EQ("nodaemon", 'D')) { + g_conf.daemonize = false; + *force_fg_logging = true; + } else if (CONF_ARG_EQ("foreground", 'f')) { + g_conf.daemonize = false; + *force_fg_logging = false; + } else if (isdaemon && (CONF_ARG_EQ("id", 'i') || CONF_ARG_EQ("name", 'n'))) { + free(g_conf.id); + CONF_SAFE_SET_ARG_VAL(&g_conf.id, OPT_STR); + } else if (!isdaemon && (CONF_ARG_EQ("id", 'I') || CONF_ARG_EQ("name", 'n'))) { + free(g_conf.id); + CONF_SAFE_SET_ARG_VAL(&g_conf.id, OPT_STR); + } else { + nargs.push_back(args[i]); + } + } + args.swap(nargs); + nargs.clear(); + + if (module_type) { + g_conf.type = strdup(module_type); + // is it "type.name"? + const char *dot = strchr(g_conf.id, '.'); + if (dot) { + int tlen = dot - g_conf.id; + g_conf.type = (char *)malloc(tlen + 1); + memcpy(g_conf.type, g_conf.id, tlen); + g_conf.type[tlen] = 0; + char *new_g_conf_id = strdup(dot + 1); + free(g_conf.id); + g_conf.id = new_g_conf_id; + } + + int len = strlen(g_conf.type) + strlen(g_conf.id) + 2; + g_conf.name = (char *)malloc(len); + snprintf(g_conf.name, len, "%s.%s", g_conf.type, g_conf.id); + g_conf.alt_name = (char *)malloc(len - 1); + snprintf(g_conf.alt_name, len - 1, "%s%s", module_type, g_conf.id); + } + + g_conf.entity_name = new EntityName; + assert(g_conf.entity_name); + + g_conf.entity_name->from_type_id(g_conf.type, g_conf.id); + + if (g_conf.cf) { + delete g_conf.cf; + g_conf.cf = NULL; + } + + // do post_process substitutions + int len = num_config_options; + for (int i = 0; i<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); + } + } + } + + if (!conf_specified) + env_override(&g_conf.conf, "CEPH_CONF"); + + // open new conf + string fn = g_conf.conf; + list<string> ls; + get_str_list(fn, ls); + bool read_conf = false; + for (list<string>::iterator p = ls.begin(); p != ls.end(); p++) { + g_conf.cf = new ConfFile(p->c_str()); + read_conf = parse_config_file(g_conf.cf, true); + if (read_conf) + break; + delete g_conf.cf; + g_conf.cf = NULL; + } + + if (conf_specified && !read_conf) { + cerr << "error reading config file(s) " << g_conf.conf << std::endl; + exit(1); + } + + if (show_config) { + if (g_conf.cf) + g_conf.cf->dump(); + exit(0); + } +} + +void parse_config_options(std::vector<const char*>& args) +{ + int opt_len = num_config_options; + DEFINE_CONF_VARS(NULL); + + std::vector<const char*> nargs; + FOR_EACH_ARG(args) { + int optn; + + for (optn = 0; optn < opt_len; optn++) { + if (CONF_ARG_EQ("lockdep", '\0')) { + CONF_SAFE_SET_ARG_VAL(&g_lockdep, OPT_INT); + } else if (CONF_ARG_EQ(config_optionsp[optn].name, + config_optionsp[optn].char_option)) { + if (__isarg || val_pos || config_optionsp[optn].type == OPT_BOOL) + CONF_SAFE_SET_ARG_VAL(config_optionsp[optn].val_ptr, config_optionsp[optn].type); + else + continue; + } else { + continue; + } + break; + } + + if (optn == opt_len) + nargs.push_back(args[i]); + } + + env_override(&g_conf.keyring, "CEPH_KEYRING"); + args = nargs; +} + +static void generic_usage(bool is_server) +{ + cout << " -c ceph.conf or --conf=ceph.conf\n"; + cout << " get options from given conf file\n"; + cout << " -D run in foreground.\n"; + cout << " -f run in foreground. Show all log messages on stdout.\n"; + if (is_server) { + cout << " --debug_ms N\n"; + cout << " set message debug level (e.g. 1)\n"; + } +} + +void generic_server_usage() +{ + generic_usage(true); + exit(1); +} +void generic_client_usage() +{ + generic_usage(false); + exit(1); +} diff --git a/src/common/ceph_argparse.h b/src/common/ceph_argparse.h new file mode 100644 index 00000000000..10d1bfe149f --- /dev/null +++ b/src/common/ceph_argparse.h @@ -0,0 +1,64 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2008-2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_ARGPARSE_H +#define CEPH_ARGPARSE_H + +/* + * Ceph argument parsing library + * + * We probably should eventually replace this with something standard like popt. + * Until we do that, though, this file is the place for argv parsing + * stuff to live. + */ + +#include <deque> +#include <string> +#include <vector> + +#include "msg/msg_types.h" + +/////////////////////// Macros /////////////////////// +#define FOR_EACH_ARG(args) \ + __isarg = 1 < args.size(); \ + for (unsigned i=0; i<args.size(); i++, __isarg = i+1 < args.size()) + +#define ARGS_USAGE() args_usage(); + +#define DEFINE_CONF_VARS(usage_func) \ + unsigned int val_pos __attribute__((unused)); \ + void (*args_usage)() __attribute__((unused)) = usage_func; \ + bool __isarg __attribute__((unused)) + +/////////////////////// Functions /////////////////////// +extern void env_to_vec(std::vector<const char*>& args); +extern void env_to_deq(std::deque<const char*>& args); +extern void argv_to_vec(int argc, const char **argv, + std::vector<const char*>& args); +extern void argv_to_deq(int argc, const char **argv, + std::deque<const char*>& args); +extern void vec_to_argv(std::vector<const char*>& args, + int& argc, const char **&argv); + +extern bool parse_ip_port_vec(const char *s, std::vector<entity_addr_t>& vec); +extern void parse_config_option_string(std::string& s); +extern void parse_startup_config_options(std::vector<const char*>& args, + const char *module_type, int flags, + bool *force_fg_logging); +extern void parse_config_options(std::vector<const char*>& args); + +extern void generic_server_usage(); +extern void generic_client_usage(); + +#endif diff --git a/src/common/common_init.cc b/src/common/common_init.cc index bf4d8328b29..f57d9940f2b 100644 --- a/src/common/common_init.cc +++ b/src/common/common_init.cc @@ -14,13 +14,17 @@ #include "auth/AuthSupported.h" #include "auth/KeyRing.h" +#include "common/ceph_argparse.h" #include "common/safe_io.h" +#include "common/signal.h" +#include "common/version.h" #include "config.h" #include "common/common_init.h" #include "common/errno.h" -#include "common/signal.h" #include "include/color.h" +#include <syslog.h> + /* Set foreground logging * * Forces the process to log only to stderr, overriding whatever was in the ceph.conf. @@ -116,7 +120,30 @@ static void keyring_init(const char *filesearch) void common_init(std::vector<const char*>& args, const char *module_type, int flags) { - parse_startup_config_options(args, module_type, flags); + bool force_fg_logging = false; + parse_startup_config_options(args, module_type, flags, &force_fg_logging); + + if (g_conf.log_to_syslog || g_conf.clog_to_syslog) { + closelog(); + // It's ok if g_conf.name is NULL here. + openlog(g_conf.name, LOG_ODELAY | LOG_PID, LOG_USER); + } + + if (force_fg_logging) + set_foreground_logging(); + + { + // In the long term, it would be best to ensure that we read ceph.conf + // before initializing dout(). For now, just force a reopen here with the + // configuration we have just read. + DoutLocker _dout_locker; + _dout_open_log(); + } + + if (!force_fg_logging) { + dout_output_ceph_version(); + } + parse_config_options(args); install_standard_sighandlers(); diff --git a/src/config.cc b/src/config.cc index 3c7b3c96a58..5c0f558f363 100644 --- a/src/config.cc +++ b/src/config.cc @@ -49,9 +49,6 @@ /* The Ceph configuration. */ md_config_t g_conf __attribute__((init_priority(103))); -/* These should be moved into md_config_t eventually, grrr */ -static ConfFile *cf = NULL; - // file layouts struct ceph_file_layout g_default_file_layout = { fl_stripe_unit: init_le32(1<<22), @@ -63,140 +60,9 @@ struct ceph_file_layout g_default_file_layout = { fl_pg_pool : init_le32(-1), }; -static void env_override(char **ceph_var, const char * const env_var) -{ - char *e = getenv(env_var); - if (!e) - return; - if (*ceph_var) - free(*ceph_var); - *ceph_var = strdup(e); -} - -void env_to_vec(std::vector<const char*>& args) -{ - char *p = getenv("CEPH_ARGS"); - if (!p) return; - - static char buf[1000]; - int len = MIN(strlen(p), sizeof(buf)-1); // bleh. - memcpy(buf, p, len); - buf[len] = 0; - //cout << "CEPH_ARGS='" << p << ";" << endl; - - p = buf; - while (*p && p < buf + len) { - char *e = p; - while (*e && *e != ' ') - e++; - *e = 0; - args.push_back(p); - //cout << "arg " << p << std::endl; - p = e+1; - } -} - -void env_to_deq(std::deque<const char*>& args) -{ - char *p = getenv("CEPH_ARGS"); - if (!p) return; - - static char buf[1000]; - int len = MIN(strlen(p), sizeof(buf)-1); // bleh. - memcpy(buf, p, len); - buf[len] = 0; - - p = buf; - while (*p && p < buf + len) { - char *e = p; - while (*e && *e != ' ') - e++; - *e = 0; - args.push_back(p); - p = e+1; - } -} - -void argv_to_vec(int argc, const char **argv, - std::vector<const char*>& args) -{ - for (int i=1; i<argc; i++) - args.push_back(argv[i]); -} - -void argv_to_deq(int argc, const char **argv, - std::deque<const char*>& args) -{ - for (int i=1; i<argc; i++) - args.push_back(argv[i]); -} - -void vec_to_argv(std::vector<const char*>& args, - int& argc, const char **&argv) -{ - const char *myname = "asdf"; - if (argc && argv) - myname = argv[0]; - argv = (const char**)malloc(sizeof(char*) * argc); - argc = 1; - argv[0] = myname; - - for (unsigned i=0; i<args.size(); i++) - argv[argc++] = args[i]; -} - -bool parse_ip_port_vec(const char *s, vector<entity_addr_t>& vec) -{ - const char *p = s; - const char *end = p + strlen(p); - while (p < end) { - entity_addr_t a; - //cout << " parse at '" << p << "'" << std::endl; - if (!a.parse(p, &p)) { - //dout(0) << " failed to parse address '" << p << "'" << dendl; - return false; - } - //cout << " got " << a << ", rest is '" << p << "'" << std::endl; - vec.push_back(a); - while (*p == ',' || *p == ' ') - p++; - } - return true; -} - -void parse_config_option_string(string& s) -{ - char b[s.length()+1]; - strcpy(b, s.c_str()); - vector<const char*> nargs; - char *p = b; - while (*p) { - nargs.push_back(p); - while (*p && *p != ' ') p++; - if (!*p) - break; - *p++ = 0; - while (*p && *p == ' ') p++; - } - parse_config_options(nargs); -} - #define _STR(x) #x #define STRINGIFY(x) _STR(x) -struct config_option { - const char *section; - const char *conf_name; - const char *name; - void *val_ptr; - - const char *def_str; - long long def_longlong; - double def_double; - - opt_type_t type; - char char_option; // if any -}; #define OPTION_OPT_STR(section, name, schar, type, def_val) \ { STRINGIFY(section), NULL, STRINGIFY(name), \ @@ -223,7 +89,7 @@ struct config_option { { STRINGIFY(section), NULL, STRINGIFY(conf_name), \ &g_conf.name, STRINGIFY(def_val), type, schar } -static struct config_option config_optionsp[] = { +struct config_option config_optionsp[] = { OPTION(host, 0, OPT_STR, "localhost"), OPTION(public_addr, 0, OPT_ADDR, ""), OPTION(cluster_addr, 0, OPT_ADDR, ""), @@ -526,6 +392,8 @@ static struct config_option config_optionsp[] = { OPTION(bdev_fake_max_mb, 0, OPT_INT, 0), }; +const int num_config_options = sizeof(config_optionsp) / sizeof(config_option); + bool conf_set_conf_val(void *field, opt_type_t type, const char *val) { switch (type) { @@ -858,9 +726,9 @@ char *conf_post_process_val(const char *val) #define OPT_READ_TYPE(ret, section, var, type, out, def) \ do { \ if (def) \ - ret = cf->read(section, var, (type *)out, *(type *)def); \ + ret = g_conf.cf->read(section, var, (type *)out, *(type *)def); \ else \ - ret = cf->read(section, var, (type *)out, 0); \ + ret = g_conf.cf->read(section, var, (type *)out, 0); \ } while (0) int conf_read_key_ext(const char *conf_name, const char *conf_alt_name, const char *conf_type, @@ -922,7 +790,7 @@ int conf_read_key_ext(const char *conf_name, const char *conf_alt_name, const ch OPT_READ_TYPE(ret, section, key, double, out, def); break; case OPT_ADDR: - ret = cf->read(section, key, &tmp, (char *)def); + ret = g_conf.cf->read(section, key, &tmp, (char *)def); if (*tmp == *((char *)def)) { ret = 0; } @@ -977,207 +845,7 @@ bool is_bool_param(const char *param) return ((strcasecmp(param, "true")==0) || (strcasecmp(param, "false")==0)); } -void parse_startup_config_options(std::vector<const char*>& args, - const char *module_type, int flags) -{ - bool show_config = false; - DEFINE_CONF_VARS(NULL); - std::vector<const char *> nargs; - bool conf_specified = false; - bool force_fg_logging = !!(flags & STARTUP_FLAG_FORCE_FG_LOGGING); - - if (!g_conf.type) - g_conf.type = (char *)""; - - bool isdaemon = g_conf.daemonize; - - FOR_EACH_ARG(args) { - if (CONF_ARG_EQ("version", 'v')) { - cout << "ceph version " << VERSION << " (commit:" << STRINGIFY(CEPH_GIT_VER) << ")" << std::endl; - _exit(0); - } else if (CONF_ARG_EQ("conf", 'c')) { - CONF_SAFE_SET_ARG_VAL(&g_conf.conf, OPT_STR); - conf_specified = true; - } else if (CONF_ARG_EQ("monmap", 'M')) { - CONF_SAFE_SET_ARG_VAL(&g_conf.monmap, OPT_STR); - } else if (CONF_ARG_EQ("show_conf", 'S')) { - show_config = true; - } else if (isdaemon && CONF_ARG_EQ("bind", 0)) { - g_conf.public_addr.parse(args[++i]); - } else if (CONF_ARG_EQ("nodaemon", 'D')) { - g_conf.daemonize = false; - force_fg_logging = true; - } else if (CONF_ARG_EQ("foreground", 'f')) { - g_conf.daemonize = false; - force_fg_logging = false; - } else if (isdaemon && (CONF_ARG_EQ("id", 'i') || CONF_ARG_EQ("name", 'n'))) { - free(g_conf.id); - CONF_SAFE_SET_ARG_VAL(&g_conf.id, OPT_STR); - } else if (!isdaemon && (CONF_ARG_EQ("id", 'I') || CONF_ARG_EQ("name", 'n'))) { - free(g_conf.id); - CONF_SAFE_SET_ARG_VAL(&g_conf.id, OPT_STR); - } else { - nargs.push_back(args[i]); - } - } - args.swap(nargs); - nargs.clear(); - - if (module_type) { - g_conf.type = strdup(module_type); - // is it "type.name"? - const char *dot = strchr(g_conf.id, '.'); - if (dot) { - int tlen = dot - g_conf.id; - g_conf.type = (char *)malloc(tlen + 1); - memcpy(g_conf.type, g_conf.id, tlen); - g_conf.type[tlen] = 0; - char *new_g_conf_id = strdup(dot + 1); - free(g_conf.id); - g_conf.id = new_g_conf_id; - } - - int len = strlen(g_conf.type) + strlen(g_conf.id) + 2; - g_conf.name = (char *)malloc(len); - snprintf(g_conf.name, len, "%s.%s", g_conf.type, g_conf.id); - g_conf.alt_name = (char *)malloc(len - 1); - snprintf(g_conf.alt_name, len - 1, "%s%s", module_type, g_conf.id); - } - - g_conf.entity_name = new EntityName; - assert(g_conf.entity_name); - - g_conf.entity_name->from_type_id(g_conf.type, g_conf.id); - - if (cf) { - delete cf; - cf = NULL; - } - - // do post_process substitutions - int len = sizeof(config_optionsp)/sizeof(config_option); - for (int i = 0; i<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); - } - } - } - - if (!conf_specified) - env_override(&g_conf.conf, "CEPH_CONF"); - - // open new conf - string fn = g_conf.conf; - list<string> ls; - get_str_list(fn, ls); - bool read_conf = false; - for (list<string>::iterator p = ls.begin(); p != ls.end(); p++) { - cf = new ConfFile(p->c_str()); - read_conf = parse_config_file(cf, true); - if (read_conf) - break; - delete cf; - cf = NULL; - } - - if (conf_specified && !read_conf) { - cerr << "error reading config file(s) " << g_conf.conf << std::endl; - exit(1); - } - - if (g_conf.log_to_syslog || g_conf.clog_to_syslog) { - closelog(); - // It's ok if g_conf.name is NULL here. - openlog(g_conf.name, LOG_ODELAY | LOG_PID, LOG_USER); - } - - if (force_fg_logging) - set_foreground_logging(); - - { - // In the long term, it would be best to ensure that we read ceph.conf - // before initializing dout(). For now, just force a reopen here with the - // configuration we have just read. - DoutLocker _dout_locker; - _dout_open_log(); - } - - if (!force_fg_logging) { - dout_output_ceph_version(); - } - - if (!cf) - return; - - if (show_config) { - cf->dump(); - exit(0); - } -} - -void generic_usage(bool is_server) -{ - cout << " -c ceph.conf or --conf=ceph.conf\n"; - cout << " get options from given conf file\n"; - cout << " -D run in foreground.\n"; - cout << " -f run in foreground. Show all log messages on stdout.\n"; - if (is_server) { - cout << " --debug_ms N\n"; - cout << " set message debug level (e.g. 1)\n"; - } -} - -void generic_server_usage() -{ - generic_usage(true); - exit(1); -} -void generic_client_usage() -{ - generic_usage(false); - exit(1); -} - -ConfFile *conf_get_conf_file() -{ - return cf; -} - -void parse_config_options(std::vector<const char*>& args) -{ - int opt_len = sizeof(config_optionsp)/sizeof(config_option); - DEFINE_CONF_VARS(NULL); - - std::vector<const char*> nargs; - FOR_EACH_ARG(args) { - int optn; - - for (optn = 0; optn < opt_len; optn++) { - if (CONF_ARG_EQ("lockdep", '\0')) { - CONF_SAFE_SET_ARG_VAL(&g_lockdep, OPT_INT); - } else if (CONF_ARG_EQ(config_optionsp[optn].name, - config_optionsp[optn].char_option)) { - if (__isarg || val_pos || config_optionsp[optn].type == OPT_BOOL) - CONF_SAFE_SET_ARG_VAL(config_optionsp[optn].val_ptr, config_optionsp[optn].type); - else - continue; - } else { - continue; - } - break; - } - - if (optn == opt_len) - nargs.push_back(args[i]); - } - - env_override(&g_conf.keyring, "CEPH_KEYRING"); - args = nargs; -} - -bool ceph_resolve_file_search(string& filename_list, string& result) +bool ceph_resolve_file_search(std::string& filename_list, std::string& result) { list<string> ls; get_str_list(filename_list, ls); @@ -1197,6 +865,7 @@ bool ceph_resolve_file_search(string& filename_list, string& result) } md_config_t::md_config_t() + : cf(NULL) { // // Note: because our md_config_t structure is a global, the memory used to diff --git a/src/config.h b/src/config.h index 06f40a1ed60..9cb17bfe6ad 100644 --- a/src/config.h +++ b/src/config.h @@ -43,10 +43,14 @@ enum log_to_stderr_t { LOG_TO_STDERR_ALL = 2, }; +struct ConfFile; + struct md_config_t { md_config_t(); ~md_config_t(); + ConfFile *cf; + char *type; char *id; char *name; @@ -467,32 +471,6 @@ typedef enum { OPT_ADDR, OPT_U32 } opt_type_t; -/** - * command line / environment argument parsing - */ -void env_to_vec(std::vector<const char*>& args); -void argv_to_vec(int argc, const char **argv, - std::vector<const char*>& args); -void vec_to_argv(std::vector<const char*>& args, - int& argc, const char **&argv); -void env_to_deq(std::deque<const char*>& args); -void argv_to_deq(int argc, const char **argv, - std::deque<const char*>& args); - -void parse_startup_config_options(std::vector<const char*>& args, - const char *module_type, int flags); -void parse_config_options(std::vector<const char*>& args); -void parse_config_option_string(string& s); - -extern bool parse_ip_port_vec(const char *s, vector<entity_addr_t>& vec); - -void generic_server_usage(); -void generic_client_usage(); -void generic_usage(); - -class ConfFile; -ConfFile *conf_get_conf_file(); - char *conf_post_process_val(const char *val); int conf_read_key(const char *alt_section, const char *key, opt_type_t type, void *out, void *def, bool free_old_val = false); bool conf_set_conf_val(void *field, opt_type_t type, const char *val); @@ -533,17 +511,24 @@ bool ceph_resolve_file_search(string& filename_list, string& result); #define CONF_ARG_EQ(str_cmd, char_cmd) \ conf_cmd_equals(args[i], str_cmd, char_cmd, &val_pos) -#define DEFINE_CONF_VARS(usage_func) \ - unsigned int val_pos __attribute__((unused)); \ - void (*args_usage)() __attribute__((unused)) = usage_func; \ - bool __isarg __attribute__((unused)) +struct config_option { + const char *section; + const char *conf_name; + const char *name; + void *val_ptr; + const char *def_str; + long long def_longlong; + double def_double; + + opt_type_t type; + char char_option; // if any +}; -#define FOR_EACH_ARG(args) \ - __isarg = 1 < args.size(); \ - for (unsigned i=0; i<args.size(); i++, __isarg = i+1 < args.size()) +extern struct config_option config_optionsp[]; +extern const int num_config_options; -#define ARGS_USAGE() args_usage(); +extern bool parse_config_file(ConfFile *cf, bool auto_update); #include "common/debug.h" diff --git a/src/cosd.cc b/src/cosd.cc index 5e6a1ba750b..b851ba50a95 100644 --- a/src/cosd.cc +++ b/src/cosd.cc @@ -32,6 +32,7 @@ using namespace std; #include "common/Timer.h" #include "common/common_init.h" +#include "common/ceph_argparse.h" #include "include/color.h" #include "common/errno.h" diff --git a/src/crushtool.cc b/src/crushtool.cc index 7b381365fdf..ce66368b77f 100644 --- a/src/crushtool.cc +++ b/src/crushtool.cc @@ -21,6 +21,7 @@ #include "config.h" +#include "common/ceph_argparse.h" #include "common/common_init.h" #include "crush/CrushWrapper.h" #include "crush/grammar.h" diff --git a/src/csyn.cc b/src/csyn.cc index 2c1fe24978d..b3c7d825055 100644 --- a/src/csyn.cc +++ b/src/csyn.cc @@ -28,6 +28,7 @@ using namespace std; #include "common/Timer.h" #include "common/common_init.h" +#include "common/ceph_argparse.h" #ifndef DARWIN #include <envz.h> diff --git a/src/dumpjournal.cc b/src/dumpjournal.cc index bf6f77076e1..34fb541103b 100644 --- a/src/dumpjournal.cc +++ b/src/dumpjournal.cc @@ -29,6 +29,7 @@ using namespace std; #include "common/Timer.h" #include "common/common_init.h" +#include "common/ceph_argparse.h" #ifndef DARWIN #include <envz.h> diff --git a/src/dupstore.cc b/src/dupstore.cc index bf0b58702a3..ccbcb359b3a 100644 --- a/src/dupstore.cc +++ b/src/dupstore.cc @@ -15,6 +15,7 @@ #include <iostream> //#include "ebofs/Ebofs.h" #include "os/FileStore.h" +#include "common/ceph_argparse.h" #include "common/common_init.h" #include <ext/hash_map> diff --git a/src/libceph.cc b/src/libceph.cc index a792ea8871a..705ffed2687 100644 --- a/src/libceph.cc +++ b/src/libceph.cc @@ -4,6 +4,7 @@ #include <fcntl.h> #include <iostream> +#include "common/ceph_argparse.h" #include "common/Mutex.h" #include "messages/MMonMap.h" #include "common/common_init.h" diff --git a/src/librados-config.cc b/src/librados-config.cc index a3f125c68d8..2b229761702 100644 --- a/src/librados-config.cc +++ b/src/librados-config.cc @@ -15,6 +15,7 @@ #define __STDC_FORMAT_MACROS #include "config.h" +#include "common/ceph_argparse.h" #include "common/common_init.h" #include "include/rados/librados.h" diff --git a/src/librados.cc b/src/librados.cc index 05a3f98e647..59086741e63 100644 --- a/src/librados.cc +++ b/src/librados.cc @@ -31,6 +31,7 @@ using namespace std; #include "msg/SimpleMessenger.h" +#include "common/ceph_argparse.h" #include "common/Timer.h" #include "common/common_init.h" diff --git a/src/librbd.cc b/src/librbd.cc index 651c9020c0b..bdf931a2099 100644 --- a/src/librbd.cc +++ b/src/librbd.cc @@ -16,6 +16,7 @@ #include "config.h" #include "common/common_init.h" +#include "common/ceph_argparse.h" #include "common/Cond.h" #include "include/rbd/librbd.hpp" #include "include/byteorder.h" diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc index b1c98c1fe48..1837f650e8d 100644 --- a/src/mds/MDS.cc +++ b/src/mds/MDS.cc @@ -17,6 +17,7 @@ #include "include/types.h" #include "common/Clock.h" #include "common/signal.h" +#include "common/ceph_argparse.h" #include "msg/Messenger.h" #include "mon/MonClient.h" diff --git a/src/mon/MonClient.cc b/src/mon/MonClient.cc index a70dae48eb6..e57b80e0d21 100644 --- a/src/mon/MonClient.cc +++ b/src/mon/MonClient.cc @@ -21,6 +21,7 @@ #include "messages/MMonSubscribe.h" #include "messages/MMonSubscribeAck.h" #include "common/ConfUtils.h" +#include "common/ceph_argparse.h" #include "MonClient.h" #include "MonMap.h" diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 6f543df7d5e..a10f4924745 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -39,6 +39,7 @@ #include "messages/MAuthReply.h" +#include "common/ceph_argparse.h" #include "common/Timer.h" #include "common/Clock.h" #include "include/color.h" diff --git a/src/monmaptool.cc b/src/monmaptool.cc index f45fdb7c14e..0e09ef7e964 100644 --- a/src/monmaptool.cc +++ b/src/monmaptool.cc @@ -23,6 +23,7 @@ using namespace std; #include "config.h" +#include "common/ceph_argparse.h" #include "common/common_init.h" #include "mon/MonMap.h" diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 0f9e3727534..aa457f325d9 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -20,6 +20,7 @@ #include "OSDMap.h" #include "Watch.h" +#include "common/ceph_argparse.h" #include "os/FileStore.h" #ifdef USE_OSBDB diff --git a/src/osdmaptool.cc b/src/osdmaptool.cc index e9d42a54275..19802528c67 100644 --- a/src/osdmaptool.cc +++ b/src/osdmaptool.cc @@ -27,6 +27,7 @@ using namespace std; #include "common/errno.h" #include "osd/OSDMap.h" #include "mon/MonMap.h" +#include "common/ceph_argparse.h" #include "common/common_init.h" void usage() diff --git a/src/rados.cc b/src/rados.cc index 358e0bce9e2..24be8000bb8 100644 --- a/src/rados.cc +++ b/src/rados.cc @@ -20,6 +20,7 @@ using namespace librados; #include "osdc/rados_bencher.h" #include "config.h" +#include "common/ceph_argparse.h" #include "common/common_init.h" #include "common/Cond.h" #include "mds/inode_backtrace.h" diff --git a/src/rbd.cc b/src/rbd.cc index ca443c4a617..09f0a21661c 100644 --- a/src/rbd.cc +++ b/src/rbd.cc @@ -16,6 +16,7 @@ #include "config.h" #include "common/errno.h" +#include "common/ceph_argparse.h" #include "common/common_init.h" #include "include/rbd/librbd.hpp" #include "include/byteorder.h" diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index fd5cd4adeb6..8586ee6e890 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -8,6 +8,7 @@ using namespace std; #include "config.h" #include <cryptopp/osrng.h> +#include "common/ceph_argparse.h" #include "common/common_init.h" #include "common/armor.h" diff --git a/src/streamtest.cc b/src/streamtest.cc index 003d837eb23..1a6261ba0d0 100644 --- a/src/streamtest.cc +++ b/src/streamtest.cc @@ -16,6 +16,7 @@ //#include "ebofs/Ebofs.h" #include "os/FileStore.h" #include "common/common_init.h" +#include "common/ceph_argparse.h" #undef dout_prefix #define dout_prefix *_dout diff --git a/src/test/TestDoutStreambuf.cc b/src/test/TestDoutStreambuf.cc index 769b9b9024b..c37b96322c0 100644 --- a/src/test/TestDoutStreambuf.cc +++ b/src/test/TestDoutStreambuf.cc @@ -19,6 +19,7 @@ * Check your syslog to see what it did. */ #include "common/DoutStreambuf.h" +#include "common/ceph_argparse.h" #include "common/common_init.h" #include "config.h" diff --git a/src/test/TestSignalHandlers.cc b/src/test/TestSignalHandlers.cc index dbb24d332ac..3f12e1e681d 100644 --- a/src/test/TestSignalHandlers.cc +++ b/src/test/TestSignalHandlers.cc @@ -18,6 +18,7 @@ * Test the Ceph signal handlers */ #include "common/DoutStreambuf.h" +#include "common/ceph_argparse.h" #include "common/common_init.h" #include "common/errno.h" #include "config.h" diff --git a/src/test/TestTimers.cc b/src/test/TestTimers.cc index e7cb941f08c..1b96b6d4509 100644 --- a/src/test/TestTimers.cc +++ b/src/test/TestTimers.cc @@ -1,3 +1,4 @@ +#include "common/ceph_argparse.h" #include "common/Mutex.h" #include "common/Timer.h" #include "common/common_init.h" diff --git a/src/test_trans.cc b/src/test_trans.cc index 33ea99ffed3..ee631d2cb47 100644 --- a/src/test_trans.cc +++ b/src/test_trans.cc @@ -14,6 +14,7 @@ #include <iostream> //#include "ebofs/Ebofs.h" +#include "common/ceph_argparse.h" #include "os/FileStore.h" #include "common/common_init.h" diff --git a/src/testmsgr.cc b/src/testmsgr.cc index 88e4aaed599..e0b6a074fbe 100644 --- a/src/testmsgr.cc +++ b/src/testmsgr.cc @@ -26,6 +26,7 @@ using namespace std; #include "common/Timer.h" #include "common/common_init.h" +#include "common/ceph_argparse.h" #ifndef DARWIN #include <envz.h> diff --git a/src/tools/ceph.cc b/src/tools/ceph.cc index c8997520da9..9996d4e1fa9 100644 --- a/src/tools/ceph.cc +++ b/src/tools/ceph.cc @@ -13,6 +13,7 @@ * */ +#include "common/ceph_argparse.h" #include "common/common_init.h" #include "common/errno.h" #include "common/safe_io.h" diff --git a/src/tools/gceph.cc b/src/tools/gceph.cc index 55baaebec64..99b66e5ff9e 100644 --- a/src/tools/gceph.cc +++ b/src/tools/gceph.cc @@ -14,6 +14,7 @@ */ #include "common/common_init.h" +#include "common/ceph_argparse.h" #include "config.h" #include "tools/common.h" |