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>
if (r < 0) {
*m_src_image_ctx = nullptr;
+ } else {
+ register_image_dispatch();
}
m_on_finish->complete(r);
mock_snapshot_interface, 0);
expect_snapshot_open(*mock_snapshot_interface, 0);
- SnapInfo snap_info{{}, {}, 123, {}, 0, 0, {}};
- expect_snapshot_get_info(*mock_snapshot_interface, snap_info);
expect_snapshot_close(*mock_snapshot_interface, 0);
mock_snapshot_interface, 0);
expect_snapshot_open(*mock_snapshot_interface, 0);
- SnapInfo snap_info{{}, {}, 123, {}, 0, 0, {}};
- expect_snapshot_get_info(*mock_snapshot_interface, snap_info);
expect_snapshot_close(*mock_snapshot_interface, 0);
mock_snapshot_interface, 0);
expect_snapshot_open(*mock_snapshot_interface, 0);
- SnapInfo snap_info{{}, {}, 123, {}, 0, 0, {}};
- expect_snapshot_get_info(*mock_snapshot_interface, snap_info);
+ SnapInfo snap_info{{}, {}, 123, {}, 0, 0, {}};
expect_snapshot_get_info(*mock_snapshot_interface, snap_info);
expect_snapshot_close(*mock_snapshot_interface, 0);
mock_snapshot_interface, 0);
expect_snapshot_open(*mock_snapshot_interface, 0);
- SnapInfo snap_info{{}, {}, 123, {}, 0, 0, {}};
- expect_snapshot_get_info(*mock_snapshot_interface, snap_info);
expect_snapshot_close(*mock_snapshot_interface, 0);
mock_snapshot_interface, 0);
expect_snapshot_open(*mock_snapshot_interface, 0);
- SnapInfo snap_info{{}, {}, 123, {}, 0, 0, {}};
- expect_snapshot_get_info(*mock_snapshot_interface, snap_info);
bufferlist expect_bl;
expect_bl.append(std::string(123, '1'));
mock_snapshot_interface, 0);
expect_snapshot_open(*mock_snapshot_interface, 0);
- SnapInfo snap_info{{}, {}, 123, {}, 0, 0, {}};
- expect_snapshot_get_info(*mock_snapshot_interface, snap_info);
+ SnapInfo snap_info{{}, {}, 123, {}, 0, 0, {}};
expect_snapshot_get_info(*mock_snapshot_interface, snap_info);
io::SparseExtents sparse_extents;
sparse_extents.insert(0, 123, {io::SPARSE_EXTENT_STATE_DATA, 123});
expect_snapshot_open(*mock_snapshot_interface, 0);
- SnapInfo snap_info{{}, {}, 123, {}, 0, 0, {}};
- expect_snapshot_get_info(*mock_snapshot_interface, snap_info);
+ SnapInfo snap_info{{}, {}, 123, {}, 0, 0, {}};
expect_snapshot_get_info(*mock_snapshot_interface, snap_info);
io::SparseExtents sparse_extents;
sparse_extents.insert(0, 123, {io::SPARSE_EXTENT_STATE_DATA, 123});
expect_snapshot_open(*mock_snapshot_interface_head, 0);
SnapInfo snap_info_head{{}, {}, 256, {}, 0, 0, {}};
- expect_snapshot_get_info(*mock_snapshot_interface_head, snap_info_head);
-
SnapInfo snap_info_1{snap_info_head};
snap_info_1.size = 123;
expect_snapshot_get_info(*mock_snapshot_interface_1, snap_info_1);