]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
conf: add observer framework
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Tue, 19 Apr 2011 21:24:41 +0000 (14:24 -0700)
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Wed, 20 Apr 2011 00:28:00 +0000 (17:28 -0700)
Objects can now register as configuration observers interested in a
subset of the configuration keys. The observers will be told exactly
which keys have changed.

The first user is dout, which now no longer needs the infamous SIGHUP
hack to know when to reopen the config file.

librados: Remove rados_reopen_log, which was basically a means for the
library user to trigger the SIGHUP behavior.

Changes are accumulated and applied all at once by apply_changes. This
function is called as part of common_init, and after every call to
injectargs.

Signed-off-by: Colin McCabe <colin.mccabe@dreamhost.com>
20 files changed:
src/common/DoutStreambuf.cc
src/common/DoutStreambuf.h
src/common/ceph_argparse.cc
src/common/ceph_argparse.h
src/common/common_init.cc
src/common/config.cc
src/common/config.h
src/common/signal.cc
src/include/rados/librados.h
src/include/rados/librados.hpp
src/librados.cc
src/mds/MDS.cc
src/mon/Monitor.cc
src/osd/OSD.cc
src/pybind/rados.py
src/test/TestDoutStreambuf.cc
src/testlibrbd.c
src/testlibrbdpp.cc
src/testrados.c
src/testradospp.cc

index 18503b838f2e92279ac89c53749eb424c7fea20b..a705eee3b1a721af1f769e5b483f8cd81eebec1f 100644 (file)
@@ -12,6 +12,7 @@
  *
  */
 
+#include "common/code_environment.h"
 #include "common/config.h"
 #include "common/DoutStreambuf.h"
 #include "common/entity_name.h"
@@ -225,7 +226,19 @@ void DoutStreambuf<charT, traits>::handle_stderr_closed()
 }
 
 template <typename charT, typename traits>
-void DoutStreambuf<charT, traits>::read_global_config(const md_config_t *conf)
+const char** DoutStreambuf<charT, traits>::
+get_tracked_conf_keys() const
+{
+  static const char *KEYS[] =
+       { "log_file", "log_dir", "log_sym_dir",
+        "log_sym_history", "log_to_stderr",
+        "log_to_syslog", "log_per_instance", NULL };
+  return KEYS;
+}
+
+template <typename charT, typename traits>
+void DoutStreambuf<charT, traits>::
+handle_conf_change(const md_config_t *conf, const std::set <std::string> &changed)
 {
   DoutLocker _dout_locker;
   type_name = conf->name.get_type_name();
@@ -238,6 +251,11 @@ void DoutStreambuf<charT, traits>::read_global_config(const md_config_t *conf)
   }
 
   if (conf->log_to_syslog) {
+    if ((changed.count("log_to_syslog") || changed.count("name")) &&
+        (g_code_env == CODE_ENVIRONMENT_DAEMON)) {
+      closelog();
+      openlog(g_conf.name.to_cstr(), LOG_ODELAY | LOG_PID, LOG_USER);
+    }
     flags |= DOUTSB_FLAG_SYSLOG;
   }
 
@@ -252,7 +270,7 @@ void DoutStreambuf<charT, traits>::read_global_config(const md_config_t *conf)
        break;
       default:
        ostringstream oss;
-       oss << "DoutStreambuf::read_global_config: can't understand "
+       oss << "DoutStreambuf::handle_conf_change: can't understand "
            << "conf->log_to_stderr = " << conf->log_to_stderr << "\n";
        dout_emergency(oss.str());
        break;
index faf2cbbd44998ad30e4c53ba75880d153924d021..c272f7d7b746d0008c4f360c1a565ba217736c58 100644 (file)
 #ifndef CEPH_DOUT_STREAMBUF_H
 #define CEPH_DOUT_STREAMBUF_H
 
+#include "common/config.h"
+
 #include <iosfwd>
 #include <string>
 
 class md_config_t;
 
 template <typename charT, typename traits = std::char_traits<charT> >
