]> git-server-git.apps.pok.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, 4 Jul 2017 20:50:30 +0000 (22:50 +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 f53a81edc259e1eefcd0c946407878e0b2a61af0..0ae8e012185ab4b5d1313acdac16d26bd5439862 100644 (file)
@@ -2478,7 +2478,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;
 
@@ -2501,16 +2501,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;
+          }
         }
       }
     }
@@ -3025,7 +3034,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 550eecf9ac5c74ce98365f7a7339e3a3d4f9c601..912da6d1dbf429e0caf874772b70450dab1c6dd8 100644 (file)
@@ -214,7 +214,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 abbc873ff5c16cf35b3c5fe6b552ef71eecbbf21..e6e4ebab06da3c1742ee2d7d98d784c2a95dda57 100644 (file)
@@ -1380,7 +1380,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) {
@@ -2965,7 +2965,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 3f32df1dbe616af4c7e87519604574dceb941065..0e4e880e77dae4a209492f330e921c1f523b466a 100644 (file)
@@ -4781,6 +4781,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 5bd6c53a469803ec95d760504369495ab7a6983a..ed4dc16a00cb39e3e7c4e21a5fc4bc76b4329044 100644 (file)
@@ -429,7 +429,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));