From 0b5c8ed4fa0bd5af3dc7feceafa8c211ccc8202f Mon Sep 17 00:00:00 2001 From: Mykola Golub Date: Sun, 26 Aug 2018 11:30:23 +0300 Subject: [PATCH] librbd: apply pool level config overrides on image refresh Signed-off-by: Mykola Golub --- src/librbd/image/RefreshRequest.cc | 51 +++++++++++++++++++ src/librbd/image/RefreshRequest.h | 24 +++++---- .../librbd/image/test_mock_RefreshRequest.cc | 2 + 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/src/librbd/image/RefreshRequest.cc b/src/librbd/image/RefreshRequest.cc index 4cdb74f68e2ba..a2563cc9683ba 100644 --- a/src/librbd/image/RefreshRequest.cc +++ b/src/librbd/image/RefreshRequest.cc @@ -535,6 +535,57 @@ Context *RefreshRequest::handle_v2_get_metadata(int *result) { } } + m_last_metadata_key.clear(); + send_v2_get_pool_metadata(); + return nullptr; +} + +template +void RefreshRequest::send_v2_get_pool_metadata() { + CephContext *cct = m_image_ctx.cct; + ldout(cct, 10) << this << " " << __func__ << ": " + << "start_key=" << m_last_metadata_key << dendl; + + librados::ObjectReadOperation op; + cls_client::metadata_list_start(&op, m_last_metadata_key, MAX_METADATA_ITEMS); + + using klass = RefreshRequest; + librados::AioCompletion *comp = + create_rados_callback(this); + m_out_bl.clear(); + m_image_ctx.md_ctx.aio_operate(RBD_INFO, comp, &op, &m_out_bl); + comp->release(); +} + +template +Context *RefreshRequest::handle_v2_get_pool_metadata(int *result) { + CephContext *cct = m_image_ctx.cct; + ldout(cct, 10) << this << " " << __func__ << ": r=" << *result << dendl; + + std::map metadata; + if (*result == 0) { + auto it = m_out_bl.cbegin(); + *result = cls_client::metadata_list_finish(&it, &metadata); + } + + if (*result == -EOPNOTSUPP || *result == -ENOENT) { + ldout(cct, 10) << "pool metadata not supported by OSD" << dendl; + } else if (*result < 0) { + lderr(cct) << "failed to retrieve pool metadata: " << cpp_strerror(*result) + << dendl; + return m_on_finish; + } + + if (!metadata.empty()) { + m_metadata.insert(metadata.begin(), metadata.end()); + m_last_metadata_key = metadata.rbegin()->first; + if (boost::starts_with(m_last_metadata_key, + ImageCtx::METADATA_CONF_PREFIX)) { + send_v2_get_pool_metadata(); + return nullptr; + } + } + bool thread_safe = m_image_ctx.image_watcher->is_unregistered(); m_image_ctx.apply_metadata(m_metadata, thread_safe); diff --git a/src/librbd/image/RefreshRequest.h b/src/librbd/image/RefreshRequest.h index 842d79f569db5..18a53f1fe1eaf 100644 --- a/src/librbd/image/RefreshRequest.h +++ b/src/librbd/image/RefreshRequest.h @@ -51,17 +51,20 @@ private: * * | (v2) v * * \-----> V2_GET_MUTABLE_METADATA V1_GET_SNAPSHOTS * * | | - * * v v - * * * * * * GET_MIGRATION_HEADER (skip if not V1_GET_LOCKS + * * | -EOPNOTSUPP v + * * | * * * V1_GET_LOCKS + * * | * * | + * * v v * v + * * V2_GET_PARENT + * * | | + * * v | + * * * * * * GET_MIGRATION_HEADER (skip if not | * (ENOENT) | migrating) | - * v v - * V2_GET_METADATA + * v | + * V2_GET_METADATA | * | | - * | -EOPNOTSUPP | - * | * * * | - * | * * | - * v v * | - * V2_GET_PARENT | + * v | + * V2_GET_POOL_METADATA | * | | * v (skip if not enabled) | * V2_GET_OP_FEATURES | @@ -188,6 +191,9 @@ private: void send_v2_get_metadata(); Context *handle_v2_get_metadata(int *result); + void send_v2_get_pool_metadata(); + Context *handle_v2_get_pool_metadata(int *result); + void send_v2_get_op_features(); Context *handle_v2_get_op_features(int *result); diff --git a/src/test/librbd/image/test_mock_RefreshRequest.cc b/src/test/librbd/image/test_mock_RefreshRequest.cc index 24cb22602f9f1..ce424245fba65 100644 --- a/src/test/librbd/image/test_mock_RefreshRequest.cc +++ b/src/test/librbd/image/test_mock_RefreshRequest.cc @@ -264,6 +264,8 @@ public: expect.WillOnce(Return(r)); } else { expect.WillOnce(DoDefault()); + EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), + exec(RBD_INFO, _, StrEq("rbd"), StrEq("metadata_list"), _, _, _)); EXPECT_CALL(*mock_image_ctx.image_watcher, is_unregistered()) .WillOnce(Return(false)); } -- 2.39.5