]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr: only queue notify events that modules ask for 44162/head
authorSage Weil <sage@newdream.net>
Thu, 2 Dec 2021 15:23:45 +0000 (10:23 -0500)
committerSage Weil <sage@newdream.net>
Fri, 3 Dec 2021 02:15:47 +0000 (21:15 -0500)
Signed-off-by: Sage Weil <sage@newdream.net>
src/mgr/ActivePyModules.cc
src/mgr/PyModule.cc
src/mgr/PyModule.h
src/mgr/PyModuleRegistry.h
src/pybind/mgr/mgr_module.py

index 27b1baf8d1edbad1d4749cd955b5cd5817505a13..a389eaa105827aa1666d3dbf351e46fb58ede0f7 100644 (file)
@@ -539,9 +539,12 @@ void ActivePyModules::notify_all(const std::string &notify_type,
 
   dout(10) << __func__ << ": notify_all " << notify_type << dendl;
   for (auto& [name, module] : modules) {
+    if (!py_module_registry.should_notify(name, notify_type)) {
+      continue;
+    }
     // Send all python calls down a Finisher to avoid blocking
     // C++ code, and avoid any potential lock cycles.
-    dout(15) << "queuing notify to " << name << dendl;
+    dout(15) << "queuing notify (" << notify_type << ") to " << name << dendl;
     // workaround for https://bugs.llvm.org/show_bug.cgi?id=35984
     finisher.queue(new LambdaContext([module=module, notify_type, notify_id]
       (int r){
@@ -556,6 +559,9 @@ void ActivePyModules::notify_all(const LogEntry &log_entry)
 
   dout(10) << __func__ << ": notify_all (clog)" << dendl;
   for (auto& [name, module] : modules) {
+    if (!py_module_registry.should_notify(name, "clog")) {
+      continue;
+    }
     // Send all python calls down a Finisher to avoid blocking
     // C++ code, and avoid any potential lock cycles.
     //
index 87100c50421ef173729abb803ea1d2ae59a9fa1b..084cf3ffc1eac44e784b122928c729091f216327 100644 (file)
@@ -398,6 +398,8 @@ int PyModule::load(PyThreadState *pMainThreadState)
       return r;
     }
 
+    load_notify_types();
+
     // We've imported the module and found a MgrModule subclass, at this
     // point the module is considered loaded.  It might still not be
     // runnable though, can_run populated later...
@@ -509,6 +511,39 @@ int PyModule::register_options(PyObject *cls)
   return 0;
 }
 
+int PyModule::load_notify_types()
+{
+  PyObject *ls = PyObject_GetAttrString(pClass, "NOTIFY_TYPES");
+  if (ls == nullptr) {
+    derr << "Module " << get_name() << " has missing NOTIFY_TYPES member" << dendl;
+    return -EINVAL;
+  }
+  if (!PyObject_TypeCheck(ls, &PyList_Type)) {
+    // Relatively easy mistake for human to make, e.g. defining COMMANDS
+    // as a {} instead of a []
+    derr << "Module " << get_name() << " has NOTIFY_TYPES that is not a list" << dendl;
+    return -EINVAL;
+  }
+
+  const size_t list_size = PyList_Size(ls);
+  for (size_t i = 0; i < list_size; ++i) {
+    PyObject *notify_type = PyList_GetItem(ls, i);
+    ceph_assert(notify_type != nullptr);
+
+    if (!PyObject_TypeCheck(notify_type, &PyUnicode_Type)) {
+      derr << "Module " << get_name() << " has non-string entry in NOTIFY_TYPES list"
+          << dendl;
+      return -EINVAL;
+    }
+
+    notify_types.insert(PyUnicode_AsUTF8(notify_type));
+  }
+  Py_DECREF(ls);
+  dout(10) << "Module " << get_name() << " notify_types " << notify_types << dendl;
+
+  return 0;
+}
+
 int PyModule::load_commands()
 {
   PyObject *pRegCmd = PyObject_CallMethod(pClass,
index fbb56080efa4a77746cf18f54068dd86ecbd594f..8d88ff94c6271cd0c65a3ee04752f10b499daff8 100644 (file)
@@ -87,6 +87,9 @@ private:
   int load_options();
   std::map<std::string, MgrMap::ModuleOption> options;
 
+  int load_notify_types();
+  std::set<std::string> notify_types;
+
 public:
   static std::string mgr_store_prefix;
 
@@ -154,6 +157,10 @@ public:
   bool is_loaded() const { std::lock_guard l(lock) ; return loaded; }
   bool is_always_on() const { std::lock_guard l(lock) ; return always_on; }
 
+  bool should_notify(const std::string& notify_type) const {
+    return notify_types.count(notify_type);
+  }
+
   const std::string &get_name() const {
     std::lock_guard l(lock) ; return module_name;
   }
index 19360b3fa2ded0916c5d4a464367e6e02248a16f..4cd98e8827e487f7308146469020733d1e2d2640 100644 (file)
@@ -191,6 +191,11 @@ public:
     }
   }
 
+  bool should_notify(const std::string& name,
+                    const std::string& notify_type) {
+    return modules.at(name)->should_notify(notify_type);
+  }
+
   std::map<std::string, std::string> get_services() const
   {
     ceph_assert(active_modules);
index 66382fb3beaaf318649ad3f875d6bdcae82503b0..7f45ad0b75f83108006f8b07a7bf39dac6c61083 100644 (file)
@@ -1189,7 +1189,9 @@ class MgrModule(ceph_module.BaseMgrModule, MgrModuleLoggingMixin):
     def notify(self, notify_type: NotifyType, notify_id: str) -> None:
         """
         Called by the ceph-mgr service to notify the Python plugin
-        that new state is available.
+        that new state is available.  This method is *only* called for
+        notify_types that are listed in the NOTIFY_TYPES string list
+        member of the module class.
 
         :param notify_type: string indicating what kind of notification,
                             such as osd_map, mon_map, fs_map, mon_status,