From 8f23ea4fc0938c35998193ea76d7a029422b89b0 Mon Sep 17 00:00:00 2001 From: Mykola Golub Date: Thu, 2 Mar 2017 17:18:18 +0100 Subject: [PATCH] librbd: relax "is parent mirrored" check when enabling mirroring for pool 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 (cherry picked from commit fe31bca22f90ce02f461d6421a4f66539db888d3) --- src/librbd/internal.cc | 27 +++++++++++++++-------- src/librbd/internal.h | 2 +- src/librbd/librbd.cc | 4 ++-- src/test/librbd/test_librbd.cc | 19 ++++++++++++++++ src/test/rbd_mirror/test_ImageReplayer.cc | 2 +- 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 9fecb1e1688f0..edd5f165e9c5d 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -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; diff --git a/src/librbd/internal.h b/src/librbd/internal.h index c08ad9f69c268..5c7ac85759c34 100644 --- a/src/librbd/internal.h +++ b/src/librbd/internal.h @@ -215,7 +215,7 @@ namespace librbd { int mirror_image_status_summary(IoCtx& io_ctx, std::map *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); diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index bbebbbaf86900..81a6f62d4d675 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -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) diff --git a/src/test/librbd/test_librbd.cc b/src/test/librbd/test_librbd.cc index 1ade21f081da3..921817d2d2099 100644 --- a/src/test/librbd/test_librbd.cc +++ b/src/test/librbd/test_librbd.cc @@ -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)); diff --git a/src/test/rbd_mirror/test_ImageReplayer.cc b/src/test/rbd_mirror/test_ImageReplayer.cc index bb65c5561c591..14ae20a6ae970 100644 --- a/src/test/rbd_mirror/test_ImageReplayer.cc +++ b/src/test/rbd_mirror/test_ImageReplayer.cc @@ -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)); -- 2.39.5