From: Jason Dillaman Date: Wed, 14 Oct 2020 20:03:47 +0000 (-0400) Subject: librbd: new migration IO image dispatch layer X-Git-Tag: v16.1.0~752^2~11 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1c47afb1974408749b7f2f951e652063c1980da5;p=ceph.git librbd: new migration IO image dispatch layer The initial hooks merely abstract the standard RBD parent/child clone relationship. The basic interface, however, is abstract enough to allow third party data formats and streams to be eventually integrated with RBD live-migration. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/CMakeLists.txt b/src/librbd/CMakeLists.txt index 291b95d39ad6..677b240a5fa1 100644 --- a/src/librbd/CMakeLists.txt +++ b/src/librbd/CMakeLists.txt @@ -116,6 +116,9 @@ set(librbd_internal_srcs managed_lock/ReacquireRequest.cc managed_lock/ReleaseRequest.cc managed_lock/Utils.cc + migration/ImageDispatch.cc + migration/NativeFormat.cc + migration/OpenSourceImageRequest.cc mirror/DemoteRequest.cc mirror/DisableRequest.cc mirror/EnableRequest.cc diff --git a/src/librbd/io/Types.h b/src/librbd/io/Types.h index a41d1e9f2374..b0428a0ba753 100644 --- a/src/librbd/io/Types.h +++ b/src/librbd/io/Types.h @@ -62,6 +62,7 @@ enum ImageDispatchLayer { IMAGE_DISPATCH_LAYER_EXCLUSIVE_LOCK, IMAGE_DISPATCH_LAYER_REFRESH, IMAGE_DISPATCH_LAYER_INTERNAL_START = IMAGE_DISPATCH_LAYER_REFRESH, + IMAGE_DISPATCH_LAYER_MIGRATION, IMAGE_DISPATCH_LAYER_JOURNAL, IMAGE_DISPATCH_LAYER_WRITE_BLOCK, IMAGE_DISPATCH_LAYER_WRITEBACK_CACHE, diff --git a/src/librbd/migration/FormatInterface.h b/src/librbd/migration/FormatInterface.h new file mode 100644 index 000000000000..27669dd51169 --- /dev/null +++ b/src/librbd/migration/FormatInterface.h @@ -0,0 +1,53 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_MIGRATION_FORMAT_INTERFACE_H +#define CEPH_LIBRBD_MIGRATION_FORMAT_INTERFACE_H + +#include "include/buffer_fwd.h" +#include "include/int_types.h" +#include "common/zipkin_trace.h" +#include "librbd/Types.h" +#include "librbd/io/Types.h" +#include + +struct Context; + +namespace librbd { + +namespace io { +struct AioCompletion; +struct ReadResult; +} // namespace io + +namespace migration { + +struct FormatInterface { + typedef std::map SnapInfos; + + virtual ~FormatInterface() { + } + + virtual void open(Context* on_finish) = 0; + virtual void close(Context* on_finish) = 0; + + virtual void get_snapshots(SnapInfos* snap_infos, Context* on_finish) = 0; + virtual void get_image_size(uint64_t snap_id, uint64_t* size, + Context* on_finish) = 0; + + virtual void read(io::AioCompletion* aio_comp, uint64_t snap_id, + io::Extents&& image_extents, io::ReadResult&& read_result, + int op_flags, int read_flags, + const ZTracer::Trace &parent_trace) = 0; + + virtual void list_snaps(io::Extents&& image_extents, io::SnapIds&& snap_ids, + int list_snaps_flags, + io::SnapshotDelta* snapshot_delta, + const ZTracer::Trace &parent_trace, + Context* on_finish) = 0; +}; + +} // namespace migration +} // namespace librbd + +#endif // CEPH_LIBRBD_MIGRATION_FORMAT_INTERFACE_H diff --git a/src/librbd/migration/ImageDispatch.cc b/src/librbd/migration/ImageDispatch.cc new file mode 100644 index 000000000000..bde0a6951c7d --- /dev/null +++ b/src/librbd/migration/ImageDispatch.cc @@ -0,0 +1,158 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "librbd/migration/ImageDispatch.h" +#include "include/neorados/RADOS.hpp" +#include "common/dout.h" +#include "librbd/ImageCtx.h" +#include "librbd/io/AioCompletion.h" +#include "librbd/migration/FormatInterface.h" + +#define dout_subsys ceph_subsys_rbd +#undef dout_prefix +#define dout_prefix *_dout << "librbd::migration::ImageDispatch: " << this \ + << " " << __func__ << ": " + +namespace librbd { +namespace migration { + +template +ImageDispatch::ImageDispatch(I* image_ctx, + std::unique_ptr format) + : m_image_ctx(image_ctx), m_format(std::move(format)) { + auto cct = m_image_ctx->cct; + ldout(cct, 10) << "ictx=" << image_ctx << dendl; +} + +template +void ImageDispatch::shut_down(Context* on_finish) { + auto cct = m_image_ctx->cct; + ldout(cct, 10) << dendl; + + on_finish->complete(0); +} + +template +bool ImageDispatch::read( + io::AioCompletion* aio_comp, io::Extents &&image_extents, + io::ReadResult &&read_result, IOContext io_context, int op_flags, + int read_flags, const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) { + auto cct = m_image_ctx->cct; + ldout(cct, 20) << dendl; + + *dispatch_result = io::DISPATCH_RESULT_COMPLETE; + m_format->read(aio_comp, io_context->read_snap().value_or(CEPH_NOSNAP), + std::move(image_extents), std::move(read_result), op_flags, + read_flags, parent_trace); + return true; +} + +template +bool ImageDispatch::write( + io::AioCompletion* aio_comp, io::Extents &&image_extents, bufferlist &&bl, + IOContext io_context, int op_flags, const ZTracer::Trace &parent_trace, + uint64_t tid, std::atomic* image_dispatch_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) { + auto cct = m_image_ctx->cct; + lderr(cct) << dendl; + + fail_io(-EROFS, aio_comp, dispatch_result); + return true; +} + +template +bool ImageDispatch::discard( + io::AioCompletion* aio_comp, io::Extents &&image_extents, + uint32_t discard_granularity_bytes, + IOContext io_context, const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) { + auto cct = m_image_ctx->cct; + lderr(cct) << dendl; + + fail_io(-EROFS, aio_comp, dispatch_result); + return true; +} + +template +bool ImageDispatch::write_same( + io::AioCompletion* aio_comp, io::Extents &&image_extents, bufferlist &&bl, + IOContext io_context, int op_flags, const ZTracer::Trace &parent_trace, + uint64_t tid, std::atomic* image_dispatch_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) { + auto cct = m_image_ctx->cct; + lderr(cct) << dendl; + + fail_io(-EROFS, aio_comp, dispatch_result); + return true; +} + +template +bool ImageDispatch::compare_and_write( + io::AioCompletion* aio_comp, io::Extents &&image_extents, + bufferlist &&cmp_bl, bufferlist &&bl, uint64_t *mismatch_offset, + IOContext io_context, int op_flags, const ZTracer::Trace &parent_trace, + uint64_t tid, std::atomic* image_dispatch_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) { + auto cct = m_image_ctx->cct; + lderr(cct) << dendl; + + fail_io(-EROFS, aio_comp, dispatch_result); + return true; +} + +template +bool ImageDispatch::flush( + io::AioCompletion* aio_comp, io::FlushSource flush_source, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) { + auto cct = m_image_ctx->cct; + ldout(cct, 20) << dendl; + + *dispatch_result = io::DISPATCH_RESULT_COMPLETE; + aio_comp->set_request_count(0); + return true; +} + +template +bool ImageDispatch::list_snaps( + io::AioCompletion* aio_comp, io::Extents&& image_extents, + io::SnapIds&& snap_ids, int list_snaps_flags, + io::SnapshotDelta* snapshot_delta, const ZTracer::Trace &parent_trace, + uint64_t tid, std::atomic* image_dispatch_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) { + auto cct = m_image_ctx->cct; + ldout(cct, 20) << dendl; + + *dispatch_result = io::DISPATCH_RESULT_COMPLETE; + + aio_comp->set_request_count(1); + auto ctx = new io::C_AioRequest(aio_comp); + + m_format->list_snaps(std::move(image_extents), std::move(snap_ids), + list_snaps_flags, snapshot_delta, parent_trace, + ctx); + return true; +} + +template +void ImageDispatch::fail_io(int r, io::AioCompletion* aio_comp, + io::DispatchResult* dispatch_result) { + *dispatch_result = io::DISPATCH_RESULT_COMPLETE; + aio_comp->fail(r); +} + +} // namespace migration +} // namespace librbd + +template class librbd::migration::ImageDispatch; diff --git a/src/librbd/migration/ImageDispatch.h b/src/librbd/migration/ImageDispatch.h new file mode 100644 index 000000000000..490ea2d3987f --- /dev/null +++ b/src/librbd/migration/ImageDispatch.h @@ -0,0 +1,98 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_MIGRATION_IMAGE_DISPATCH_H +#define CEPH_LIBRBD_MIGRATION_IMAGE_DISPATCH_H + +#include "librbd/io/ImageDispatchInterface.h" +#include + +struct Context; + +namespace librbd { + +struct ImageCtx; + +namespace migration { + +struct FormatInterface; + +template +class ImageDispatch : public io::ImageDispatchInterface { +public: + static ImageDispatch* create(ImageCtxT* image_ctx, + std::unique_ptr source) { + return new ImageDispatch(image_ctx, std::move(source)); + } + + ImageDispatch(ImageCtxT* image_ctx, std::unique_ptr source); + + void shut_down(Context* on_finish) override; + + io::ImageDispatchLayer get_dispatch_layer() const override { + return io::IMAGE_DISPATCH_LAYER_MIGRATION; + } + + bool read( + io::AioCompletion* aio_comp, io::Extents &&image_extents, + io::ReadResult &&read_result, IOContext io_context, int op_flags, + int read_flags, const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override; + bool write( + io::AioCompletion* aio_comp, io::Extents &&image_extents, bufferlist &&bl, + IOContext io_context, int op_flags, const ZTracer::Trace &parent_trace, + uint64_t tid, std::atomic* image_dispatch_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override; + bool discard( + io::AioCompletion* aio_comp, io::Extents &&image_extents, + uint32_t discard_granularity_bytes, + IOContext io_context, const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override; + bool write_same( + io::AioCompletion* aio_comp, io::Extents &&image_extents, bufferlist &&bl, + IOContext io_context, int op_flags, const ZTracer::Trace &parent_trace, + uint64_t tid, std::atomic* image_dispatch_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override; + bool compare_and_write( + io::AioCompletion* aio_comp, io::Extents &&image_extents, + bufferlist &&cmp_bl, bufferlist &&bl, uint64_t *mismatch_offset, + IOContext io_context, int op_flags, const ZTracer::Trace &parent_trace, + uint64_t tid, std::atomic* image_dispatch_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override; + bool flush( + io::AioCompletion* aio_comp, io::FlushSource flush_source, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override; + + bool list_snaps( + io::AioCompletion* aio_comp, io::Extents&& image_extents, + io::SnapIds&& snap_ids, int list_snaps_flags, + io::SnapshotDelta* snapshot_delta, const ZTracer::Trace &parent_trace, + uint64_t tid, std::atomic* image_dispatch_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override; + +private: + ImageCtxT* m_image_ctx; + std::unique_ptr m_format; + + void fail_io(int r, io::AioCompletion* aio_comp, + io::DispatchResult* dispatch_result); + +}; + +} // namespace migration +} // namespace librbd + +extern template class librbd::migration::ImageDispatch; + +#endif // CEPH_LIBRBD_MIGRATION_IMAGE_DISPATCH_H diff --git a/src/librbd/migration/NativeFormat.cc b/src/librbd/migration/NativeFormat.cc new file mode 100644 index 000000000000..bf6a78fc53f8 --- /dev/null +++ b/src/librbd/migration/NativeFormat.cc @@ -0,0 +1,142 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "librbd/migration/NativeFormat.h" +#include "include/neorados/RADOS.hpp" +#include "common/dout.h" +#include "librbd/ImageCtx.h" +#include "librbd/ImageState.h" +#include "librbd/Utils.h" +#include "librbd/asio/ContextWQ.h" +#include "librbd/io/ImageDispatchSpec.h" + +#define dout_subsys ceph_subsys_rbd +#undef dout_prefix +#define dout_prefix *_dout << "librbd::migration::NativeFormat: " << this \ + << " " << __func__ << ": " + +namespace librbd { +namespace migration { + +template +NativeFormat::NativeFormat( + I* image_ctx, const MigrationInfo& migration_info) + : m_image_ctx(image_ctx), m_migration_info(migration_info) { +} + +template +void NativeFormat::open(Context* on_finish) { + auto cct = m_image_ctx->cct; + ldout(cct, 10) << dendl; + + // TODO add support for external clusters + librados::IoCtx io_ctx; + int r = util::create_ioctx(m_image_ctx->md_ctx, "source image", + m_migration_info.pool_id, + m_migration_info.pool_namespace, &io_ctx); + if (r < 0) { + on_finish->complete(r); + return; + } + + m_image_ctx->md_ctx.dup(io_ctx); + m_image_ctx->data_ctx.dup(io_ctx); + + uint64_t flags = 0; + if (m_migration_info.image_id.empty()) { + m_image_ctx->name = m_migration_info.image_name; + flags |= OPEN_FLAG_OLD_FORMAT; + } else { + m_image_ctx->id = m_migration_info.image_id; + } + + // set rados flags for reading the parent image + if (m_image_ctx->child->config.template get_val("rbd_balance_parent_reads")) { + m_image_ctx->set_read_flag(librados::OPERATION_BALANCE_READS); + } else if (m_image_ctx->child->config.template get_val("rbd_localize_parent_reads")) { + m_image_ctx->set_read_flag(librados::OPERATION_LOCALIZE_READS); + } + + // open the source RBD image + auto ctx = util::create_async_context_callback(*m_image_ctx, on_finish); + m_image_ctx->state->open(flags, ctx); +} + +template +void NativeFormat::close(Context* on_finish) { + auto cct = m_image_ctx->cct; + ldout(cct, 10) << dendl; + + // the native librbd::image::CloseRequest handles all cleanup + on_finish->complete(0); +} + +template +void NativeFormat::get_snapshots(SnapInfos* snap_infos, Context* on_finish) { + auto cct = m_image_ctx->cct; + ldout(cct, 10) << dendl; + + m_image_ctx->image_lock.lock_shared(); + *snap_infos = m_image_ctx->snap_info; + m_image_ctx->image_lock.unlock_shared(); + + on_finish->complete(0); +} + +template +void NativeFormat::get_image_size(uint64_t snap_id, uint64_t* size, + Context* on_finish) { + auto cct = m_image_ctx->cct; + ldout(cct, 10) << dendl; + + m_image_ctx->image_lock.lock_shared(); + *size = m_image_ctx->get_image_size(snap_id); + m_image_ctx->image_lock.unlock_shared(); + + + on_finish->complete(0); +} + +template +void NativeFormat::read( + io::AioCompletion* aio_comp, uint64_t snap_id, io::Extents&& image_extents, + io::ReadResult&& read_result, int op_flags, int read_flags, + const ZTracer::Trace &parent_trace) { + auto cct = m_image_ctx->cct; + ldout(cct, 20) << "snap_id=" << snap_id << ", " + << "image_extents=" << image_extents << dendl; + + auto io_context = m_image_ctx->duplicate_data_io_context(); + if (snap_id != CEPH_NOSNAP) { + io_context->read_snap(snap_id); + } + + auto req = io::ImageDispatchSpec::create_read( + *m_image_ctx, io::IMAGE_DISPATCH_LAYER_MIGRATION, aio_comp, + std::move(image_extents), std::move(read_result), io_context, op_flags, + read_flags, {}); + req->send(); +} + +template +void NativeFormat::list_snaps(io::Extents&& image_extents, + io::SnapIds&& snap_ids, int list_snaps_flags, + io::SnapshotDelta* snapshot_delta, + const ZTracer::Trace &parent_trace, + Context* on_finish) { + auto cct = m_image_ctx->cct; + ldout(cct, 20) << "image_extents=" << image_extents << dendl; + + auto aio_comp = io::AioCompletion::create_and_start( + on_finish, util::get_image_ctx(m_image_ctx), io::AIO_TYPE_GENERIC); + auto req = io::ImageDispatchSpec::create_list_snaps( + *m_image_ctx, io::IMAGE_DISPATCH_LAYER_MIGRATION, aio_comp, + std::move(image_extents), std::move(snap_ids), list_snaps_flags, + snapshot_delta, {}); + req->send(); +} + +} // namespace migration +} // namespace librbd + +template class librbd::migration::NativeFormat; diff --git a/src/librbd/migration/NativeFormat.h b/src/librbd/migration/NativeFormat.h new file mode 100644 index 000000000000..0f0d43adc390 --- /dev/null +++ b/src/librbd/migration/NativeFormat.h @@ -0,0 +1,61 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_MIGRATION_NATIVE_FORMAT_H +#define CEPH_LIBRBD_MIGRATION_NATIVE_FORMAT_H + +#include "include/int_types.h" +#include "librbd/Types.h" +#include "librbd/migration/FormatInterface.h" +#include + +struct Context; + +namespace librbd { + +struct AsioEngine; +struct ImageCtx; + +namespace migration { + +template +class NativeFormat : public FormatInterface { +public: + static NativeFormat* create(ImageCtxT* image_ctx, + const MigrationInfo& migration_info) { + return new NativeFormat(image_ctx, migration_info); + } + + NativeFormat(ImageCtxT* image_ctx, const MigrationInfo& migration_info); + NativeFormat(const NativeFormat&) = delete; + NativeFormat& operator=(const NativeFormat&) = delete; + + void open(Context* on_finish) override; + void close(Context* on_finish) override; + + void get_snapshots(SnapInfos* snap_infos, Context* on_finish) override; + void get_image_size(uint64_t snap_id, uint64_t* size, + Context* on_finish) override; + + void read(io::AioCompletion* aio_comp, uint64_t snap_id, + io::Extents&& image_extents, io::ReadResult&& read_result, + int op_flags, int read_flags, + const ZTracer::Trace &parent_trace) override; + + void list_snaps(io::Extents&& image_extents, io::SnapIds&& snap_ids, + int list_snaps_flags, io::SnapshotDelta* snapshot_delta, + const ZTracer::Trace &parent_trace, + Context* on_finish) override; + +private: + ImageCtxT* m_image_ctx; + MigrationInfo m_migration_info; + +}; + +} // namespace migration +} // namespace librbd + +extern template class librbd::migration::NativeFormat; + +#endif // CEPH_LIBRBD_MIGRATION_NATIVE_FORMAT_H diff --git a/src/librbd/migration/OpenSourceImageRequest.cc b/src/librbd/migration/OpenSourceImageRequest.cc new file mode 100644 index 000000000000..0fc80d40a520 --- /dev/null +++ b/src/librbd/migration/OpenSourceImageRequest.cc @@ -0,0 +1,93 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "librbd/migration/OpenSourceImageRequest.h" +#include "common/dout.h" +#include "common/errno.h" +#include "librbd/ImageCtx.h" +#include "librbd/Utils.h" +#include "librbd/io/ImageDispatcher.h" +#include "librbd/migration/ImageDispatch.h" +#include "librbd/migration/NativeFormat.h" + +#define dout_subsys ceph_subsys_rbd +#undef dout_prefix +#define dout_prefix *_dout << "librbd::migration::OpenSourceImageRequest: " \ + << this << " " << __func__ << ": " + +namespace librbd { +namespace migration { + +template +OpenSourceImageRequest::OpenSourceImageRequest( + I* dst_image_ctx, uint64_t src_snap_id, + const MigrationInfo &migration_info, I** src_image_ctx, Context* on_finish) + : m_dst_image_ctx(dst_image_ctx), m_src_snap_id(src_snap_id), + m_migration_info(migration_info), m_src_image_ctx(src_image_ctx), + m_on_finish(on_finish) { + auto cct = m_dst_image_ctx->cct; + ldout(cct, 10) << dendl; +} + +template +void OpenSourceImageRequest::send() { + open_source(); +} + +template +void OpenSourceImageRequest::open_source() { + auto cct = m_dst_image_ctx->cct; + ldout(cct, 10) << dendl; + + // note that all source image ctx properties are placeholders + *m_src_image_ctx = I::create("", "", m_src_snap_id, + m_dst_image_ctx->md_ctx, true); + (*m_src_image_ctx)->child = m_dst_image_ctx; + + // TODO use factory once multiple sources are available + m_format = std::unique_ptr(NativeFormat::create( + *m_src_image_ctx, m_migration_info)); + + auto ctx = util::create_context_callback< + OpenSourceImageRequest, + &OpenSourceImageRequest::handle_open_source>(this); + m_format->open(ctx); +} + +template +void OpenSourceImageRequest::handle_open_source(int r) { + auto cct = m_dst_image_ctx->cct; + ldout(cct, 10) << "r=" << r << dendl; + + if (r < 0) { + lderr(cct) << "failed to open migration source: " << cpp_strerror(r) + << dendl; + finish(r); + return; + } + + // intercept any IO requests to the source image + auto io_image_dispatch = ImageDispatch::create( + *m_src_image_ctx, std::move(m_format)); + (*m_src_image_ctx)->io_image_dispatcher->register_dispatch(io_image_dispatch); + + finish(0); +} + +template +void OpenSourceImageRequest::finish(int r) { + auto cct = m_dst_image_ctx->cct; + ldout(cct, 10) << "r=" << r << dendl; + + if (r < 0) { + delete *m_src_image_ctx; + *m_src_image_ctx = nullptr; + } + m_on_finish->complete(r); + delete this; +} + +} // namespace migration +} // namespace librbd + +template class librbd::migration::OpenSourceImageRequest; diff --git a/src/librbd/migration/OpenSourceImageRequest.h b/src/librbd/migration/OpenSourceImageRequest.h new file mode 100644 index 000000000000..1ad247686a1d --- /dev/null +++ b/src/librbd/migration/OpenSourceImageRequest.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 CEPH_LIBRBD_MIGRATION_OPEN_SOURCE_IMAGE_REQUEST_H +#define CEPH_LIBRBD_MIGRATION_OPEN_SOURCE_IMAGE_REQUEST_H + +#include "librbd/Types.h" +#include + +struct Context; + +namespace librbd { + +struct ImageCtx; + +namespace migration { + +struct FormatInterface; + +template +class OpenSourceImageRequest { +public: + static OpenSourceImageRequest* create(ImageCtxT* destination_image_ctx, + uint64_t src_snap_id, + const MigrationInfo &migration_info, + ImageCtxT** source_image_ctx, + Context* on_finish) { + return new OpenSourceImageRequest(destination_image_ctx, src_snap_id, + migration_info, source_image_ctx, + on_finish); + } + + OpenSourceImageRequest(ImageCtxT* destination_image_ctx, + uint64_t src_snap_id, + const MigrationInfo &migration_info, + ImageCtxT** source_image_ctx, + Context* on_finish); + + void send(); + +private: + /** + * @verbatim + * + * + * | + * v + * OPEN_SOURCE + * | + * v + * + * + * @endverbatim + */ + + ImageCtxT* m_dst_image_ctx; + uint64_t m_src_snap_id; + MigrationInfo m_migration_info; + ImageCtxT** m_src_image_ctx; + Context* m_on_finish; + + std::unique_ptr m_format; + + void open_source(); + void handle_open_source(int r); + + void finish(int r); + +}; + +} // namespace migration +} // namespace librbd + +extern template class librbd::migration::OpenSourceImageRequest; + +#endif // CEPH_LIBRBD_MIGRATION_OPEN_SOURCE_IMAGE_REQUEST_H