-class DoutStreambuf : public std::basic_streambuf<charT, traits>
+class DoutStreambuf : public std::basic_streambuf<charT, traits>,
+                     public md_config_obs_t
 {
 public:
   enum dout_streambuf_flags_t {
@@ -53,8 +56,10 @@ public:
   // for the error to happen.
   void handle_stderr_closed();
 
-  // Set the flags based on the global configuration
-  void read_global_config(const md_config_t *conf);
+  virtual const char** get_tracked_conf_keys() const;
+
+  virtual void handle_conf_change(const md_config_t *conf,
+                            const std::set <std::string> &changed);
 
   // Set the priority of the messages being put into the stream
   void set_prio(int prio);
index 9583a5d5af1edb9387c5cb90a2b9d337a25ffd90..6a7b6253a5a5facc64dcc50f5898210b860bd136 100644 (file)
@@ -219,23 +219,6 @@ bool parse_ip_port_vec(const char *s, vector<entity_addr_t>& vec)
   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++;
-  }
-  g_conf.parse_argv(nargs);
-}
-
 // The defaults for CephInitParameters
 CephInitParameters::CephInitParameters(uint32_t module_type, const char *conf_file_)
   : conf_file(conf_file_)
index d6c70147573c7a2b0bc662d926e2af2ed6778fed..1b74a41d871fa9e7adb5dee96494ee5396320b3b 100644 (file)
@@ -92,7 +92,6 @@ 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);
 bool ceph_argparse_flag(std::vector<const char*> &args,
        std::vector<const char*>::iterator &i, ...);
 bool ceph_argparse_witharg(std::vector<const char*> &args,
index de533910a45f52a002adf238c0295d0c611dcc02..1c84e033ece64a94ee0533174c5e864b2cedf7a0 100644 (file)
@@ -30,6 +30,9 @@
 #include <deque>
 #include <syslog.h>
 
+#define _STR(x) #x
+#define STRINGIFY(x) _STR(x)
+
 int keyring_init(md_config_t *conf)
 {
   if (!is_supported_auth(CEPH_AUTH_CEPHX))
@@ -90,6 +93,7 @@ md_config_t *common_preinit(const CephInitParameters &iparams,
   // Create a configuration object
   // TODO: de-globalize
   md_config_t *conf = &g_conf; //new md_config_t();
+  // add config observers here
 
   // Set up our entity name.
   conf->name = iparams.name;
@@ -99,13 +103,13 @@ md_config_t *common_preinit(const CephInitParameters &iparams,
     case CODE_ENVIRONMENT_DAEMON:
       conf->daemonize = true;
       if (!(flags & CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS)) {
-       conf->log_dir = "/var/log/ceph";
-       conf->pid_file = "/var/run/ceph/$type.$id.pid";
+       conf->set_val_or_die("log_dir", "/var/log/ceph");
+       conf->set_val_or_die("pid_file", "/var/run/ceph/$type.$id.pid");
       }
-      conf->log_to_stderr = LOG_TO_STDERR_SOME;
+      conf->set_val_or_die("log_to_stderr", STRINGIFY(LOG_TO_STDERR_SOME));
       break;
     default:
-      conf->daemonize = false;
+      conf->set_val_or_die("daemonize", "false");
       break;
   }
 
@@ -165,15 +169,8 @@ void common_init(std::vector < const char* >& args,
     conf->log_per_instance = false;
   }
 
-  conf->expand_all_meta();
-
-  if (conf->log_to_syslog || conf->clog_to_syslog) {
-    closelog();
-    openlog(g_conf.name.to_cstr(), LOG_ODELAY | LOG_PID, LOG_USER);
-  }
-
-  // Force a reopen of dout() with the configuration we have just read.
-  _doss->read_global_config(&g_conf);
+  // Expand metavariables. Invoke configuration observers.
+  conf->apply_changes();
 
   // Now we're ready to complain about config file parse errors
   complain_about_parse_errors(&parse_errors);
index 863aebed971410d2dabd98b82a7fddc1b1b75779..f86288cf6fa2fd1349b38a54c6a1aec74484639e 100644 (file)
 #undef generic_dout
 #undef dendl
 
+using std::map;
+using std::multimap;
+using std::pair;
+using std::set;
+using std::string;
+
 const char *CEPH_CONF_FILE_DEFAULT = "/etc/ceph/ceph.conf, ~/.ceph/config, ceph.conf";
 
 /* The Ceph configuration. */
@@ -449,6 +455,8 @@ md_config_t()
     config_option *opt = config_optionsp + i;
     set_val_from_default(opt);
   }
+
+  add_observer(_doss);
 }
 
 md_config_t::
@@ -456,6 +464,16 @@ md_config_t::
 {
 }
 
+void md_config_t::
+add_observer(md_config_obs_t* observer_)
+{
+  const char **keys = observer_->get_tracked_conf_keys();
+  for (const char ** k = keys; *k; ++k) {
+    obs_map_t::value_type val(*k, observer_);
+    observers.insert(val);
+  }
+}
+
 int md_config_t::
 parse_config_files(const std::list<std::string> &conf_files,
                   std::deque<std::string> *parse_errors)
@@ -519,6 +537,9 @@ parse_env()
 void md_config_t::
 parse_argv(std::vector<const char*>& args)
 {
+  // In this function, don't change any parts of g_conf directly.
+  // Instead, use set_val to set them. This will allow us to send the proper
+  // observer notifications later.
   std::string val;
   for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ) {
     if (ceph_argparse_flag(args, i, "--show_conf", (char*)NULL)) {
@@ -526,39 +547,39 @@ parse_argv(std::vector<const char*>& args)
       _exit(0);
     }
     else if (ceph_argparse_flag(args, i, "--foreground", "-f", (char*)NULL)) {
-      daemonize = false;
-      pid_file = "";
+      set_val_or_die("daemonize", "false");
+      set_val_or_die("pid_file", "");
     }
     else if (ceph_argparse_flag(args, i, "-d", (char*)NULL)) {
-      daemonize = false;
-      log_dir = "";
-      pid_file = "";
-      log_sym_dir = "";
-      log_sym_history = 0;
-      log_to_stderr = LOG_TO_STDERR_ALL;
-      log_to_syslog = false;
-      log_per_instance = false;
+      set_val_or_die("daemonize", "false");
+      set_val_or_die("log_dir", "");
+      set_val_or_die("pid_file", "");
+      set_val_or_die("log_sym_dir", "");
+      set_val_or_die("log_sym_history", "0");
+      set_val_or_die("log_to_stderr", STRINGIFY(LOG_TO_STDERR_ALL));
+      set_val_or_die("log_to_syslog", "false");
+      set_val_or_die("log_per_instance", "false");
     }
     // Some stuff that we wanted to give universal single-character options for
     // Careful: you can burn through the alphabet pretty quickly by adding
     // to this list.
     else if (ceph_argparse_witharg(args, i, &val, "--monmap", "-M", (char*)NULL)) {
-      monmap = val;
+      set_val("monmap", val.c_str());
     }
     else if (ceph_argparse_witharg(args, i, &val, "--mon_host", "-m", (char*)NULL)) {
-      mon_host = val;
+      set_val("mon_host", val.c_str());
     }
     else if (ceph_argparse_witharg(args, i, &val, "--bind", (char*)NULL)) {
-      public_addr.parse(val.c_str());
+      set_val("public_addr", val.c_str());
     }
     else if (ceph_argparse_witharg(args, i, &val, "--keyfile", "-K", (char*)NULL)) {
-      keyfile = val;
+      set_val("keyfile", val.c_str());
     }
     else if (ceph_argparse_witharg(args, i, &val, "--keyring", "-k", (char*)NULL)) {
-      keyring = val;
+      set_val("keyring", val.c_str());
     }
     else if (ceph_argparse_witharg(args, i, &val, "--client_mountpoint", "-r", (char*)NULL)) {
-      client_mountpoint = val;
+      set_val("client_mountpoint", val.c_str());
     }
     else {
       int o;
@@ -583,6 +604,75 @@ parse_argv(std::vector<const char*>& args)
       }
     }
   }
