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