1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
8 #include <boost/variant.hpp>
9 #include "include/str_list.h"
10 #include "msg/msg_types.h"
11 #include "include/uuid.h"
24 const char *type_to_str(type_t t) const {
26 case TYPE_UINT: return "uint64_t";
27 case TYPE_INT: return "int64_t";
28 case TYPE_STR: return "std::string";
29 case TYPE_FLOAT: return "double";
30 case TYPE_BOOL: return "bool";
31 case TYPE_ADDR: return "entity_addr_t";
32 case TYPE_UUID: return "uuid_d";
33 default: return "unknown";
38 * Basic: for users, configures some externally visible functional aspect
39 * Advanced: for users, configures some internal behaviour
40 * Development: not for users. May be dangerous, may not be documented.
48 const char *level_to_str(level_t l) const {
50 case LEVEL_BASIC: return "basic";
51 case LEVEL_ADVANCED: return "advanced";
52 case LEVEL_DEV: return "developer";
53 default: return "unknown";
57 using value_t = boost::variant<
66 const std::string name;
71 std::string long_desc;
76 // Items like mon, osd, rgw, rbd, ceph-fuse. This is advisory metadata
77 // for presentation layers (like web dashboards, or generated docs), so that
78 // they know which options to display where.
79 // Additionally: "common" for settings that exist in any Ceph code. Do
80 // not use common for settings that are just shared some places: for those
82 std::list<const char*> services;
85 // "service": a catchall for the boring stuff like log/asok paths.
87 // "performance": a setting that may need adjustment depending on
88 // environment/workload to get best performance.
89 std::list<const char*> tags;
91 std::list<const char*> see_also;
94 std::list<std::string> enum_allowed;
99 * Return nonzero and set second argument to error string if the
102 * These callbacks are more than just validators, as they can also
103 * modify the value as it passes through.
105 typedef std::function<int(std::string *, std::string *)> validator_fn_t;
106 validator_fn_t validator;
108 Option(std::string const &name, type_t t, level_t l)
109 : name(name), type(t), level(l), safe(false)
111 // While value_t is nullable (via boost::blank), we don't ever
112 // want it set that way in an Option instance: within an instance,
113 // the type of ::value should always match the declared type.
114 if (type == TYPE_INT) {
116 } else if (type == TYPE_UINT) {
118 } else if (type == TYPE_STR) {
119 value = std::string("");
120 } else if (type == TYPE_FLOAT) {
122 } else if (type == TYPE_BOOL) {
124 } else if (type == TYPE_ADDR) {
125 value = entity_addr_t();
126 } else if (type == TYPE_UUID) {
133 void dump_value(const char *field_name, const value_t &v, Formatter *f) const;
135 // Validate and potentially modify incoming string value
136 int pre_validate(std::string *new_value, std::string *err) const;
138 // Validate properly typed value against bounds
139 int validate(const Option::value_t &new_value, std::string *err) const;
141 // const char * must be explicit to avoid it being treated as an int
142 Option& set_value(value_t& v, const char *new_value) {
143 v = std::string(new_value);
147 // bool is an integer, but we don't think so. teach it the hard way.
149 using is_not_integer = std::enable_if<!std::is_integral<T>::value ||
150 std::is_same<T, bool>::value, int>;
152 using is_integer = std::enable_if<std::is_integral<T>::value &&
153 !std::is_same<T, bool>::value, int>;
154 template<typename T, typename is_not_integer<T>::type = 0>
155 Option& set_value(value_t& v, const T& new_value) {
160 // For potentially ambiguous types, inspect Option::type and
161 // do some casting. This is necessary to make sure that setting
162 // a float option to "0" actually sets the double part of variant.
163 template<typename T, typename is_integer<T>::type = 0>
164 Option& set_value(value_t& v, T new_value) {
165 if (type == TYPE_INT) {
166 v = int64_t(new_value);
167 } else if (type == TYPE_UINT) {
168 v = uint64_t(new_value);
169 } else if (type == TYPE_FLOAT) {
170 v = double(new_value);
171 } else if (type == TYPE_BOOL) {
174 std::cerr << "Bad type in set_value: " << name << ": "
175 << typeid(T).name() << std::endl;
182 Option& set_default(const T& v) {
183 return set_value(value, v);
187 Option& set_daemon_default(const T& v) {
188 return set_value(daemon_value, v);
190 Option& add_tag(const char* tag) {
194 Option& add_tag(std::initializer_list<const char*> ts) {
195 tags.insert(tags.end(), ts);
198 Option& add_service(const char* service) {
199 services.push_back(service);
202 Option& add_service(std::initializer_list<const char*> ss) {
203 services.insert(services.end(), ss);
206 Option& add_see_also(const char* t) {
207 see_also.push_back(t);
210 Option& add_see_also(std::initializer_list<const char*> ts) {
211 see_also.insert(see_also.end(), ts);
214 Option& set_description(const char* new_desc) {
218 Option& set_long_description(const char* new_desc) {
219 long_desc = new_desc;
224 Option& set_min(const T& mi) {
230 Option& set_min_max(const T& mi, const T& ma) {
236 Option& set_enum_allowed(const std::list<std::string> allowed)
238 enum_allowed = allowed;
247 Option &set_validator(const validator_fn_t &validator_)
249 validator = validator_;
253 void dump(Formatter *f) const;
256 * A crude indicator of whether the value may be
257 * modified safely at runtime -- should be replaced
258 * with proper locking!
262 return safe || type == TYPE_BOOL || type == TYPE_INT
263 || type == TYPE_UINT || type == TYPE_FLOAT;
267 extern const std::vector<Option> ceph_options;