From dacf628d244315d4b748239de3924b04e4b0ff6c Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Tue, 20 Mar 2018 12:09:46 +0800 Subject: [PATCH] pybind/rbd: added 'set_snap_by_id' API method Signed-off-by: Jason Dillaman --- src/pybind/rbd/rbd.pyx | 22 ++++++++++++++++++++++ src/test/pybind/test_rbd.py | 18 ++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/pybind/rbd/rbd.pyx b/src/pybind/rbd/rbd.pyx index e2ba0f7978c9a..b9104e894beab 100644 --- a/src/pybind/rbd/rbd.pyx +++ b/src/pybind/rbd/rbd.pyx @@ -47,6 +47,10 @@ cdef extern from "time.h": cdef extern from "limits.h": cdef uint64_t INT64_MAX +cdef extern from "rados/librados.h": + enum: + _LIBRADOS_SNAP_HEAD "LIBRADOS_SNAP_HEAD" + cdef extern from "rbd/librbd.h" nogil: enum: _RBD_FEATURE_LAYERING "RBD_FEATURE_LAYERING" @@ -322,6 +326,7 @@ cdef extern from "rbd/librbd.h" nogil: int rbd_snap_set_limit(rbd_image_t image, uint64_t limit) int rbd_snap_get_timestamp(rbd_image_t image, uint64_t snap_id, timespec *timestamp) int rbd_snap_set(rbd_image_t image, const char *snapname) + int rbd_snap_set_by_id(rbd_image_t image, uint64_t snap_id) int rbd_snap_get_namespace_type(rbd_image_t image, uint64_t snap_id, rbd_snap_namespace_type_t *namespace_type) @@ -2485,6 +2490,23 @@ cdef class Image(object): if ret != 0: raise make_ex(ret, 'error setting image %s to snapshot %s' % (self.name, name)) + def set_snap_by_id(self, snap_id): + """ + Set the snapshot to read from. Writes will raise ReadOnlyImage + while a snapshot is set. Pass None to unset the snapshot + (reads come from the current image) , and allow writing again. + + :param snap_id: the snapshot to read from, or None to unset the snapshot + :type snap_id: int + """ + if not snap_id: + snap_id = _LIBRADOS_SNAP_HEAD + cdef int64_t _snap_id = snap_id + with nogil: + ret = rbd_snap_set_by_id(self.image, _snap_id) + if ret != 0: + raise make_ex(ret, 'error setting image %s to snapshot %d' % (self.name, snap_id)) + def read(self, offset, length, fadvise_flags=0): """ Read data from the image. Raises :class:`InvalidArgument` if diff --git a/src/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py index 6ce6c32c9d5cc..169b22ccfcbad 100644 --- a/src/test/pybind/test_rbd.py +++ b/src/test/pybind/test_rbd.py @@ -734,6 +734,24 @@ class TestImage(object): eq(read, data) self.image.remove_snap('snap1') + def test_set_snap_by_id(self): + self.image.write(b'\0' * 256, 0) + self.image.create_snap('snap1') + read = self.image.read(0, 256) + eq(read, b'\0' * 256) + data = rand_data(256) + self.image.write(data, 0) + read = self.image.read(0, 256) + eq(read, data) + snaps = list(self.image.list_snaps()) + self.image.set_snap_by_id(snaps[0]['id']) + read = self.image.read(0, 256) + eq(read, b'\0' * 256) + self.image.set_snap_by_id(None) + read = self.image.read(0, 256) + eq(read, data) + self.image.remove_snap('snap1') + def test_set_snap_sparse(self): self.image.create_snap('snap1') read = self.image.read(0, 256) -- 2.39.5