]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/options.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
9 #include <boost/variant.hpp>
10 #include "include/str_list.h"
11 #include "msg/msg_types.h"
12 #include "include/uuid.h"
28 static const char *type_to_c_type_str(type_t t
) {
30 case TYPE_UINT
: return "uint64_t";
31 case TYPE_INT
: return "int64_t";
32 case TYPE_STR
: return "std::string";
33 case TYPE_FLOAT
: return "double";
34 case TYPE_BOOL
: return "bool";
35 case TYPE_ADDR
: return "entity_addr_t";
36 case TYPE_ADDRVEC
: return "entity_addrvec_t";
37 case TYPE_UUID
: return "uuid_d";
38 case TYPE_SIZE
: return "size_t";
39 case TYPE_SECS
: return "secs";
40 default: return "unknown";
43 static const char *type_to_str(type_t t
) {
45 case TYPE_UINT
: return "uint";
46 case TYPE_INT
: return "int";
47 case TYPE_STR
: return "str";
48 case TYPE_FLOAT
: return "float";
49 case TYPE_BOOL
: return "bool";
50 case TYPE_ADDR
: return "addr";
51 case TYPE_ADDRVEC
: return "addrvec";
52 case TYPE_UUID
: return "uuid";
53 case TYPE_SIZE
: return "size";
54 case TYPE_SECS
: return "secs";
55 default: return "unknown";
58 static int str_to_type(const std::string
& s
) {
93 * Basic: for users, configures some externally visible functional aspect
94 * Advanced: for users, configures some internal behaviour
95 * Development: not for users. May be dangerous, may not be documented.
104 static const char *level_to_str(level_t l
) {
106 case LEVEL_BASIC
: return "basic";
107 case LEVEL_ADVANCED
: return "advanced";
108 case LEVEL_DEV
: return "dev";
109 default: return "unknown";
114 FLAG_RUNTIME
= 0x1, ///< option can change changed at runtime
115 FLAG_NO_MON_UPDATE
= 0x2, ///< option cannot be changed via mon config
116 FLAG_STARTUP
= 0x4, ///< option can only take effect at startup
117 FLAG_CLUSTER_CREATE
= 0x8, ///< option only has effect at cluster creation
118 FLAG_CREATE
= 0x10, ///< option only has effect at daemon creation
119 FLAG_MGR
= 0x20, ///< option is a mgr module option
120 FLAG_MINIMAL_CONF
= 0x40, ///< option should go in a minimal ceph.conf
125 operator uint64_t() const {
126 return static_cast<uint64_t>(value
);
128 bool operator==(const size_t& rhs
) const {
129 return value
== rhs
.value
;
133 using value_t
= boost::variant
<
142 std::chrono::seconds
,
145 const std::string name
;
150 std::string long_desc
;
154 int subsys
= -1; // if >= 0, we are a subsys debug level
157 value_t daemon_value
;
159 static std::string
to_str(const value_t
& v
);
161 // Items like mon, osd, rgw, rbd, ceph-fuse. This is advisory metadata
162 // for presentation layers (like web dashboards, or generated docs), so that
163 // they know which options to display where.
164 // Additionally: "common" for settings that exist in any Ceph code. Do
165 // not use common for settings that are just shared some places: for those
166 // places, list them.
167 std::vector
<const char*> services
;
170 // "service": a catchall for the boring stuff like log/asok paths.
172 // "performance": a setting that may need adjustment depending on
173 // environment/workload to get best performance.
174 std::vector
<const char*> tags
;
176 std::vector
<const char*> see_also
;
179 std::vector
<const char*> enum_allowed
;
182 * Return nonzero and set second argument to error string if the
185 * These callbacks are more than just validators, as they can also
186 * modify the value as it passes through.
188 typedef std::function
<int(std::string
*, std::string
*)> validator_fn_t
;
189 validator_fn_t validator
;
191 Option(std::string
const &name
, type_t t
, level_t l
)
192 : name(name
), type(t
), level(l
)
194 // While value_t is nullable (via boost::blank), we don't ever
195 // want it set that way in an Option instance: within an instance,
196 // the type of ::value should always match the declared type.
199 value
= int64_t(0); break;
201 value
= uint64_t(0); break;
203 value
= std::string(""); break;
207 value
= false; break;
209 value
= entity_addr_t(); break;
211 value
= entity_addrvec_t(); break;
213 value
= uuid_d(); break;
215 value
= size_t{0}; break;
217 value
= std::chrono::seconds
{0}; break;
223 void dump_value(const char *field_name
, const value_t
&v
, ceph::Formatter
*f
) const;
225 // Validate and potentially modify incoming string value
226 int pre_validate(std::string
*new_value
, std::string
*err
) const;
228 // Validate properly typed value against bounds
229 int validate(const Option::value_t
&new_value
, std::string
*err
) const;
231 // const char * must be explicit to avoid it being treated as an int
232 Option
& set_value(value_t
& v
, const char *new_value
) {
233 v
= std::string(new_value
);
237 // bool is an integer, but we don't think so. teach it the hard way.
239 using is_not_integer
= std::enable_if
<!std::is_integral
<T
>::value
||
240 std::is_same
<T
, bool>::value
, int>;
242 using is_integer
= std::enable_if
<std::is_integral
<T
>::value
&&
243 !std::is_same
<T
, bool>::value
, int>;
244 template<typename T
, typename is_not_integer
<T
>::type
= 0>
245 Option
& set_value(value_t
& v
, const T
& new_value
) {
250 // For potentially ambiguous types, inspect Option::type and
251 // do some casting. This is necessary to make sure that setting
252 // a float option to "0" actually sets the double part of variant.
253 template<typename T
, typename is_integer
<T
>::type
= 0>
254 Option
& set_value(value_t
& v
, T new_value
) {
257 v
= int64_t(new_value
); break;
259 v
= uint64_t(new_value
); break;
261 v
= double(new_value
); break;
263 v
= bool(new_value
); break;
265 v
= size_t{static_cast<std::size_t>(new_value
)}; break;
267 v
= std::chrono::seconds
{new_value
}; break;
269 std::cerr
<< "Bad type in set_value: " << name
<< ": "
270 << typeid(T
).name() << std::endl
;
276 /// parse and validate a string input
278 const std::string
& raw_val
,
280 std::string
*error_message
,
281 std::string
*normalized_value
=nullptr) const;
284 Option
& set_default(const T
& v
) {
285 return set_value(value
, v
);
289 Option
& set_daemon_default(const T
& v
) {
290 return set_value(daemon_value
, v
);
292 Option
& add_tag(const char* tag
) {
296 Option
& add_tag(const std::initializer_list
<const char*>& ts
) {
297 tags
.insert(tags
.end(), ts
);
300 Option
& add_service(const char* service
) {
301 services
.push_back(service
);
304 Option
& add_service(const std::initializer_list
<const char*>& ss
) {
305 services
.insert(services
.end(), ss
);
308 Option
& add_see_also(const char* t
) {
309 see_also
.push_back(t
);
312 Option
& add_see_also(const std::initializer_list
<const char*>& ts
) {
313 see_also
.insert(see_also
.end(), ts
);
316 Option
& set_description(const char* new_desc
) {
320 Option
& set_long_description(const char* new_desc
) {
321 long_desc
= new_desc
;
326 Option
& set_min(const T
& mi
) {
332 Option
& set_min_max(const T
& mi
, const T
& ma
) {
338 Option
& set_enum_allowed(const std::vector
<const char*>& allowed
)
340 enum_allowed
= allowed
;
344 Option
&set_flag(flag_t f
) {
348 Option
&set_flags(flag_t f
) {
353 Option
&set_validator(const validator_fn_t
&validator_
)
355 validator
= validator_
;
359 Option
&set_subsys(int s
) {
364 void dump(ceph::Formatter
*f
) const;
365 void print(std::ostream
*out
) const;
367 bool has_flag(flag_t f
) const {
372 * A crude indicator of whether the value may be
373 * modified safely at runtime -- should be replaced
374 * with proper locking!
376 bool can_update_at_runtime() const
379 (has_flag(FLAG_RUNTIME
)
380 || (!has_flag(FLAG_MGR
)
381 && (type
== TYPE_BOOL
|| type
== TYPE_INT
382 || type
== TYPE_UINT
|| type
== TYPE_FLOAT
383 || type
== TYPE_SIZE
|| type
== TYPE_SECS
)))
384 && !has_flag(FLAG_STARTUP
)
385 && !has_flag(FLAG_CLUSTER_CREATE
)
386 && !has_flag(FLAG_CREATE
);
390 extern const std::vector
<Option
> ceph_options
;