]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr: maintain a ConfigMap copy
authorSage Weil <sage@newdream.net>
Tue, 16 Feb 2021 22:06:35 +0000 (17:06 -0500)
committerSage Weil <sage@newdream.net>
Wed, 17 Feb 2021 17:27:58 +0000 (12:27 -0500)
Signed-off-by: Sage Weil <sage@newdream.net>
src/mgr/ActivePyModules.cc
src/mgr/ActivePyModules.h
src/mgr/CMakeLists.txt

index 7c81c736a50c6faf4596d8d7050f5054252e6ffc..6ca2b49e2fdf0fb3fd1adee0e867d9eca1ee3aa2 100644 (file)
@@ -53,6 +53,10 @@ ActivePyModules::ActivePyModules(
   server(server), py_module_registry(pmr)
 {
   store_cache = std::move(store_data);
+  // we can only trust our ConfigMap if the mon cluster has provided
+  // kv sub since our startup.
+  have_local_config_map = mon_provides_kv_sub;
+  _refresh_config_map();
   cmd_finisher.start();
 }
 
@@ -767,6 +771,7 @@ void ActivePyModules::update_kv_data(
   const map<std::string, boost::optional<bufferlist>, std::less<>>& data)
 {
   std::lock_guard l(lock);
+  bool do_config = false;
   if (!incremental) {
     dout(10) << "full update on " << prefix << dendl;
     auto p = store_cache.lower_bound(prefix);
@@ -785,6 +790,68 @@ void ActivePyModules::update_kv_data(
       dout(20) << " rm " << i.first << dendl;
       store_cache.erase(i.first);
     }
+    if (i.first.find("config/") == 0) {
+      do_config = true;
+    }
+  }
+  if (do_config) {
+    _refresh_config_map();
+  }
+}
+
+void ActivePyModules::_refresh_config_map()
+{
+  dout(10) << dendl;
+  config_map.clear();
+  for (auto p = store_cache.lower_bound("config/");
+       p != store_cache.end() && p->first.find("config/") == 0;
+       ++p) {
+    string key = p->first.substr(7);
+    if (key.find("mgr/") == 0) {
+      // NOTE: for now, we ignore module options.  see also ceph_foreign_option_get().
+      continue;
+    }
+    string value = p->second;
+    string name;
+    string who;
+    config_map.parse_key(key, &name, &who);
+
+    const Option *opt = g_conf().find_option(name);
+    if (!opt) {
+      config_map.stray_options.push_back(
+       std::unique_ptr<Option>(
+         new Option(name, Option::TYPE_STR, Option::LEVEL_UNKNOWN)));
+      opt = config_map.stray_options.back().get();
+    }
+
+    string err;
+    int r = opt->pre_validate(&value, &err);
+    if (r < 0) {
+      dout(10) << __func__ << " pre-validate failed on '" << name << "' = '"
+              << value << "' for " << name << dendl;
+    }
+
+    MaskedOption mopt(opt);
+    mopt.raw_value = value;
+    string section_name;
+    if (who.size() &&
+       !ConfigMap::parse_mask(who, &section_name, &mopt.mask)) {
+      derr << __func__ << " invalid mask for key " << key << dendl;
+    } else if (opt->has_flag(Option::FLAG_NO_MON_UPDATE)) {
+      dout(10) << __func__ << " NO_MON_UPDATE option '"
+              << name << "' = '" << value << "' for " << name
+              << dendl;
+    } else {
+      Section *section = &config_map.global;;
+      if (section_name.size() && section_name != "global") {
+       if (section_name.find('.') != std::string::npos) {
+         section = &config_map.by_id[section_name];
+       } else {
+         section = &config_map.by_type[section_name];
+       }
+      }
+      section->options.insert(make_pair(name, std::move(mopt)));
+    }
   }
 }
 
index b59c0dff36c921d0501294fda02cc8f8737242df..d28ffa054e42c256c3d28ff7c7c560b616ba9692 100644 (file)
@@ -26,6 +26,7 @@
 #include "mon/MgrMap.h"
 #include "mon/MonCommand.h"
 #include "mon/mon_types.h"
+#include "mon/ConfigMap.h"
 
 #include "DaemonState.h"
 #include "ClusterState.h"
@@ -46,6 +47,7 @@ class ActivePyModules
   PyModuleConfig &module_config;
   bool have_local_config_map = false;
   std::map<std::string, std::string> store_cache;
+  ConfigMap config_map;  ///< derived from store_cache config/ keys
   DaemonStateIndex &daemon_state;
   ClusterState &cluster_state;
   MonClient &monc;
@@ -169,6 +171,7 @@ public:
     const std::string prefix,
     bool incremental,
     const map<std::string, boost::optional<bufferlist>, std::less<>>& data);
+  void _refresh_config_map();
 
   // Public so that MonCommandCompletion can use it
   // FIXME: for send_command completion notifications,
index 0d9cbdf34446b4e5df0b0ce0fd10a8d1dbf6a366..f2187407a88a83456f17e54b34485edcee96573b 100644 (file)
@@ -5,6 +5,7 @@ if(WITH_MGR)
   set(mgr_srcs
     ${CMAKE_SOURCE_DIR}/src/ceph_mgr.cc
     ${CMAKE_SOURCE_DIR}/src/mon/PGMap.cc
+    ${CMAKE_SOURCE_DIR}/src/mon/ConfigMap.cc
     ActivePyModule.cc
     ActivePyModules.cc
     BaseMgrModule.cc