]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
pybind/rbd: added 'set_snap_by_id' API method
authorJason Dillaman <dillaman@redhat.com>
Tue, 20 Mar 2018 04:09:46 +0000 (12:09 +0800)
committerJason Dillaman <dillaman@redhat.com>
Tue, 20 Mar 2018 04:33:03 +0000 (12:33 +0800)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/pybind/rbd/rbd.pyx
src/test/pybind/test_rbd.py

index e2ba0f7978c9a50f831a3522fbd41bfe79aff663..b9104e894beabc02817162f15b3011f2b1e8c350 100644 (file)
@@ -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
index 6ce6c32c9d5cc22d7c964dc1caa1d4504c5a200c..169b22ccfcbad70ae89ceb592d29b4b847d1f680 100644 (file)
@@ -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)