+
+}
+
+void md_config_t::
+apply_changes()
+{
+  /* Maps observers to the configuration options that they care about which
+   * have changed. */
+  typedef std::map < md_config_obs_t*, std::set <std::string> > rev_obs_map_t;
+
+  // Expand all metavariables
+  for (int i = 0; i < NUM_CONFIG_OPTIONS; i++) {
+    config_option *opt = config_optionsp + i;
+    if (opt->type == OPT_STR) {
+      std::string *str = (std::string *)opt->conf_ptr(this);
+      expand_meta(*str);
+    }
+  }
+
+  // create the reverse observer mapping, mapping observers to the set of
+  // changed keys that they'll get.
+  rev_obs_map_t robs;
+  std::set <std::string> empty_set;
+  for (changed_set_t::const_iterator c = changed.begin();
+       c != changed.end(); ++c) {
+    const std::string &key(*c);
+    pair < obs_map_t::iterator, obs_map_t::iterator >
+      range(observers.equal_range(key));
+    for (obs_map_t::iterator r = range.first; r != range.second; ++r) {
+      rev_obs_map_t::value_type robs_val(r->second, empty_set);
+      pair < rev_obs_map_t::iterator, bool > robs_ret(robs.insert(robs_val));
+      std::set <std::string> &keys(robs_ret.first->second);
+      keys.insert(key);
+    }
+  }
+
+  // Make any pending observer callbacks
+  for (rev_obs_map_t::const_iterator r = robs.begin(); r != robs.end(); ++r) {
+    md_config_obs_t *obs = r->first;
+    obs->handle_conf_change(this, r->second);
+  }
+
+  changed.clear();
+}
+
+void md_config_t::
+injectargs(const 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_argv(nargs);
+  apply_changes();
+}
+
+void md_config_t::
+set_val_or_die(const char *key, const char *val)
+{
+  int ret = set_val(key, val);
+  assert(ret == 0);
 }
 
 int md_config_t::
