1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "common/config_validators.h"
5 #include "include/stringify.h"
7 #include <boost/algorithm/string.hpp>
8 #include <boost/lexical_cast.hpp>
9 #include <boost/regex.hpp>
11 int validate(md_config_t::option_rbd_default_pool_t
*,
12 std::string
*value
, std::string
*error_message
) {
13 boost::regex
pattern("^[^@/]+$");
14 if (!boost::regex_match (*value
, pattern
)) {
16 *error_message
= "invalid RBD default pool, resetting to 'rbd'";
21 int validate(md_config_t::option_rbd_default_data_pool_t
*,
22 std::string
*value
, std::string
*error_message
) {
23 boost::regex
pattern("^[^@/]*$");
24 if (!boost::regex_match (*value
, pattern
)) {
26 *error_message
= "ignoring invalid RBD data pool";
31 int validate(md_config_t::option_rbd_default_features_t
*,
32 std::string
*value
, std::string
*error_message
) {
33 static const std::map
<std::string
, uint64_t> FEATURE_MAP
= {
34 {RBD_FEATURE_NAME_LAYERING
, RBD_FEATURE_LAYERING
},
35 {RBD_FEATURE_NAME_STRIPINGV2
, RBD_FEATURE_STRIPINGV2
},
36 {RBD_FEATURE_NAME_EXCLUSIVE_LOCK
, RBD_FEATURE_EXCLUSIVE_LOCK
},
37 {RBD_FEATURE_NAME_OBJECT_MAP
, RBD_FEATURE_OBJECT_MAP
},
38 {RBD_FEATURE_NAME_FAST_DIFF
, RBD_FEATURE_FAST_DIFF
},
39 {RBD_FEATURE_NAME_DEEP_FLATTEN
, RBD_FEATURE_DEEP_FLATTEN
},
40 {RBD_FEATURE_NAME_JOURNALING
, RBD_FEATURE_JOURNALING
},
41 {RBD_FEATURE_NAME_DATA_POOL
, RBD_FEATURE_DATA_POOL
},
43 static_assert((RBD_FEATURE_DATA_POOL
<< 1) > RBD_FEATURES_ALL
,
44 "new RBD feature added");
46 // convert user-friendly comma delimited feature name list to a bitmask
47 // that is used by the librbd API
48 uint64_t features
= 0;
49 error_message
->clear();
52 features
= boost::lexical_cast
<decltype(features
)>(*value
);
54 uint64_t unsupported_features
= (features
& ~RBD_FEATURES_ALL
);
55 if (unsupported_features
!= 0ull) {
56 features
&= RBD_FEATURES_ALL
;
59 ss
<< "ignoring unknown feature mask 0x"
60 << std::hex
<< unsupported_features
;
61 *error_message
= ss
.str();
63 } catch (const boost::bad_lexical_cast
& ) {
65 std::vector
<std::string
> feature_names
;
66 boost::split(feature_names
, *value
, boost::is_any_of(","));
67 for (auto feature_name
: feature_names
) {
68 boost::trim(feature_name
);
69 auto feature_it
= FEATURE_MAP
.find(feature_name
);
70 if (feature_it
!= FEATURE_MAP
.end()) {
71 features
+= feature_it
->second
;
73 if (!error_message
->empty()) {
74 *error_message
+= ", ";
76 *error_message
+= "ignoring unknown feature " + feature_name
;
81 if (features
== 0 && r
== -EINVAL
) {
82 features
= RBD_FEATURES_DEFAULT
;
85 *value
= stringify(features
);