]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: read image size when opening migration raw format
authorJason Dillaman <dillaman@redhat.com>
Wed, 21 Oct 2020 19:32:47 +0000 (15:32 -0400)
committerJason Dillaman <dillaman@redhat.com>
Sun, 1 Nov 2020 14:22:38 +0000 (09:22 -0500)
The migration prepare operation will need to know the size of
the source image so that it can create the destination image.

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

index 24ba7ef31c9e743610b953b2a41688c810f83421..2136f6ccf591a5be7f84082221ce6674a872a796 100644 (file)
@@ -5,6 +5,7 @@
 #include "common/dout.h"
 #include "common/errno.h"
 #include "librbd/ImageCtx.h"
+#include "librbd/Utils.h"
 #include "librbd/io/AioCompletion.h"
 #include "librbd/io/ReadResult.h"
 #include "librbd/migration/FileStream.h"
 namespace librbd {
 namespace migration {
 
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::migration::RawFormat::OpenRequest " \
+                           << this << " " << __func__ << ": "
+
+template <typename I>
+struct RawFormat<I>::OpenRequest {
+  RawFormat* raw_format;
+  Context* on_finish;
+
+  uint64_t image_size = 0;
+
+  OpenRequest(RawFormat* raw_format, Context* on_finish)
+    : raw_format(raw_format), on_finish(on_finish) {
+  }
+
+  void send() {
+    open_stream();
+  }
+
+  void open_stream() {
+    auto cct = raw_format->m_image_ctx->cct;
+    ldout(cct, 10) << dendl;
+
+    auto ctx = util::create_context_callback<
+      OpenRequest, &OpenRequest::handle_open_stream>(this);
+    raw_format->m_stream->open(ctx);
+  }
+
+  void handle_open_stream(int r) {
+    auto cct = raw_format->m_image_ctx->cct;
+    ldout(cct, 10) << "r=" << r << dendl;
+
+    if (r < 0) {
+      lderr(cct) << "failed to open stream: " << cpp_strerror(r) << dendl;
+      finish(r);
+      return;
+    }
+
+    get_image_size();
+  }
+
+  void get_image_size() {
+    auto cct = raw_format->m_image_ctx->cct;
+    ldout(cct, 10) << dendl;
+
+    auto ctx = util::create_context_callback<
+      OpenRequest, &OpenRequest::handle_get_image_size>(this);
+    raw_format->get_image_size(CEPH_NOSNAP, &image_size, ctx);
+  }
+
+  void handle_get_image_size(int r) {
+    auto cct = raw_format->m_image_ctx->cct;
+    ldout(cct, 10) << "r=" << r << dendl;
+
+    if (r < 0) {
+      lderr(cct) << "failed to open stream: " << cpp_strerror(r) << dendl;
+      finish(r);
+      return;
+    }
+
+    raw_format->m_image_ctx->image_lock.lock();
+    raw_format->m_image_ctx->size = image_size;
+    raw_format->m_image_ctx->image_lock.unlock();
+
+    finish(0);
+  }
+
+  void finish(int r) {
+    auto cct = raw_format->m_image_ctx->cct;
+    ldout(cct, 10) << "r=" << r << dendl;
+
+    on_finish->complete(r);
+    delete this;
+  }
+};
+
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::migration::RawFormat: " << this \
+                           << " " << __func__ << ": "
+
 template <typename I>
 RawFormat<I>::RawFormat(
     I* image_ctx, const json_spirit::mObject& json_object,
@@ -40,7 +122,8 @@ void RawFormat<I>::open(Context* on_finish) {
     return;
   }
 
-  m_stream->open(on_finish);
+  auto req = new OpenRequest(this, on_finish);
+  req->send();
 }
 
 template <typename I>
index ab185a5b596b116b16030cec9ce87a11a363a4c6..750ef8561cbdb334e1848f9803a7d278c8beff6e 100644 (file)
@@ -54,6 +54,8 @@ public:
                   Context* on_finish) override;
 
 private:
+  struct OpenRequest;
+
   ImageCtxT* m_image_ctx;
   json_spirit::mObject m_json_object;
   const SourceSpecBuilder<ImageCtxT>* m_source_spec_builder;
index c67694c63f94be50f0107a360e35985be0029627..b269ac2dc6c381353c049d4150be24fb47868483 100644 (file)
@@ -118,6 +118,7 @@ TEST_F(TestMockMigrationRawFormat, OpenClose) {
   expect_build_stream(mock_source_spec_builder, mock_stream_interface, 0);
 
   expect_stream_open(*mock_stream_interface, 0);
+  expect_stream_get_size(*mock_stream_interface, 0, 0);
 
   expect_stream_close(*mock_stream_interface, 0);
 
@@ -143,6 +144,7 @@ TEST_F(TestMockMigrationRawFormat, GetSnapshots) {
   expect_build_stream(mock_source_spec_builder, mock_stream_interface, 0);
 
   expect_stream_open(*mock_stream_interface, 0);
+  expect_stream_get_size(*mock_stream_interface, 0, 0);
 
   expect_stream_close(*mock_stream_interface, 0);
 
@@ -174,6 +176,7 @@ TEST_F(TestMockMigrationRawFormat, GetImageSize) {
   expect_build_stream(mock_source_spec_builder, mock_stream_interface, 0);
 
   expect_stream_open(*mock_stream_interface, 0);
+  expect_stream_get_size(*mock_stream_interface, 0, 0);
 
   expect_stream_get_size(*mock_stream_interface, 123, 0);
 
@@ -207,6 +210,7 @@ TEST_F(TestMockMigrationRawFormat, GetImageSizeSnapshot) {
   expect_build_stream(mock_source_spec_builder, mock_stream_interface, 0);
 
   expect_stream_open(*mock_stream_interface, 0);
+  expect_stream_get_size(*mock_stream_interface, 0, 0);
 
   expect_stream_close(*mock_stream_interface, 0);
 
@@ -237,6 +241,7 @@ TEST_F(TestMockMigrationRawFormat, Read) {
   expect_build_stream(mock_source_spec_builder, mock_stream_interface, 0);
 
   expect_stream_open(*mock_stream_interface, 0);
+  expect_stream_get_size(*mock_stream_interface, 0, 0);
 
   bufferlist expect_bl;
   expect_bl.append(std::string(123, '1'));
@@ -276,6 +281,7 @@ TEST_F(TestMockMigrationRawFormat, ListSnaps) {
   expect_build_stream(mock_source_spec_builder, mock_stream_interface, 0);
 
   expect_stream_open(*mock_stream_interface, 0);
+  expect_stream_get_size(*mock_stream_interface, 0, 0);
 
   expect_stream_close(*mock_stream_interface, 0);