]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-mirror: move remote image life-cycle management to state builder
authorJason Dillaman <dillaman@redhat.com>
Mon, 27 Jan 2020 19:21:29 +0000 (14:21 -0500)
committerJason Dillaman <dillaman@redhat.com>
Thu, 30 Jan 2020 15:26:36 +0000 (10:26 -0500)
snapshot-based mirroring will need to leave the remote image open during
replay.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc
src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc
src/tools/rbd_mirror/image_replayer/StateBuilder.cc
src/tools/rbd_mirror/image_replayer/StateBuilder.h
src/tools/rbd_mirror/image_replayer/journal/StateBuilder.cc

index a765c46067212dd1e5c8d9a45ece4f8a5084cad8..3eb42cf08e18d6354534dc62a05bf42a2e53bcb9 100644 (file)
@@ -7,7 +7,6 @@
 #include "tools/rbd_mirror/InstanceWatcher.h"
 #include "tools/rbd_mirror/Threads.h"
 #include "tools/rbd_mirror/image_replayer/BootstrapRequest.h"
-#include "tools/rbd_mirror/image_replayer/CloseImageRequest.h"
 #include "tools/rbd_mirror/image_replayer/OpenImageRequest.h"
 #include "tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h"
 #include "tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.h"
@@ -89,33 +88,6 @@ struct InstanceWatcher<librbd::MockTestImageCtx> {
 
 namespace image_replayer {
 
-template<>
-struct CloseImageRequest<librbd::MockTestImageCtx> {
-  static CloseImageRequest* s_instance;
-  librbd::MockTestImageCtx **image_ctx = nullptr;
-  Context *on_finish = nullptr;
-
-  static CloseImageRequest* create(librbd::MockTestImageCtx **image_ctx,
-                                   Context *on_finish) {
-    ceph_assert(s_instance != nullptr);
-    s_instance->image_ctx = image_ctx;
-    s_instance->on_finish = on_finish;
-    s_instance->construct(*image_ctx);
-    return s_instance;
-  }
-
-  CloseImageRequest() {
-    ceph_assert(s_instance == nullptr);
-    s_instance = this;
-  }
-  ~CloseImageRequest() {
-    s_instance = nullptr;
-  }
-
-  MOCK_METHOD1(construct, void(librbd::MockTestImageCtx *image_ctx));
-  MOCK_METHOD0(send, void());
-};
-
 template<>
 struct OpenImageRequest<librbd::MockTestImageCtx> {
   static OpenImageRequest* s_instance;
@@ -262,6 +234,8 @@ struct StateBuilder<librbd::MockTestImageCtx> {
   MOCK_CONST_METHOD0(is_local_primary, bool());
   MOCK_CONST_METHOD0(is_linked, bool());
 
+  MOCK_METHOD1(close_remote_image, void(Context*));
+
   MOCK_METHOD5(create_local_image_request,
                BaseRequest*(Threads<librbd::MockTestImageCtx>*,
                             librados::IoCtx&,
@@ -279,8 +253,6 @@ struct StateBuilder<librbd::MockTestImageCtx> {
   }
 };
 
-CloseImageRequest<librbd::MockTestImageCtx>*
-  CloseImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
 OpenImageRequest<librbd::MockTestImageCtx>*
   OpenImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
 OpenLocalImageRequest<librbd::MockTestImageCtx>*
@@ -321,7 +293,6 @@ class TestMockImageReplayerBootstrapRequest : public TestMockFixture {
 public:
   typedef Threads<librbd::MockTestImageCtx> MockThreads;
   typedef BootstrapRequest<librbd::MockTestImageCtx> MockBootstrapRequest;
-  typedef CloseImageRequest<librbd::MockTestImageCtx> MockCloseImageRequest;
   typedef ImageSync<librbd::MockTestImageCtx> MockImageSync;
   typedef InstanceWatcher<librbd::MockTestImageCtx> MockInstanceWatcher;
   typedef OpenImageRequest<librbd::MockTestImageCtx> MockOpenImageRequest;
@@ -415,13 +386,13 @@ public:
         }));
   }
 
-  void expect_close_image(MockCloseImageRequest &mock_close_image_request,
-                          librbd::MockTestImageCtx &mock_image_ctx, int r) {
-    EXPECT_CALL(mock_close_image_request, construct(&mock_image_ctx));
-    EXPECT_CALL(mock_close_image_request, send())
-      .WillOnce(Invoke([this, &mock_close_image_request, r]() {
-          *mock_close_image_request.image_ctx = nullptr;
-          m_threads->work_queue->queue(mock_close_image_request.on_finish, r);
+  void expect_close_remote_image(
+      MockStateBuilder& mock_state_builder, int r) {
+    EXPECT_CALL(mock_state_builder, close_remote_image(_))
+      .WillOnce(Invoke([this, &mock_state_builder, r]
+                       (Context* on_finish) {
+          mock_state_builder.remote_image_ctx = nullptr;
+          on_finish->complete(r);
         }));
   }
 
@@ -531,8 +502,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, Success) {
   expect_is_disconnected(mock_state_builder, false);
 
   // close remote image
-  MockCloseImageRequest mock_close_image_request;
-  expect_close_image(mock_close_image_request, mock_remote_image_ctx, 0);
+  expect_close_remote_image(mock_state_builder, 0);
 
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
@@ -573,8 +543,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, OpenLocalImageError) {
                           -EINVAL);
 
   // close remote image
-  MockCloseImageRequest mock_close_image_request;
-  expect_close_image(mock_close_image_request, mock_remote_image_ctx, 0);
+  expect_close_remote_image(mock_state_builder, 0);
 
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
@@ -626,8 +595,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, OpenLocalImageDNE) {
   expect_is_disconnected(mock_state_builder, false);
 
   // close remote image
-  MockCloseImageRequest mock_close_image_request;
-  expect_close_image(mock_close_image_request, mock_remote_image_ctx, 0);
+  expect_close_remote_image(mock_state_builder, 0);
 
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
@@ -668,8 +636,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, OpenLocalImagePrimary) {
                           -EREMOTEIO);
 
   // close remote image
-  MockCloseImageRequest mock_close_image_request;
-  expect_close_image(mock_close_image_request, mock_remote_image_ctx, 0);
+  expect_close_remote_image(mock_state_builder, 0);
 
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
@@ -706,8 +673,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, CreateLocalImageError) {
   expect_create_local_image(mock_state_builder, "local image id", -EINVAL);
 
   // close remote image
-  MockCloseImageRequest mock_close_image_request;
-  expect_close_image(mock_close_image_request, mock_remote_image_ctx, 0);
+  expect_close_remote_image(mock_state_builder, 0);
 
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
@@ -750,8 +716,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplayError) {
   expect_prepare_replay(mock_state_builder, false, false, -EINVAL);
 
   // close remote image
-  MockCloseImageRequest mock_close_image_request;
-  expect_close_image(mock_close_image_request, mock_remote_image_ctx, 0);
+  expect_close_remote_image(mock_state_builder, 0);
 
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
@@ -794,8 +759,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplayResyncRequested) {
   expect_prepare_replay(mock_state_builder, true, false, 0);
 
   // close remote image
-  MockCloseImageRequest mock_close_image_request;
-  expect_close_image(mock_close_image_request, mock_remote_image_ctx, 0);
+  expect_close_remote_image(mock_state_builder, 0);
 
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
@@ -844,8 +808,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplaySyncing) {
   expect_image_sync(mock_image_sync, 0);
 
   // close remote image
-  MockCloseImageRequest mock_close_image_request;
-  expect_close_image(mock_close_image_request, mock_remote_image_ctx, 0);
+  expect_close_remote_image(mock_state_builder, 0);
 
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
@@ -889,8 +852,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplayDisconnected) {
   expect_is_disconnected(mock_state_builder, false);
 
   // close remote image
-  MockCloseImageRequest mock_close_image_request;
-  expect_close_image(mock_close_image_request, mock_remote_image_ctx, 0);
+  expect_close_remote_image(mock_state_builder, 0);
 
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
@@ -938,8 +900,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, ImageSyncError) {
   expect_image_sync(mock_image_sync, -EINVAL);
 
   // close remote image
-  MockCloseImageRequest mock_close_image_request;
-  expect_close_image(mock_close_image_request, mock_remote_image_ctx, 0);
+  expect_close_remote_image(mock_state_builder, 0);
 
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
@@ -983,8 +944,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, ImageSyncCanceled) {
   expect_is_disconnected(mock_state_builder, false);
 
   // close remote image
-  MockCloseImageRequest mock_close_image_request;
-  expect_close_image(mock_close_image_request, mock_remote_image_ctx, 0);
+  expect_close_remote_image(mock_state_builder, 0);
 
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
@@ -1028,8 +988,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, CloseRemoteImageError) {
   expect_prepare_replay(mock_state_builder, false, false, 0);
   expect_is_disconnected(mock_state_builder, false);
 
-  MockCloseImageRequest mock_close_image_request;
-  expect_close_image(mock_close_image_request, mock_remote_image_ctx, -EINVAL);
+  expect_close_remote_image(mock_state_builder, -EINVAL);
 
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
index 739a5599f1b3d52af141ea386c4723226ef5a045..7f338cc3e0875b342a10d8b048e48fbbe4404fda 100644 (file)
@@ -3,7 +3,6 @@
 
 #include "include/compat.h"
 #include "BootstrapRequest.h"
-#include "CloseImageRequest.h"
 #include "CreateImageRequest.h"
 #include "OpenImageRequest.h"
 #include "OpenLocalImageRequest.h"
@@ -426,9 +425,7 @@ void BootstrapRequest<I>::close_remote_image() {
     BootstrapRequest<I>,
     &BootstrapRequest<I>::handle_close_remote_image>(this);
   ceph_assert(*m_state_builder != nullptr);
-  auto request = CloseImageRequest<I>::create(
-    &(*m_state_builder)->remote_image_ctx, ctx);
-  request->send();
+  (*m_state_builder)->close_remote_image(ctx);
 }
 
 template <typename I>
index 1e8420bbbc8c411bf3785853d398de6e91575024..20a5378d47a586b0436914c0df4ca23aedb069d8 100644 (file)
@@ -78,6 +78,35 @@ void StateBuilder<I>::handle_close_local_image(int r, Context* on_finish) {
   on_finish->complete(r);
 }
 
+template <typename I>
+void StateBuilder<I>::close_remote_image(Context* on_finish) {
+  if (remote_image_ctx == nullptr) {
+    on_finish->complete(0);
+    return;
+  }
+
+  dout(10) << dendl;
+  auto ctx = new LambdaContext([this, on_finish](int r) {
+      handle_close_remote_image(r, on_finish);
+    });
+  auto request = image_replayer::CloseImageRequest<I>::create(
+    &remote_image_ctx, ctx);
+  request->send();
+}
+
+template <typename I>
+void StateBuilder<I>::handle_close_remote_image(int r, Context* on_finish) {
+  dout(10) << "r=" << r << dendl;
+
+  ceph_assert(remote_image_ctx == nullptr);
+  if (r < 0) {
+    derr << "failed to close remote image for image " << global_image_id << ": "
+         << cpp_strerror(r) << dendl;
+  }
+
+  on_finish->complete(r);
+}
+
 template <typename I>
 void StateBuilder<I>::destroy_sync_point_handler() {
   if (m_sync_point_handler == nullptr) {
index c6bf3ea8fd0418ae92489e1378fae950d3656986..a85cb3b779a5356222a909d9864436abfb74f40c 100644 (file)
@@ -49,6 +49,8 @@ public:
   virtual image_sync::SyncPointHandler* create_sync_point_handler() = 0;
   void destroy_sync_point_handler();
 
+  void close_remote_image(Context* on_finish);
+
   virtual BaseRequest* create_local_image_request(
       Threads<ImageCtxT>* threads,
       librados::IoCtx& local_io_ctx,
@@ -91,6 +93,7 @@ protected:
 
 private:
   void handle_close_local_image(int r, Context* on_finish);
+  void handle_close_remote_image(int r, Context* on_finish);
 };
 
 } // namespace image_replayer
index 01d51e7d56985cd3ddbd65bd50e8b9d9eb5122f3..9056785475b59fa5a9fb5105f41107fbf2a5f5a1 100644 (file)
@@ -43,10 +43,13 @@ void StateBuilder<I>::close(Context* on_finish) {
   // close the remote journaler after closing the local image
   // in case we have lost contact w/ the remote cluster and
   // will block
-  auto ctx = new LambdaContext([this, on_finish](int) {
+  on_finish = new LambdaContext([this, on_finish](int) {
       shut_down_remote_journaler(on_finish);
     });
-  this->close_local_image(ctx);
+  on_finish = new LambdaContext([this, on_finish](int) {
+      this->close_local_image(on_finish);
+    });
+  this->close_remote_image(on_finish);
 }
 
 template <typename I>