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