int rbd_mirror_image_demote(rbd_image_t image)
int rbd_mirror_image_resync(rbd_image_t image)
int rbd_mirror_image_create_snapshot(rbd_image_t image, uint64_t *snap_id)
+ int rbd_aio_mirror_image_create_snapshot(rbd_image_t image, uint32_t flags,
+ uint64_t *snap_id,
+ rbd_completion_t c)
int rbd_mirror_image_get_info(rbd_image_t image,
rbd_mirror_image_info_t *mirror_image_info,
size_t info_size)
"""
Create mirror snapshot.
- :param force: ignore mirror snapshot limit
- :type force: bool
:returns: int - the snapshot Id
"""
cdef:
self.name)
return snap_id
+ @requires_not_closed
+ def aio_mirror_image_create_snapshot(self, flags, oncomplete):
+ """
+ Asynchronously create mirror snapshot.
+
+ Raises :class:`InvalidArgument` if the image is not in mirror
+ snapshot mode.
+
+ oncomplete will be called with the created snap ID as
+ well as the completion:
+
+ oncomplete(completion, snap_id)
+
+ :param flags: create snapshot flags
+ :type flags: int
+ :param oncomplete: what to do when the read is complete
+ :type oncomplete: completion
+ :returns: :class:`Completion` - the completion object
+ :raises: :class:`InvalidArgument`
+ """
+ cdef:
+ uint32_t _flags = flags
+ Completion completion
+
+ def oncomplete_(completion_v):
+ cdef Completion _completion_v = completion_v
+ return_value = _completion_v.get_return_value()
+ snap_id = <object>(<uint64_t *>_completion_v.buf)[0] \
+ if return_value >= 0 else None
+ return oncomplete(_completion_v, snap_id)
+
+ completion = self.__get_completion(oncomplete_)
+ completion.buf = PyBytes_FromStringAndSize(NULL, sizeof(uint64_t))
+ try:
+ completion.__persist()
+ with nogil:
+ ret = rbd_aio_mirror_image_create_snapshot(self.image, _flags,
+ <uint64_t *>completion.buf,
+ completion.rbd_comp)
+ if ret < 0:
+ raise make_ex(ret, 'error creating mirror snapshot for image %s' %
+ self.name)
+ except:
+ completion.__unpersist()
+ raise
+
+ return completion
+
@requires_not_closed
def mirror_image_get_info(self):
"""
self.rbd.mirror_peer_remove(ioctx, peer2_uuid)
self.image.mirror_image_promote(False)
+ def test_aio_mirror_image_create_snapshot(self):
+ peer_uuid = self.rbd.mirror_peer_add(ioctx, "cluster", "client")
+ self.rbd.mirror_mode_set(ioctx, RBD_MIRROR_MODE_IMAGE)
+ self.image.mirror_image_disable(False)
+ self.image.mirror_image_enable(RBD_MIRROR_IMAGE_MODE_SNAPSHOT)
+
+ snaps = list(self.image.list_snaps())
+ eq(1, len(snaps))
+ snap = snaps[0]
+ eq(snap['namespace'], RBD_SNAP_NAMESPACE_TYPE_MIRROR)
+ eq(RBD_SNAP_MIRROR_STATE_PRIMARY, snap['mirror']['state'])
+
+ # this is a list so that the local cb() can modify it
+ snap_id = [None]
+ def cb(_, _snap_id):
+ snap_id[0] = _snap_id
+
+ comp = self.image.aio_mirror_image_create_snapshot(0, cb)
+ comp.wait_for_complete_and_cb()
+ assert_not_equal(snap_id[0], None)
+ eq(comp.get_return_value(), 0)
+ eq(sys.getrefcount(comp), 2)
+
+ snaps = list(self.image.list_snaps())
+ eq(2, len(snaps))
+ snap = snaps[1]
+ eq(snap['id'], snap_id[0])
+ eq(snap['namespace'], RBD_SNAP_NAMESPACE_TYPE_MIRROR)
+ eq(RBD_SNAP_MIRROR_STATE_PRIMARY, snap['mirror']['state'])
+ eq([peer_uuid], snap['mirror']['mirror_peer_uuids'])
+
+ self.rbd.mirror_peer_remove(ioctx, peer_uuid)
+
class TestTrash(object):
def setUp(self):