From: Jason Dillaman Date: Wed, 25 May 2016 19:16:28 +0000 (-0400) Subject: rbd-mirror: helper state machine to open remote/read-only images X-Git-Tag: v10.2.2~40^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2c2f4b251d0c8b870728293d06e9c853856c8092;p=ceph.git rbd-mirror: helper state machine to open remote/read-only images Signed-off-by: Jason Dillaman (cherry picked from commit 3731c3c34c15f8dcfbab444bdbf3c05976b03431) --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 423bbf6db665..3e7b3e6cde91 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -999,17 +999,18 @@ if(${WITH_RBD}) add_subdirectory(librbd) 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 diff --git a/src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc b/src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc index 0cec3a26e319..a36162796a1d 100644 --- a/src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc +++ b/src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc @@ -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 { MOCK_METHOD0(send, void()); }; +template<> +struct OpenImageRequest { + 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 { static OpenLocalImageRequest* s_instance; @@ -101,6 +125,7 @@ struct OpenLocalImageRequest { }; CloseImageRequest* CloseImageRequest::s_instance = nullptr; +OpenImageRequest* OpenImageRequest::s_instance = nullptr; OpenLocalImageRequest* OpenLocalImageRequest::s_instance = nullptr; } // namespace image_replayer diff --git a/src/tools/Makefile-client.am b/src/tools/Makefile-client.am index 8e4eecfd5d21..d92aa3fd0bda 100644 --- a/src/tools/Makefile-client.am +++ b/src/tools/Makefile-client.am @@ -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 \ diff --git a/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc b/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc index 9e10add37e1b..357795a18afa 100644 --- a/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc +++ b/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc @@ -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::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, &BootstrapRequest::handle_open_remote_image>( this); - m_remote_image_ctx->state->open(ctx); + OpenImageRequest *request = OpenImageRequest::create( + m_remote_io_ctx, &m_remote_image_ctx, m_remote_image_id, false, + m_work_queue, ctx); + request->send(); } template @@ -291,8 +293,8 @@ void BootstrapRequest::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 index 000000000000..9cf6af2b3219 --- /dev/null +++ b/src/tools/rbd_mirror/image_replayer/OpenImageRequest.cc @@ -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 + +#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 +OpenImageRequest::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 +void OpenImageRequest::send() { + send_open_image(); +} + +template +void OpenImageRequest::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, &OpenImageRequest::handle_open_image>( + this); + (*m_image_ctx)->state->open(ctx); +} + +template +void OpenImageRequest::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 +void OpenImageRequest::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, &OpenImageRequest::handle_close_image>( + this); + CloseImageRequest *request = CloseImageRequest::create( + m_image_ctx, m_work_queue, true, ctx); + request->send(); +} + +template +void OpenImageRequest::handle_close_image(int r) { + dout(20) << dendl; + + assert(r == 0); + finish(m_ret_val); +} + +template +void OpenImageRequest::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; diff --git a/src/tools/rbd_mirror/image_replayer/OpenImageRequest.h b/src/tools/rbd_mirror/image_replayer/OpenImageRequest.h new file mode 100644 index 000000000000..d9407c052b16 --- /dev/null +++ b/src/tools/rbd_mirror/image_replayer/OpenImageRequest.h @@ -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 + +class Context; +class ContextWQ; +namespace librbd { class ImageCtx; } + +namespace rbd { +namespace mirror { +namespace image_replayer { + +template +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 + * + * + * | + * v + * OPEN_IMAGE * * * * * * * * + * | * + * v v + * <---------- 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; + +#endif // RBD_MIRROR_IMAGE_REPLAYER_OPEN_IMAGE_REQUEST_H