]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr: implement get_store in StandbyPyModules
authorJohn Spray <john.spray@redhat.com>
Thu, 26 Apr 2018 09:56:56 +0000 (05:56 -0400)
committerJohn Spray <john.spray@redhat.com>
Fri, 27 Apr 2018 13:58:46 +0000 (09:58 -0400)
Signed-off-by: John Spray <john.spray@redhat.com>
src/mgr/BaseMgrStandbyModule.cc
src/mgr/MgrStandby.cc
src/mgr/PyModuleRegistry.cc
src/mgr/PyModuleRegistry.h
src/mgr/StandbyPyModules.cc
src/mgr/StandbyPyModules.h

index b6f6e53255d8619b53e4fa2de7c737061cc8b645..468e970359d2645c97808e75227155f118bdca3e 100644 (file)
@@ -89,8 +89,14 @@ ceph_store_get(BaseMgrStandbyModule *self, PyObject *args)
     return nullptr;
   }
 
+  // Drop GIL for blocking mon command execution
+  PyThreadState *tstate = PyEval_SaveThread();
+
   std::string value;
   bool found = self->this_module->get_store(what, &value);
+
+  PyEval_RestoreThread(tstate);
+
   if (found) {
     dout(10) << "ceph_store_get " << what << " found: " << value.c_str() << dendl;
     return PyString_FromString(value.c_str());
index 9de2e88abc750985d83f2ed91d15b4f297968460..5e267feab693a7572c4873dbed6952bea2fb1237 100644 (file)
@@ -400,7 +400,7 @@ void MgrStandby::handle_mgr_map(MMgrMap* mmap)
       // I am the standby and someone else is active, start modules
       // in standby mode to do redirects if needed
       if (!py_module_registry.is_standby_running()) {
-        py_module_registry.standby_start();
+        py_module_registry.standby_start(monc);
       }
     }
   }
index bd05a68ed737e4da26a0743659f74a03751ae013..3ceb4d0e93934f5d21d85dbf7e0ec8a43b7d8140 100644 (file)
@@ -124,7 +124,7 @@ bool PyModuleRegistry::handle_mgr_map(const MgrMap &mgr_map_)
 
 
 
-void PyModuleRegistry::standby_start()
+void PyModuleRegistry::standby_start(MonClient &mc)
 {
   Mutex::Locker l(lock);
   assert(active_modules == nullptr);
@@ -137,7 +137,7 @@ void PyModuleRegistry::standby_start()
   dout(4) << "Starting modules in standby mode" << dendl;
 
   standby_modules.reset(new StandbyPyModules(
-        mgr_map, module_config, clog));
+        mgr_map, module_config, clog, mc));
 
   std::set<std::string> failed_modules;
   for (const auto &i : modules) {
index c7563c29b9405460f0976f50dac5d19456d81cc5..5fb0148e7102eb12ef15173948d04a1001c9adff 100644 (file)
@@ -96,7 +96,7 @@ public:
                 const std::map<std::string, std::string> &kv_store,
                 MonClient &mc, LogChannelRef clog_, Objecter &objecter_,
                 Client &client_, Finisher &f);
-  void standby_start();
+  void standby_start(MonClient &mc);
 
   bool is_standby_running() const
   {
index 560902eece30a2087abeb28d4723f6aeb9b46867..4909c5d9d1def14a6e5f829cd0dedb0ebf7c9a92 100644 (file)
 
 StandbyPyModules::StandbyPyModules(
     const MgrMap &mgr_map_,
-    PyModuleConfig &module_config, LogChannelRef clog_)
-    : state(module_config),
+    PyModuleConfig &module_config,
+    LogChannelRef clog_,
+    MonClient &monc_)
+    : state(module_config, monc_),
       clog(clog_)
 {
   state.set_mgr_map(mgr_map_);
@@ -123,9 +125,6 @@ int StandbyPyModule::load()
 bool StandbyPyModule::get_config(const std::string &key,
                                  std::string *value) const
 {
-  PyThreadState *tstate = PyEval_SaveThread();
-  PyEval_RestoreThread(tstate);
-
   const std::string global_key = PyModule::config_prefix
     + get_name() + "/" + key;
 
@@ -141,6 +140,52 @@ bool StandbyPyModule::get_config(const std::string &key,
   });
 }
 
+bool StandbyPyModule::get_store(const std::string &key,
+                                std::string *value) const
+{
+
+  const std::string global_key = PyModule::config_prefix
+    + get_name() + "/" + key;
+
+  dout(4) << __func__ << " key: " << global_key << dendl;
+
+  // Active modules use a cache of store values (kept up to date
+  // as writes pass through the active mgr), but standbys
+  // fetch values synchronously to get an up to date value.
+  // It's an acceptable cost because standby modules should not be
+  // doing a lot.
+  
+  MonClient &monc = state.get_monc();
+
+  std::ostringstream cmd_json;
+  cmd_json << "{\"prefix\": \"config-key get\", \"key\": \""
+           << global_key << "\"}";
+
+  bufferlist outbl;
+  std::string outs;
+  C_SaferCond c;
+  monc.start_mon_command(
+      {cmd_json.str()},
+      {},
+      &outbl,
+      &outs,
+      &c);
+
+  int r = c.wait();
+  if (r == -ENOENT) {
+    return false;
+  } else if (r != 0) {
+    // This is some internal error, not meaningful to python modules,
+    // so let them just see no value.
+    derr << __func__ << " error fetching store key '" << global_key << "': "
+         << cpp_strerror(r) << " " << outs << dendl;
+    return false;
+  } else {
+    *value = outbl.to_str();
+    return true;
+  }
+}
+
 std::string StandbyPyModule::get_active_uri() const
 {
   std::string result;
index 2def578b38561176025088040fead9b3fb75a4f7..f443ba67e7947ebeda2ceeb5ae00e279398c048e 100644 (file)
@@ -35,12 +35,13 @@ class StandbyPyModuleState
 
   MgrMap mgr_map;
   PyModuleConfig &module_config;
+  MonClient &monc;
 
 public:
 
   
-  StandbyPyModuleState(PyModuleConfig &module_config_)
-    : module_config(module_config_)
+  StandbyPyModuleState(PyModuleConfig &module_config_, MonClient &monc_)
+    : module_config(module_config_), monc(monc_)
   {}
 
   void set_mgr_map(const MgrMap &mgr_map_)
@@ -50,6 +51,10 @@ public:
     mgr_map = mgr_map_;
   }
 
+  // MonClient does all its own locking so we're happy to hand out
+  // references.
+  MonClient &get_monc() {return monc;};
+
   template<typename Callback, typename...Args>
   void with_mgr_map(Callback&& cb, Args&&...args) const
   {
@@ -84,6 +89,7 @@ class StandbyPyModule : public PyModuleRunner
   }
 
   bool get_config(const std::string &key, std::string *value) const;
+  bool get_store(const std::string &key, std::string *value) const;
   std::string get_active_uri() const;
 
   int load();
@@ -104,7 +110,8 @@ public:
   StandbyPyModules(
       const MgrMap &mgr_map_,
       PyModuleConfig &module_config,
-      LogChannelRef clog_);
+      LogChannelRef clog_,
+      MonClient &monc);
 
   int start_one(PyModuleRef py_module);