]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: API method to get mirror image mode
authorMykola Golub <mgolub@suse.com>
Wed, 13 Nov 2019 16:24:48 +0000 (16:24 +0000)
committerMykola Golub <mgolub@suse.com>
Tue, 10 Dec 2019 15:45:30 +0000 (15:45 +0000)
Signed-off-by: Mykola Golub <mgolub@suse.com>
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/api/Mirror.cc
src/librbd/api/Mirror.h
src/librbd/librbd.cc
src/pybind/rbd/rbd.pyx
src/test/librbd/test_mirroring.cc
src/test/pybind/test_rbd.py

index c5bdd8ae838e5c7ba924292a76125a0c0810f424..a53e2c448fb78ea9d3af0e3a74610a6f8d96033e 100644 (file)
@@ -171,6 +171,11 @@ typedef struct {
 #define RBD_MIRROR_PEER_ATTRIBUTE_NAME_MON_HOST "mon_host"
 #define RBD_MIRROR_PEER_ATTRIBUTE_NAME_KEY      "key"
 
+typedef enum {
+  RBD_MIRROR_IMAGE_MODE_JOURNAL  = 0,
+  RBD_MIRROR_IMAGE_MODE_SNAPSHOT = 1,
+} rbd_mirror_image_mode_t;
+
 typedef enum {
   RBD_MIRROR_IMAGE_DISABLING = 0,
   RBD_MIRROR_IMAGE_ENABLED = 1,
@@ -1185,6 +1190,8 @@ CEPH_RBD_API int rbd_mirror_image_create_snapshot(rbd_image_t image,
 CEPH_RBD_API int rbd_mirror_image_get_info(rbd_image_t image,
                                            rbd_mirror_image_info_t *mirror_image_info,
                                            size_t info_size);
+CEPH_RBD_API int rbd_mirror_image_get_mode(rbd_image_t image,
+                                           rbd_mirror_image_mode_t *mode);
 
 CEPH_RBD_API int rbd_mirror_image_get_global_status(
     rbd_image_t image,
index 40777b3af8275bf0356329115eda021a9e9f05f8..e53495e18427ff82865b1d721935043a26979b1d 100644 (file)
@@ -108,6 +108,7 @@ namespace librbd {
     time_t last_seen;
   } mirror_peer_site_t;
 
+  typedef rbd_mirror_image_mode_t mirror_image_mode_t;
   typedef rbd_mirror_image_state_t mirror_image_state_t;
 
   typedef struct {
@@ -735,6 +736,7 @@ public:
   int mirror_image_create_snapshot(uint64_t *snap_id);
   int mirror_image_get_info(mirror_image_info_t *mirror_image_info,
                             size_t info_size);
+  int mirror_image_get_mode(mirror_image_mode_t *mode);
   int mirror_image_get_global_status(
       mirror_image_global_status_t *mirror_image_global_status,
       size_t status_size);
@@ -746,6 +748,8 @@ public:
   int aio_mirror_image_demote(RBD::AioCompletion *c);
   int aio_mirror_image_get_info(mirror_image_info_t *mirror_image_info,
                                 size_t info_size, RBD::AioCompletion *c);
+  int aio_mirror_image_get_mode(mirror_image_mode_t *mode,
+                                RBD::AioCompletion *c);
   int aio_mirror_image_get_global_status(
       mirror_image_global_status_t *mirror_image_global_status,
       size_t status_size, RBD::AioCompletion *c);
index 76d0e7915ddfdfe73759a48bc27f22482ee28a96..8fb822a18bebfddf6d9ea917a5506252d7334285 100644 (file)
@@ -276,13 +276,16 @@ int list_mirror_images(librados::IoCtx& io_ctx,
 
 struct C_ImageGetInfo : public Context {
   mirror_image_info_t *mirror_image_info;
+  mirror_image_mode_t *mirror_image_mode;
   Context *on_finish;
 
   cls::rbd::MirrorImage mirror_image;
   mirror::PromotionState promotion_state = mirror::PROMOTION_STATE_PRIMARY;
 
-  C_ImageGetInfo(mirror_image_info_t *mirror_image_info, Context *on_finish)
-    : mirror_image_info(mirror_image_info), on_finish(on_finish) {
+  C_ImageGetInfo(mirror_image_info_t *mirror_image_info,
+                 mirror_image_mode_t *mirror_image_mode,  Context *on_finish)
+    : mirror_image_info(mirror_image_info),
+      mirror_image_mode(mirror_image_mode), on_finish(on_finish) {
   }
 
   void finish(int r) override {
@@ -291,11 +294,19 @@ struct C_ImageGetInfo : public Context {
       return;
     }
 
-    mirror_image_info->global_id = mirror_image.global_image_id;
-    mirror_image_info->state = static_cast<rbd_mirror_image_state_t>(
-      mirror_image.state);
-    mirror_image_info->primary = (
-      promotion_state == mirror::PROMOTION_STATE_PRIMARY);
+    if (mirror_image_info != nullptr) {
+      mirror_image_info->global_id = mirror_image.global_image_id;
+      mirror_image_info->state = static_cast<rbd_mirror_image_state_t>(
+        mirror_image.state);
+      mirror_image_info->primary = (
+        promotion_state == mirror::PROMOTION_STATE_PRIMARY);
+    }
+
+    if (mirror_image_mode != nullptr) {
+      *mirror_image_mode =
+        static_cast<rbd_mirror_image_mode_t>(mirror_image.mode);
+    }
+
     on_finish->complete(0);
   }
 };
@@ -310,7 +321,7 @@ struct C_ImageGetGlobalStatus : public C_ImageGetInfo {
       const std::string &image_name,
       mirror_image_global_status_t *mirror_image_global_status,
       Context *on_finish)
-    : C_ImageGetInfo(&mirror_image_global_status->info, on_finish),
+    : C_ImageGetInfo(&mirror_image_global_status->info, nullptr, on_finish),
       image_name(image_name),
       mirror_image_global_status(mirror_image_global_status) {
   }
@@ -611,7 +622,7 @@ void Mirror<I>::image_get_info(I *ictx, mirror_image_info_t *mirror_image_info,
   CephContext *cct = ictx->cct;
   ldout(cct, 20) << "ictx=" << ictx << dendl;
 
-  auto ctx = new C_ImageGetInfo(mirror_image_info, on_finish);
+  auto ctx = new C_ImageGetInfo(mirror_image_info, nullptr, on_finish);
   auto req = mirror::GetInfoRequest<I>::create(*ictx, &ctx->mirror_image,
                                                &ctx->promotion_state,
                                                ctx);
@@ -630,6 +641,31 @@ int Mirror<I>::image_get_info(I *ictx, mirror_image_info_t *mirror_image_info) {
   return 0;
 }
 
+template <typename I>
+void Mirror<I>::image_get_mode(I *ictx, mirror_image_mode_t *mode,
+                               Context *on_finish) {
+  CephContext *cct = ictx->cct;
+  ldout(cct, 20) << "ictx=" << ictx << dendl;
+
+  auto ctx = new C_ImageGetInfo(nullptr, mode, on_finish);
+  auto req = mirror::GetInfoRequest<I>::create(*ictx, &ctx->mirror_image,
+                                               &ctx->promotion_state,
+                                               ctx);
+  req->send();
+}
+
+template <typename I>
+int Mirror<I>::image_get_mode(I *ictx, mirror_image_mode_t *mode) {
+  C_SaferCond ctx;
+  image_get_mode(ictx, mode, &ctx);
+
+  int r = ctx.wait();
+  if (r < 0) {
+    return r;
+  }
+  return 0;
+}
+
 template <typename I>
 void Mirror<I>::image_get_global_status(I *ictx,
                                         mirror_image_global_status_t *status,
index 6391b37fb8e20cbd2ac3ef08ee2d87e52699943e..c26c88d4b213b0dc97e4504297ce4e297e9e2ffc 100644 (file)
@@ -81,6 +81,9 @@ struct Mirror {
   static void image_get_info(ImageCtxT *ictx,
                              mirror_image_info_t *mirror_image_info,
                              Context *on_finish);
+  static int image_get_mode(ImageCtxT *ictx, mirror_image_mode_t *mode);
+  static void image_get_mode(ImageCtxT *ictx, mirror_image_mode_t *mode,
+                             Context *on_finish);
   static int image_get_global_status(ImageCtxT *ictx,
                                      mirror_image_global_status_t *status);
   static void image_get_global_status(ImageCtxT *ictx,
index 5a7c0a5a3a77b1621f8d547675f6df89d4efa0e2..3238d77157107718098051360d5f80d8d4443459 100644 (file)
@@ -2827,6 +2827,12 @@ namespace librbd {
     return librbd::api::Mirror<>::image_get_info(ictx, mirror_image_info);
   }
 
+  int Image::mirror_image_get_mode(mirror_image_mode_t *mode) {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+
+    return librbd::api::Mirror<>::image_get_mode(ictx, mode);
+  }
+
   int Image::mirror_image_get_global_status(
       mirror_image_global_status_t *mirror_image_global_status,
       size_t status_size) {
@@ -2912,6 +2918,16 @@ namespace librbd {
     return 0;
   }
 
+  int Image::aio_mirror_image_get_mode(mirror_image_mode_t *mode,
+                                       RBD::AioCompletion *c) {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+
+    librbd::api::Mirror<>::image_get_mode(
+      ictx, mode, new C_AioCompletion(ictx, librbd::io::AIO_TYPE_GENERIC,
+                                      get_aio_completion(c)));
+    return 0;
+  }
+
   int Image::aio_mirror_image_get_global_status(
       mirror_image_global_status_t *status, size_t status_size,
       RBD::AioCompletion *c) {
@@ -6196,6 +6212,14 @@ extern "C" int rbd_mirror_image_get_info(rbd_image_t image,
   return 0;
 }
 
+extern "C" int rbd_mirror_image_get_mode(rbd_image_t image,
+                                         rbd_mirror_image_mode_t *mode)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+
+  return librbd::api::Mirror<>::image_get_mode(ictx, mode);
+}
+
 extern "C" int rbd_mirror_image_get_global_status(
     rbd_image_t image, rbd_mirror_image_global_status_t *status,
     size_t status_size)
@@ -6302,6 +6326,18 @@ extern "C" int rbd_aio_mirror_image_get_info(rbd_image_t image,
   return 0;
 }
 
+extern "C" int rbd_aio_mirror_image_get_mode(rbd_image_t image,
+                                             rbd_mirror_image_mode_t *mode,
+                                             rbd_completion_t c) {
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
+
+  librbd::api::Mirror<>::image_get_mode(
+    ictx, mode, new C_AioCompletion(ictx, librbd::io::AIO_TYPE_GENERIC,
+                                    get_aio_completion(comp)));
+  return 0;
+}
+
 extern "C" int rbd_aio_mirror_image_get_global_status(
     rbd_image_t image, rbd_mirror_image_global_status_t *status,
     size_t status_size, rbd_completion_t c) {
index 2162fa60a3a72438fc228739a722ba21fba95cb0..6544bfbdf15bf64a78dca6a51ed78882f72163fe 100644 (file)
@@ -187,6 +187,10 @@ cdef extern from "rbd/librbd.h" nogil:
     cdef char* _RBD_MIRROR_PEER_ATTRIBUTE_NAME_MON_HOST "RBD_MIRROR_PEER_ATTRIBUTE_NAME_MON_HOST"
     cdef char* _RBD_MIRROR_PEER_ATTRIBUTE_NAME_KEY "RBD_MIRROR_PEER_ATTRIBUTE_NAME_KEY"
 
+    ctypedef enum rbd_mirror_image_mode_t:
+        _RBD_MIRROR_IMAGE_MODE_JOURNAL "RBD_MIRROR_IMAGE_MODE_JOURNAL"
+        _RBD_MIRROR_IMAGE_MODE_SNAPSHOT "RBD_MIRROR_IMAGE_MODE_SNAPSHOT"
+
     ctypedef enum rbd_mirror_image_state_t:
         _RBD_MIRROR_IMAGE_DISABLING "RBD_MIRROR_IMAGE_DISABLING"
         _RBD_MIRROR_IMAGE_ENABLED "RBD_MIRROR_IMAGE_ENABLED"
@@ -587,6 +591,8 @@ cdef extern from "rbd/librbd.h" nogil:
     int rbd_mirror_image_get_info(rbd_image_t image,
                                   rbd_mirror_image_info_t *mirror_image_info,
                                   size_t info_size)
+    int rbd_mirror_image_get_mode(rbd_image_t image,
+                                  rbd_mirror_image_mode_t *mode)
     int rbd_mirror_image_get_global_status(
         rbd_image_t image,
         rbd_mirror_image_global_status_t *mirror_image_global_status,
@@ -718,6 +724,9 @@ RBD_MIRROR_PEER_DIRECTION_RX = _RBD_MIRROR_PEER_DIRECTION_RX
 RBD_MIRROR_PEER_DIRECTION_TX = _RBD_MIRROR_PEER_DIRECTION_TX
 RBD_MIRROR_PEER_DIRECTION_RX_TX = _RBD_MIRROR_PEER_DIRECTION_RX_TX
 
+RBD_MIRROR_IMAGE_MODE_JOURNAL = _RBD_MIRROR_IMAGE_MODE_JOURNAL
+RBD_MIRROR_IMAGE_MODE_SNAPSHOT = _RBD_MIRROR_IMAGE_MODE_SNAPSHOT
+
 RBD_MIRROR_IMAGE_DISABLING = _RBD_MIRROR_IMAGE_DISABLING
 RBD_MIRROR_IMAGE_ENABLED = _RBD_MIRROR_IMAGE_ENABLED
 RBD_MIRROR_IMAGE_DISABLED = _RBD_MIRROR_IMAGE_DISABLED
@@ -4595,6 +4604,19 @@ written." % (self.name, ret, length))
         free(c_info.global_id)
         return info
 
+    def mirror_image_get_mode(self):
+        """
+        Get mirror mode for the image.
+
+        :returns: int - mirror mode
+        """
+        cdef rbd_mirror_image_mode_t c_mode
+        with nogil:
+            ret = rbd_mirror_image_get_mode(self.image, &c_mode)
+        if ret != 0:
+            raise make_ex(ret, 'error getting mirror mode for image %s' % self.name)
+        return int(c_mode)
+
     def mirror_image_get_status(self):
         """
         Get mirror status for the image.
index 3770dfdaa19cc98febc17b1cd130640bcf085622..76518cda15ffabb72ad919fb92d404472c529f86 100644 (file)
@@ -95,7 +95,8 @@ public:
 
   void check_mirror_image_enable(
       rbd_mirror_mode_t mirror_mode, uint64_t features, int expected_r,
-      rbd_mirror_image_state_t mirror_state) {
+      rbd_mirror_image_state_t mirror_state,
+      rbd_mirror_image_mode_t mirror_image_mode = RBD_MIRROR_IMAGE_MODE_JOURNAL) {
 
     ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
 
@@ -112,6 +113,12 @@ public:
     ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
     ASSERT_EQ(mirror_state, mirror_image.state);
 
+    if (mirror_image.state == RBD_MIRROR_IMAGE_ENABLED) {
+      librbd::mirror_image_mode_t mode;
+      ASSERT_EQ(0, image.mirror_image_get_mode(&mode));
+      ASSERT_EQ(mirror_image_mode, mode);
+    }
+
     librbd::mirror_image_global_status_t status;
     ASSERT_EQ(0, image.mirror_image_get_global_status(&status, sizeof(status)));
     librbd::mirror_image_site_status_t local_status;
@@ -227,7 +234,8 @@ public:
   void check_mirroring_on_update_features(
       uint64_t init_features, bool enable, bool enable_mirroring,
       uint64_t features, int expected_r, rbd_mirror_mode_t mirror_mode,
-      rbd_mirror_image_state_t mirror_state) {
+      rbd_mirror_image_state_t mirror_state,
+      rbd_mirror_image_mode_t mirror_image_mode = RBD_MIRROR_IMAGE_MODE_JOURNAL) {
 
     ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
 
@@ -246,6 +254,12 @@ public:
     ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
     ASSERT_EQ(mirror_state, mirror_image.state);
 
+    if (mirror_image.state == RBD_MIRROR_IMAGE_ENABLED) {
+      librbd::mirror_image_mode_t mode;
+      ASSERT_EQ(0, image.mirror_image_get_mode(&mode));
+      ASSERT_EQ(mirror_image_mode, mode);
+    }
+
     librbd::mirror_image_global_status_t status;
     ASSERT_EQ(0, image.mirror_image_get_global_status(&status, sizeof(status)));
     librbd::mirror_image_site_status_t local_status;
@@ -402,7 +416,7 @@ TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeImage) {
   features |= RBD_FEATURE_EXCLUSIVE_LOCK;
   features |= RBD_FEATURE_JOURNALING;
   check_mirror_image_enable(RBD_MIRROR_MODE_IMAGE, features, 0,
-      RBD_MIRROR_IMAGE_ENABLED);
+      RBD_MIRROR_IMAGE_ENABLED, RBD_MIRROR_IMAGE_MODE_JOURNAL);
 }
 
 TEST_F(TestMirroring, EnableImageMirror_In_MirrorModePool) {
@@ -411,7 +425,7 @@ TEST_F(TestMirroring, EnableImageMirror_In_MirrorModePool) {
   features |= RBD_FEATURE_EXCLUSIVE_LOCK;
   features |= RBD_FEATURE_JOURNALING;
   check_mirror_image_enable(RBD_MIRROR_MODE_POOL, features, -EINVAL,
-      RBD_MIRROR_IMAGE_ENABLED);
+      RBD_MIRROR_IMAGE_ENABLED, RBD_MIRROR_IMAGE_MODE_JOURNAL);
 }
 
 TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeDisabled) {
@@ -554,13 +568,13 @@ TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeImage_WithoutJournaling) {
   features |= RBD_FEATURE_OBJECT_MAP;
   features |= RBD_FEATURE_EXCLUSIVE_LOCK;
   check_mirror_image_enable(RBD_MIRROR_MODE_IMAGE, features, 0,
-      RBD_MIRROR_IMAGE_ENABLED);
+      RBD_MIRROR_IMAGE_ENABLED, RBD_MIRROR_IMAGE_MODE_SNAPSHOT);
 }
 
 TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeImage_WithoutExclusiveLock) {
   uint64_t features = 0;
   check_mirror_image_enable(RBD_MIRROR_MODE_IMAGE, features, 0,
-      RBD_MIRROR_IMAGE_ENABLED);
+      RBD_MIRROR_IMAGE_ENABLED, RBD_MIRROR_IMAGE_MODE_SNAPSHOT);
 }
 
 TEST_F(TestMirroring, CreateImage_In_MirrorModeDisabled) {
@@ -630,7 +644,8 @@ TEST_F(TestMirroring, EnableJournaling_In_MirrorModeImage_MirroringEnabled) {
   init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
   uint64_t features = RBD_FEATURE_JOURNALING;
   check_mirroring_on_update_features(init_features, true, true, features,
-                      -EINVAL, RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_ENABLED);
+                      -EINVAL, RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_ENABLED,
+                      RBD_MIRROR_IMAGE_MODE_SNAPSHOT);
 }
 
 TEST_F(TestMirroring, EnableJournaling_In_MirrorModePool) {
@@ -639,7 +654,8 @@ TEST_F(TestMirroring, EnableJournaling_In_MirrorModePool) {
   init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
   uint64_t features = RBD_FEATURE_JOURNALING;
   check_mirroring_on_update_features(init_features, true, false, features, 0,
-                      RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_ENABLED);
+                      RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_ENABLED,
+                      RBD_MIRROR_IMAGE_MODE_JOURNAL);
 }
 
 TEST_F(TestMirroring, DisableJournaling_In_MirrorModePool) {
@@ -659,7 +675,8 @@ TEST_F(TestMirroring, DisableJournaling_In_MirrorModeImage) {
   init_features |= RBD_FEATURE_JOURNALING;
   uint64_t features = RBD_FEATURE_JOURNALING;
   check_mirroring_on_update_features(init_features, false, true, features,
-                      -EINVAL, RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_ENABLED);
+                      -EINVAL, RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_ENABLED,
+                      RBD_MIRROR_IMAGE_MODE_JOURNAL);
 }
 
 TEST_F(TestMirroring, MirrorModeSet_DisabledMode_To_PoolMode) {
@@ -1105,6 +1122,9 @@ TEST_F(TestMirroring, Snapshot)
   ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE));
   ASSERT_EQ(-EINVAL, image.mirror_image_create_snapshot(&snap_id));
   ASSERT_EQ(0, image.mirror_image_enable());
+  librbd::mirror_image_mode_t mode;
+  ASSERT_EQ(0, image.mirror_image_get_mode(&mode));
+  ASSERT_EQ(RBD_MIRROR_IMAGE_MODE_SNAPSHOT, mode);
   ASSERT_EQ(-EINVAL, image.mirror_image_create_snapshot(&snap_id));
   std::string peer_uuid;
   ASSERT_EQ(0, m_rbd.mirror_peer_site_add(m_ioctx, &peer_uuid,
index d16f5f590f80860c5aabd4ed6c82500b58845158..3077a806b8b58f7aaaca9939cfd1c8b7050e0dd0 100644 (file)
@@ -28,6 +28,7 @@ from rbd import (RBD, Group, Image, ImageNotFound, InvalidArgument, ImageExists,
                  RBD_MIRROR_MODE_DISABLED, RBD_MIRROR_MODE_IMAGE,
                  RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_ENABLED,
                  RBD_MIRROR_IMAGE_DISABLED, MIRROR_IMAGE_STATUS_STATE_UNKNOWN,
+                 RBD_MIRROR_IMAGE_MODE_SNAPSHOT,
                  RBD_LOCK_MODE_EXCLUSIVE, RBD_OPERATION_FEATURE_GROUP,
                  RBD_SNAP_NAMESPACE_TYPE_TRASH,
                  RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY,
@@ -2060,6 +2061,8 @@ class TestMirroring(object):
         peer2_uuid = self.rbd.mirror_peer_add(ioctx, "cluster2", "client")
         self.rbd.mirror_mode_set(ioctx, RBD_MIRROR_MODE_IMAGE)
         self.image.mirror_image_enable()
+        mode = self.image.mirror_image_get_mode()
+        eq(RBD_MIRROR_IMAGE_MODE_SNAPSHOT, mode)
 
         snap_id = self.image.mirror_image_create_snapshot()