From: Adam Wolfe Gordon Date: Tue, 28 Nov 2017 20:37:57 +0000 (+0000) Subject: pybind: Add support for rbd_watchers_list X-Git-Tag: v13.0.2~846^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=027f4d0196e06c6d89bc3a5eb7e4e345bd1d0c0b;p=ceph.git pybind: Add support for rbd_watchers_list Also add a test. Signed-off-by: Adam Wolfe Gordon --- diff --git a/src/pybind/rbd/rbd.pyx b/src/pybind/rbd/rbd.pyx index 949504a34d2b..37b1c7d963e3 100644 --- a/src/pybind/rbd/rbd.pyx +++ b/src/pybind/rbd/rbd.pyx @@ -154,6 +154,11 @@ cdef extern from "rbd/librbd.h" nogil: time_t deletion_time time_t deferment_end_time + ctypedef struct rbd_image_watcher_t: + char *addr + int64_t id + uint64_t cookie + ctypedef void (*rbd_callback_t)(rbd_completion_t cb, void *arg) ctypedef int (*librbd_progress_fn_t)(uint64_t offset, uint64_t total, void* ptr) @@ -349,6 +354,11 @@ cdef extern from "rbd/librbd.h" nogil: char *keys, size_t *key_len, char *values, size_t *vals_len) + int rbd_watchers_list(rbd_image_t image, rbd_image_watcher_t *watchers, + size_t *max_watchers) + void rbd_watchers_list_cleanup(rbd_image_watcher_t *watchers, + size_t num_watchers) + RBD_FEATURE_LAYERING = _RBD_FEATURE_LAYERING RBD_FEATURE_STRIPINGV2 = _RBD_FEATURE_STRIPINGV2 RBD_FEATURE_EXCLUSIVE_LOCK = _RBD_FEATURE_EXCLUSIVE_LOCK @@ -2755,6 +2765,16 @@ written." % (self.name, ret, length)) """ return MetadataIterator(self) + + def watchers_list(self): + """ + List image watchers. + + :returns: :class:`WatcherIterator` + """ + return WatcherIterator(self) + + cdef class LockOwnerIterator(object): """ Iterator over managed lock owners for an image @@ -3026,3 +3046,50 @@ cdef class ChildIterator(object): if self.children: rbd_list_children_cleanup(self.children, self.num_children) free(self.children) + +cdef class WatcherIterator(object): + """ + Iterator over watchers of an image. + + Yields a dictionary containing information about a watcher. + + Keys are: + + * ``addr`` (str) - address of the watcher + + * ``id`` (int) - id of the watcher + + * ``cookie`` (int) - the watcher's cookie + """ + + cdef rbd_image_watcher_t *watchers + cdef size_t num_watchers + cdef object image + + def __init__(self, Image image): + self.image = image + self.watchers = NULL + self.num_watchers = 10 + while True: + self.watchers = realloc_chk(self.watchers, + self.num_watchers * + sizeof(rbd_image_watcher_t)) + with nogil: + ret = rbd_watchers_list(image.image, self.watchers, &self.num_watchers) + if ret >= 0: + break + elif ret != -errno.ERANGE: + raise make_ex(ret, 'error listing watchers.') + + def __iter__(self): + for i in range(self.num_watchers): + yield { + 'addr' : decode_cstr(self.watchers[i].addr), + 'id' : self.watchers[i].id, + 'cookie' : self.watchers[i].cookie + } + + def __dealloc__(self): + if self.watchers: + rbd_watchers_list_cleanup(self.watchers, self.num_watchers) + free(self.watchers) diff --git a/src/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py index f46f09cedcf9..b5a7ce3ec8d0 100644 --- a/src/test/pybind/test_rbd.py +++ b/src/test/pybind/test_rbd.py @@ -854,6 +854,12 @@ class TestImage(object): metadata = list(self.image.metadata_list()) eq(len(metadata), N - i - 1) + def test_watchers_list(self): + watchers = list(self.image.watchers_list()) + # The image is open (in r/w mode) from setup, so expect there to be one + # watcher. + eq(len(watchers), 1) + def check_diff(image, offset, length, from_snapshot, expected): extents = [] def cb(offset, length, exists):