diff options
Diffstat (limited to 'src/librbd/migration/OpenSourceImageRequest.cc')
-rw-r--r-- | src/librbd/migration/OpenSourceImageRequest.cc | 144 |
1 files changed, 123 insertions, 21 deletions
diff --git a/src/librbd/migration/OpenSourceImageRequest.cc b/src/librbd/migration/OpenSourceImageRequest.cc index 499525395d3..e19739b5e11 100644 --- a/src/librbd/migration/OpenSourceImageRequest.cc +++ b/src/librbd/migration/OpenSourceImageRequest.cc @@ -5,6 +5,7 @@ #include "common/dout.h" #include "common/errno.h" #include "librbd/ImageCtx.h" +#include "librbd/ImageState.h" #include "librbd/Utils.h" #include "librbd/io/ImageDispatcher.h" #include "librbd/migration/ImageDispatch.h" @@ -21,13 +22,13 @@ namespace migration { template <typename I> OpenSourceImageRequest<I>::OpenSourceImageRequest( - I* dst_image_ctx, uint64_t src_snap_id, + librados::IoCtx& io_ctx, 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_cct(reinterpret_cast<CephContext*>(io_ctx.cct())), m_io_ctx(io_ctx), + 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; + ldout(m_cct, 10) << dendl; } template <typename I> @@ -37,12 +38,10 @@ void OpenSourceImageRequest<I>::send() { template <typename I> void OpenSourceImageRequest<I>::open_source() { - auto cct = m_dst_image_ctx->cct; - ldout(cct, 10) << dendl; + ldout(m_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 = I::create("", "", m_src_snap_id, m_io_ctx, true); auto src_image_ctx = *m_src_image_ctx; src_image_ctx->child = m_dst_image_ctx; @@ -69,8 +68,9 @@ void OpenSourceImageRequest<I>::open_source() { int r = source_spec_builder.parse_source_spec(source_spec, &source_spec_object); if (r < 0) { - lderr(cct) << "failed to parse migration source-spec:" << cpp_strerror(r) - << dendl; + lderr(m_cct) << "failed to parse migration source-spec:" << cpp_strerror(r) + << dendl; + (*m_src_image_ctx)->state->close(); finish(r); return; } @@ -78,8 +78,9 @@ void OpenSourceImageRequest<I>::open_source() { r = source_spec_builder.build_format(source_spec_object, import_only, &m_format); if (r < 0) { - lderr(cct) << "failed to build migration format handler: " - << cpp_strerror(r) << dendl; + lderr(m_cct) << "failed to build migration format handler: " + << cpp_strerror(r) << dendl; + (*m_src_image_ctx)->state->close(); finish(r); return; } @@ -92,33 +93,134 @@ void OpenSourceImageRequest<I>::open_source() { template <typename I> void OpenSourceImageRequest<I>::handle_open_source(int r) { - auto cct = m_dst_image_ctx->cct; - ldout(cct, 10) << "r=" << r << dendl; + ldout(m_cct, 10) << "r=" << r << dendl; if (r < 0) { - lderr(cct) << "failed to open migration source: " << cpp_strerror(r) - << dendl; + lderr(m_cct) << "failed to open migration source: " << cpp_strerror(r) + << dendl; finish(r); return; } + get_image_size(); +} + +template <typename I> +void OpenSourceImageRequest<I>::get_image_size() { + ldout(m_cct, 10) << dendl; + + auto ctx = util::create_context_callback< + OpenSourceImageRequest<I>, + &OpenSourceImageRequest<I>::handle_get_image_size>(this); + m_format->get_image_size(CEPH_NOSNAP, &m_image_size, ctx); +} + +template <typename I> +void OpenSourceImageRequest<I>::handle_get_image_size(int r) { + ldout(m_cct, 10) << "r=" << r << ", " + << "image_size=" << m_image_size << dendl; + + if (r < 0) { + lderr(m_cct) << "failed to retrieve image size: " << cpp_strerror(r) + << dendl; + close_image(r); + return; + } + + auto src_image_ctx = *m_src_image_ctx; + src_image_ctx->image_lock.lock(); + src_image_ctx->size = m_image_size; + src_image_ctx->image_lock.unlock(); + + get_snapshots(); +} + +template <typename I> +void OpenSourceImageRequest<I>::get_snapshots() { + ldout(m_cct, 10) << dendl; + + auto ctx = util::create_context_callback< + OpenSourceImageRequest<I>, + &OpenSourceImageRequest<I>::handle_get_snapshots>(this); + m_format->get_snapshots(&m_snap_infos, ctx); +} + +template <typename I> +void OpenSourceImageRequest<I>::handle_get_snapshots(int r) { + ldout(m_cct, 10) << "r=" << r << dendl; + + if (r < 0) { + lderr(m_cct) << "failed to retrieve snapshots: " << cpp_strerror(r) + << dendl; + close_image(r); + return; + } + + // copy snapshot metadata to image ctx + auto src_image_ctx = *m_src_image_ctx; + src_image_ctx->image_lock.lock(); + + src_image_ctx->snaps.clear(); + src_image_ctx->snap_info.clear(); + src_image_ctx->snap_ids.clear(); + + ::SnapContext snapc; + for (auto it = m_snap_infos.rbegin(); it != m_snap_infos.rend(); ++it) { + auto& [snap_id, snap_info] = *it; + snapc.snaps.push_back(snap_id); + + src_image_ctx->add_snap( + snap_info.snap_namespace, snap_info.name, snap_id, + snap_info.size, snap_info.parent, snap_info.protection_status, + snap_info.flags, snap_info.timestamp); + } + if (!snapc.snaps.empty()) { + snapc.seq = snapc.snaps[0]; + } + src_image_ctx->snapc = snapc; + + // ensure data_ctx and data_io_context are pointing to correct snapshot + if (src_image_ctx->open_snap_id != CEPH_NOSNAP) { + int r = src_image_ctx->snap_set(src_image_ctx->open_snap_id); + ceph_assert(r == 0); + src_image_ctx->open_snap_id = CEPH_NOSNAP; + } + + src_image_ctx->image_lock.unlock(); + + finish(0); +} + +template <typename I> +void OpenSourceImageRequest<I>::close_image(int r) { + ldout(m_cct, 10) << "r=" << r << dendl; + + auto ctx = new LambdaContext([this, r](int) { + finish(r); + }); + (*m_src_image_ctx)->state->close(ctx); +} + +template <typename I> +void OpenSourceImageRequest<I>::register_image_dispatch() { + ldout(m_cct, 10) << dendl; + // intercept any IO requests to the source image auto io_image_dispatch = ImageDispatch<I>::create( *m_src_image_ctx, std::move(m_format)); (*m_src_image_ctx)->io_image_dispatcher->register_dispatch(io_image_dispatch); - - finish(0); } template <typename I> void OpenSourceImageRequest<I>::finish(int r) { - auto cct = m_dst_image_ctx->cct; - ldout(cct, 10) << "r=" << r << dendl; + ldout(m_cct, 10) << "r=" << r << dendl; if (r < 0) { - delete *m_src_image_ctx; *m_src_image_ctx = nullptr; + } else { + register_image_dispatch(); } + m_on_finish->complete(r); delete this; } |