From: Patrick Donnelly Date: Tue, 3 Mar 2026 16:36:12 +0000 (-0500) Subject: mgr: add ceph binding for exit X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=377b7e81dafabed3b72cb564a0af83cbcd1a5e9e;p=ceph.git mgr: add ceph binding for exit So we can work around modules disabling calls to sys._exit Fixes: https://tracker.ceph.com/issues/74605 Fixes: 78983ad0d0cce422da32dc4876ac186f6d32c3f5 Fixes: ceph/ceph.git#66244 Signed-off-by: Patrick Donnelly (cherry picked from commit 378a21aa4076e536d17bb9c8ab749b12d9647174) --- diff --git a/src/mgr/BaseMgrModule.cc b/src/mgr/BaseMgrModule.cc index 7a57246db30f..5855c67f8281 100644 --- a/src/mgr/BaseMgrModule.cc +++ b/src/mgr/BaseMgrModule.cc @@ -1480,7 +1480,39 @@ ceph_get_daemon_health_metrics(BaseMgrModule *self, PyObject *args) return self->py_modules->get_daemon_health_metrics(); } +static PyObject* +ceph_exit(BaseMgrModule *self, PyObject *args, PyObject *kwargs) +{ + int status = 0; + int hard = 0; + static const char *keywords[] = { "status", "hard", nullptr }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|p:ceph_exit", + const_cast(keywords), &status, &hard)) { + return nullptr; + } + + + if (hard) { + // Immediate OS-level termination via syscall exit_group or similar. + // XXX DO NOT RELEASE THE GIL + ::_exit(status); + } else { + // Standard C library exit (runs atexit handlers, flushes stdio) + // It is good practice to release the GIL before abruptly terminating the C process. + PyThreadState *tstate = PyEval_SaveThread(); + std::exit(status); + PyEval_RestoreThread(tstate); + } + ceph_abort(); + + Py_RETURN_NONE; +} + PyMethodDef BaseMgrModule_methods[] = { + {"_ceph_exit", (PyCFunction)ceph_exit, METH_VARARGS | METH_KEYWORDS, + "Exit the ceph-mgr process directly, bypassing Python's sys/os modules."}, + {"_ceph_get", (PyCFunction)ceph_state_get, METH_VARARGS, "Get a cluster object"}, diff --git a/src/pybind/mgr/ceph_module.pyi b/src/pybind/mgr/ceph_module.pyi index 9c9e4c0d339a..d5eac8babfc4 100644 --- a/src/pybind/mgr/ceph_module.pyi +++ b/src/pybind/mgr/ceph_module.pyi @@ -63,6 +63,7 @@ PerfCounterT = Dict[str, Any] class BaseMgrModule(object): def __init__(self, py_modules_ptr: object, this_ptr: object) -> None: pass + def _ceph_exit(self, status: int, hard: bool = False) -> None: ... def _ceph_get_version(self) -> str: ... def _ceph_get_release_name(self) -> str: ... def _ceph_lookup_release_name(self, release: int) -> str: ...