]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd/migration: don't instantiate NativeFormat, handle it via dispatch
authorIlya Dryomov <idryomov@gmail.com>
Thu, 18 Jul 2024 16:11:18 +0000 (18:11 +0200)
committerIlya Dryomov <idryomov@gmail.com>
Tue, 30 Jul 2024 21:05:51 +0000 (23:05 +0200)
Trying to shoehorn NativeFormat under FormatInterface doesn't really
work.  It fundamentally doesn't fit in:

- Unlike for RawFormat and QCOWFormat, src_image_ctx for NativeFormat
  is not dummy -- it's an ImageCtx for a real RBD image.  Pre-creating
  it in OpenSourceImageRequest with the expectation that placeholder
  values would be overridden later forces NativeFormat to reach into
  ImageCtx guts, duplicating the logic in the constructor.  This also
  necessitates calling snap_set() in a separate step, since snap_id
  isn't known at the time ImageCtx is created.

- Unlike for RawFormat and QCOWFormat, get_image_size() and
  get_snapshots() implementations for NativeFormat are dummy.

- read() and list_snaps() implementations for NativeFormat are
  inconsistent: read() passes through io::ImageDispatch layer, but
  list_snaps() doesn't.  Both can be passing through, meaning that in
  essence these are also dummy.

All of this is with today's code.  Additional complications arise with
planned support for migrating from external clusters where src_image_ctx
would require more invasive patching to "move" to an IoCtx belonging to
an external cluster's CephContext and also with other work.

With the above in mind, NativeFormat actually consists of:

1. Code that parses the "type: native" source spec
2. Code that patches ImageCtx, working around the fact that it's
   pre-created in OpenSourceImageRequest
3. A bunch of dummy implementations for FormatInterface

With this change, (1) is wrapped into a static method that also creates
ImageCtx after all required parameters are known and (2) and (3) go away
entirely.  NativeFormat no longer implements FormatInterface and doesn't
get instantiated at all.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
src/librbd/migration/ImageDispatch.cc
src/librbd/migration/ImageDispatch.h
src/librbd/migration/NativeFormat.cc
src/librbd/migration/NativeFormat.h
src/librbd/migration/OpenSourceImageRequest.cc
src/librbd/migration/OpenSourceImageRequest.h
src/librbd/migration/SourceSpecBuilder.cc
src/librbd/migration/SourceSpecBuilder.h