@@ -608,6 +698,7 @@ set_val(const char *key, const char *val)
   return -ENOENT;
 }
 
+
 int md_config_t::
 get_val(const char *key, char **buf, int len) const
 {
@@ -716,6 +807,11 @@ get_val_from_conf_file(const std::vector <std::string> &sections,
 void md_config_t::
 set_val_from_default(const config_option *opt)
 {
+  // set_val_from_default can't fail! Unless the programmer screwed up, and
+  // in that case we'll abort.
+  // Anyway, we know that this function changed something.
+  changed.insert(opt->name);
+
   switch (opt->type) {
     case OPT_INT:
       *(int*)opt->conf_ptr(this) = opt->def_longlong;
@@ -780,6 +876,16 @@ set_val_from_default(const config_option *opt)
 
 int md_config_t::
 set_val_impl(const char *val, const config_option *opt)
+{
+  int ret = set_val_raw(val, opt);
+  if (ret)
+    return ret;
+  changed.insert(opt->name);
+  return 0;
+}
+
+int md_config_t::
+set_val_raw(const char *val, const config_option *opt)
 {
   switch (opt->type) {
     case OPT_INT: {
@@ -847,18 +953,6 @@ set_val_impl(const char *val, const config_option *opt)
   return -ENOSYS;
 }
 
-void md_config_t::
-expand_all_meta()
-{
-  for (int i = 0; i < NUM_CONFIG_OPTIONS; i++) {
-    config_option *opt = config_optionsp + i;
-    if (opt->type == OPT_STR) {
-      std::string *str = (std::string *)opt->conf_ptr(this);
-      expand_meta(*str);
-    }
-  }
-}
-
 static const char *CONF_METAVARIABLES[] =
       { "type", "name", "host", "num", "id" };
 static const int NUM_CONF_METAVARIABLES =
@@ -907,3 +1001,8 @@ expand_meta(std::string &val) const
   val = out;
   return found_meta;
 }
+
+md_config_obs_t::
+~md_config_obs_t()
+{
+}
index 91b8ad9254c867fa5bcc4fad62a1fc0d44de0347..9ed8e3835da7f032c902b88aa61a76fc58259ba4 100644 (file)
@@ -19,6 +19,7 @@ extern struct ceph_file_layout g_default_file_layout;
 
 #include <vector>
 #include <map>
+#include <set>
 
 #include "common/ConfUtils.h"
 #include "common/entity_name.h"
@@ -31,24 +32,40 @@ extern struct ceph_file_layout g_default_file_layout;
 #define OSD_REP_CHAIN   2
 
 class config_option;
+class md_config_obs_t;
 
 extern const char *CEPH_CONF_FILE_DEFAULT;
 
-enum log_to_stderr_t {
-  LOG_TO_STDERR_NONE = 0,
-  LOG_TO_STDERR_SOME = 1,
-  LOG_TO_STDERR_ALL = 2,
-};
+#define LOG_TO_STDERR_NONE 0
+#define LOG_TO_STDERR_SOME 1
+#define LOG_TO_STDERR_ALL 2
 
 template <typename T, typename U>
 class DoutStreambuf;
 
-struct md_config_t
-{
+struct md_config_t {
 public:
+  /* Maps configuration options to the observer listening for them. */
+  typedef std::multimap <std::string, md_config_obs_t*> obs_map_t;
+
+  /* Set of configuration options that have changed since the last
+   * apply_changes */
+  typedef std::set < std::string > changed_set_t;
+
+  // Create a new md_config_t structure.
   md_config_t();
   ~md_config_t();
 
+  // Adds a new observer to this configuration. You can do this at any time,
+  // but it will only receive notifications for the changes that happen after
+  // you attach it, obviously.
+  //
+  // Most developers will probably attach their observers after common_init,
+  // but before anyone can call injectargs.
+  //
+  // The caller is responsible for allocating observers.
+  void add_observer(md_config_obs_t* observer_);
+
   // Parse a config file
   int parse_config_files(const std::list<std::string> &conf_files,
                         std::deque<std::string> *parse_errors);
@@ -59,6 +76,16 @@ public:
   // Absorb config settings from argv
   void parse_argv(std::vector<const char*>& args);
 
+  // Expand all metavariables. Make any pending observer callbacks.
+  void apply_changes();
+
+  // Called by the Ceph daemons to make configuration changes at runtime
+  void injectargs(const std::string &s);
+
+  // Set a configuration value, or crash
+  // Metavariables will be expanded.
+  void set_val_or_die(const char *key, const char *val);
+
   // Set a configuration value.
   // Metavariables will be expanded.
   int set_val(const char *key, const char *val);
@@ -78,9 +105,6 @@ public:
   int get_val_from_conf_file(const std::vector <std::string> &sections,
                   const char *key, std::string &out, bool emeta) const;
 
-  // Perform metavariable expansion on all the data members of md_config_t.
-  void expand_all_meta();
-
   // Expand metavariables in the provided string.
   // Returns true if any metavariables were found and expanded.
   bool expand_meta(std::string &val) const;
@@ -90,10 +114,14 @@ private:
   void set_val_from_default(const config_option *opt);
 
   int set_val_impl(const char *val, const config_option *opt);
+  int set_val_raw(const char *val, const config_option *opt);
 
   // The configuration file we read, or NULL if we haven't read one.
   ConfFile cf;
 
+  obs_map_t observers;
+  changed_set_t changed;
+
 public:
   std::string host;
 
@@ -496,6 +524,14 @@ struct config_option {
   const void *conf_ptr(const md_config_t *conf) const;
 };
 
+class md_config_obs_t {
+public:
+  virtual ~md_config_obs_t();
+  virtual const char** get_tracked_conf_keys() const = 0;
+  virtual void handle_conf_change(const md_config_t *conf,
+                         const std::set <std::string> &changed) = 0;
+};
+
 #include "common/debug.h"
 
 #endif
index 5d740db6c5c8583dd36d88a1d70f24976fbbe1d1..fa479b701ffdc7fa9e0d06e3a9898a7d7ebd538a 100644 (file)
@@ -51,8 +51,10 @@ void install_sighandler(int signum, signal_handler_t handler, int flags)
 
 void sighup_handler(int signum)
 {
-  // do nothing
-  // logger_reopen_all
+  /* In the past, users had to send a SIGHUP to the process after making a
+   * change to certain parts of the logging configuration. Now, this is no
+   * longer necessary. Now we want to ignore SIGHUP signals.
+   */
 }
 
 static void reraise_fatal(int signum)
index 65195548614b60f166a01b99b9e8b62e2ad06280..9fe328522fcf5a409dd0c7df416c140951c999ef 100644 (file)
@@ -76,13 +76,6 @@ int rados_conf_read_file(rados_t cluster, const char *path);
  * Returns 0 on success, error code otherwise. */
 int rados_conf_set(rados_t cluster, const char *option, const char *value);
 
-/* Reopens the log file.
- * You must do this after changing the logging configuration.
- * It is also good practice to call this from your SIGHUP signal handler, so that users can send you
- * a SIGHUP to reopen the log.
- */
-void rados_reopen_log(rados_t cluster);
-
 /* Returns a configuration value as a string.
  * If len is positive, that is the maximum number of bytes we'll write into the
  * buffer. If len == -1, we'll call malloc() and set *buf.
index 593995ba18539a4c92934bba40e0e065d40f5183..5a9b79da8ed68695a3cc6eda9e29a3be4b809786 100644 (file)
@@ -255,7 +255,6 @@ namespace librados
     void shutdown();
     int conf_read_file(const char * const path) const;
     int conf_set(const char *option, const char *value);
-    void reopen_log();
     int conf_get(const char *option, std::string &val);
 
     int pool_create(const char *name);
index b7b8cbeb50133171c304b369591bd96430d167c8..288616ec3cde244e184147103bd0977c4fc6d5f3 100644 (file)
@@ -2643,12 +2643,6 @@ conf_set(const char *option, const char *value)
   return rados_conf_set((rados_t)client, option, value);
 }
 
-void librados::Rados::
-reopen_log()
-{
-  rados_reopen_log((rados_t)client);
-}
-
 int librados::Rados::
 conf_get(const char *option, std::string &val)
 {
@@ -2793,7 +2787,7 @@ extern "C" int rados_create(rados_t *pcluster, const char * const id)
     // configuration
     md_config_t *conf = common_preinit(iparams, CODE_ENVIRONMENT_LIBRARY, 0);
     conf->parse_env(); // environment variables override
-    conf->expand_all_meta(); // future proofing
+    conf->apply_changes();
 
     ++rados_initialized;
   }
@@ -2863,21 +2857,19 @@ extern "C" int rados_conf_read_file(rados_t cluster, const char *path)
   if (ret)
     return ret;
   g_conf.parse_env(); // environment variables override
-  g_conf.expand_all_meta(); // handle metavariables in the config
 
+  g_conf.apply_changes();
   complain_about_parse_errors(&parse_errors);
-
   return 0;
 }
 
 extern "C" int rados_conf_set(rados_t cluster, const char *option, const char *value)
 {
-  return g_conf.set_val(option, value);
-}
-
-extern "C" void rados_reopen_log(rados_t cluster)
-{
-  sighup_handler(SIGHUP);
+  int ret = g_conf.set_val(option, value);
+  if (ret)
+    return ret;
+  g_conf.apply_changes();
+  return 0;
 }
 
 /* cluster info */
index 435848ebf3868365d546ad5da513432e14587672..cd96e64a12b38274f2671152652acbd1de5b047e 100644 (file)
@@ -709,7 +709,7 @@ void MDS::handle_command(MMonCommand *m)
 {
   dout(10) << "handle_command args: " << m->cmd << dendl;
   if (m->cmd[0] == "injectargs")
-    parse_config_option_string(m->cmd[1]);
+    g_conf.injectargs(m->cmd[1]);
   else if (m->cmd[0] == "dumpcache") {
     if (m->cmd.size() > 1)
       mdcache->dump_cache(m->cmd[1].c_str());
index e9bf67458496bffe0e672e28c33fde7e995b6601..476b74f3f2623e366d8ca46e4efcdd37a2c0a147 100644 (file)
@@ -333,7 +333,7 @@ void Monitor::handle_command(MMonCommand *m)
 
     if (m->cmd[0] == "_injectargs") {
       dout(0) << "parsing injected options '" << m->cmd[1] << "'" << dendl;
-      parse_config_option_string(m->cmd[1]);
+      g_conf.injectargs(m->cmd[1]);
       return;
     } 
     if (m->cmd[0] == "class") {
index a39779f585579089b31a138e8785eae2cd951ccc..926273d384d0a8723c34894e555271905ad88f0e 100644 (file)
@@ -2169,7 +2169,7 @@ void OSD::handle_command(MMonCommand *m)
 
   dout(20) << "handle_command args: " << m->cmd << dendl;
   if (m->cmd[0] == "injectargs")
-    parse_config_option_string(m->cmd[1]);
+    g_conf.injectargs(m->cmd[1]);
   else if (m->cmd[0] == "stop") {
     dout(0) << "got shutdown" << dendl;
     shutdown();
index b92c663bd8670b1843b3ce9fbb157779161dba83..449550c41f9cd65e7ff661dd6730d072f71d4be7 100755 (executable)
@@ -143,10 +143,6 @@ Rados object in state %s." % (self.state))
         if (ret != 0):
             raise make_ex(ret, "error calling conf_set")
 
-    def reopen_log(self):
-        self.require_state("configuring", "connected")
-        self.librados.rados_reopen_log(self.cluster);
-
     def connect(self):
         self.require_state("configuring")
         ret = self.librados.rados_connect(self.cluster)
index 93f8b84d01651606819cbb919ac3325b75496e44..8eda5ba3860981f35e545781e64045dc826f603e 100644 (file)
@@ -24,6 +24,7 @@
 #include "common/config.h"
 
 #include <iostream>
+#include <set>
 #include <sstream>
 #include <string>
 #include <syslog.h>
@@ -41,8 +42,12 @@ int main(int argc, const char **argv)
   DoutStreambuf<char> *dos = new DoutStreambuf<char>();
 
   {
+    std::set <std::string> changed;
+    for (const char** t = dos->get_tracked_conf_keys(); *t; ++t) {
+      changed.insert(*t);
+    }
     DoutLocker _dout_locker;
-    dos->read_global_config(&g_conf);
+    dos->handle_conf_change(&g_conf, changed);
   }
   derr << "using configuration: " << dos->config_to_str() << dendl;
 
index 162aa21277253eda15b783b2baa17227d010cb1e..120b47ad1b11f040662a4bb910372dc880afe36c 100644 (file)
@@ -335,7 +335,6 @@ int main(int argc, const char **argv)
 
   assert(rados_create(&cluster, NULL) == 0);
   assert(rados_conf_read_file(cluster, NULL) == 0);
-  rados_reopen_log(cluster);
   assert(rados_connect(cluster) == 0);
 
   if (rados_pool_lookup(cluster, TEST_POOL) != -ENOENT) {
index 61913f2169c4ed33aed72859c567414232b7d0a4..c7882bf83827a1f37e49fbb829430dba1711109e 100644 (file)
@@ -246,7 +246,6 @@ int main(int argc, const char **argv)
   rbd = new librbd::RBD();
   assert(rados.init(NULL) == 0);
   assert(rados.conf_read_file(NULL) == 0);
-  rados.reopen_log();
   assert(rados.connect() == 0);
   if (rados.pool_lookup(TEST_POOL) != -ENOENT) {
     int r = rados.pool_delete(TEST_POOL);
index e1e8247b6d5324c99884209dcebe39a8554edf01..7991f57e684ae36c60cf2bc15071d15e12702c3d 100644 (file)
@@ -52,7 +52,6 @@ int main(int argc, const char **argv)
     printf("error: error setting log_to_stderr\n");
     exit(1);
   }
-  rados_reopen_log(cl);
   if (rados_conf_get(cl, "log to stderr", tmp, sizeof(tmp))) {
     printf("error: failed to read log_to_stderr from config\n");
     exit(1);
index 1caa075b3bee622e41c94c43f272c0138ccbcb0a..a5944d64077ceb478a2ef6409d8be7737ba2ae55 100644 (file)
@@ -66,7 +66,6 @@ int main(int argc, const char **argv)
     printf("error: error setting log_to_stderr\n");
     exit(1);
   }
-  rados.reopen_log();
   std::string tmp;
   if (rados.conf_get("log to stderr", tmp)) {
     printf("error: failed to read log_to_stderr from config\n");