]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr: add ceph binding for exit
authorPatrick Donnelly <pdonnell@ibm.com>
Tue, 3 Mar 2026 16:36:12 +0000 (11:36 -0500)
committerPatrick Donnelly <pdonnell@ibm.com>
Tue, 21 Apr 2026 15:25:28 +0000 (11:25 -0400)
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 <pdonnell@ibm.com>
(cherry picked from commit 378a21aa4076e536d17bb9c8ab749b12d9647174)

src/mgr/BaseMgrModule.cc
src/pybind/mgr/ceph_module.pyi

index 7a57246db30f71ad2ca8f2369348b081f33ccaba..5855c67f8281919479685bf9ba479bdd39eb05f8 100644 (file)
@@ -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<char**>(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"},
 
index 9c9e4c0d339a8c94ae724c9124a55dd7fcf34614..d5eac8babfc4ad594682e7159eb8921f1041e726 100644 (file)
@@ -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: ...