]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mgr: add mgr_subinterpreter_modules config
authorSamuel Just <sjust@redhat.com>
Fri, 7 Nov 2025 23:56:14 +0000 (23:56 +0000)
committerSamuel Just <sjust@redhat.com>
Tue, 27 Jan 2026 00:29:03 +0000 (00:29 +0000)
This commit adds a mgr_subinterpreter_modules config to cause specified
modules (or all if * is specified) to be loaded in individual
subinterpreters.

This changes the default behavior of ceph-mgr from running each module
in a distinct subinterpreter to running them all in the same main
interpreter.  We can reintroduce subinterpreter support over time by
adding modules to the list as we test them.

Fixes: https://tracker.ceph.com/issues/73857
Fixes: https://tracker.ceph.com/issues/73859
Signed-off-by: Samuel Just <sjust@redhat.com>
src/common/options/CMakeLists.txt
src/common/options/mgr.yaml.in
src/mgr/PyModule.cc
src/mgr/PyModule.h

index 60cdbc3f224b8bc2795c73ed1e621f4df17dd0e8..916f55dcfbd3a2f567b406b80b67c021cf6673d2 100644 (file)
@@ -82,6 +82,8 @@ if(WITH_MGR)
   endif()
 endif()
 
+set(mgr_subinterpreter_modules "")
+
 add_options(global)
 add_options(cephfs-mirror)
 add_options(crimson)
index c6bdee1d156dad88ea09473ce6d421396a24090c..aaddf7cb2d1a66a31c2e7ae8dfb412e135e3e400 100644 (file)
@@ -145,6 +145,19 @@ options:
   - mgr_module_path
   flags:
   - startup
+- name: mgr_subinterpreter_modules
+  type: str
+  level: advanced
+  desc: List of manager modules to load in independent subinterpreters
+  long_desc: A comma delimited list of module names. This list is read by manager
+    when it starts. By default, manager loads each module into the main interpreter.
+    Modules in this list will instead be loaded into independent subinterpreters.
+    Specifying '*' will cause all modules to be run in independent subinterpreters.
+  default: @mgr_subinterpreter_modules@
+  services:
+  - mgr
+  flags:
+  - startup
 - name: mgr_initial_modules
   type: str
   level: basic
index e412713e2102d72f26c9632c37432be285d21e9a..1c75d70f4663465dee92b3ca6e053b8722da59c9 100644 (file)
@@ -23,6 +23,7 @@
 #include "include/stringify.h"
 #include "common/BackTrace.h"
 #include "common/JSONFormatter.h"
+#include "common/split.h"
 #include "global/signal_handler.h"
 
 #include "common/debug.h"
@@ -335,8 +336,23 @@ int PyModule::load(PyThreadState *pMainThreadState)
 {
   ceph_assert(pMainThreadState != nullptr);
 
-  // Configure sub-interpreter
-  {
+  const auto subinterpreter_modules_opt = g_conf().get_val<std::string>(
+    "mgr_subinterpreter_modules"
+  );
+  auto subinterpreter_modules = ceph::split(subinterpreter_modules_opt);
+  use_main_interpreter = std::count(
+    subinterpreter_modules.begin(), subinterpreter_modules.end(), "*"
+  ) == 0 && std::count(
+    subinterpreter_modules.begin(), subinterpreter_modules.end(), module_name
+  ) == 0;
+
+  if (use_main_interpreter) {
+    // Use main interpreter
+    derr << "Loading module " << module_name << " in main interpreter" << dendl;
+    pMyThreadState.set(pMainThreadState);
+  } else {
+    // Configure sub-interpreter
+    derr << "Loading module " << module_name << " in sub-interpreter" << dendl;
     SafeThreadState sts(pMainThreadState);
     Gil gil(sts);
 
@@ -348,6 +364,7 @@ int PyModule::load(PyThreadState *pMainThreadState)
       pMyThreadState.set(thread_state);
     }
   }
+
   // Environment is all good, import the external module
   {
     Gil gil(pMyThreadState);
@@ -768,7 +785,9 @@ PyModule::~PyModule()
     Py_XDECREF(pClass);
     Py_XDECREF(pStandbyClass);
     Py_XDECREF(pPickleModule);
-    Py_EndInterpreter(pMyThreadState.ts);
+    if (use_main_interpreter) {
+      Py_EndInterpreter(pMyThreadState.ts);
+    }
     pMyThreadState.ts = nullptr;
   }
 }
index c67dfc9a5e5e6862e668da4690dab45969514040..01cca1d8e27ed274ec0699ce1b05a7c3a0fd9189 100644 (file)
@@ -105,6 +105,9 @@ public:
   PyObject *pStandbyClass = nullptr;
   PyObject *pPickleModule = nullptr;
 
+  // true unless module in mgr_subinterpreter_modules
+  bool use_main_interpreter = true;
+
   explicit PyModule(const std::string &module_name_)
     : module_name(module_name_)
   {