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,
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):
"""
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):
"""
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