]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> | |
7 | * | |
8 | * This is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License version 2.1, as published by the Free Software | |
11 | * Foundation. See file COPYING. | |
12 | * | |
13 | */ | |
14 | ||
15 | #ifndef CEPH_CONFIG_H | |
16 | #define CEPH_CONFIG_H | |
17 | ||
11fdf7f2 | 18 | #include <map> |
20effc67 | 19 | #include <variant> |
11fdf7f2 | 20 | #include <boost/container/small_vector.hpp> |
7c673cae | 21 | #include "common/ConfUtils.h" |
c07f9fc5 | 22 | #include "common/code_environment.h" |
7c673cae | 23 | #include "log/SubsystemMap.h" |
c07f9fc5 | 24 | #include "common/options.h" |
11fdf7f2 TL |
25 | #include "common/subsys_types.h" |
26 | #include "common/config_tracker.h" | |
27 | #include "common/config_values.h" | |
9f95a23c | 28 | #include "include/common_fwd.h" |
7c673cae | 29 | |
11fdf7f2 TL |
30 | enum { |
31 | CONF_DEFAULT, | |
32 | CONF_MON, | |
33 | CONF_FILE, | |
34 | CONF_ENV, | |
35 | CONF_CMDLINE, | |
36 | CONF_OVERRIDE, | |
37 | CONF_FINAL | |
38 | }; | |
7c673cae | 39 | |
11fdf7f2 | 40 | extern const char *ceph_conf_level_name(int level); |
7c673cae FG |
41 | |
42 | /** This class represents the current Ceph configuration. | |
43 | * | |
44 | * For Ceph daemons, this is the daemon configuration. Log levels, caching | |
45 | * settings, btrfs settings, and so forth can all be found here. For libcephfs | |
46 | * and librados users, this is the configuration associated with their context. | |
47 | * | |
48 | * For information about how this class is loaded from a configuration file, | |
49 | * see common/ConfUtils. | |
50 | * | |
51 | * ACCESS | |
52 | * | |
53 | * There are 3 ways to read the ceph context-- the old way and two new ways. | |
54 | * In the old way, code would simply read the public variables of the | |
55 | * configuration, without taking a lock. In the new way #1, code registers a | |
11fdf7f2 | 56 | * configuration observer which receives callbacks when a value changes. These |
7c673cae FG |
57 | * callbacks take place under the md_config_t lock. Alternatively one can use |
58 | * get_val(const char *name) method to safely get a copy of the value. | |
59 | * | |
60 | * To prevent serious problems resulting from thread-safety issues, we disallow | |
61 | * changing std::string configuration values after | |
11fdf7f2 | 62 | * md_config_t::safe_to_start_threads becomes true. You can still |
7c673cae FG |
63 | * change integer or floating point values, and the option declared with |
64 | * SAFE_OPTION macro. Notice the latter options can not be read directly | |
65 | * (conf->foo), one should use either observers or get_val() method | |
66 | * (conf->get_val("foo")). | |
67 | * | |
68 | * FIXME: really we shouldn't allow changing integer or floating point values | |
69 | * while another thread is reading them, either. | |
70 | */ | |
71 | struct md_config_t { | |
72 | public: | |
20effc67 TL |
73 | typedef std::variant<int64_t ConfigValues::*, |
74 | uint64_t ConfigValues::*, | |
75 | std::string ConfigValues::*, | |
76 | double ConfigValues::*, | |
77 | bool ConfigValues::*, | |
78 | entity_addr_t ConfigValues::*, | |
79 | entity_addrvec_t ConfigValues::*, | |
80 | uuid_d ConfigValues::*> member_ptr_t; | |
11fdf7f2 TL |
81 | |
82 | // For use when intercepting configuration updates | |
83 | typedef std::function<bool( | |
84 | const std::string &k, const std::string &v)> config_callback; | |
85 | ||
86 | /// true if we are a daemon (as per CephContext::code_env) | |
87 | const bool is_daemon; | |
7c673cae | 88 | |
c07f9fc5 FG |
89 | /* |
90 | * Mapping from legacy config option names to class members | |
91 | */ | |
9f95a23c | 92 | std::map<std::string_view, member_ptr_t> legacy_values; |
c07f9fc5 FG |
93 | |
94 | /** | |
95 | * The configuration schema, in the form of Option objects describing | |
96 | * possible settings. | |
97 | */ | |
9f95a23c | 98 | std::map<std::string_view, const Option&> schema; |
c07f9fc5 | 99 | |
11fdf7f2 TL |
100 | /// values from mon that we failed to set |
101 | std::map<std::string,std::string> ignored_mon_values; | |
102 | ||
103 | /// original raw values saved that may need to re-expand at certain time | |
adb31ebb | 104 | mutable std::vector<std::string> may_reexpand_meta; |
11fdf7f2 TL |
105 | |
106 | /// encoded, cached copy of of values + ignored_mon_values | |
9f95a23c | 107 | ceph::bufferlist values_bl; |
11fdf7f2 TL |
108 | |
109 | /// version for values_bl; increments each time there is a change | |
110 | uint64_t values_bl_version = 0; | |
111 | ||
112 | /// encoded copy of defaults (map<string,string>) | |
9f95a23c | 113 | ceph::bufferlist defaults_bl; |
7c673cae | 114 | |
7c673cae | 115 | // Create a new md_config_t structure. |
11fdf7f2 TL |
116 | explicit md_config_t(ConfigValues& values, |
117 | const ConfigTracker& tracker, | |
118 | bool is_daemon=false); | |
7c673cae FG |
119 | ~md_config_t(); |
120 | ||
7c673cae | 121 | // Parse a config file |
11fdf7f2 TL |
122 | int parse_config_files(ConfigValues& values, const ConfigTracker& tracker, |
123 | const char *conf_files, | |
7c673cae | 124 | std::ostream *warnings, int flags); |
f67539c2 TL |
125 | int parse_buffer(ConfigValues& values, const ConfigTracker& tracker, |
126 | const char* buf, size_t len, | |
127 | std::ostream *warnings); | |
128 | void update_legacy_vals(ConfigValues& values); | |
7c673cae | 129 | // Absorb config settings from the environment |
11fdf7f2 TL |
130 | void parse_env(unsigned entity_type, |
131 | ConfigValues& values, const ConfigTracker& tracker, | |
132 | const char *env_var = "CEPH_ARGS"); | |
7c673cae FG |
133 | |
134 | // Absorb config settings from argv | |
11fdf7f2 TL |
135 | int parse_argv(ConfigValues& values, const ConfigTracker& tracker, |
136 | std::vector<const char*>& args, int level=CONF_CMDLINE); | |
137 | ||
138 | // do any commands we got from argv (--show-config, --show-config-val) | |
139 | void do_argv_commands(const ConfigValues& values) const; | |
7c673cae | 140 | |
9f95a23c | 141 | bool _internal_field(const std::string& k); |
11fdf7f2 TL |
142 | |
143 | void set_safe_to_start_threads(); | |
144 | void _clear_safe_to_start_threads(); // this is only used by the unit test | |
145 | ||
146 | /// Look up an option in the schema | |
9f95a23c | 147 | const Option *find_option(const std::string_view name) const; |
11fdf7f2 TL |
148 | |
149 | /// Set a default value | |
150 | void set_val_default(ConfigValues& values, | |
151 | const ConfigTracker& tracker, | |
9f95a23c | 152 | const std::string_view key, const std::string &val); |
11fdf7f2 TL |
153 | |
154 | /// Set a values from mon | |
155 | int set_mon_vals(CephContext *cct, | |
9f95a23c TL |
156 | ConfigValues& values, |
157 | const ConfigTracker& tracker, | |
158 | const std::map<std::string,std::string, std::less<>>& kv, | |
159 | config_callback config_cb); | |
7c673cae FG |
160 | |
161 | // Called by the Ceph daemons to make configuration changes at runtime | |
11fdf7f2 TL |
162 | int injectargs(ConfigValues& values, |
163 | const ConfigTracker& tracker, | |
164 | const std::string &s, | |
165 | std::ostream *oss); | |
7c673cae FG |
166 | |
167 | // Set a configuration value, or crash | |
168 | // Metavariables will be expanded. | |
11fdf7f2 | 169 | void set_val_or_die(ConfigValues& values, const ConfigTracker& tracker, |
9f95a23c | 170 | const std::string_view key, const std::string &val); |
7c673cae FG |
171 | |
172 | // Set a configuration value. | |
173 | // Metavariables will be expanded. | |
11fdf7f2 | 174 | int set_val(ConfigValues& values, const ConfigTracker& tracker, |
9f95a23c | 175 | const std::string_view key, const char *val, |
c07f9fc5 | 176 | std::stringstream *err_ss=nullptr); |
11fdf7f2 | 177 | int set_val(ConfigValues& values, const ConfigTracker& tracker, |
9f95a23c | 178 | const std::string_view key, const std::string& s, |
c07f9fc5 | 179 | std::stringstream *err_ss=nullptr) { |
11fdf7f2 | 180 | return set_val(values, tracker, key, s.c_str(), err_ss); |
7c673cae FG |
181 | } |
182 | ||
11fdf7f2 | 183 | /// clear override value |
9f95a23c | 184 | int rm_val(ConfigValues& values, const std::string_view key); |
11fdf7f2 TL |
185 | |
186 | /// get encoded map<string,map<int32_t,string>> of entire config | |
187 | void get_config_bl(const ConfigValues& values, | |
188 | uint64_t have_version, | |
9f95a23c | 189 | ceph::buffer::list *bl, |
11fdf7f2 TL |
190 | uint64_t *got_version); |
191 | ||
192 | /// get encoded map<string,string> of compiled-in defaults | |
9f95a23c | 193 | void get_defaults_bl(const ConfigValues& values, ceph::buffer::list *bl); |
11fdf7f2 | 194 | |
a4b75251 TL |
195 | /// Get the default value of a configuration option |
196 | std::optional<std::string> get_val_default(std::string_view key); | |
197 | ||
7c673cae FG |
198 | // Get a configuration value. |
199 | // No metavariables will be returned (they will have already been expanded) | |
9f95a23c TL |
200 | int get_val(const ConfigValues& values, const std::string_view key, char **buf, int len) const; |
201 | int get_val(const ConfigValues& values, const std::string_view key, std::string *val) const; | |
202 | template<typename T> const T get_val(const ConfigValues& values, const std::string_view key) const; | |
11fdf7f2 | 203 | template<typename T, typename Callback, typename...Args> |
9f95a23c | 204 | auto with_val(const ConfigValues& values, const std::string_view key, |
11fdf7f2 TL |
205 | Callback&& cb, Args&&... args) const -> |
206 | std::result_of_t<Callback(const T&, Args...)> { | |
207 | return std::forward<Callback>(cb)( | |
20effc67 | 208 | std::get<T>(this->get_val_generic(values, key)), |
11fdf7f2 TL |
209 | std::forward<Args>(args)...); |
210 | } | |
7c673cae FG |
211 | |
212 | void get_all_keys(std::vector<std::string> *keys) const; | |
213 | ||
214 | // Return a list of all the sections that the current entity is a member of. | |
f67539c2 | 215 | std::vector<std::string> get_my_sections(const ConfigValues& values) const; |
7c673cae FG |
216 | |
217 | // Return a list of all sections | |
218 | int get_all_sections(std::vector <std::string> §ions) const; | |
219 | ||
220 | // Get a value from the configuration file that we read earlier. | |
221 | // Metavariables will be expanded if emeta is true. | |
11fdf7f2 TL |
222 | int get_val_from_conf_file(const ConfigValues& values, |
223 | const std::vector <std::string> §ions, | |
9f95a23c | 224 | const std::string_view key, std::string &out, bool emeta) const; |
7c673cae FG |
225 | |
226 | /// dump all config values to a stream | |
11fdf7f2 | 227 | void show_config(const ConfigValues& values, std::ostream& out) const; |
7c673cae | 228 | /// dump all config values to a formatter |
9f95a23c TL |
229 | void show_config(const ConfigValues& values, ceph::Formatter *f) const; |
230 | ||
1adf2230 | 231 | /// dump all config settings to a formatter |
9f95a23c | 232 | void config_options(ceph::Formatter *f) const; |
7c673cae | 233 | |
11fdf7f2 TL |
234 | /// dump config diff from default, conf, mon, etc. |
235 | void diff(const ConfigValues& values, | |
9f95a23c TL |
236 | ceph::Formatter *f, |
237 | std::string name = {}) const; | |
31f18b77 | 238 | |
7c673cae | 239 | /// print/log warnings/errors from parsing the config |
9f95a23c | 240 | void complain_about_parse_error(CephContext *cct); |
7c673cae FG |
241 | |
242 | private: | |
11fdf7f2 | 243 | // we use this to avoid variable expansion loops |
9f95a23c TL |
244 | typedef boost::container::small_vector<std::pair<const Option*, |
245 | const Option::value_t*>, | |
11fdf7f2 TL |
246 | 4> expand_stack_t; |
247 | ||
c07f9fc5 | 248 | void validate_schema(); |
7c673cae FG |
249 | void validate_default_settings(); |
250 | ||
9f95a23c TL |
251 | Option::value_t get_val_generic(const ConfigValues& values, |
252 | const std::string_view key) const; | |
11fdf7f2 | 253 | int _get_val_cstr(const ConfigValues& values, |
9f95a23c | 254 | const std::string& key, char **buf, int len) const; |
11fdf7f2 | 255 | Option::value_t _get_val(const ConfigValues& values, |
9f95a23c | 256 | const std::string_view key, |
11fdf7f2 TL |
257 | expand_stack_t *stack=0, |
258 | std::ostream *err=0) const; | |
259 | Option::value_t _get_val(const ConfigValues& values, | |
260 | const Option& o, | |
261 | expand_stack_t *stack=0, | |
262 | std::ostream *err=0) const; | |
263 | const Option::value_t& _get_val_default(const Option& o) const; | |
264 | Option::value_t _get_val_nometa(const ConfigValues& values, | |
265 | const Option& o) const; | |
7c673cae | 266 | |
9f95a23c | 267 | int _rm_val(ConfigValues& values, const std::string_view key, int level); |
11fdf7f2 TL |
268 | |
269 | void _refresh(ConfigValues& values, const Option& opt); | |
270 | ||
271 | void _show_config(const ConfigValues& values, | |
9f95a23c | 272 | std::ostream *out, ceph::Formatter *f) const; |
11fdf7f2 | 273 | |
9f95a23c TL |
274 | int _get_val_from_conf_file(const std::vector<std::string> §ions, |
275 | const std::string_view key, std::string &out) const; | |
7c673cae | 276 | |
11fdf7f2 TL |
277 | int parse_option(ConfigValues& values, |
278 | const ConfigTracker& tracker, | |
279 | std::vector<const char*>& args, | |
7c673cae | 280 | std::vector<const char*>::iterator& i, |
11fdf7f2 TL |
281 | std::ostream *oss, |
282 | int level); | |
283 | int parse_injectargs(ConfigValues& values, | |
284 | const ConfigTracker& tracker, | |
285 | std::vector<const char*>& args, | |
286 | std::ostream *oss); | |
287 | ||
288 | // @returns negative number for an error, otherwise a | |
289 | // @c ConfigValues::set_value_result_t is returned. | |
290 | int _set_val( | |
291 | ConfigValues& values, | |
292 | const ConfigTracker& tracker, | |
293 | const std::string &val, | |
294 | const Option &opt, | |
295 | int level, // CONF_* | |
296 | std::string *error_message); | |
c07f9fc5 FG |
297 | |
298 | template <typename T> | |
299 | void assign_member(member_ptr_t ptr, const Option::value_t &val); | |
300 | ||
301 | ||
11fdf7f2 TL |
302 | void update_legacy_val(ConfigValues& values, |
303 | const Option &opt, | |
304 | member_ptr_t member); | |
31f18b77 | 305 | |
11fdf7f2 TL |
306 | Option::value_t _expand_meta( |
307 | const ConfigValues& values, | |
308 | const Option::value_t& in, | |
309 | const Option *o, | |
310 | expand_stack_t *stack, | |
311 | std::ostream *err) const; | |
31f18b77 | 312 | |
7c673cae | 313 | public: // for global_init |
11fdf7f2 TL |
314 | void early_expand_meta(const ConfigValues& values, |
315 | std::string &val, | |
316 | std::ostream *oss) const; | |
317 | ||
318 | // for those want to reexpand special meta, e.g, $pid | |
319 | bool finalize_reexpand_meta(ConfigValues& values, | |
320 | const ConfigTracker& tracker); | |
7c673cae | 321 | |
f67539c2 TL |
322 | std::list<std::string> get_conffile_paths(const ConfigValues& values, |
323 | const char *conf_files, | |
324 | std::ostream *warnings, | |
325 | int flags) const; | |
b3b6e05e TL |
326 | |
327 | const std::string& get_conf_path() const { | |
328 | return conf_path; | |
329 | } | |
f67539c2 TL |
330 | private: |
331 | static std::string get_cluster_name(const char* conffile_path); | |
7c673cae FG |
332 | // The configuration file we read, or NULL if we haven't read one. |
333 | ConfFile cf; | |
b3b6e05e | 334 | std::string conf_path; |
7c673cae | 335 | public: |
9f95a23c | 336 | std::string parse_error; |
7c673cae FG |
337 | private: |
338 | ||
11fdf7f2 TL |
339 | // This will be set to true when it is safe to start threads. |
340 | // Once it is true, it will never change. | |
341 | bool safe_to_start_threads = false; | |
7c673cae | 342 | |
11fdf7f2 | 343 | bool do_show_config = false; |
9f95a23c | 344 | std::string do_show_config_value; |
7c673cae | 345 | |
9f95a23c | 346 | std::vector<Option> subsys_options; |
7c673cae | 347 | |
11fdf7f2 | 348 | public: |
9f95a23c | 349 | std::string data_dir_option; ///< data_dir config option, if any |
7c673cae | 350 | |
c07f9fc5 | 351 | public: |
11fdf7f2 TL |
352 | unsigned get_osd_pool_default_min_size(const ConfigValues& values, |
353 | uint8_t size) const { | |
354 | uint8_t min_size = get_val<uint64_t>(values, "osd_pool_default_min_size"); | |
355 | return min_size ? std::min(min_size, size) : (size - size / 2); | |
7c673cae FG |
356 | } |
357 | ||
7c673cae | 358 | friend class test_md_config_t; |
7c673cae FG |
359 | }; |
360 | ||
361 | template<typename T> | |
11fdf7f2 | 362 | const T md_config_t::get_val(const ConfigValues& values, |
9f95a23c | 363 | const std::string_view key) const { |
20effc67 | 364 | return std::get<T>(this->get_val_generic(values, key)); |
7c673cae FG |
365 | } |
366 | ||
20effc67 | 367 | inline std::ostream& operator<<(std::ostream& o, const std::monostate&) { |
7c673cae FG |
368 | return o << "INVALID_CONFIG_VALUE"; |
369 | } | |
370 | ||
371 | int ceph_resolve_file_search(const std::string& filename_list, | |
372 | std::string& result); | |
373 | ||
7c673cae | 374 | #endif |