From: Ved-vampir Date: Fri, 3 Jun 2016 10:13:12 +0000 (+0300) Subject: rbd: add possibility to set rbd_default_features config option via string X-Git-Tag: v11.1.0~573^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9b8a2da1902710960a45159172a1f1b8184fa1a2;p=ceph.git rbd: add possibility to set rbd_default_features config option via string Signed-off-by: Alyona Kiseleva Signed-off-by: Alexey Sheplyakov --- diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 2f10cefa2163..98d5328afc2a 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -1256,11 +1256,7 @@ OPTION(rbd_default_format, OPT_INT, 2) OPTION(rbd_default_order, OPT_INT, 22) OPTION(rbd_default_stripe_count, OPT_U64, 0) // changing requires stripingv2 feature OPTION(rbd_default_stripe_unit, OPT_U64, 0) // changing to non-object size requires stripingv2 feature -OPTION(rbd_default_features, OPT_INT, 61) // only applies to format 2 images - // +1 for layering, +2 for stripingv2, - // +4 for exclusive lock, +8 for object map - // +16 for fast-diff, +32 for deep-flatten, - // +64 for journaling, +128 for data pool +SAFE_OPTION(rbd_default_features, OPT_STR, "layering,exclusive-lock,object-map,fast-diff,deep-flatten") // only applies to format 2 images OPTION(rbd_default_data_pool, OPT_STR, "") // optional default pool for storing image data blocks OPTION(rbd_default_map_options, OPT_STR, "") // default rbd map -o / --options diff --git a/src/include/rbd/features.h b/src/include/rbd/features.h index 15e0d1854572..efdcf0e8e668 100644 --- a/src/include/rbd/features.h +++ b/src/include/rbd/features.h @@ -10,6 +10,21 @@ #define RBD_FEATURE_JOURNALING (1ULL<<6) #define RBD_FEATURE_DATA_POOL (1ULL<<7) +#define RBD_FEATURES_DEFAULT (RBD_FEATURE_LAYERING | \ + RBD_FEATURE_EXCLUSIVE_LOCK | \ + RBD_FEATURE_OBJECT_MAP | \ + RBD_FEATURE_FAST_DIFF | \ + RBD_FEATURE_DEEP_FLATTEN) + +#define RBD_FEATURE_NAME_LAYERING "layering" +#define RBD_FEATURE_NAME_STRIPINGV2 "striping" +#define RBD_FEATURE_NAME_EXCLUSIVE_LOCK "exclusive-lock" +#define RBD_FEATURE_NAME_OBJECT_MAP "object-map" +#define RBD_FEATURE_NAME_FAST_DIFF "fast-diff" +#define RBD_FEATURE_NAME_DEEP_FLATTEN "deep-flatten" +#define RBD_FEATURE_NAME_JOURNALING "journaling" +#define RBD_FEATURE_NAME_DATA_POOL "data-pool" + /// features that make an image inaccessible for read or write by /// clients that don't understand them #define RBD_FEATURES_INCOMPATIBLE (RBD_FEATURE_LAYERING | \ diff --git a/src/librbd/Utils.cc b/src/librbd/Utils.cc index da54bb286ff0..81495623a262 100644 --- a/src/librbd/Utils.cc +++ b/src/librbd/Utils.cc @@ -1,9 +1,18 @@ // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab +#include +#include + #include "librbd/Utils.h" #include "include/rbd_types.h" #include "include/stringify.h" +#include "include/rbd/features.h" +#include "common/dout.h" + +#define dout_subsys ceph_subsys_rbd +#undef dout_prefix +#define dout_prefix *_dout << "librbd: " namespace librbd { namespace util { @@ -55,5 +64,40 @@ std::string generate_image_id(librados::IoCtx &ioctx) { return id; } +uint64_t parse_rbd_default_features(CephContext* cct) +{ + int ret = 0; + uint64_t value = 0; + auto str_val = cct->_conf->get_val("rbd_default_features"); + try { + value = boost::lexical_cast(str_val); + } catch (const boost::bad_lexical_cast& ) { + map conf_vals = {{RBD_FEATURE_NAME_LAYERING, RBD_FEATURE_LAYERING}, + {RBD_FEATURE_NAME_STRIPINGV2, RBD_FEATURE_STRIPINGV2}, + {RBD_FEATURE_NAME_EXCLUSIVE_LOCK, RBD_FEATURE_EXCLUSIVE_LOCK}, + {RBD_FEATURE_NAME_OBJECT_MAP, RBD_FEATURE_OBJECT_MAP}, + {RBD_FEATURE_NAME_FAST_DIFF, RBD_FEATURE_FAST_DIFF}, + {RBD_FEATURE_NAME_DEEP_FLATTEN, RBD_FEATURE_DEEP_FLATTEN}, + {RBD_FEATURE_NAME_JOURNALING, RBD_FEATURE_JOURNALING}, + {RBD_FEATURE_NAME_DATA_POOL, RBD_FEATURE_DATA_POOL}, + }; + std::vector strs; + boost::split(strs, str_val, boost::is_any_of(",")); + for (auto feature: strs) { + boost::trim(feature); + if (conf_vals.find(feature) != conf_vals.end()) { + value += conf_vals[feature]; + } else { + ret = -EINVAL; + ldout(cct, 1) << "Warning: unknown rbd feature " << feature << dendl; + } + } + if (value == 0 && ret == -EINVAL) + value = RBD_FEATURES_DEFAULT; + } + return value; +} + } // namespace util + } // namespace librbd diff --git a/src/librbd/Utils.h b/src/librbd/Utils.h index b098881d6f5a..09c2974f0168 100644 --- a/src/librbd/Utils.h +++ b/src/librbd/Utils.h @@ -197,7 +197,10 @@ private: Context *m_on_finish = nullptr; }; +uint64_t parse_rbd_default_features(CephContext* cct); + } // namespace util + } // namespace librbd #endif // CEPH_LIBRBD_UTILS_H diff --git a/src/librbd/image/CreateRequest.cc b/src/librbd/image/CreateRequest.cc index 09aa17871a8d..fd9e21427b1e 100644 --- a/src/librbd/image/CreateRequest.cc +++ b/src/librbd/image/CreateRequest.cc @@ -135,7 +135,7 @@ CreateRequest::CreateRequest(IoCtx &ioctx, const std::string &image_name, m_objmap_name = ObjectMap::object_map_name(m_image_id, CEPH_NOSNAP); if (image_options.get(RBD_IMAGE_OPTION_FEATURES, &m_features) != 0) { - m_features = m_cct->_conf->rbd_default_features; + m_features = util::parse_rbd_default_features(m_cct); } uint64_t features_clear = 0; diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index b365b574ea0a..f08f13d91165 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -884,7 +884,7 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force, { CephContext *cct = (CephContext *)io_ctx.cct(); bool old_format = cct->_conf->rbd_default_format == 1; - uint64_t features = old_format ? 0 : cct->_conf->rbd_default_features; + uint64_t features = old_format ? 0 : librbd::util::parse_rbd_default_features(cct); return create(io_ctx, imgname, size, old_format, features, order, 0, 0); } diff --git a/src/test/cli/rbd/help.t b/src/test/cli/rbd/help.t index ea9e6eeacad3..651d1d55f202 100644 --- a/src/test/cli/rbd/help.t +++ b/src/test/cli/rbd/help.t @@ -171,7 +171,7 @@ --image-feature arg image features [layering(+), striping, exclusive-lock(+*), object-map(+*), fast-diff(+*), deep-flatten(+-), - journaling(*)] + journaling(*), data-pool] --image-shared shared image --stripe-unit arg stripe unit --stripe-count arg stripe count @@ -217,7 +217,7 @@ --image-feature arg image features [layering(+), striping, exclusive-lock(+*), object-map(+*), fast-diff(+*), deep-flatten(+-), - journaling(*)] + journaling(*), data-pool] --image-shared shared image --stripe-unit arg stripe unit --stripe-count arg stripe count @@ -261,7 +261,7 @@ --image-feature arg image features [layering(+), striping, exclusive-lock(+*), object-map(+*), fast-diff(+*), deep-flatten(+-), - journaling(*)] + journaling(*), data-pool] --image-shared shared image --stripe-unit arg stripe unit --stripe-count arg stripe count @@ -371,7 +371,7 @@ (example: [/]) image features [layering, striping, exclusive-lock, object-map, - fast-diff, deep-flatten, journaling] + fast-diff, deep-flatten, journaling, data-pool] Optional arguments -p [ --pool ] arg pool name @@ -391,7 +391,7 @@ (example: [/]) image features [layering, striping, exclusive-lock, object-map, - fast-diff, deep-flatten, journaling] + fast-diff, deep-flatten, journaling, data-pool] Optional arguments -p [ --pool ] arg pool name @@ -607,7 +607,7 @@ --image-feature arg image features [layering(+), striping, exclusive-lock(+*), object-map(+*), fast-diff(+*), deep-flatten(+-), - journaling(*)] + journaling(*), data-pool] --image-shared shared image --stripe-unit arg stripe unit --stripe-count arg stripe count diff --git a/src/test/rbd_mirror/test_ImageReplayer.cc b/src/test/rbd_mirror/test_ImageReplayer.cc index 24d070999975..cce955646026 100644 --- a/src/test/rbd_mirror/test_ImageReplayer.cc +++ b/src/test/rbd_mirror/test_ImageReplayer.cc @@ -99,7 +99,7 @@ public: m_remote_ioctx)); m_image_name = get_temp_image_name(); - uint64_t features = g_ceph_context->_conf->rbd_default_features; + uint64_t features = librbd::util::parse_rbd_default_features(g_ceph_context); features |= RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING; int order = 0; EXPECT_EQ(0, librbd::create(m_remote_ioctx, m_image_name.c_str(), 1 << 22, diff --git a/src/test/rbd_mirror/test_PoolWatcher.cc b/src/test/rbd_mirror/test_PoolWatcher.cc index 2a2708ed686c..76d0385b4767 100644 --- a/src/test/rbd_mirror/test_PoolWatcher.cc +++ b/src/test/rbd_mirror/test_PoolWatcher.cc @@ -84,7 +84,7 @@ TestPoolWatcher() : m_lock("TestPoolWatcherLock"), void create_image(const string &pool_name, bool mirrored=true, string *image_name=nullptr) { - uint64_t features = g_ceph_context->_conf->rbd_default_features; + uint64_t features = librbd::util::parse_rbd_default_features(g_ceph_context); string name = "image" + stringify(++m_image_number); if (mirrored) { features |= RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING; @@ -132,7 +132,7 @@ TestPoolWatcher() : m_lock("TestPoolWatcherLock"), ictx->state->close(); } - uint64_t features = g_ceph_context->_conf->rbd_default_features; + uint64_t features = librbd::util::parse_rbd_default_features(g_ceph_context); string name = "clone" + stringify(++m_image_number); if (mirrored) { features |= RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING; diff --git a/src/tools/rbd/ArgumentTypes.cc b/src/tools/rbd/ArgumentTypes.cc index 9ec3ec8a3f8b..62b681483824 100644 --- a/src/tools/rbd/ArgumentTypes.cc +++ b/src/tools/rbd/ArgumentTypes.cc @@ -3,6 +3,7 @@ #include "tools/rbd/ArgumentTypes.h" #include "tools/rbd/Shell.h" +#include "tools/rbd/Utils.h" #include "include/rbd/features.h" #include "common/config.h" #include "common/strtol.h" @@ -17,13 +18,15 @@ namespace argument_types { namespace po = boost::program_options; const std::map ImageFeatures::FEATURE_MAPPING = { - {RBD_FEATURE_LAYERING, "layering"}, - {RBD_FEATURE_STRIPINGV2, "striping"}, - {RBD_FEATURE_EXCLUSIVE_LOCK, "exclusive-lock"}, - {RBD_FEATURE_OBJECT_MAP, "object-map"}, - {RBD_FEATURE_FAST_DIFF, "fast-diff"}, - {RBD_FEATURE_DEEP_FLATTEN, "deep-flatten"}, - {RBD_FEATURE_JOURNALING, "journaling"}}; + {RBD_FEATURE_LAYERING, RBD_FEATURE_NAME_LAYERING}, + {RBD_FEATURE_STRIPINGV2, RBD_FEATURE_NAME_STRIPINGV2}, + {RBD_FEATURE_EXCLUSIVE_LOCK, RBD_FEATURE_NAME_EXCLUSIVE_LOCK}, + {RBD_FEATURE_OBJECT_MAP, RBD_FEATURE_NAME_OBJECT_MAP}, + {RBD_FEATURE_FAST_DIFF, RBD_FEATURE_NAME_FAST_DIFF}, + {RBD_FEATURE_DEEP_FLATTEN, RBD_FEATURE_NAME_DEEP_FLATTEN}, + {RBD_FEATURE_JOURNALING, RBD_FEATURE_NAME_JOURNALING}, + {RBD_FEATURE_DATA_POOL, RBD_FEATURE_NAME_DATA_POOL}, +}; Format::Formatter Format::create_formatter(bool pretty) const { if (value == "json") { @@ -340,7 +343,7 @@ std::string get_short_features_help(bool append_suffix) { std::string suffix; if (append_suffix) { - if ((pair.first & g_conf->rbd_default_features) != 0) { + if ((pair.first & rbd::utils::parse_rbd_default_features(g_ceph_context)) != 0) { suffix += "+"; } if ((pair.first & RBD_FEATURES_MUTABLE) != 0) { diff --git a/src/tools/rbd/Utils.cc b/src/tools/rbd/Utils.cc index 679de96964cc..16de4666f0e7 100644 --- a/src/tools/rbd/Utils.cc +++ b/src/tools/rbd/Utils.cc @@ -14,6 +14,8 @@ #include "global/global_context.h" #include #include +#include +#include namespace rbd { namespace utils { @@ -540,6 +542,8 @@ int get_image_options(const boost::program_options::variables_map &vm, if (vm.count(at::IMAGE_FEATURES)) { features = vm[at::IMAGE_FEATURES].as(); features_specified = true; + } else { + features = parse_rbd_default_features(g_ceph_context); } if (vm.count(at::IMAGE_STRIPE_UNIT)) { @@ -870,5 +874,41 @@ std::string timestr(time_t t) { return buf; } +// FIXME (asheplyakov): use function from librbd/Utils.cc + +uint64_t parse_rbd_default_features(CephContext* cct) +{ + int ret = 0; + uint64_t value = 0; + auto features = cct->_conf->get_val("rbd_default_features"); + try { + value = boost::lexical_cast(features); + } catch (const boost::bad_lexical_cast& ) { + map conf_vals = {{RBD_FEATURE_NAME_LAYERING, RBD_FEATURE_LAYERING}, + {RBD_FEATURE_NAME_STRIPINGV2, RBD_FEATURE_STRIPINGV2}, + {RBD_FEATURE_NAME_EXCLUSIVE_LOCK, RBD_FEATURE_EXCLUSIVE_LOCK}, + {RBD_FEATURE_NAME_OBJECT_MAP, RBD_FEATURE_OBJECT_MAP}, + {RBD_FEATURE_NAME_FAST_DIFF, RBD_FEATURE_FAST_DIFF}, + {RBD_FEATURE_NAME_DEEP_FLATTEN, RBD_FEATURE_DEEP_FLATTEN}, + {RBD_FEATURE_NAME_JOURNALING, RBD_FEATURE_JOURNALING}, + {RBD_FEATURE_NAME_DATA_POOL, RBD_FEATURE_DATA_POOL}, + }; + std::vector strs; + boost::split(strs, features, boost::is_any_of(",")); + for (auto feature: strs) { + boost::trim(feature); + if (conf_vals.find(feature) != conf_vals.end()) { + value += conf_vals[feature]; + } else { + ret = -EINVAL; + std::cerr << "Warning: unknown rbd feature " << feature << std::endl; + } + } + if (value == 0 && ret == -EINVAL) + value = RBD_FEATURES_DEFAULT; + } + return value; +} + } // namespace utils } // namespace rbd diff --git a/src/tools/rbd/Utils.h b/src/tools/rbd/Utils.h index e19a5b3b91cd..7b426132b5ca 100644 --- a/src/tools/rbd/Utils.h +++ b/src/tools/rbd/Utils.h @@ -134,6 +134,9 @@ std::string mirror_image_status_state(librbd::mirror_image_status_t status); std::string timestr(time_t t); +// duplicate here to not include librbd_internal lib +uint64_t parse_rbd_default_features(CephContext* cct); + } // namespace utils } // namespace rbd