/
config_validators.cc
67 lines (58 loc) · 2.23 KB
/
config_validators.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#include "common/config_validators.h"
#include "include/stringify.h"
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
int validate(md_config_t::option_rbd_default_features_t *,
std::string *value, std::string *error_message) {
static const std::map<std::string, uint64_t> FEATURE_MAP = {
{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},
};
static_assert((RBD_FEATURE_DATA_POOL << 1) > RBD_FEATURES_ALL,
"new RBD feature added");
// convert user-friendly comma delimited feature name list to a bitmask
// that is used by the librbd API
uint64_t features = 0;
error_message->clear();
try {
features = boost::lexical_cast<decltype(features)>(*value);
uint64_t unsupported_features = (features & ~RBD_FEATURES_ALL);
if (unsupported_features != 0ull) {
features &= RBD_FEATURES_ALL;
std::stringstream ss;
ss << "ignoring unknown feature mask 0x"
<< std::hex << unsupported_features;
*error_message = ss.str();
}
} catch (const boost::bad_lexical_cast& ) {
int r = 0;
std::vector<std::string> feature_names;
boost::split(feature_names, *value, boost::is_any_of(","));
for (auto feature_name: feature_names) {
boost::trim(feature_name);
auto feature_it = FEATURE_MAP.find(feature_name);
if (feature_it != FEATURE_MAP.end()) {
features += feature_it->second;
} else {
if (!error_message->empty()) {
*error_message += ", ";
}
*error_message += "ignoring unknown feature " + feature_name;
r = -EINVAL;
}
}
if (features == 0 && r == -EINVAL) {
features = RBD_FEATURES_DEFAULT;
}
}
*value = stringify(features);
return 0;
}