From: Jason Dillaman Date: Wed, 21 Oct 2020 19:32:47 +0000 (-0400) Subject: librbd: read image size when opening migration raw format X-Git-Tag: v16.1.0~702^2~12 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d63a564f2269e42379d148a34071f46b0b0a6c95;p=ceph.git librbd: read image size when opening migration raw format 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 --- diff --git a/src/librbd/migration/RawFormat.cc b/src/librbd/migration/RawFormat.cc index 24ba7ef31c9e..2136f6ccf591 100644 --- a/src/librbd/migration/RawFormat.cc +++ b/src/librbd/migration/RawFormat.cc @@ -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" @@ -19,6 +20,87 @@ namespace librbd { namespace migration { +#define dout_subsys ceph_subsys_rbd +#undef dout_prefix +#define dout_prefix *_dout << "librbd::migration::RawFormat::OpenRequest " \ + << this << " " << __func__ << ": " + +template +struct RawFormat::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 RawFormat::RawFormat( I* image_ctx, const json_spirit::mObject& json_object, @@ -40,7 +122,8 @@ void RawFormat::open(Context* on_finish) { return; } - m_stream->open(on_finish); + auto req = new OpenRequest(this, on_finish); + req->send(); } template diff --git a/src/librbd/migration/RawFormat.h b/src/librbd/migration/RawFormat.h index ab185a5b596b..750ef8561cbd 100644 --- a/src/librbd/migration/RawFormat.h +++ b/src/librbd/migration/RawFormat.h @@ -54,6 +54,8 @@ public: Context* on_finish) override; private: + struct OpenRequest; + ImageCtxT* m_image_ctx; json_spirit::mObject m_json_object; const SourceSpecBuilder* m_source_spec_builder; diff --git a/src/test/librbd/migration/test_mock_RawFormat.cc b/src/test/librbd/migration/test_mock_RawFormat.cc index c67694c63f94..b269ac2dc6c3 100644 --- a/src/test/librbd/migration/test_mock_RawFormat.cc +++ b/src/test/librbd/migration/test_mock_RawFormat.cc @@ -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);