]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common: Split argument parsing into ceph_argparse
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Sun, 20 Feb 2011 17:18:03 +0000 (09:18 -0800)
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Sun, 20 Feb 2011 18:17:11 +0000 (10:17 -0800)
Signed-off-by: Colin McCabe <colin.mccabe@dreamhost.com>
37 files changed:
src/Makefile.am
src/cauthtool.cc
src/cconf.cc
src/cfuse.cc
src/cmds.cc
src/cmon.cc
src/common/ceph_argparse.cc [new file with mode: 0644]
src/common/ceph_argparse.h [new file with mode: 0644]
src/common/common_init.cc
src/config.cc
src/config.h
src/cosd.cc
src/crushtool.cc
src/csyn.cc
src/dumpjournal.cc
src/dupstore.cc
src/libceph.cc
src/librados-config.cc
src/librados.cc
src/librbd.cc
src/mds/MDS.cc
src/mon/MonClient.cc
src/mon/Monitor.cc
src/monmaptool.cc
src/osd/OSD.cc
src/osdmaptool.cc
src/rados.cc
src/rbd.cc
src/rgw/rgw_admin.cc
src/streamtest.cc
src/test/TestDoutStreambuf.cc
src/test/TestSignalHandlers.cc
src/test/TestTimers.cc
src/test_trans.cc
src/testmsgr.cc
src/tools/ceph.cc
src/tools/gceph.cc

