]>
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
10 #include "include/str_list.h"
11 #include "msg/msg_types.h"
12 #include "include/uuid.h"
29 static const char *type_to_c_type_str(type_t t
) {
31 case TYPE_UINT
: return "uint64_t";
32 case TYPE_INT
: return "int64_t";
33 case TYPE_STR
: return "std::string";
34 case TYPE_FLOAT
: return "double";
35 case TYPE_BOOL
: return "bool";
36 case TYPE_ADDR
: return "entity_addr_t";
37 case TYPE_ADDRVEC
: return "entity_addrvec_t";
38 case TYPE_UUID
: return "uuid_d";
39 case TYPE_SIZE
: return "uint64_t";
40 case TYPE_SECS
: return "secs";
41 case TYPE_MILLISECS
: return "millisecs";
42 default: return "unknown";
45 static const char *type_to_str(type_t t
) {
47 case TYPE_UINT
: return "uint";
48 case TYPE_INT
: return "int";
49 case TYPE_STR
: return "str";
50 case TYPE_FLOAT
: return "float";
51 case TYPE_BOOL
: return "bool";
52 case TYPE_ADDR
: return "addr";
53 case TYPE_ADDRVEC
: return "addrvec";
54 case TYPE_UUID
: return "uuid";
55 case TYPE_SIZE
: return "size";
56 case TYPE_SECS
: return "secs";
57 case TYPE_MILLISECS
: return "millisecs";
58 default: return "unknown";
61 static int str_to_type(const std::string
& s
) {
92 if (s
== "millisecs") {
93 return TYPE_MILLISECS
;
99 * Basic: for users, configures some externally visible functional aspect
100 * Advanced: for users, configures some internal behaviour
101 * Development: not for users. May be dangerous, may not be documented.
110 static const char *level_to_str(level_t l
) {
112 case LEVEL_BASIC
: return "basic";
113 case LEVEL_ADVANCED
: return "advanced";
114 case LEVEL_DEV
: return "dev";
115 default: return "unknown";
120 FLAG_RUNTIME
= 0x1, ///< option can be changed at runtime
121 FLAG_NO_MON_UPDATE
= 0x2, ///< option cannot be changed via mon config
122 FLAG_STARTUP
= 0x4, ///< option can only take effect at startup
123 FLAG_CLUSTER_CREATE
= 0x8, ///< option only has effect at cluster creation
124 FLAG_CREATE
= 0x10, ///< option only has effect at daemon creation
125 FLAG_MGR
= 0x20, ///< option is a mgr module option
126 FLAG_MINIMAL_CONF
= 0x40, ///< option should go in a minimal ceph.conf
131 operator uint64_t() const {
132 return static_cast<uint64_t>(value
);
134 bool operator==(const size_t& rhs
) const {
135 return value
== rhs
.value
;
139 using value_t
= std::variant
<
148 std::chrono::seconds
,
149 std::chrono::milliseconds
,
152 const std::string name
;
157 std::string long_desc
;
161 int subsys
= -1; // if >= 0, we are a subsys debug level
164 value_t daemon_value
;
166 static std::string
to_str(const value_t
& v
);
168 // Items like mon, osd, rgw, rbd, ceph-fuse. This is advisory metadata
169 // for presentation layers (like web dashboards, or generated docs), so that
170 // they know which options to display where.
171 // Additionally: "common" for settings that exist in any Ceph code. Do
172 // not use common for settings that are just shared some places: for those
173 // places, list them.
174 std::vector
<const char*> services
;
177 // "service": a catchall for the boring stuff like log/asok paths.
179 // "performance": a setting that may need adjustment depending on
180 // environment/workload to get best performance.
181 std::vector
<const char*> tags
;
183 std::vector
<const char*> see_also
;
186 std::vector
<const char*> enum_allowed
;
189 * Return nonzero and set second argument to error string if the
192 * These callbacks are more than just validators, as they can also
193 * modify the value as it passes through.
195 typedef std::function
<int(std::string
*, std::string
*)> validator_fn_t
;
196 validator_fn_t validator
;
198 Option(std::string
const &name
, type_t t
, level_t l
)
199 : name(name
), type(t
), level(l
)
201 // While value_t is nullable (via std::monostate), we don't ever
202 // want it set that way in an Option instance: within an instance,
203 // the type of ::value should always match the declared type.
206 value
= int64_t(0); break;
208 value
= uint64_t(0); break;
210 value
= std::string(""); break;
214 value
= false; break;
216 value
= entity_addr_t(); break;
218 value
= entity_addrvec_t(); break;
220 value
= uuid_d(); break;
222 value
= size_t{0}; break;
224 value
= std::chrono::seconds
{0}; break;
226 value
= std::chrono::milliseconds
{0}; break;
232 void dump_value(const char *field_name
, const value_t
&v
, ceph::Formatter
*f
) const;
234 // Validate and potentially modify incoming string value
235 int pre_validate(std::string
*new_value
, std::string
*err
) const;
237 // Validate properly typed value against bounds
238 int validate(const Option::value_t
&new_value
, std::string
*err
) const;
240 // const char * must be explicit to avoid it being treated as an int
241 Option
& set_value(value_t
& v
, const char *new_value
) {
242 v
= std::string(new_value
);
246 // bool is an integer, but we don't think so. teach it the hard way.
248 using is_not_integer_t
=
249 std::enable_if_t
<!std::is_integral_v
<T
> || std::is_same_v
<T
, bool>, int>;
252 std::enable_if_t
<std::is_integral_v
<T
> && !std::is_same_v
<T
, bool>, int>;
253 template<typename T
, typename
= is_not_integer_t
<T
>>
254 Option
& set_value(value_t
& v
, const T
& new_value
) {
259 // For potentially ambiguous types, inspect Option::type and
260 // do some casting. This is necessary to make sure that setting
261 // a float option to "0" actually sets the double part of variant.
262 template<typename T
, typename
= is_integer_t
<T
>>
263 Option
& set_value(value_t
& v
, T new_value
) {
266 v
= int64_t(new_value
); break;
268 v
= uint64_t(new_value
); break;
270 v
= double(new_value
); break;
272 v
= bool(new_value
); break;
274 v
= size_t{static_cast<std::uint64_t>(new_value
)}; break;
276 v
= std::chrono::seconds
{new_value
}; break;
278 v
= std::chrono::milliseconds
{new_value
}; break;
280 std::cerr
<< "Bad type in set_value: " << name
<< ": "
281 << typeid(T
).name() << std::endl
;
287 /// parse and validate a string input
289 const std::string
& raw_val
,
291 std::string
*error_message
,
292 std::string
*normalized_value
=nullptr) const;
295 Option
& set_default(const T
& v
) {
296 return set_value(value
, v
);
300 Option
& set_daemon_default(const T
& v
) {
301 return set_value(daemon_value
, v
);
303 Option
& add_tag(const char* tag
) {
307 Option
& add_tag(const std::initializer_list
<const char*>& ts
) {
308 tags
.insert(tags
.end(), ts
);
311 Option
& add_service(const char* service
) {
312 services
.push_back(service
);
315 Option
& add_service(const std::initializer_list
<const char*>& ss
) {
316 services
.insert(services
.end(), ss
);
319 Option
& add_see_also(const char* t
) {
320 see_also
.push_back(t
);
323 Option
& add_see_also(const std::initializer_list
<const char*>& ts
) {
324 see_also
.insert(see_also
.end(), ts
);
327 Option
& set_description(const char* new_desc
) {
331 Option
& set_long_description(const char* new_desc
) {
332 long_desc
= new_desc
;
337 Option
& set_min(const T
& mi
) {
343 Option
& set_min_max(const T
& mi
, const T
& ma
) {
349 Option
& set_enum_allowed(const std::vector
<const char*>& allowed
)
351 enum_allowed
= allowed
;
355 Option
&set_flag(flag_t f
) {
359 Option
&set_flags(flag_t f
) {
364 Option
&set_validator(const validator_fn_t
&validator_
)
366 validator
= validator_
;
370 Option
&set_subsys(int s
) {
375 void dump(ceph::Formatter
*f
) const;
376 void print(std::ostream
*out
) const;
378 bool has_flag(flag_t f
) const {
383 * A crude indicator of whether the value may be
384 * modified safely at runtime -- should be replaced
385 * with proper locking!
387 bool can_update_at_runtime() const
390 (has_flag(FLAG_RUNTIME
)
391 || (!has_flag(FLAG_MGR
)
392 && (type
== TYPE_BOOL
|| type
== TYPE_INT
393 || type
== TYPE_UINT
|| type
== TYPE_FLOAT
394 || type
== TYPE_SIZE
|| type
== TYPE_SECS
395 || type
== TYPE_MILLISECS
)))
396 && !has_flag(FLAG_STARTUP
)
397 && !has_flag(FLAG_CLUSTER_CREATE
)
398 && !has_flag(FLAG_CREATE
);
402 constexpr unsigned long long operator"" _min (unsigned long long min
) {
405 constexpr unsigned long long operator"" _hr (unsigned long long hr
) {
408 constexpr unsigned long long operator"" _day (unsigned long long day
) {
409 return day
* 24 * 60 * 60;
411 constexpr unsigned long long operator"" _K (unsigned long long n
) {
414 constexpr unsigned long long operator"" _M (unsigned long long n
) {
417 constexpr unsigned long long operator"" _G (unsigned long long n
) {
420 constexpr unsigned long long operator"" _T (unsigned long long n
) {
424 extern const std::vector
<Option
> ceph_options
;