]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: relax "is parent mirrored" check when enabling mirroring for pool
authorMykola Golub <mgolub@mirantis.com>
Thu, 2 Mar 2017 16:18:18 +0000 (17:18 +0100)
committerNathan Cutler <ncutler@suse.com>
Tue, 22 Aug 2017 07:39:18 +0000 (09:39 +0200)
If the parent is in the same pool and has the journaling feature enabled
we can assume the mirroring will eventually be enabled for it.

Fixes: http://tracker.ceph.com/issues/19130
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
(cherry picked from commit fe31bca22f90ce02f461d6421a4f66539db888d3)

src/librbd/internal.cc
src/librbd/internal.h
src/librbd/librbd.cc
src/test/librbd/test_librbd.cc
src/test/rbd_mirror/test_ImageReplayer.cc

index 9fecb1e1688f0b8acbcb282553ffd5c1d413f03a..edd5f165e9c5d1252c7ec2d202025252806fd912 100644 (file)
@@ -3089,7 +3089,7 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
     return cls_client::metadata_list(&ictx->md_ctx, ictx->header_oid, start, max, pairs);
   }
 
-  int mirror_image_enable(ImageCtx *ictx) {
+  int mirror_image_enable(ImageCtx *ictx, bool relax_same_pool_parent_check) {
     CephContext *cct = ictx->cct;
     ldout(cct, 20) << "mirror_image_enable " << ictx << dendl;
 
@@ -3112,16 +3112,25 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
       return -EINVAL;
     }
 
-    // is mirroring not enabled for the parent? 
+    // is mirroring not enabled for the parent?
     {
       RWLock::RLocker l(ictx->parent_lock);
       ImageCtx *parent = ictx->parent;
-      if(parent) {
-        cls::rbd::MirrorImage mirror_image_internal;
-        r = cls_client::mirror_image_get(&(parent->md_ctx), parent->id, &mirror_image_internal);
-        if (r == -ENOENT) {
-          lderr(cct) << "mirroring is not enabled for the parent" << dendl;
-          return -EINVAL;
+      if (parent) {
+        if (relax_same_pool_parent_check &&
+            parent->md_ctx.get_id() == ictx->md_ctx.get_id()) {
+          if (!parent->test_features(RBD_FEATURE_JOURNALING)) {
+            lderr(cct) << "journaling is not enabled for the parent" << dendl;
+            return -EINVAL;
+          }
+        } else {
+          cls::rbd::MirrorImage mirror_image_internal;
+          r = cls_client::mirror_image_get(&(parent->md_ctx), parent->id,
+                                           &mirror_image_internal);
+          if (r == -ENOENT) {
+            lderr(cct) << "mirroring is not enabled for the parent" << dendl;
+            return -EINVAL;
+          }
         }
       }
     }
@@ -3627,7 +3636,7 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
             return r;
           }
 
-          r = mirror_image_enable(img_ctx);
+          r = mirror_image_enable(img_ctx, true);
           if (r < 0) {
             lderr(cct) << "error enabling mirroring for image "
                        << img_pair.first << ": " << cpp_strerror(r) << dendl;
index c08ad9f69c268d34bdcbe56903b346654dbcdfea..5c7ac85759c3455fc48eae56cfff535a256f6e33 100644 (file)
@@ -215,7 +215,7 @@ namespace librbd {
   int mirror_image_status_summary(IoCtx& io_ctx,
       std::map<mirror_image_status_state_t, int> *states);
 
-  int mirror_image_enable(ImageCtx *ictx);
+  int mirror_image_enable(ImageCtx *ictx, bool relax_same_pool_parent_check);
   int mirror_image_disable(ImageCtx *ictx, bool force);
   int mirror_image_promote(ImageCtx *ictx, bool force);
   int mirror_image_demote(ImageCtx *ictx);
index bbebbbaf869009eae97e7b9fd30420055b34c6eb..81a6f62d4d67571c62c17e0417c22919106a4738 100644 (file)
@@ -1328,7 +1328,7 @@ namespace librbd {
 
   int Image::mirror_image_enable() {
     ImageCtx *ictx = (ImageCtx *)ctx;
-    return librbd::mirror_image_enable(ictx);
+    return librbd::mirror_image_enable(ictx, false);
   }
 
   int Image::mirror_image_disable(bool force) {
@@ -2873,7 +2873,7 @@ extern "C" int rbd_metadata_list(rbd_image_t image, const char *start, uint64_t
 extern "C" int rbd_mirror_image_enable(rbd_image_t image)
 {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
-  return librbd::mirror_image_enable(ictx);
+  return librbd::mirror_image_enable(ictx, false);
 }
 
 extern "C" int rbd_mirror_image_disable(rbd_image_t image, bool force)
index 1ade21f081da3f543a8424ad517e1806d6132d6e..921817d2d20996e0d52ddfee5ee3998ad648ec69 100644 (file)
@@ -4552,6 +4552,25 @@ TEST_F(TestLibRBD, Mirror) {
 
   ASSERT_EQ(0, rbd.mirror_mode_set(ioctx, RBD_MIRROR_MODE_IMAGE));
   ASSERT_EQ(0, rbd.mirror_mode_get(ioctx, &mirror_mode));
+
+  // Add some images to the pool
+  int order = 0;
+  ASSERT_EQ(0, create_image_pp(rbd, ioctx, "parent", 2 << 20, &order));
+  bool old_format;
+  uint64_t features;
+  ASSERT_EQ(0, get_features(&old_format, &features));
+  if ((features & RBD_FEATURE_LAYERING) != 0) {
+    librbd::Image parent;
+    ASSERT_EQ(0, rbd.open(ioctx, parent, "parent", NULL));
+    ASSERT_EQ(0, parent.snap_create("parent_snap"));
+    ASSERT_EQ(0, parent.close());
+    ASSERT_EQ(0, rbd.open(ioctx, parent, "parent", "parent_snap"));
+    ASSERT_EQ(0, parent.snap_protect("parent_snap"));
+    ASSERT_EQ(0, parent.close());
+    ASSERT_EQ(0, rbd.clone(ioctx, "parent", "parent_snap", ioctx, "child",
+                           features, &order));
+  }
+
   ASSERT_EQ(RBD_MIRROR_MODE_IMAGE, mirror_mode);
 
   ASSERT_EQ(0, rbd.mirror_mode_set(ioctx, RBD_MIRROR_MODE_POOL));
index bb65c5561c591dfd0c2e229516580751e5c7f715..14ae20a6ae970894282ddd0a395965f0e038026e 100644 (file)
@@ -426,7 +426,7 @@ TEST_F(TestImageReplayer, BootstrapMirrorDisabling)
   ASSERT_EQ(0, librbd::mirror_mode_set(m_remote_ioctx, RBD_MIRROR_MODE_IMAGE));
   librbd::ImageCtx *ictx;
   open_remote_image(&ictx);
-  ASSERT_EQ(0, librbd::mirror_image_enable(ictx));
+  ASSERT_EQ(0, librbd::mirror_image_enable(ictx, false));
   cls::rbd::MirrorImage mirror_image;
   ASSERT_EQ(0, librbd::cls_client::mirror_image_get(&m_remote_ioctx, ictx->id,
                                                     &mirror_image));