]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
pybind/cephfs: wire up mds_command2
authorPatrick Donnelly <pdonnell@ibm.com>
Wed, 5 Feb 2025 16:21:41 +0000 (11:21 -0500)
committerPatrick Donnelly <pdonnell@ibm.com>
Mon, 17 Mar 2025 19:43:21 +0000 (15:43 -0400)
Signed-off-by: Patrick Donnelly <pdonnell@ibm.com>
(cherry picked from commit 72d0a76e8c5cbb357e4f4c355e8630ec8aa02088)

src/pybind/cephfs/c_cephfs.pxd
src/pybind/cephfs/cephfs.pyx
src/pybind/cephfs/mock_cephfs.pxi

index 69d24912b4c492a0448b3e8f6a4fcebd2c664769..ddb2659a4dfda3db4a0516b2c4e508b151bd808d 100644 (file)
@@ -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)
index b9cd96172c26755684b4db832b073b9c3ad07242..b6b810c7ca61833befac4b54a770de8409f6d605 100644 (file)
@@ -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 = (<unsigned char*>out)[:outlen]
+        pyouts = (<unsigned char*>outs)[:outslen]
+        (<object>ud).complete(rc, pyout, pyouts)
+        ref.Py_DECREF(<object>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,
+                                        <const char **>_cmd, _cmdlen,
+                                        <const char*>_inbuf, _inbuf_len,
+                                        _one_shot,
+                                        completion_callback,
+                                        <void*>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
index 54b27d04c6742b7dc57a0f34babd33e54f1f05ef..631625e861a34a80927aaeef7852b281f2fe017b 100644 (file)
@@ -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):