${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
#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"
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;
};
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
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 \
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 \
#include "BootstrapRequest.h"
#include "CloseImageRequest.h"
+#include "OpenImageRequest.h"
#include "OpenLocalImageRequest.h"
#include "common/debug.h"
#include "common/dout.h"
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>
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;
}
--- /dev/null
+// -*- 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>;
--- /dev/null
+// -*- 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