index 8b89a8d48d783c46bce045ac1df662758645e6f0..a6ac02feec5a5b95dd51cd24939ae79a91256611 100644 (file)
@@ -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 \
index 8d8e6a55687206531feb2a4edfc2e1d1f354d646..d0c27b331040b94f80fc986395008b774046a2e1 100644 (file)
@@ -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"
index 182a9ee132683c5d180982ae8359ab401bc1d542..47f4385b2f781429fdd0c401069c77c6a1f441de 100644 (file)
@@ -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))) {
index e8ff5694f5a45d4950a4c856c21ee04c4e79457f..a883e227470fbc44210512dc508ed2a0ff27acfd 100644 (file)
@@ -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"
index f23e61ecd0851e65083db3f9fb91b54dd06794ca..7dba179b77ca184ebe0d63eebf3aec99ccec14d9 100644 (file)
@@ -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"
 
index 591b856970b5d7b0f0b0c65cab63d46f8e864631..8fe95e41d7f438118b7770a160073979b734406e 100644 (file)
@@ -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 (file)
index 0000000..af71458
--- /dev/null
@@ -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 (file)
index 0000000..10d1bfe
--- /dev/null
@@ -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
index bf4d8328b299fc69c5d188b6d16fb988c78f61e9..f57d9940f2bd23c4c76665be6fdeab9105eb802d 100644 (file)
 
 #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();
 
index 3c7b3c96a5808a67a9be3192b4efec325a2716de..5c0f558f3638f19faf11bf49de325565d6df16ef 100644 (file)
@@ -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
index 06f40a1ed60f90bf9724c09f8435908b4e6f4eea..9cb17bfe6ad65c739a7ff8fb3c504f1334c08179 100644 (file)
@@ -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"
 
index 5e6a1ba750bb3de19286d3973acac783a3db0457..b851ba50a956c27351993225d93ba34ed4a5e574 100644 (file)
@@ -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"
index 7b381365fdff96e5ed4f19ab103e27a94a1f98ca..ce66368b77fca9ed0ef455b2cdc4f196756bf184 100644 (file)
@@ -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"
index 2c1fe24978d3c5342758d8121c7017ec8d913594..b3c7d8250552cf4fd3e7f787a7f3866cd7ee911d 100644 (file)
@@ -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>
index bf6f77076e1534bdba2eea591839f1ee65a3dd53..34fb541103bef31bb424fc27885e3abad1903234 100644 (file)
@@ -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>
index bf0b58702a3ea6ba53433c63411841be5642774e..ccbcb359b3af66c90c023cc8ef9242fa952e6b46 100644 (file)
@@ -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>
index a792ea8871a745a12b74faeeebec19b370b6c9ff..705ffed26877a46e1998ecdb324813fb713399a2 100644 (file)
@@ -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"
index a3f125c68d895450398b3757b7f7d908d72a7cd9..2b229761702c75abdf5bdbd44ca9853ca4ff5775 100644 (file)
@@ -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"
 
index 05a3f98e647cd3185b055e53113cb899ac71c45e..59086741e63d8ce96c09a4a2f9ba8451016810e5 100644 (file)
@@ -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"
 
index 651c9020c0b88ceed5b06acc68421e5ce9019027..bdf931a2099c4cddb1965887622fc09d30c9bf39 100644 (file)
@@ -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"
index b1c98c1fe489bcd983846e9ec98f475d3bbe1fad..1837f650e8d5106337daeb9cbb8c7fd312867d37 100644 (file)
@@ -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"
index a70dae48eb6874cffdbc14ef2f50fe94bdb2bbf8..e57b80e0d21798026ca6e81c433c546976ce5c72 100644 (file)
@@ -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"
index 6f543df7d5ed909ebfba9a60b068d599a96cb6c2..a10f49247458c5552c57fe2b44159bbb6bd76bd6 100644 (file)
@@ -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"
index f45fdb7c14e4c893073d10a75e61b9e879d216bb..0e09ef7e9641f6614d3768b00b0abcb12f8e4cd6 100644 (file)
@@ -23,6 +23,7 @@
 using namespace std;
 
 #include "config.h"
+#include "common/ceph_argparse.h"
 #include "common/common_init.h"
 #include "mon/MonMap.h"
 
index 0f9e37275344be0c20b7e18d108aa893e2b69860..aa457f325d9b941152234bb474c417b3a3bce2e8 100644 (file)
@@ -20,6 +20,7 @@
 #include "OSDMap.h"
 #include "Watch.h"
 
+#include "common/ceph_argparse.h"
 #include "os/FileStore.h"
 
 #ifdef USE_OSBDB
index e9d42a542757f0a18fa3972b0fa2340750adebfd..19802528c6727d2714a539f503394cfd04f8b139 100644 (file)
@@ -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()
index 358e0bce9e269b4318f61652475748ce2bf45746..24be8000bb8e190bedaa145c243cdb40704a7b16 100644 (file)
@@ -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"
index ca443c4a617f73c5809d3d333414c87372621118..09f0a21661cd3e2525c18d28138cceea2c58a87b 100644 (file)
@@ -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"
index fd5cd4adeb6e309333d4a40353bfb3017b2b0c88..8586ee6e890fda881cfca4697ca35b704cba15ea 100644 (file)
@@ -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"
index 003d837eb23854af0b7624093c27bca2478ca15d..1a6261ba0d0fc68461482e37df45ff02babd20c5 100644 (file)
@@ -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
index 769b9b9024b37b1f85869a6517d6d6d0467c2d69..c37b96322c0bb7c6d584121ea27e8d9fba878692 100644 (file)
@@ -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"
 
index dbb24d332ac102765a8fb3b06ad825461fbc235a..3f12e1e681dce0f94c8c5e484539f2cb49f36054 100644 (file)
@@ -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"
index e7cb941f08c392164a129869bd3bf1378bd17eb1..1b96b6d450930410c4be18be556ae1af034ecad3 100644 (file)
@@ -1,3 +1,4 @@
+#include "common/ceph_argparse.h"
 #include "common/Mutex.h"
 #include "common/Timer.h"
 #include "common/common_init.h"
index 33ea99ffed386447843bc90ffabed9f7628054c5..ee631d2cb478bb0c38cb90abcff3ac733e8fcd41 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <iostream>
 //#include "ebofs/Ebofs.h"
+#include "common/ceph_argparse.h"
 #include "os/FileStore.h"
 #include "common/common_init.h"
 
index 88e4aaed5996f23656b7c72f862cb3023d7756fe..e0b6a074fbea0a93540ae8e4d25f8eead8b72de1 100644 (file)
@@ -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>
index c8997520da90cc53b827d5c4eb000ee894aab903..9996d4e1fa9b5e283ea485f324d6269ef9975fce 100644 (file)
@@ -13,6 +13,7 @@
  *
  */
 
+#include "common/ceph_argparse.h"
 #include "common/common_init.h"
 #include "common/errno.h"
 #include "common/safe_io.h"
index 55baaebec6433d8e89ad07305ab43d736a5f5108..99b66e5ff9e60702deb28ec9985df240a1add9f2 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include "common/common_init.h"
+#include "common/ceph_argparse.h"
 #include "config.h"
 #include "tools/common.h"