pybind/rbd: add async mirror image get mode and info methods

Signed-off-by: Mykola Golub <mgolub@suse.com>
This commit is contained in:
Mykola Golub 2020-10-26 11:09:28 +00:00
parent fd5e642cd7
commit 13ce488d7a
2 changed files with 118 additions and 0 deletions

View File

@ -629,8 +629,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,
@ -5057,6 +5063,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):
"""
@ -5071,6 +5124,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):
"""

View File

@ -2253,6 +2253,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