From 56f42144ee6d895c2021642ca46b00ae12e1bee8 Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Wed, 5 Feb 2025 11:21:41 -0500 Subject: [PATCH] pybind/cephfs: wire up mds_command2 Signed-off-by: Patrick Donnelly (cherry picked from commit 72d0a76e8c5cbb357e4f4c355e8630ec8aa02088) --- src/pybind/cephfs/c_cephfs.pxd | 4 +++ src/pybind/cephfs/cephfs.pyx | 50 +++++++++++++++++++++++++++++++ src/pybind/cephfs/mock_cephfs.pxi | 3 ++ 3 files changed, 57 insertions(+) diff --git a/src/pybind/cephfs/c_cephfs.pxd b/src/pybind/cephfs/c_cephfs.pxd index 69d24912b4c49..ddb2659a4dfda 100644 --- a/src/pybind/cephfs/c_cephfs.pxd +++ b/src/pybind/cephfs/c_cephfs.pxd @@ -71,6 +71,10 @@ cdef extern from "cephfs/libcephfs.h" nogil: int ceph_setattrx(ceph_mount_info *cmount, const char *relpath, statx *stx, int mask, int flags) int ceph_fsetattrx(ceph_mount_info *cmount, int fd, statx *stx, int mask) + + ctypedef void (*libcephfs_c_completion_t)(int rc, const void* out, size_t outlen, const void* outs, size_t outslen, void* ud) nogil + int ceph_mds_command2(ceph_mount_info* cmount, const char* mds_spec, const char** cmd, size_t cmdlen, const char* inbuf, size_t inbuflen, int one_shot, libcephfs_c_completion_t c, void* ud) + int ceph_mds_command(ceph_mount_info *cmount, const char *mds_spec, const char **cmd, size_t cmdlen, const char *inbuf, size_t inbuflen, char **outbuf, size_t *outbuflen, char **outs, size_t *outslen) diff --git a/src/pybind/cephfs/cephfs.pyx b/src/pybind/cephfs/cephfs.pyx index b9cd96172c267..b6b810c7ca618 100644 --- a/src/pybind/cephfs/cephfs.pyx +++ b/src/pybind/cephfs/cephfs.pyx @@ -111,6 +111,13 @@ cdef extern from "Python.h": int _PyBytes_Resize(PyObject **string, Py_ssize_t newsize) except -1 void PyEval_InitThreads() +cdef void completion_callback(int rc, const void* out, size_t outlen, const void* outs, size_t outslen, void* ud) nogil: + # This GIL awkwardness is due to incompatible types with function pointers defined with mds_command2: + with gil: + pyout = (out)[:outlen] + pyouts = (outs)[:outslen] + (ud).complete(rc, pyout, pyouts) + ref.Py_DECREF(ud) class Error(Exception): def get_error_code(self): @@ -2280,6 +2287,49 @@ cdef class LibCephFS(object): raise make_ex(ret, "error in rename {} to {}".format(src.decode( 'utf-8'), dst.decode('utf-8'))) + def mds_command2(self, result, mds_spec, args, input_data=None, one_shot=False): + """ + :param: result: a completion object with a complete method accepting an integer rc, bytes output, and bytes error output + :param: mds_spec: the identity of one or more MDS to send the command to (e.g. "*" or "fsname:0") + :param: args: the JSON-encoded MDS command + :param: input_data: optional input data to the command + :param: one_shot: optional boolean indicating if the command should only be tried/sent once + :returns: 0 if command is/will be sent or an exception is raised + """ + + if input_data is None: + input_data = "" + + mds_spec = cstr(mds_spec, 'mds_spec') + args = cstr(args, 'args') + input_data = cstr(input_data, 'input_data') + + cdef: + char *_mds_spec = opt_str(mds_spec) + char **_cmd = to_bytes_array([args]) + size_t _cmdlen = 1 + + char *_inbuf = input_data + size_t _inbuf_len = len(input_data) + + int _one_shot = one_shot + + + try: + with nogil: + ret = ceph_mds_command2(self.cluster, _mds_spec, + _cmd, _cmdlen, + _inbuf, _inbuf_len, + _one_shot, + completion_callback, + result) + if ret == 0: + ref.Py_INCREF(result) + else: + raise make_ex(ret, "error in mds_command2") + finally: + free(_cmd) + def mds_command(self, mds_spec, args, input_data): """ :returns: 3-tuple of output status int, output status string, output data diff --git a/src/pybind/cephfs/mock_cephfs.pxi b/src/pybind/cephfs/mock_cephfs.pxi index 54b27d04c6742..631625e861a34 100644 --- a/src/pybind/cephfs/mock_cephfs.pxi +++ b/src/pybind/cephfs/mock_cephfs.pxi @@ -95,6 +95,9 @@ cdef nogil: pass int ceph_fsetattrx(ceph_mount_info *cmount, int fd, statx *stx, int mask): pass + ctypedef void (*libcephfs_c_completion_t)(int rc, const void* out, size_t outlen, const void* outs, size_t outslen, void* ud) nogil + int ceph_mds_command2(ceph_mount_info* cmount, const char* mds_spec, const char** cmd, size_t cmdlen, const char* inbuf, size_t inbuflen, int one_shot, libcephfs_c_completion_t c, void* ud): + pass int ceph_mds_command(ceph_mount_info *cmount, const char *mds_spec, const char **cmd, size_t cmdlen, const char *inbuf, size_t inbuflen, char **outbuf, size_t *outbuflen, char **outs, size_t *outslen): -- 2.39.5