]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: enable mirroring for non-primary images w/o journaling
authorJason Dillaman <dillaman@redhat.com>
Tue, 10 Mar 2020 02:26:13 +0000 (22:26 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 10 Mar 2020 23:23:02 +0000 (19:23 -0400)
The state machine was incorrectly skipping over the mirror enable
step for non-primary images when the journaling feature bit was not
enabled.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/image/CloneRequest.cc
src/librbd/image/CreateRequest.cc
src/test/librbd/image/test_mock_CloneRequest.cc

index 5da8769a3ef86c661fa283c86d2e5dde7f42b735..0de9f78afa4dd473af8cde1f2eac1ee9d439aa8e 100644 (file)
@@ -424,7 +424,10 @@ template <typename I>
 void CloneRequest<I>::get_mirror_mode() {
   ldout(m_cct, 15) << dendl;
 
-  if (!m_imctx->test_features(RBD_FEATURE_JOURNALING)) {
+  if (!m_non_primary_global_image_id.empty()) {
+    enable_mirror();
+    return;
+  } else if (!m_imctx->test_features(RBD_FEATURE_JOURNALING)) {
     close_child();
     return;
   }
@@ -455,15 +458,12 @@ void CloneRequest<I>::handle_get_mirror_mode(int r) {
                  << dendl;
 
     m_r_saved = r;
-    close_child();
-  } else {
-    if (m_mirror_mode == cls::rbd::MIRROR_MODE_POOL ||
-       !m_non_primary_global_image_id.empty()) {
-      enable_mirror();
-    } else {
-      close_child();
-    }
+  } else if (m_mirror_mode == cls::rbd::MIRROR_MODE_POOL) {
+    enable_mirror();
+    return;
   }
+
+  close_child();
 }
 
 template <typename I>
index ca4f141652e2c3aa41e07614c54dfb5bd5aeb3b5..175565223c7e2a8763ca3a77b80cde621cd70e15 100644 (file)
@@ -544,7 +544,7 @@ void CreateRequest<I>::handle_object_map_resize(int r) {
 template<typename I>
 void CreateRequest<I>::fetch_mirror_mode() {
   if ((m_features & RBD_FEATURE_JOURNALING) == 0) {
-    complete(0);
+    mirror_image_enable();
     return;
   }
 
index d21a83a40e3b7737cbf67fa27a0b3b14d824a63b..41b362ab3821a7a41205c7eaf8f366abe1f7556e 100644 (file)
@@ -917,5 +917,48 @@ TEST_F(TestMockImageCloneRequest, CloseParentError) {
   ASSERT_EQ(-EINVAL, ctx.wait());
 }
 
+TEST_F(TestMockImageCloneRequest, SnapshotMirrorEnableNonPrimary) {
+  REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
+
+  MockTestImageCtx mock_image_ctx(*image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  expect_open(mock_image_ctx, 0);
+
+  expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
+  expect_is_snap_protected(mock_image_ctx, true, 0);
+
+  MockCreateRequest mock_create_request;
+  expect_create(mock_create_request, 0);
+
+  expect_open(mock_image_ctx, 0);
+
+  MockAttachParentRequest mock_attach_parent_request;
+  expect_attach_parent(mock_attach_parent_request, 0);
+
+  MockAttachChildRequest mock_attach_child_request;
+  expect_attach_child(mock_attach_child_request, 2, 0);
+
+  MockMetadataCopyRequest mock_request;
+  expect_metadata_copy(mock_request, 0);
+
+  MockMirrorEnableRequest mock_mirror_enable_request;
+  expect_mirror_enable(mock_mirror_enable_request, 0);
+
+  expect_close(mock_image_ctx, 0);
+  expect_close(mock_image_ctx, 0);
+
+  C_SaferCond ctx;
+  ImageOptions clone_opts;
+  auto req = new MockCloneRequest(m_cct->_conf, m_ioctx, "parent id", "", {}, 123,
+                                  m_ioctx, "clone name", "clone id", clone_opts,
+                                  cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
+                                  "global image id", "primary mirror uuid",
+                                  image_ctx->op_work_queue, &ctx);
+  req->send();
+  ASSERT_EQ(0, ctx.wait());
+}
+
 } // namespace image
 } // namespace librbd