From: Samuel Just Date: Fri, 7 Nov 2025 23:56:14 +0000 (+0000) Subject: mgr: add mgr_subinterpreter_modules config X-Git-Tag: testing/wip-pdonnell-testing-20260128.205435-debug~3^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=239b0dc8a9c42449ee1faa1bf78bdcc380345ae2;p=ceph-ci.git mgr: add mgr_subinterpreter_modules config 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 --- diff --git a/src/common/options/CMakeLists.txt b/src/common/options/CMakeLists.txt index 60cdbc3f224..916f55dcfbd 100644 --- a/src/common/options/CMakeLists.txt +++ b/src/common/options/CMakeLists.txt @@ -82,6 +82,8 @@ if(WITH_MGR) endif() endif() +set(mgr_subinterpreter_modules "") + add_options(global) add_options(cephfs-mirror) add_options(crimson) diff --git a/src/common/options/mgr.yaml.in b/src/common/options/mgr.yaml.in index c6bdee1d156..aaddf7cb2d1 100644 --- a/src/common/options/mgr.yaml.in +++ b/src/common/options/mgr.yaml.in @@ -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 diff --git a/src/mgr/PyModule.cc b/src/mgr/PyModule.cc index e412713e210..1c75d70f466 100644 --- a/src/mgr/PyModule.cc +++ b/src/mgr/PyModule.cc @@ -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( + "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; } } diff --git a/src/mgr/PyModule.h b/src/mgr/PyModule.h index c67dfc9a5e5..01cca1d8e27 100644 --- a/src/mgr/PyModule.h +++ b/src/mgr/PyModule.h @@ -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_) {