]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: add possibility to set rbd_default_features config option via string 11175/head
authorVed-vampir <akiselyova@mirantis.com>
Fri, 3 Jun 2016 10:13:12 +0000 (13:13 +0300)
committerAlexey Sheplyakov <asheplyakov@mirantis.com>
Mon, 17 Oct 2016 06:06:28 +0000 (09:06 +0300)
Signed-off-by: Alyona Kiseleva <akiselyova@mirantis.com>
Signed-off-by: Alexey Sheplyakov <asheplyakov@mirantis.com>
12 files changed:
src/common/config_opts.h
src/include/rbd/features.h
src/librbd/Utils.cc
src/librbd/Utils.h
src/librbd/image/CreateRequest.cc
src/librbd/internal.cc
src/test/cli/rbd/help.t
src/test/rbd_mirror/test_ImageReplayer.cc
src/test/rbd_mirror/test_PoolWatcher.cc
src/tools/rbd/ArgumentTypes.cc
src/tools/rbd/Utils.cc
src/tools/rbd/Utils.h

index 2f10cefa21632b1d91261b8406cff098ff3909ac..98d5328afc2a843b2a332c9dd47f4d702b50e988 100644 (file)
@@ -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
index 15e0d18545723f5b64633f6ee3d070017b82ed19..efdcf0e8e6682663c38e3fcc7f8ef2d50e5c4c7c 100644 (file)
 #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       | \
index da54bb286ff0651e85b9f632b24af4156d481003..81495623a262d056a4a708d932994c8fb5cfd581 100644 (file)
@@ -1,9 +1,18 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#include <boost/algorithm/string.hpp>
+#include <boost/lexical_cast.hpp>
+
 #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<std::string>("rbd_default_features");
+  try {
+      value = boost::lexical_cast<decltype(value)>(str_val);
+  } catch (const boost::bad_lexical_cast& ) {
+    map<std::string, int> 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<std::string> 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
index b098881d6f5a988d81b69c3e2154b9b8da8da88d..09c2974f0168288f47d57250031a499a431e02b0 100644 (file)
@@ -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
index 09aa17871a8daa2f49b52160034596dee7f22773..fd9e21427b1edddd2fb565c633cea108e7a42211 100644 (file)
@@ -135,7 +135,7 @@ CreateRequest<I>::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;
index b365b574ea0a852715b8f3edb3c2b7937e635fcb..f08f13d911658449e99198270c49ca267fdc1f56 100644 (file)
@@ -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);
   }
 
index ea9e6eeacad3a080520208df370440680a84ca8d..651d1d55f202fc3dc0bfc72402247090edbe5cda 100644 (file)
     --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
     --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
     --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
                          (example: [<pool-name>/]<image-name>)
     <features>           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
                               (example: [<pool-name>/]<image-name>)
     <features>                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
     --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
index 24d0709999754144ba5301b11a8c404f7c231a86..cce9556460268e257efddd261b35a65557e95e3c 100644 (file)
@@ -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,
index 2a2708ed686c329507cfd8c9702da0e57624989c..76d0385b476771d8a06a1ed581522759fc3630e5 100644 (file)
@@ -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;
index 9ec3ec8a3f8bf76716a4431385f9317aa1504caf..62b6814838249cf2d1286bcaecd3367d859a1099 100644 (file)
@@ -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<uint64_t, std::string> 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) {
index 679de96964cc6c2c3f7e1697dc5cbbf26cc2bfda..16de4666f0e7bc90f21a4f918bf52c94bea76ede 100644 (file)
@@ -14,6 +14,8 @@
 #include "global/global_context.h"
 #include <iostream>
 #include <boost/regex.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/lexical_cast.hpp>
 
 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<uint64_t>();
     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<std::string>("rbd_default_features");
+  try {
+    value = boost::lexical_cast<decltype(value)>(features);
+  } catch (const boost::bad_lexical_cast& ) {
+    map<std::string, int> 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<std::string> 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
index e19a5b3b91cd92d077c39c4709d70f97f0f68ac9..7b426132b5ca0479a17c0c36e1a11c3cd4e9edc1 100644 (file)
@@ -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