index ad9fdb45166f04027d0bad05c13c180affa4c547..f5b90066c68882345697cc29d1ee18c2391baf8a 100644 (file)
@@ -43,6 +43,12 @@ bool ImageDispatch<I>::read(
   auto cct = m_image_ctx->cct;
   ldout(cct, 20) << dendl;
 
+  // let io::ImageDispatch layer (IMAGE_DISPATCH_LAYER_CORE) handle
+  // native format
+  if (!m_format) {
+    return false;
+  }
+
   *dispatch_result = io::DISPATCH_RESULT_COMPLETE;
   return m_format->read(aio_comp, io_context->get_read_snap(),
                         std::move(image_extents), std::move(read_result),
@@ -132,6 +138,12 @@ bool ImageDispatch<I>::list_snaps(
   auto cct = m_image_ctx->cct;
   ldout(cct, 20) << dendl;
 
+  // let io::ImageDispatch layer (IMAGE_DISPATCH_LAYER_CORE) handle
+  // native format
+  if (!m_format) {
+    return false;
+  }
+
   *dispatch_result = io::DISPATCH_RESULT_COMPLETE;
 
   aio_comp->set_request_count(1);
index cd96141c0cc749e13b5169d456953ea1a9963404..6c67d63a8d50884e75f2ab8d2f33d249785cc8db 100644 (file)
@@ -86,6 +86,8 @@ public:
 
 private:
   ImageCtxT* m_image_ctx;
+
+  // empty (nullptr) for native format
   std::unique_ptr<FormatInterface> m_format;
 
   void fail_io(int r, io::AioCompletion* aio_comp,
index 370494d7d75db0dfb3c767e5559c8b5e2e94f7d4..6d4c3bcbba4c348da6135235961b279a0782ecc8 100644 (file)
@@ -16,8 +16,8 @@
 
 #define dout_subsys ceph_subsys_rbd
 #undef dout_prefix
-#define dout_prefix *_dout << "librbd::migration::NativeFormat: " << this \
-                           << " " << __func__ << ": "
+#define dout_prefix *_dout << "librbd::migration::NativeFormat: " << __func__ \
+                           << ": "
 
 namespace librbd {
 namespace migration {
@@ -51,45 +51,47 @@ std::string NativeFormat<I>::build_source_spec(
 }
 
 template <typename I>
-NativeFormat<I>::NativeFormat(
-    I* image_ctx, const json_spirit::mObject& json_object, bool import_only)
-  : m_image_ctx(image_ctx), m_json_object(json_object),
-    m_import_only(import_only) {
+bool NativeFormat<I>::is_source_spec(
+    const json_spirit::mObject& source_spec_object) {
+  auto it = source_spec_object.find(TYPE_KEY);
+  return it != source_spec_object.end() &&
+         it->second.type() == json_spirit::str_type &&
+         it->second.get_str() == "native";
 }
 
 template <typename I>
-void NativeFormat<I>::open(Context* on_finish) {
-  auto cct = m_image_ctx->cct;
-  ldout(cct, 10) << dendl;
-
+int NativeFormat<I>::create_image_ctx(
+    librados::IoCtx& dst_io_ctx,
+    const json_spirit::mObject& source_spec_object,
+    bool import_only, uint64_t src_snap_id, I** src_image_ctx) {
+  auto cct = reinterpret_cast<CephContext*>(dst_io_ctx.cct());
   int64_t pool_id = -1;
   std::string pool_namespace;
   std::string image_name;
   std::string image_id;
+  std::string snap_name;
+  uint64_t snap_id = CEPH_NOSNAP;
 
-  if (auto it = m_json_object.find(POOL_NAME_KEY);
-      it != m_json_object.end()) {
+  if (auto it = source_spec_object.find(POOL_NAME_KEY);
+      it != source_spec_object.end()) {
     if (it->second.type() == json_spirit::str_type) {
-      librados::Rados rados(m_image_ctx->md_ctx);
+      librados::Rados rados(dst_io_ctx);
       pool_id = rados.pool_lookup(it->second.get_str().c_str());
       if (pool_id < 0) {
         lderr(cct) << "failed to lookup pool" << dendl;
-        on_finish->complete(static_cast<int>(pool_id));
-        return;
+        return static_cast<int>(pool_id);
       }
     } else {
       lderr(cct) << "invalid pool name" << dendl;
-      on_finish->complete(-EINVAL);
-      return;
+      return -EINVAL;
     }
   }
 
-  if (auto it = m_json_object.find(POOL_ID_KEY);
-      it != m_json_object.end()) {
+  if (auto it = source_spec_object.find(POOL_ID_KEY);
+      it != source_spec_object.end()) {
     if (pool_id != -1) {
       lderr(cct) << "cannot specify both pool name and pool id" << dendl;
-      on_finish->complete(-EINVAL);
-      return;
+      return -EINVAL;
     }
     if (it->second.type() == json_spirit::int_type) {
       pool_id = it->second.get_int64();
@@ -101,232 +103,107 @@ void NativeFormat<I>::open(Context* on_finish) {
     }
     if (pool_id == -1) {
       lderr(cct) << "invalid pool id" << dendl;
-      on_finish->complete(-EINVAL);
-      return;
+      return -EINVAL;
     }
   }
 
   if (pool_id == -1) {
     lderr(cct) << "missing pool name or pool id" << dendl;
-    on_finish->complete(-EINVAL);
-    return;
+    return -EINVAL;
   }
 
-  if (auto it = m_json_object.find(POOL_NAMESPACE_KEY);
-      it != m_json_object.end()) {
+  if (auto it = source_spec_object.find(POOL_NAMESPACE_KEY);
+      it != source_spec_object.end()) {
     if (it->second.type() == json_spirit::str_type) {
       pool_namespace = it->second.get_str();
     } else {
       lderr(cct) << "invalid pool namespace" << dendl;
-      on_finish->complete(-EINVAL);
-      return;
+      return -EINVAL;
     }
   }
 
-  if (auto it = m_json_object.find(IMAGE_NAME_KEY);
-      it != m_json_object.end()) {
+  if (auto it = source_spec_object.find(IMAGE_NAME_KEY);
+      it != source_spec_object.end()) {
     if (it->second.type() == json_spirit::str_type) {
       image_name = it->second.get_str();
     } else {
       lderr(cct) << "invalid image name" << dendl;
-      on_finish->complete(-EINVAL);
-      return;
+      return -EINVAL;
     }
   } else {
     lderr(cct) << "missing image name" << dendl;
-    on_finish->complete(-EINVAL);
-    return;
+    return -EINVAL;
   }
 
-  if (auto it = m_json_object.find(IMAGE_ID_KEY);
-      it != m_json_object.end()) {
+  if (auto it = source_spec_object.find(IMAGE_ID_KEY);
+      it != source_spec_object.end()) {
     if (it->second.type() == json_spirit::str_type) {
       image_id = it->second.get_str();
     } else {
       lderr(cct) << "invalid image id" << dendl;
-      on_finish->complete(-EINVAL);
-      return;
+      return -EINVAL;
     }
   }
 
-  if (auto it = m_json_object.find(SNAP_NAME_KEY);
-      it != m_json_object.end()) {
+  if (auto it = source_spec_object.find(SNAP_NAME_KEY);
+      it != source_spec_object.end()) {
     if (it->second.type() == json_spirit::str_type) {
-      m_snap_name = it->second.get_str();
+      snap_name = it->second.get_str();
     } else {
       lderr(cct) << "invalid snap name" << dendl;
-      on_finish->complete(-EINVAL);
-      return;
+      return -EINVAL;
     }
   }
 
-  if (auto it = m_json_object.find(SNAP_ID_KEY);
-      it != m_json_object.end()) {
-    if (!m_snap_name.empty()) {
+  if (auto it = source_spec_object.find(SNAP_ID_KEY);
+      it != source_spec_object.end()) {
+    if (!snap_name.empty()) {
       lderr(cct) << "cannot specify both snap name and snap id" << dendl;
-      on_finish->complete(-EINVAL);
-      return;
+      return -EINVAL;
     }
     if (it->second.type() == json_spirit::int_type) {
-      m_snap_id = it->second.get_uint64();
+      snap_id = it->second.get_uint64();
     } else if (it->second.type() == json_spirit::str_type) {
       try {
-        m_snap_id = boost::lexical_cast<uint64_t>(it->second.get_str());
+        snap_id = boost::lexical_cast<uint64_t>(it->second.get_str());
       } catch (boost::bad_lexical_cast&) {
       }
     }
-    if (m_snap_id == CEPH_NOSNAP) {
+    if (snap_id == CEPH_NOSNAP) {
       lderr(cct) << "invalid snap id" << dendl;
-      on_finish->complete(-EINVAL);
-      return;
+      return -EINVAL;
     }
   }
 
   // snapshot is required for import to keep source read-only
-  if (m_import_only && m_snap_name.empty() && m_snap_id == CEPH_NOSNAP) {
+  if (import_only && snap_name.empty() && snap_id == CEPH_NOSNAP) {
     lderr(cct) << "snapshot required for import" << dendl;
-    on_finish->complete(-EINVAL);
-    return;
-  }
-
-  // TODO add support for external clusters
-  librados::IoCtx io_ctx;
-  int r = util::create_ioctx(m_image_ctx->md_ctx, "source image",
-                             pool_id, 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);
-  m_image_ctx->name = image_name;
-
-  uint64_t flags = 0;
-  if (image_id.empty() && !m_import_only) {
-    flags |= OPEN_FLAG_OLD_FORMAT;
-  } else {
-    m_image_ctx->id = image_id;
+    return -EINVAL;
   }
 
-  if (m_image_ctx->child != nullptr) {
-    // set rados flags for reading the parent image
-    if (m_image_ctx->child->config.template get_val<bool>("rbd_balance_parent_reads")) {
-      m_image_ctx->set_read_flag(librados::OPERATION_BALANCE_READS);
-    } else if (m_image_ctx->child->config.template get_val<bool>("rbd_localize_parent_reads")) {
-      m_image_ctx->set_read_flag(librados::OPERATION_LOCALIZE_READS);
-    }
+  // import snapshot is used only for destination image HEAD
+  // otherwise, src_snap_id corresponds to destination image "opened at"
+  // snap_id
+  if (src_snap_id != CEPH_NOSNAP) {
+    snap_id = src_snap_id;
   }
 
-  // open the source RBD image
-  on_finish = new LambdaContext([this, on_finish](int r) {
-    handle_open(r, on_finish); });
-  m_image_ctx->state->open(flags, on_finish);
-}
-
-template <typename I>
-void NativeFormat<I>::handle_open(int r, Context* on_finish) {
-  auto cct = m_image_ctx->cct;
-  ldout(cct, 10) << "r=" << r << dendl;
-
+  // TODO add support for external clusters
+  librados::IoCtx src_io_ctx;
+  int r = util::create_ioctx(dst_io_ctx, "source image", pool_id,
+                             pool_namespace, &src_io_ctx);
   if (r < 0) {
-    lderr(cct) << "failed to open image: " << cpp_strerror(r) << dendl;
-    on_finish->complete(r);
-    return;
-  }
-
-  if (m_snap_id == CEPH_NOSNAP && m_snap_name.empty()) {
-    on_finish->complete(0);
-    return;
-  }
-
-  if (!m_snap_name.empty()) {
-    std::shared_lock image_locker{m_image_ctx->image_lock};
-    m_snap_id = m_image_ctx->get_snap_id(cls::rbd::UserSnapshotNamespace{},
-                                         m_snap_name);
-  }
-
-  if (m_snap_id == CEPH_NOSNAP) {
-    lderr(cct) << "failed to locate snapshot " << m_snap_name << dendl;
-    on_finish = new LambdaContext([on_finish](int) {
-      on_finish->complete(-ENOENT); });
-    m_image_ctx->state->close(on_finish);
-    return;
+    return r;
   }
 
-  on_finish = new LambdaContext([this, on_finish](int r) {
-    handle_snap_set(r, on_finish); });
-  m_image_ctx->state->snap_set(m_snap_id, on_finish);
-}
-
-template <typename I>
-void NativeFormat<I>::handle_snap_set(int r, Context* on_finish) {
-  auto cct = m_image_ctx->cct;
-  ldout(cct, 10) << "r=" << r << dendl;
-
-  if (r < 0) {
-    lderr(cct) << "failed to set snapshot " << m_snap_id << ": "
-               << cpp_strerror(r) << dendl;
-    on_finish = new LambdaContext([r, on_finish](int) {
-      on_finish->complete(r); });
-    m_image_ctx->state->close(on_finish);
-    return;
+  if (!snap_name.empty() && snap_id == CEPH_NOSNAP) {
+    *src_image_ctx = I::create(image_name, image_id, snap_name.c_str(),
+                               src_io_ctx, true);
+  } else {
+    *src_image_ctx = I::create(image_name, image_id, snap_id, src_io_ctx,
+                               true);
   }
-
-  on_finish->complete(0);
-}
-
-template <typename I>
-void NativeFormat<I>::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 <typename I>
-void NativeFormat<I>::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 <typename I>
-void NativeFormat<I>::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 <typename I>
-void NativeFormat<I>::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), io::ImageArea::DATA, std::move(snap_ids),
-    list_snaps_flags, snapshot_delta, {});
-  req->send();
+  return 0;
 }
 
 } // namespace migration
index c0124d6f9eed390148427298e5c496f4ca8f3a46..b4a84ae3e18381bb53545496fa6a1a69662034e4 100644 (file)
@@ -5,69 +5,30 @@
 #define CEPH_LIBRBD_MIGRATION_NATIVE_FORMAT_H
 
 #include "include/int_types.h"
-#include "librbd/Types.h"
-#include "librbd/migration/FormatInterface.h"
+#include "include/rados/librados_fwd.hpp"
 #include "json_spirit/json_spirit.h"
-#include <memory>
-
-struct Context;
+#include <string>
 
 namespace librbd {
 
-struct AsioEngine;
 struct ImageCtx;
 
 namespace migration {
 
 template <typename ImageCtxT>
-class NativeFormat : public FormatInterface {
+class NativeFormat {
 public:
   static std::string build_source_spec(int64_t pool_id,
                                        const std::string& pool_namespace,
                                        const std::string& image_name,
                                        const std::string& image_id);
 
-  static NativeFormat* create(ImageCtxT* image_ctx,
-                              const json_spirit::mObject& json_object,
-                              bool import_only) {
-    return new NativeFormat(image_ctx, json_object, import_only);
-  }
-
-  NativeFormat(ImageCtxT* image_ctx, const json_spirit::mObject& json_object,
-               bool import_only);
-  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;
-
-  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 {
-    return false;
-  }
-
-  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;
-  json_spirit::mObject m_json_object;
-  bool m_import_only;
-
-  std::string m_snap_name;
-  uint64_t m_snap_id = CEPH_NOSNAP;
-
-  void handle_open(int r, Context* on_finish);
-  void handle_snap_set(int r, Context* on_finish);
+  static bool is_source_spec(const json_spirit::mObject& source_spec_object);
 
+  static int create_image_ctx(librados::IoCtx& dst_io_ctx,
+                              const json_spirit::mObject& source_spec_object,
+                              bool import_only, uint64_t src_snap_id,
+                              ImageCtxT** src_image_ctx);
 };
 
 } // namespace migration
index 079aaec61facbc11166004f6d26bfdc8431982a5..4bd9241ec29126386572c75eba4697d0d8d5d1e1 100644 (file)
@@ -8,6 +8,7 @@
 #include "librbd/ImageState.h"
 #include "librbd/Utils.h"
 #include "librbd/io/ImageDispatcher.h"
+#include "librbd/migration/FormatInterface.h"
 #include "librbd/migration/ImageDispatch.h"
 #include "librbd/migration/NativeFormat.h"
 #include "librbd/migration/SourceSpecBuilder.h"
@@ -59,20 +60,77 @@ void OpenSourceImageRequest<I>::send() {
     return;
   }
 
-  open_source(source_spec_object, import_only);
+  if (NativeFormat<I>::is_source_spec(source_spec_object)) {
+    open_native(source_spec_object, import_only);
+  } else {
+    open_format(source_spec_object);
+  }
 }
 
 template <typename I>
-void OpenSourceImageRequest<I>::open_source(
+void OpenSourceImageRequest<I>::open_native(
     const json_spirit::mObject& source_spec_object, bool import_only) {
   ldout(m_cct, 10) << dendl;
 
+  int r = NativeFormat<I>::create_image_ctx(m_dst_io_ctx, source_spec_object,
+                                            import_only, m_src_snap_id,
+                                            m_src_image_ctx);
+  if (r < 0) {
+    lderr(m_cct) << "failed to create native image context: "
+                 << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  auto src_image_ctx = *m_src_image_ctx;
+  src_image_ctx->child = m_dst_image_ctx;
+
+  if (m_dst_image_ctx != nullptr) {
+    // set rados flags for reading the source image
+    if (m_dst_image_ctx->config.template get_val<bool>("rbd_balance_parent_reads")) {
+      src_image_ctx->set_read_flag(librados::OPERATION_BALANCE_READS);
+    } else if (m_dst_image_ctx->config.template get_val<bool>("rbd_localize_parent_reads")) {
+      src_image_ctx->set_read_flag(librados::OPERATION_LOCALIZE_READS);
+    }
+  }
+
+  uint64_t flags = 0;
+  if (src_image_ctx->id.empty() && !import_only) {
+    flags |= OPEN_FLAG_OLD_FORMAT;
+  }
+
+  // open the source image
+  auto ctx = util::create_context_callback<
+    OpenSourceImageRequest<I>,
+    &OpenSourceImageRequest<I>::handle_open_native>(this);
+  src_image_ctx->state->open(flags, ctx);
+}
+
+template <typename I>
+void OpenSourceImageRequest<I>::handle_open_native(int r) {
+  ldout(m_cct, 10) << "r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(m_cct) << "failed to open native image: " << cpp_strerror(r)
+                 << dendl;
+    finish(r);
+    return;
+  }
+
+  finish(0);
+}
+
+template <typename I>
+void OpenSourceImageRequest<I>::open_format(
+    const json_spirit::mObject& source_spec_object) {
+  ldout(m_cct, 10) << dendl;
+
   // note that all source image ctx properties are placeholders
   *m_src_image_ctx = I::create("", "", CEPH_NOSNAP, m_dst_io_ctx, true);
   auto src_image_ctx = *m_src_image_ctx;
   src_image_ctx->child = m_dst_image_ctx;
 
-  // use default layout values (can be overridden by source layers later)
+  // use default layout values (can be overridden by migration formats later)
   src_image_ctx->order = 22;
   src_image_ctx->layout = file_layout_t();
   src_image_ctx->layout.stripe_count = 1;
@@ -81,8 +139,7 @@ void OpenSourceImageRequest<I>::open_source(
   src_image_ctx->layout.pool_id = -1;
 
   SourceSpecBuilder<I> source_spec_builder{src_image_ctx};
-  int r = source_spec_builder.build_format(source_spec_object, import_only,
-                                           &m_format);
+  int r = source_spec_builder.build_format(source_spec_object, &m_format);
   if (r < 0) {
     lderr(m_cct) << "failed to build migration format handler: "
                  << cpp_strerror(r) << dendl;
@@ -93,16 +150,16 @@ void OpenSourceImageRequest<I>::open_source(
 
   auto ctx = util::create_context_callback<
     OpenSourceImageRequest<I>,
-    &OpenSourceImageRequest<I>::handle_open_source>(this);
+    &OpenSourceImageRequest<I>::handle_open_format>(this);
   m_format->open(ctx);
 }
 
 template <typename I>
-void OpenSourceImageRequest<I>::handle_open_source(int r) {
+void OpenSourceImageRequest<I>::handle_open_format(int r) {
   ldout(m_cct, 10) << "r=" << r << dendl;
 
   if (r < 0) {
-    lderr(m_cct) << "failed to open migration source: " << cpp_strerror(r)
+    lderr(m_cct) << "failed to open migration format: " << cpp_strerror(r)
                  << dendl;
     finish(r);
     return;
index 0f62665d9094789e6bea828e0631a0049d1c2dbc..465e0aa14f35af18282b114b25c7311f99d8f658 100644 (file)
@@ -47,19 +47,26 @@ private:
   /**
    * @verbatim
    *
-   * <start>
-   *    |
-   *    v
-   * OPEN_SOURCE
-   *    |
-   *    v
-   * GET_IMAGE_SIZE  * * * * * * *
-   *    |                        *
-   *    v                        v
-   * GET_SNAPSHOTS * * * * > CLOSE_IMAGE
-   *    |                        |
-   *    v                        |
-   * <finish> <------------------/
+   *                  <start>
+   *                     |
+   *                     v
+   *             PARSE_SOURCE_SPEC
+   *   (native)          |          (raw or qcow)
+   *     /--------------/ \-------------------\
+   *     |                                    |
+   *     v                                    v
+   * OPEN_NATIVE          * * * * * * * * OPEN_FORMAT
+   *     |               *                    |
+   *     |               *                    v
+   *     |               * * * * * * * GET_IMAGE_SIZE
+   *     |               *                    |
+   *     |               v                    v
+   *     |          CLOSE_IMAGE < * * * GET_SNAPSHOTS
+   *     |               |                    |
+   *     |/--------------/--------------------/
+   *     |
+   *     v
+   *  <finish>
    *
    * @endverbatim
    */
@@ -79,9 +86,12 @@ private:
   uint64_t m_image_size = 0;
   SnapInfos m_snap_infos;
 
-  void open_source(const json_spirit::mObject& source_spec_object,
+  void open_native(const json_spirit::mObject& source_spec_object,
                    bool import_only);
-  void handle_open_source(int r);
+  void handle_open_native(int r);
+
+  void open_format(const json_spirit::mObject& source_spec_object);
+  void handle_open_format(int r);
 
   void get_image_size();
   void handle_get_image_size(int r);
index 74b29a11bbad3679efcdbbf58fbcb3ccc11eda5a..f44d97d58f1c6d7485cc87c54450ec697525257e 100644 (file)
@@ -45,7 +45,7 @@ int SourceSpecBuilder<I>::parse_source_spec(
 
 template <typename I>
 int SourceSpecBuilder<I>::build_format(
-    const json_spirit::mObject& source_spec_object, bool import_only,
+    const json_spirit::mObject& source_spec_object,
     std::unique_ptr<FormatInterface>* format) const {
   auto cct = m_image_ctx->cct;
   ldout(cct, 10) << dendl;
@@ -58,10 +58,7 @@ int SourceSpecBuilder<I>::build_format(
   }
 
   auto& type = type_value_it->second.get_str();
-  if (type == "native") {
-    format->reset(NativeFormat<I>::create(m_image_ctx, source_spec_object,
-                                          import_only));
-  } else if (type == "qcow") {
+  if (type == "qcow") {
     format->reset(QCOWFormat<I>::create(m_image_ctx, source_spec_object, this));
   } else if (type == "raw") {
     format->reset(RawFormat<I>::create(m_image_ctx, source_spec_object, this));
index 58f83139476a7039e819c6942f0818a299c52e95..1dd069cfdabf0f65b8cad6fb4b5511108ad776a6 100644 (file)
@@ -30,7 +30,7 @@ public:
   SourceSpecBuilder(ImageCtxT* image_ctx) : m_image_ctx(image_ctx) {
   }
 
-  int build_format(const json_spirit::mObject& format_object, bool import_only,
+  int build_format(const json_spirit::mObject& format_object,
                    std::unique_ptr<FormatInterface>* format) const;
 
   int build_snapshot(const json_spirit::mObject& source_spec_object,