summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>2011-02-20 09:18:03 -0800
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>2011-02-20 10:17:11 -0800
commit2a59b2132fae02b2b136b0bab0d3cacdfe288217 (patch)
treeae7ad07c8ce59aa71d148592044f13f837524031 /src
parent349cb128597f84b80a5177de57013bdfee48ff22 (diff)
downloadceph-2a59b2132fae02b2b136b0bab0d3cacdfe288217.tar.gz
common: Split argument parsing into ceph_argparse
Signed-off-by: Colin McCabe <colin.mccabe@dreamhost.com>
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/cauthtool.cc1
-rw-r--r--src/cconf.cc16
-rw-r--r--src/cfuse.cc1
-rw-r--r--src/cmds.cc1
-rw-r--r--src/cmon.cc1
-rw-r--r--src/common/ceph_argparse.cc334
-rw-r--r--src/common/ceph_argparse.h64
-rw-r--r--src/common/common_init.cc31
-rw-r--r--src/config.cc347
-rw-r--r--src/config.h53
-rw-r--r--src/cosd.cc1
-rw-r--r--src/crushtool.cc1
-rw-r--r--src/csyn.cc1
-rw-r--r--src/dumpjournal.cc1
-rw-r--r--src/dupstore.cc1
-rw-r--r--src/libceph.cc1
-rw-r--r--src/librados-config.cc1
-rw-r--r--src/librados.cc1
-rw-r--r--src/librbd.cc1
-rw-r--r--src/mds/MDS.cc1
-rw-r--r--src/mon/MonClient.cc1
-rw-r--r--src/mon/Monitor.cc1
-rw-r--r--src/monmaptool.cc1
-rw-r--r--src/osd/OSD.cc1
-rw-r--r--src/osdmaptool.cc1
-rw-r--r--src/rados.cc1
-rw-r--r--src/rbd.cc1
-rw-r--r--src/rgw/rgw_admin.cc1
-rw-r--r--src/streamtest.cc1
-rw-r--r--src/test/TestDoutStreambuf.cc1
-rw-r--r--src/test/TestSignalHandlers.cc1
-rw-r--r--src/test/TestTimers.cc1
-rw-r--r--src/test_trans.cc1
-rw-r--r--src/testmsgr.cc1
-rw-r--r--src/tools/ceph.cc1
-rw-r--r--src/tools/gceph.cc1
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 *> &sections,
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 *> &sections,
}
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 *> &sections,
{
// 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"