]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-mirror: helper state machine to open remote/read-only images
authorJason Dillaman <dillaman@redhat.com>
Wed, 25 May 2016 19:16:28 +0000 (15:16 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 31 May 2016 20:39:41 +0000 (16:39 -0400)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/CMakeLists.txt
src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc
src/tools/Makefile-client.am
src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc
src/tools/rbd_mirror/image_replayer/OpenImageRequest.cc [new file with mode: 0644]
src/tools/rbd_mirror/image_replayer/OpenImageRequest.h [new file with mode: 0644]

index c1a94f97dde9934e5d59987199cb5054395a737d..d49bbf698350186ff150639761a4a53b32100bfe 100644 (file)
@@ -1151,17 +1151,18 @@ if(${WITH_RBD})
     ${Boost_REGEX_LIBRARY})
 
   set(rbd_mirror_internal
-    tools/rbd_mirror/ClusterWatcher.cc 
+    tools/rbd_mirror/ClusterWatcher.cc
     tools/rbd_mirror/ImageReplayer.cc
     tools/rbd_mirror/ImageDeleter.cc
     tools/rbd_mirror/ImageSync.cc
-    tools/rbd_mirror/Mirror.cc 
-    tools/rbd_mirror/PoolWatcher.cc 
-    tools/rbd_mirror/Replayer.cc 
+    tools/rbd_mirror/Mirror.cc
+    tools/rbd_mirror/PoolWatcher.cc
+    tools/rbd_mirror/Replayer.cc
     tools/rbd_mirror/Threads.cc
     tools/rbd_mirror/types.cc
     tools/rbd_mirror/image_replayer/BootstrapRequest.cc
     tools/rbd_mirror/image_replayer/CloseImageRequest.cc
+    tools/rbd_mirror/image_replayer/OpenImageRequest.cc
     tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc
     tools/rbd_mirror/image_replayer/ReplayStatusFormatter.cc
     tools/rbd_mirror/image_sync/ImageCopyRequest.cc
index 0cec3a26e3195498effd6fab8d2a4a72b6bb1ee6..a36162796a1d69237e5a62f208b267ef2ce02b33 100644 (file)
@@ -6,6 +6,7 @@
 #include "tools/rbd_mirror/ImageSync.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 "test/journal/mock/MockJournaler.h"
 #include "test/librbd/mock/MockImageCtx.h"
@@ -76,6 +77,29 @@ struct CloseImageRequest<librbd::MockImageCtx> {
   MOCK_METHOD0(send, void());
 };
 
+template<>
+struct OpenImageRequest<librbd::MockImageCtx> {
+  static OpenImageRequest* s_instance;
+  Context *on_finish = nullptr;
+
+  static OpenImageRequest* create(librados::IoCtx &io_ctx,
+                                  librbd::MockImageCtx **image_ctx,
+                                  const std::string &local_image_id,
+                                  bool read_only, ContextWQ *work_queue,
+                                  Context *on_finish) {
+    assert(s_instance != nullptr);
+    s_instance->on_finish = on_finish;
+    return s_instance;
+  }
+
+  OpenImageRequest() {
+    assert(s_instance == nullptr);
+    s_instance = this;
+  }
+
+  MOCK_METHOD0(send, void());
+};
+
 template<>
 struct OpenLocalImageRequest<librbd::MockImageCtx> {
   static OpenLocalImageRequest* s_instance;
@@ -101,6 +125,7 @@ struct OpenLocalImageRequest<librbd::MockImageCtx> {
 };
 
 CloseImageRequest<librbd::MockImageCtx>* CloseImageRequest<librbd::MockImageCtx>::s_instance = nullptr;
+OpenImageRequest<librbd::MockImageCtx>* OpenImageRequest<librbd::MockImageCtx>::s_instance = nullptr;
 OpenLocalImageRequest<librbd::MockImageCtx>* OpenLocalImageRequest<librbd::MockImageCtx>::s_instance = nullptr;
 
 } // namespace image_replayer
index 8e4eecfd5d213b49e4e49a092b02f57abfa8c803..d92aa3fd0bdabda3e391309ea269063448d6c036 100644 (file)
@@ -100,6 +100,7 @@ librbd_mirror_internal_la_SOURCES = \
        tools/rbd_mirror/types.cc \
        tools/rbd_mirror/image_replayer/BootstrapRequest.cc \
        tools/rbd_mirror/image_replayer/CloseImageRequest.cc \
+       tools/rbd_mirror/image_replayer/OpenImageRequest.cc \
        tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc \
        tools/rbd_mirror/image_replayer/ReplayStatusFormatter.cc \
        tools/rbd_mirror/image_sync/ImageCopyRequest.cc \
@@ -122,6 +123,7 @@ noinst_HEADERS += \
        tools/rbd_mirror/types.h \
        tools/rbd_mirror/image_replayer/BootstrapRequest.h \
        tools/rbd_mirror/image_replayer/CloseImageRequest.h \
+       tools/rbd_mirror/image_replayer/OpenImageRequest.h \
        tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h \
        tools/rbd_mirror/image_replayer/ReplayStatusFormatter.h \
        tools/rbd_mirror/image_sync/ImageCopyRequest.h \
index 9e10add37e1b9b3081a2a3102c8b1626814e624c..357795a18afa227f12c582d6928a6ca95c1e111a 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "BootstrapRequest.h"
 #include "CloseImageRequest.h"
+#include "OpenImageRequest.h"
 #include "OpenLocalImageRequest.h"
 #include "common/debug.h"
 #include "common/dout.h"
@@ -274,12 +275,13 @@ void BootstrapRequest<I>::open_remote_image() {
 
   update_progress("OPEN_REMOTE_IMAGE");
 
-  m_remote_image_ctx = I::create("", m_remote_image_id, nullptr,
-                                 m_remote_io_ctx, false);
   Context *ctx = create_context_callback<
     BootstrapRequest<I>, &BootstrapRequest<I>::handle_open_remote_image>(
       this);
-  m_remote_image_ctx->state->open(ctx);
+  OpenImageRequest<I> *request = OpenImageRequest<I>::create(
+    m_remote_io_ctx, &m_remote_image_ctx, m_remote_image_id, false,
+    m_work_queue, ctx);
+  request->send();
 }
 
 template <typename I>
@@ -291,8 +293,8 @@ void BootstrapRequest<I>::handle_open_remote_image(int r) {
 
   if (r < 0) {
     derr << ": failed to open remote image: " << cpp_strerror(r) << dendl;
-    m_ret_val = r;
-    close_remote_image();
+    assert(m_remote_image_ctx == nullptr);
+    finish(r);
     return;
   }
 
diff --git a/src/tools/rbd_mirror/image_replayer/OpenImageRequest.cc b/src/tools/rbd_mirror/image_replayer/OpenImageRequest.cc
new file mode 100644 (file)
index 0000000..9cf6af2
--- /dev/null
@@ -0,0 +1,100 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "OpenImageRequest.h"
+#include "CloseImageRequest.h"
+#include "common/errno.h"
+#include "common/WorkQueue.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/Utils.h"
+#include <type_traits>
+
+#define dout_subsys ceph_subsys_rbd_mirror
+#undef dout_prefix
+#define dout_prefix *_dout << "rbd::mirror::image_replayer::OpenImageRequest: " \
+                           << this << " " << __func__ << " "
+
+namespace rbd {
+namespace mirror {
+namespace image_replayer {
+
+using librbd::util::create_context_callback;
+
+template <typename I>
+OpenImageRequest<I>::OpenImageRequest(librados::IoCtx &io_ctx, I **image_ctx,
+                                      const std::string &image_id,
+                                      bool read_only, ContextWQ *work_queue,
+                                      Context *on_finish)
+  : m_io_ctx(io_ctx), m_image_ctx(image_ctx), m_image_id(image_id),
+    m_read_only(read_only), m_work_queue(work_queue), m_on_finish(on_finish) {
+}
+
+template <typename I>
+void OpenImageRequest<I>::send() {
+  send_open_image();
+}
+
+template <typename I>
+void OpenImageRequest<I>::send_open_image() {
+  dout(20) << dendl;
+
+  *m_image_ctx = I::create("", m_image_id, nullptr, m_io_ctx, m_read_only);
+
+  Context *ctx = create_context_callback<
+    OpenImageRequest<I>, &OpenImageRequest<I>::handle_open_image>(
+      this);
+  (*m_image_ctx)->state->open(ctx);
+}
+
+template <typename I>
+void OpenImageRequest<I>::handle_open_image(int r) {
+  dout(20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    derr << ": failed to open image '" << m_image_id << "': "
+         << cpp_strerror(r) << dendl;
+    send_close_image(r);
+    return;
+  }
+
+  finish(0);
+}
+
+template <typename I>
+void OpenImageRequest<I>::send_close_image(int r) {
+  dout(20) << dendl;
+
+  if (m_ret_val == 0 && r < 0) {
+    m_ret_val = r;
+  }
+
+  Context *ctx = create_context_callback<
+    OpenImageRequest<I>, &OpenImageRequest<I>::handle_close_image>(
+      this);
+  CloseImageRequest<I> *request = CloseImageRequest<I>::create(
+    m_image_ctx, m_work_queue, true, ctx);
+  request->send();
+}
+
+template <typename I>
+void OpenImageRequest<I>::handle_close_image(int r) {
+  dout(20) << dendl;
+
+  assert(r == 0);
+  finish(m_ret_val);
+}
+
+template <typename I>
+void OpenImageRequest<I>::finish(int r) {
+  dout(20) << ": r=" << r << dendl;
+
+  m_on_finish->complete(r);
+  delete this;
+}
+
+} // namespace image_replayer
+} // namespace mirror
+} // namespace rbd
+
+template class rbd::mirror::image_replayer::OpenImageRequest<librbd::ImageCtx>;
diff --git a/src/tools/rbd_mirror/image_replayer/OpenImageRequest.h b/src/tools/rbd_mirror/image_replayer/OpenImageRequest.h
new file mode 100644 (file)
index 0000000..d9407c0
--- /dev/null
@@ -0,0 +1,76 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RBD_MIRROR_IMAGE_REPLAYER_OPEN_IMAGE_REQUEST_H
+#define RBD_MIRROR_IMAGE_REPLAYER_OPEN_IMAGE_REQUEST_H
+
+#include "include/int_types.h"
+#include "librbd/ImageCtx.h"
+#include <string>
+
+class Context;
+class ContextWQ;
+namespace librbd { class ImageCtx; }
+
+namespace rbd {
+namespace mirror {
+namespace image_replayer {
+
+template <typename ImageCtxT = librbd::ImageCtx>
+class OpenImageRequest {
+public:
+  static OpenImageRequest* create(librados::IoCtx &io_ctx,
+                                  ImageCtxT **image_ctx,
+                                  const std::string &image_id,
+                                  bool read_only, ContextWQ *work_queue,
+                                  Context *on_finish) {
+    return new OpenImageRequest(io_ctx, image_ctx, image_id, read_only,
+                                work_queue, on_finish);
+  }
+
+  OpenImageRequest(librados::IoCtx &io_ctx, ImageCtxT **image_ctx,
+                   const std::string &image_id, bool read_only,
+                   ContextWQ *m_work_queue, Context *on_finish);
+
+  void send();
+
+private:
+  /**
+   * @verbatim
+   *
+   * <start>
+   *    |
+   *    v
+   * OPEN_IMAGE * * * * * * * *
+   *    |                     *
+   *    v                     v
+   * <finish> <---------- CLOSE_IMAGE
+   *
+   * @endverbatim
+   */
+  librados::IoCtx &m_io_ctx;
+  ImageCtxT **m_image_ctx;
+  std::string m_image_id;
+  bool m_read_only;
+  ContextWQ *m_work_queue;
+  Context *m_on_finish;
+
+  int m_ret_val = 0;
+
+  void send_open_image();
+  void handle_open_image(int r);
+
+  void send_close_image(int r);
+  void handle_close_image(int r);
+
+  void finish(int r);
+
+};
+
+} // namespace image_replayer
+} // namespace mirror
+} // namespace rbd
+
+extern template class rbd::mirror::image_replayer::OpenImageRequest<librbd::ImageCtx>;
+
+#endif // RBD_MIRROR_IMAGE_REPLAYER_OPEN_IMAGE_REQUEST_H