]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd/migration: generic method for applying source image metadata
authorJason Dillaman <dillaman@redhat.com>
Wed, 2 Dec 2020 02:25:34 +0000 (21:25 -0500)
committerJason Dillaman <dillaman@redhat.com>
Wed, 2 Dec 2020 03:48:16 +0000 (22:48 -0500)
Collect the image size and snapshot details from the constructed format
and apply it to the source image ctx.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/migration/OpenSourceImageRequest.cc
src/librbd/migration/OpenSourceImageRequest.h
src/librbd/migration/RawFormat.cc
src/test/librbd/migration/test_mock_RawFormat.cc

index 8dd3a6fc016215518bf6221f8be1c01500cf5d65..e19739b5e11fefa6d36149a202695eaf6475636c 100644 (file)
@@ -102,12 +102,113 @@ void OpenSourceImageRequest<I>::handle_open_source(int 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>
@@ -116,6 +217,8 @@ void OpenSourceImageRequest<I>::finish(int r) {
 
   if (r < 0) {
     *m_src_image_ctx = nullptr;
+  } else {
+    register_image_dispatch();
   }
 
   m_on_finish->complete(r);
index a9099452d607d4e8c5917ac4b0d8626574311c99..f0dab3ad99c095499e87838e9bbab610ffa92262 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "include/rados/librados_fwd.hpp"
 #include "librbd/Types.h"
+#include <map>
 #include <memory>
 
 struct Context;
@@ -51,11 +52,19 @@ private:
    * OPEN_SOURCE
    *    |
    *    v
-   * <finish>
+   * GET_IMAGE_SIZE  * * * * * * *
+   *    |                        *
+   *    v                        v
+   * GET_SNAPSHOTS * * * * > CLOSE_IMAGE
+   *    |                        |
+   *    v                        |
+   * <finish> <------------------/
    *
    * @endverbatim
    */
 
+  typedef std::map<uint64_t, SnapInfo> SnapInfos;
+
   CephContext* m_cct;
   librados::IoCtx& m_io_ctx;
   ImageCtxT* m_dst_image_ctx;
@@ -66,9 +75,22 @@ private:
 
   std::unique_ptr<FormatInterface> m_format;
 
+  uint64_t m_image_size = 0;
+  SnapInfos m_snap_infos;
+
   void open_source();
   void handle_open_source(int r);
 
+  void get_image_size();
+  void handle_get_image_size(int r);
+
+  void get_snapshots();
+  void handle_get_snapshots(int r);
+
+  void close_image(int r);
+
+  void register_image_dispatch();
+
   void finish(int r);
 
 };
index a4e3faf777fab606bfe0069b1e43c832eb84af0f..8cd0ff2bc8834bb60bd48a5fa8e066522c86f7a8 100644 (file)
@@ -114,12 +114,6 @@ void RawFormat<I>::handle_open(int r, Context* on_finish) {
     return;
   }
 
-  auto head_snapshot = m_snapshots[CEPH_NOSNAP];
-  ceph_assert(head_snapshot);
-
-  m_image_ctx->image_lock.lock();
-  m_image_ctx->size = head_snapshot->get_snap_info().size;
-  m_image_ctx->image_lock.unlock();
   on_finish->complete(0);
 }
 
index d46ca436999e3b8345ed35e823a7e6019453b6d7..fd83de013be0f00cda294b4e8f4da05d6bb9da33 100644 (file)
@@ -146,8 +146,6 @@ TEST_F(TestMockMigrationRawFormat, OpenClose) {
                         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);
 
@@ -230,8 +228,6 @@ TEST_F(TestMockMigrationRawFormat, GetSnapshots) {
                         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);
 
@@ -264,9 +260,8 @@ TEST_F(TestMockMigrationRawFormat, GetImageSize) {
                         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);
@@ -300,8 +295,6 @@ TEST_F(TestMockMigrationRawFormat, GetImageSizeSnapshotDNE) {
                         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);
 
@@ -333,8 +326,6 @@ TEST_F(TestMockMigrationRawFormat, Read) {
                         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'));
@@ -375,9 +366,8 @@ TEST_F(TestMockMigrationRawFormat, ListSnaps) {
                         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});
@@ -420,9 +410,8 @@ TEST_F(TestMockMigrationRawFormat, ListSnapsError) {
 
 
   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});
@@ -473,8 +462,6 @@ TEST_F(TestMockMigrationRawFormat, ListSnapsMerge) {
   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);