]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
pybind/rbd: add async mirror image get mode and info methods
authorMykola Golub <mgolub@suse.com>
Mon, 26 Oct 2020 11:09:28 +0000 (11:09 +0000)
committerJason Dillaman <dillaman@redhat.com>
Wed, 10 Feb 2021 18:37:15 +0000 (13:37 -0500)
Signed-off-by: Mykola Golub <mgolub@suse.com>
(cherry picked from commit 13ce488d7aaf60f85429c2e4c036362d61e5f763)

src/pybind/rbd/rbd.pyx
src/test/pybind/test_rbd.py

index 466a2ff292c41ffa3779d629382a0bc42bbe53db..0bdfcf52adeae4b94c51646656cc8ac904254769 100644 (file)
@@ -622,8 +622,14 @@ cdef extern from "rbd/librbd.h" nogil:
                                   size_t info_size)
     void rbd_mirror_image_get_info_cleanup(
         rbd_mirror_image_info_t *mirror_image_info)
+    int rbd_aio_mirror_image_get_info(
+        rbd_image_t image, rbd_mirror_image_info_t *mirror_image_info,
+        size_t info_size, rbd_completion_t c)
     int rbd_mirror_image_get_mode(rbd_image_t image,
                                   rbd_mirror_image_mode_t *mode)
+    int rbd_aio_mirror_image_get_mode(rbd_image_t image,
+                                      rbd_mirror_image_mode_t *mode,
+                                      rbd_completion_t c)
     int rbd_mirror_image_get_global_status(
         rbd_image_t image,
         rbd_mirror_image_global_status_t *mirror_image_global_status,
@@ -5040,6 +5046,53 @@ written." % (self.name, ret, length))
         rbd_mirror_image_get_info_cleanup(&c_info)
         return info
 
+    @requires_not_closed
+    def aio_mirror_image_get_info(self,  oncomplete):
+        """
+         Asynchronously get mirror info for the image.
+
+        oncomplete will be called with the returned info as
+        well as the completion:
+
+        oncomplete(completion, info)
+
+        :param oncomplete: what to do when get info is complete
+        :type oncomplete: completion
+        :returns: :class:`Completion` - the completion object
+        """
+        cdef:
+            Completion completion
+
+        def oncomplete_(completion_v):
+            cdef:
+                Completion _completion_v = completion_v
+                rbd_mirror_image_info_t *c_info = <rbd_mirror_image_info_t *>_completion_v.buf
+            info = {
+                'global_id' : decode_cstr(c_info[0].global_id),
+                'state'     : int(c_info[0].state),
+                'primary'   : c_info[0].primary,
+            }
+            rbd_mirror_image_get_info_cleanup(c_info)
+            return oncomplete(_completion_v, info)
+
+        completion = self.__get_completion(oncomplete_)
+        completion.buf = PyBytes_FromStringAndSize(
+            NULL, sizeof(rbd_mirror_image_info_t))
+        try:
+            completion.__persist()
+            with nogil:
+                ret = rbd_aio_mirror_image_get_info(
+                    self.image, <rbd_mirror_image_info_t *>completion.buf,
+                    sizeof(rbd_mirror_image_info_t), completion.rbd_comp)
+            if ret != 0:
+                raise make_ex(
+                    ret, 'error getting mirror info for image %s' % self.name)
+        except:
+            completion.__unpersist()
+            raise
+
+        return completion
+
     @requires_not_closed
     def mirror_image_get_mode(self):
         """
@@ -5054,6 +5107,48 @@ written." % (self.name, ret, length))
             raise make_ex(ret, 'error getting mirror mode for image %s' % self.name)
         return int(c_mode)
 
+    @requires_not_closed
+    def aio_mirror_image_get_mode(self,  oncomplete):
+        """
+         Asynchronously get mirror mode for the image.
+
+        oncomplete will be called with the returned mode as
+        well as the completion:
+
+        oncomplete(completion, mode)
+
+        :param oncomplete: what to do when get info is complete
+        :type oncomplete: completion
+        :returns: :class:`Completion` - the completion object
+        """
+        cdef:
+            Completion completion
+
+        def oncomplete_(completion_v):
+            cdef Completion _completion_v = completion_v
+            return_value = _completion_v.get_return_value()
+            mode = int((<rbd_mirror_image_mode_t *>_completion_v.buf)[0]) \
+                if return_value >= 0 else None
+            return oncomplete(_completion_v, mode)
+
+        completion = self.__get_completion(oncomplete_)
+        completion.buf = PyBytes_FromStringAndSize(
+            NULL, sizeof(rbd_mirror_image_mode_t))
+        try:
+            completion.__persist()
+            with nogil:
+                ret = rbd_aio_mirror_image_get_mode(
+                    self.image, <rbd_mirror_image_mode_t *>completion.buf,
+                    completion.rbd_comp)
+            if ret != 0:
+                raise make_ex(
+                    ret, 'error getting mirror mode for image %s' % self.name)
+        except:
+            completion.__unpersist()
+            raise
+
+        return completion
+
     @requires_not_closed
     def mirror_image_get_status(self):
         """
index 7242e6646dd5a4f64c7993adcd4aee4a499d8345..03ecdde691c587c7c79465669a62d2795aef9890 100644 (file)
@@ -2208,6 +2208,29 @@ class TestMirroring(object):
         eq(RBD_SNAP_MIRROR_STATE_PRIMARY, snap['mirror']['state'])
 
         # this is a list so that the local cb() can modify it
+        info = [None]
+        def cb(_, _info):
+            info[0] = _info
+
+        comp = self.image.aio_mirror_image_get_info(cb)
+        comp.wait_for_complete_and_cb()
+        assert_not_equal(info[0], None)
+        eq(comp.get_return_value(), 0)
+        eq(sys.getrefcount(comp), 2)
+        info = info[0]
+        global_id = info['global_id']
+        self.check_info(info, global_id, RBD_MIRROR_IMAGE_ENABLED, True)
+
+        mode = [None]
+        def cb(_, _mode):
+            mode[0] = _mode
+
+        comp = self.image.aio_mirror_image_get_mode(cb)
+        comp.wait_for_complete_and_cb()
+        eq(comp.get_return_value(), 0)
+        eq(sys.getrefcount(comp), 2)
+        eq(mode[0], RBD_MIRROR_IMAGE_MODE_SNAPSHOT)
+
         snap_id = [None]
         def cb(_, _snap_id):
             snap_id[0] = _snap_id