From e6918187568dbd01842d8d1d2c808ce16a894239 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 21 Apr 2024 13:54:28 +0200 Subject: Adding upstream version 18.2.2. Signed-off-by: Daniel Baumann --- src/librbd/migration/QCOWFormat.h | 211 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 src/librbd/migration/QCOWFormat.h (limited to 'src/librbd/migration/QCOWFormat.h') diff --git a/src/librbd/migration/QCOWFormat.h b/src/librbd/migration/QCOWFormat.h new file mode 100644 index 000000000..b36506716 --- /dev/null +++ b/src/librbd/migration/QCOWFormat.h @@ -0,0 +1,211 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_MIGRATION_QCOW_FORMAT_H +#define CEPH_LIBRBD_MIGRATION_QCOW_FORMAT_H + +#include "include/int_types.h" +#include "librbd/Types.h" +#include "librbd/migration/FormatInterface.h" +#include "librbd/migration/QCOW.h" +#include "acconfig.h" +#include "json_spirit/json_spirit.h" +#include +#include +#include +#include +#include + +struct Context; + +namespace librbd { + +struct AsioEngine; +struct ImageCtx; + +namespace migration { + +template struct SourceSpecBuilder; +struct StreamInterface; + +namespace qcow_format { + +struct LookupTable { + LookupTable() {} + LookupTable(uint32_t size) : size(size) {} + + bufferlist bl; + uint64_t* cluster_offsets = nullptr; + uint32_t size = 0; + bool decoded = false; + + void init(); + void decode(); +}; + +} // namespace qcow_format + +template +class QCOWFormat : public FormatInterface { +public: + static QCOWFormat* create( + ImageCtxT* image_ctx, const json_spirit::mObject& json_object, + const SourceSpecBuilder* source_spec_builder) { + return new QCOWFormat(image_ctx, json_object, source_spec_builder); + } + + QCOWFormat(ImageCtxT* image_ctx, const json_spirit::mObject& json_object, + const SourceSpecBuilder* source_spec_builder); + QCOWFormat(const QCOWFormat&) = delete; + QCOWFormat& operator=(const QCOWFormat&) = 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; + + bool 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: + /** + * @verbatim + * + * + * | + * v + * OPEN + * | + * v + * PROBE + * | + * |\---> READ V1 HEADER ----------\ + * | | + * \----> READ V2 HEADER | + * | | + * | /----------\ | + * | | | | + * v v | | + * READ SNAPSHOT | | + * | | | + * v | | + * READ SNAPSHOT EXTRA | | + * | | | + * v | | + * READ SNAPSHOT L1 TABLE | + * | | + * \--------------------\| + * | + * v + * READ L1 TABLE + * | + * v + * READ BACKING FILE + * | + * /-------------------------------/ + * | + * v + * + * + * @endverbatim + */ + + struct Cluster; + struct ClusterCache; + struct L2TableCache; + struct ReadRequest; + struct ListSnapsRequest; + + struct Snapshot { + std::string id; + std::string name; + + utime_t timestamp; + uint64_t size = 0; + + uint64_t l1_table_offset = 0; + qcow_format::LookupTable l1_table; + + uint32_t extra_data_size = 0; + }; + + ImageCtxT* m_image_ctx; + json_spirit::mObject m_json_object; + const SourceSpecBuilder* m_source_spec_builder; + + boost::asio::io_context::strand m_strand; + std::shared_ptr m_stream; + + bufferlist m_bl; + + uint64_t m_size = 0; + + uint64_t m_backing_file_offset = 0; + uint32_t m_backing_file_size = 0; + + uint32_t m_cluster_bits = 0; + uint32_t m_cluster_size = 0; + uint64_t m_cluster_offset_mask = 0; + uint64_t m_cluster_mask = 0; + + uint32_t m_l1_shift = 0; + uint64_t m_l1_table_offset = 0; + qcow_format::LookupTable m_l1_table; + + uint32_t m_l2_bits = 0; + uint32_t m_l2_size = 0; + + uint32_t m_snapshot_count = 0; + uint64_t m_snapshots_offset = 0; + std::map m_snapshots; + + std::unique_ptr m_l2_table_cache; + std::unique_ptr m_cluster_cache; + + void handle_open(int r, Context* on_finish); + + void probe(Context* on_finish); + void handle_probe(int r, Context* on_finish); + +#ifdef WITH_RBD_MIGRATION_FORMAT_QCOW_V1 + void read_v1_header(Context* on_finish); + void handle_read_v1_header(int r, Context* on_finish); +#endif // WITH_RBD_MIGRATION_FORMAT_QCOW_V1 + + void read_v2_header(Context* on_finish); + void handle_read_v2_header(int r, Context* on_finish); + + void read_snapshot(Context* on_finish); + void handle_read_snapshot(int r, Context* on_finish); + + void read_snapshot_extra(Context* on_finish); + void handle_read_snapshot_extra(int r, Context* on_finish); + + void read_snapshot_l1_table(Context* on_finish); + void handle_read_snapshot_l1_table(int r, Context* on_finish); + + void read_l1_table(Context* on_finish); + void handle_read_l1_table(int r, Context* on_finish); + + void read_backing_file(Context* on_finish); + + void handle_list_snaps(int r, io::Extents&& image_extents, + io::SnapIds&& snap_ids, + io::SnapshotDelta* snapshot_delta, Context* on_finish); +}; + +} // namespace migration +} // namespace librbd + +extern template class librbd::migration::QCOWFormat; + +#endif // CEPH_LIBRBD_MIGRATION_QCOW_FORMAT_H -- cgit v1.2.3