]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/config.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / common / config.h
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
18 #include <map>
19 #include <variant>
20 #include <boost/container/small_vector.hpp>
21 #include "common/ConfUtils.h"
22 #include "common/code_environment.h"
23 #include "log/SubsystemMap.h"
24 #include "common/options.h"
25 #include "common/subsys_types.h"
26 #include "common/config_tracker.h"
27 #include "common/config_values.h"
28 #include "include/common_fwd.h"
29
30 enum {
31 CONF_DEFAULT,
32 CONF_MON,
33 CONF_FILE,
34 CONF_ENV,
35 CONF_CMDLINE,
36 CONF_OVERRIDE,
37 CONF_FINAL
38 };
39
40 extern const char *ceph_conf_level_name(int level);
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
56 * configuration observer which receives callbacks when a value changes. These
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
62 * md_config_t::safe_to_start_threads becomes true. You can still
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:
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;
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;
88
89 /*
90 * Mapping from legacy config option names to class members
91 */
92 std::map<std::string_view, member_ptr_t> legacy_values;
93
94 /**
95 * The configuration schema, in the form of Option objects describing
96 * possible settings.
97 */
98 std::map<std::string_view, const Option&> schema;
99
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
104 mutable std::vector<std::string> may_reexpand_meta;
105
106 /// encoded, cached copy of of values + ignored_mon_values
107 ceph::bufferlist values_bl;
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>)
113 ceph::bufferlist defaults_bl;
114
115 // Create a new md_config_t structure.
116 explicit md_config_t(ConfigValues& values,
117 const ConfigTracker& tracker,
118 bool is_daemon=false);
119 ~md_config_t();
120
121 // Parse a config file
122 int parse_config_files(ConfigValues& values, const ConfigTracker& tracker,
123 const char *conf_files,
124 std::ostream *warnings, int flags);
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);
129 // Absorb config settings from the environment
130 void parse_env(unsigned entity_type,
131 ConfigValues& values, const ConfigTracker& tracker,
132 const char *env_var = "CEPH_ARGS");
133
134 // Absorb config settings from argv
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;
140
141 bool _internal_field(const std::string& k);
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
147 const Option *find_option(const std::string_view name) const;
148
149 /// Set a default value
150 void set_val_default(ConfigValues& values,
151 const ConfigTracker& tracker,
152 const std::string_view key, const std::string &val);
153
154 /// Set a values from mon
155 int set_mon_vals(CephContext *cct,
156 ConfigValues& values,
157 const ConfigTracker& tracker,
158 const std::map<std::string,std::string, std::less<>>& kv,
159 config_callback config_cb);
160
161 // Called by the Ceph daemons to make configuration changes at runtime
162 int injectargs(ConfigValues& values,
163 const ConfigTracker& tracker,
164 const std::string &s,
165 std::ostream *oss);
166
167 // Set a configuration value, or crash
168 // Metavariables will be expanded.
169 void set_val_or_die(ConfigValues& values, const ConfigTracker& tracker,
170 const std::string_view key, const std::string &val);
171
172 // Set a configuration value.
173 // Metavariables will be expanded.
174 int set_val(ConfigValues& values, const ConfigTracker& tracker,
175 const std::string_view key, const char *val,
176 std::stringstream *err_ss=nullptr);
177 int set_val(ConfigValues& values, const ConfigTracker& tracker,
178 const std::string_view key, const std::string& s,
179 std::stringstream *err_ss=nullptr) {
180 return set_val(values, tracker, key, s.c_str(), err_ss);
181 }
182
183 /// clear override value
184 int rm_val(ConfigValues& values, const std::string_view key);
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,
189 ceph::buffer::list *bl,
190 uint64_t *got_version);
191
192 /// get encoded map<string,string> of compiled-in defaults
193 void get_defaults_bl(const ConfigValues& values, ceph::buffer::list *bl);
194
195 /// Get the default value of a configuration option
196 std::optional<std::string> get_val_default(std::string_view key);
197
198 // Get a configuration value.
199 // No metavariables will be returned (they will have already been expanded)
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;
203 template<typename T, typename Callback, typename...Args>
204 auto with_val(const ConfigValues& values, const std::string_view key,
205 Callback&& cb, Args&&... args) const ->
206 std::result_of_t<Callback(const T&, Args...)> {
207 return std::forward<Callback>(cb)(
208 std::get<T>(this->get_val_generic(values, key)),
209 std::forward<Args>(args)...);
210 }
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.
215 std::vector<std::string> get_my_sections(const ConfigValues& values) const;
216
217 // Return a list of all sections
218 int get_all_sections(std::vector <std::string> &sections) const;
219
220 // Get a value from the configuration file that we read earlier.
221 // Metavariables will be expanded if emeta is true.
222 int get_val_from_conf_file(const ConfigValues& values,
223 const std::vector <std::string> &sections,
224 const std::string_view key, std::string &out, bool emeta) const;
225
226 /// dump all config values to a stream
227 void show_config(const ConfigValues& values, std::ostream& out) const;
228 /// dump all config values to a formatter
229 void show_config(const ConfigValues& values, ceph::Formatter *f) const;
230
231 /// dump all config settings to a formatter
232 void config_options(ceph::Formatter *f) const;
233
234 /// dump config diff from default, conf, mon, etc.
235 void diff(const ConfigValues& values,
236 ceph::Formatter *f,
237 std::string name = {}) const;
238
239 /// print/log warnings/errors from parsing the config
240 void complain_about_parse_error(CephContext *cct);
241
242 private:
243 // we use this to avoid variable expansion loops
244 typedef boost::container::small_vector<std::pair<const Option*,
245 const Option::value_t*>,
246 4> expand_stack_t;
247
248 void validate_schema();
249 void validate_default_settings();
250
251 Option::value_t get_val_generic(const ConfigValues& values,
252 const std::string_view key) const;
253 int _get_val_cstr(const ConfigValues& values,
254 const std::string& key, char **buf, int len) const;
255 Option::value_t _get_val(const ConfigValues& values,
256 const std::string_view key,
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;
266
267 int _rm_val(ConfigValues& values, const std::string_view key, int level);
268
269 void _refresh(ConfigValues& values, const Option& opt);
270
271 void _show_config(const ConfigValues& values,
272 std::ostream *out, ceph::Formatter *f) const;
273
274 int _get_val_from_conf_file(const std::vector<std::string> &sections,
275 const std::string_view key, std::string &out) const;
276
277 int parse_option(ConfigValues& values,
278 const ConfigTracker& tracker,
279 std::vector<const char*>& args,
280 std::vector<const char*>::iterator& i,
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);
297
298 template <typename T>
299 void assign_member(member_ptr_t ptr, const Option::value_t &val);
300
301
302 void update_legacy_val(ConfigValues& values,
303 const Option &opt,
304 member_ptr_t member);
305
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;
312
313 public: // for global_init
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);
321
322 std::list<std::string> get_conffile_paths(const ConfigValues& values,
323 const char *conf_files,
324 std::ostream *warnings,
325 int flags) const;
326
327 const std::string& get_conf_path() const {
328 return conf_path;
329 }
330 private:
331 static std::string get_cluster_name(const char* conffile_path);
332 // The configuration file we read, or NULL if we haven't read one.
333 ConfFile cf;
334 std::string conf_path;
335 public:
336 std::string parse_error;
337 private:
338
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;
342
343 bool do_show_config = false;
344 std::string do_show_config_value;
345
346 std::vector<Option> subsys_options;
347
348 public:
349 std::string data_dir_option; ///< data_dir config option, if any
350
351 public:
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);
356 }
357
358 friend class test_md_config_t;
359 };
360
361 template<typename T>
362 const T md_config_t::get_val(const ConfigValues& values,
363 const std::string_view key) const {
364 return std::get<T>(this->get_val_generic(values, key));
365 }
366
367 inline std::ostream& operator<<(std::ostream& o, const std::monostate&) {
368 return o << "INVALID_CONFIG_VALUE";
369 }
370
371 int ceph_resolve_file_search(const std::string& filename_list,
372 std::string& result);
373
374 #endif