From 8399c8481f2dcfea762faeb20e52ef1b61fa6f08 Mon Sep 17 00:00:00 2001 From: Mykola Golub Date: Sun, 26 Aug 2018 11:29:04 +0300 Subject: [PATCH] librbd: apply pool level config overrides on image create Signed-off-by: Mykola Golub --- src/librbd/image/CreateRequest.cc | 144 ++++++++++++++++++++++-------- src/librbd/image/CreateRequest.h | 22 +++-- 2 files changed, 122 insertions(+), 44 deletions(-) diff --git a/src/librbd/image/CreateRequest.cc b/src/librbd/image/CreateRequest.cc index 08abc6831f5dd..fac1bb884b0c2 100644 --- a/src/librbd/image/CreateRequest.cc +++ b/src/librbd/image/CreateRequest.cc @@ -1,11 +1,14 @@ // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab +#include + #include "librbd/image/CreateRequest.h" #include "common/dout.h" #include "common/errno.h" #include "cls/rbd/cls_rbd_client.h" #include "include/ceph_assert.h" +#include "librbd/Features.h" #include "librbd/Utils.h" #include "common/ceph_context.h" #include "osdc/Striper.h" @@ -30,6 +33,8 @@ using util::create_context_callback; namespace { +const uint64_t MAX_METADATA_ITEMS = 128; + int validate_features(CephContext *cct, uint64_t features, bool force_non_primary) { if (features & ~RBD_FEATURES_ALL) { @@ -121,8 +126,9 @@ CreateRequest::CreateRequest(IoCtx &ioctx, const std::string &image_name, const std::string &primary_mirror_uuid, bool skip_mirror_enable, ContextWQ *op_work_queue, Context *on_finish) - : m_image_name(image_name), m_image_id(image_id), - m_size(size), m_non_primary_global_image_id(non_primary_global_image_id), + : m_image_name(image_name), m_image_id(image_id), m_size(size), + m_image_options(image_options), + m_non_primary_global_image_id(non_primary_global_image_id), m_primary_mirror_uuid(primary_mirror_uuid), m_skip_mirror_enable(skip_mirror_enable), m_op_work_queue(op_work_queue), m_on_finish(on_finish) { @@ -133,16 +139,84 @@ CreateRequest::CreateRequest(IoCtx &ioctx, const std::string &image_name, m_id_obj = util::id_obj_name(m_image_name); m_header_obj = util::header_name(m_image_id); m_objmap_name = ObjectMap<>::object_map_name(m_image_id, CEPH_NOSNAP); + m_force_non_primary = !non_primary_global_image_id.empty(); +} + +template +void CreateRequest::send() { + ldout(m_cct, 20) << dendl; + + get_pool_metadata(); +} + +template +void CreateRequest::get_pool_metadata() { + ldout(m_cct, 20) << "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 = CreateRequest; + librados::AioCompletion *comp = + create_rados_callback(this); + m_outbl.clear(); + m_io_ctx.aio_operate(RBD_INFO, comp, &op, &m_outbl); + comp->release(); +} + +template +void CreateRequest::handle_get_pool_metadata(int r) { + ldout(m_cct, 20) << "r=" << r << dendl; + + std::map metadata; + if (r == 0) { + auto it = m_outbl.cbegin(); + r = cls_client::metadata_list_finish(&it, &metadata); + } + + if (r == -EOPNOTSUPP || r == -ENOENT) { + ldout(m_cct, 10) << "pool metadata not supported by OSD" << dendl; + } else if (r < 0) { + lderr(m_cct) << "failed to retrieve pool metadata: " << cpp_strerror(r) + << dendl; + complete(r); + return; + } + + 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)) { + get_pool_metadata(); + return; + } + } - if (image_options.get(RBD_IMAGE_OPTION_FEATURES, &m_features) != 0) { - m_features = util::get_rbd_default_features(m_cct); + ConfigProxy config(m_cct->_conf); + for (auto &it : m_metadata) { + std::string key; + if (!util::is_metadata_config_override(it.first, &key)) { + continue; + } + std::string value(it.second.c_str(), it.second.length()); + r = config.set_val(key.c_str(), value); + if (r != 0) { + lderr(m_cct) << " failed to set config " << key << " with value " + << it.second << ": " << cpp_strerror(r) << dendl; + } + } + + if (m_image_options.get(RBD_IMAGE_OPTION_FEATURES, &m_features) != 0) { + m_features = librbd::rbd_features_from_string( + config.get_val("rbd_default_features"), nullptr); m_negotiate_features = true; } uint64_t features_clear = 0; uint64_t features_set = 0; - image_options.get(RBD_IMAGE_OPTION_FEATURES_CLEAR, &features_clear); - image_options.get(RBD_IMAGE_OPTION_FEATURES_SET, &features_set); + m_image_options.get(RBD_IMAGE_OPTION_FEATURES_CLEAR, &features_clear); + m_image_options.get(RBD_IMAGE_OPTION_FEATURES_SET, &features_set); uint64_t features_conflict = features_clear & features_set; features_clear &= ~features_conflict; @@ -154,31 +228,32 @@ CreateRequest::CreateRequest(IoCtx &ioctx, const std::string &image_name, m_features |= RBD_FEATURE_FAST_DIFF; } - if (image_options.get(RBD_IMAGE_OPTION_STRIPE_UNIT, &m_stripe_unit) != 0 || + if (m_image_options.get(RBD_IMAGE_OPTION_STRIPE_UNIT, &m_stripe_unit) != 0 || m_stripe_unit == 0) { - m_stripe_unit = m_cct->_conf.get_val("rbd_default_stripe_unit"); + m_stripe_unit = config.get_val("rbd_default_stripe_unit"); } - if (image_options.get(RBD_IMAGE_OPTION_STRIPE_COUNT, &m_stripe_count) != 0 || - m_stripe_count == 0) { - m_stripe_count = m_cct->_conf.get_val("rbd_default_stripe_count"); + if (m_image_options.get(RBD_IMAGE_OPTION_STRIPE_COUNT, + &m_stripe_count) != 0 || m_stripe_count == 0) { + m_stripe_count = config.get_val("rbd_default_stripe_count"); } - if (get_image_option(image_options, RBD_IMAGE_OPTION_ORDER, &m_order) != 0 || - m_order == 0) { - m_order = m_cct->_conf.get_val("rbd_default_order"); + if (get_image_option(m_image_options, RBD_IMAGE_OPTION_ORDER, + &m_order) != 0 || m_order == 0) { + m_order = config.get_val("rbd_default_order"); } - if (get_image_option(image_options, RBD_IMAGE_OPTION_JOURNAL_ORDER, - &m_journal_order) != 0) { - m_journal_order = m_cct->_conf.get_val("rbd_journal_order"); + if (get_image_option(m_image_options, RBD_IMAGE_OPTION_JOURNAL_ORDER, + &m_journal_order) != 0) { + m_journal_order = config.get_val("rbd_journal_order"); } - if (get_image_option(image_options, RBD_IMAGE_OPTION_JOURNAL_SPLAY_WIDTH, + if (get_image_option(m_image_options, RBD_IMAGE_OPTION_JOURNAL_SPLAY_WIDTH, &m_journal_splay_width) != 0) { - m_journal_splay_width = m_cct->_conf.get_val("rbd_journal_splay_width"); + m_journal_splay_width = config.get_val("rbd_journal_splay_width"); } - if (image_options.get(RBD_IMAGE_OPTION_JOURNAL_POOL, &m_journal_pool) != 0) { - m_journal_pool = m_cct->_conf.get_val("rbd_journal_pool"); + if (m_image_options.get(RBD_IMAGE_OPTION_JOURNAL_POOL, + &m_journal_pool) != 0) { + m_journal_pool = config.get_val("rbd_journal_pool"); } - if (image_options.get(RBD_IMAGE_OPTION_DATA_POOL, &m_data_pool) != 0) { - m_data_pool = m_cct->_conf.get_val("rbd_default_data_pool"); + if (m_image_options.get(RBD_IMAGE_OPTION_DATA_POOL, &m_data_pool) != 0) { + m_data_pool = config.get_val("rbd_default_data_pool"); } m_layout.object_size = 1ull << m_order; @@ -190,9 +265,7 @@ CreateRequest::CreateRequest(IoCtx &ioctx, const std::string &image_name, m_layout.stripe_count = m_stripe_count; } - m_force_non_primary = !non_primary_global_image_id.empty(); - - if (!m_data_pool.empty() && m_data_pool != ioctx.get_pool_name()) { + if (!m_data_pool.empty() && m_data_pool != m_io_ctx.get_pool_name()) { m_features |= RBD_FEATURE_DATA_POOL; } else { m_data_pool.clear(); @@ -218,13 +291,8 @@ CreateRequest::CreateRequest(IoCtx &ioctx, const std::string &image_name, << (uint64_t)m_journal_splay_width << ", " << "journal_pool=" << m_journal_pool << ", " << "data_pool=" << m_data_pool << dendl; -} -template -void CreateRequest::send() { - ldout(m_cct, 20) << dendl; - - int r = validate_features(m_cct, m_features, m_force_non_primary); + r = validate_features(m_cct, m_features, m_force_non_primary); if (r < 0) { complete(r); return; @@ -248,11 +316,6 @@ void CreateRequest::send() { return; } - validate_data_pool(); -} - -template -void CreateRequest::validate_data_pool() { m_data_io_ctx = m_io_ctx; if ((m_features & RBD_FEATURE_DATA_POOL) != 0) { librados::Rados rados(m_io_ctx); @@ -266,11 +329,16 @@ void CreateRequest::validate_data_pool() { m_data_io_ctx.set_namespace(m_io_ctx.get_namespace()); } - if (!m_cct->_conf.get_val("rbd_validate_pool")) { + if (!config.get_val("rbd_validate_pool")) { add_image_to_directory(); return; } + validate_data_pool(); +} + +template +void CreateRequest::validate_data_pool() { ldout(m_cct, 20) << dendl; using klass = CreateRequest; diff --git a/src/librbd/image/CreateRequest.h b/src/librbd/image/CreateRequest.h index 24aa0eb3f1b3c..98f950cf9e861 100644 --- a/src/librbd/image/CreateRequest.h +++ b/src/librbd/image/CreateRequest.h @@ -51,12 +51,15 @@ private: /** * @verbatim * - * . . . . > . . . . . - * | . - * v . - * VALIDATE DATA POOL v (pool validation - * | . disabled) - * v . + * + * | + * v + * GET POOL METADATA + * | + * v + * VALIDATE DATA POOL . . . . . . + * | . (pool validation + * v . disabled) * (error: bottom up) ADD IMAGE TO DIRECTORY < . . . . * _______<_______ | * | | v @@ -103,6 +106,7 @@ private: std::string m_image_name; std::string m_image_id; uint64_t m_size; + ImageOptions m_image_options; uint8_t m_order = 0; uint64_t m_features = 0; uint64_t m_stripe_unit = 0; @@ -130,6 +134,12 @@ private: rbd_mirror_mode_t m_mirror_mode = RBD_MIRROR_MODE_DISABLED; cls::rbd::MirrorImage m_mirror_image_internal; + std::string m_last_metadata_key; + std::map m_metadata; + + void get_pool_metadata(); + void handle_get_pool_metadata(int r); + void validate_data_pool(); void handle_validate_data_pool(int r); -- 2.39.5