1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
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.
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"
39 extern const char *ceph_conf_level_name(int level
);
41 /** This class represents the current Ceph configuration.
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.
47 * For information about how this class is loaded from a configuration file,
48 * see common/ConfUtils.
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.
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")).
67 * FIXME: really we shouldn't allow changing integer or floating point values
68 * while another thread is reading them, either.
72 typedef boost::variant
<int64_t ConfigValues::*,
73 uint64_t ConfigValues::*,
74 std::string
ConfigValues::*,
75 double ConfigValues::*,
77 entity_addr_t
ConfigValues::*,
78 entity_addrvec_t
ConfigValues::*,
79 uuid_d
ConfigValues::*> member_ptr_t
;
81 // For use when intercepting configuration updates
82 typedef std::function
<bool(
83 const std::string
&k
, const std::string
&v
)> config_callback
;
85 /// true if we are a daemon (as per CephContext::code_env)
89 * Mapping from legacy config option names to class members
91 std::map
<std::string_view
, member_ptr_t
> legacy_values
;
94 * The configuration schema, in the form of Option objects describing
97 std::map
<std::string_view
, const Option
&> schema
;
99 /// values from mon that we failed to set
100 std::map
<std::string
,std::string
> ignored_mon_values
;
102 /// original raw values saved that may need to re-expand at certain time
103 mutable std::vector
<std::string
> may_reexpand_meta
;
105 /// encoded, cached copy of of values + ignored_mon_values
106 ceph::bufferlist values_bl
;
108 /// version for values_bl; increments each time there is a change
109 uint64_t values_bl_version
= 0;
111 /// encoded copy of defaults (map<string,string>)
112 ceph::bufferlist defaults_bl
;
114 // Create a new md_config_t structure.
115 explicit md_config_t(ConfigValues
& values
,
116 const ConfigTracker
& tracker
,
117 bool is_daemon
=false);
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");
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
);
137 // do any commands we got from argv (--show-config, --show-config-val)
138 void do_argv_commands(const ConfigValues
& values
) const;
140 bool _internal_field(const std::string
& k
);
142 void set_safe_to_start_threads();
143 void _clear_safe_to_start_threads(); // this is only used by the unit test
145 /// Look up an option in the schema
146 const Option
*find_option(const std::string_view name
) const;
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
);
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
);
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
,
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
);
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
);
182 /// clear override value
183 int rm_val(ConfigValues
& values
, const std::string_view key
);
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
);
191 /// get encoded map<string,string> of compiled-in defaults
192 void get_defaults_bl(const ConfigValues
& values
, ceph::buffer::list
*bl
);
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
)...);
208 void get_all_keys(std::vector
<std::string
> *keys
) const;
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;
213 // Return a list of all sections
214 int get_all_sections(std::vector
<std::string
> §ions
) const;
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
> §ions
,
220 const std::string_view key
, std::string
&out
, bool emeta
) const;
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;
227 /// dump all config settings to a formatter
228 void config_options(ceph::Formatter
*f
) const;
230 /// dump config diff from default, conf, mon, etc.
231 void diff(const ConfigValues
& values
,
233 std::string name
= {}) const;
235 /// print/log warnings/errors from parsing the config
236 void complain_about_parse_error(CephContext
*cct
);
239 // we use this to avoid variable expansion loops
240 typedef boost::container::small_vector
<std::pair
<const Option
*,
241 const Option::value_t
*>,
244 void validate_schema();
245 void validate_default_settings();
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
,
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;
263 int _rm_val(ConfigValues
& values
, const std::string_view key
, int level
);
265 void _refresh(ConfigValues
& values
, const Option
& opt
);
267 void _show_config(const ConfigValues
& values
,
268 std::ostream
*out
, ceph::Formatter
*f
) const;
270 int _get_val_from_conf_file(const std::vector
<std::string
> §ions
,
271 const std::string_view key
, std::string
&out
) const;
273 int parse_option(ConfigValues
& values
,
274 const ConfigTracker
& tracker
,
275 std::vector
<const char*>& args
,
276 std::vector
<const char*>::iterator
& i
,
279 int parse_injectargs(ConfigValues
& values
,
280 const ConfigTracker
& tracker
,
281 std::vector
<const char*>& args
,
284 // @returns negative number for an error, otherwise a
285 // @c ConfigValues::set_value_result_t is returned.
287 ConfigValues
& values
,
288 const ConfigTracker
& tracker
,
289 const std::string
&val
,
292 std::string
*error_message
);
294 template <typename T
>
295 void assign_member(member_ptr_t ptr
, const Option::value_t
&val
);
298 void update_legacy_val(ConfigValues
& values
,
300 member_ptr_t member
);
302 Option::value_t
_expand_meta(
303 const ConfigValues
& values
,
304 const Option::value_t
& in
,
306 expand_stack_t
*stack
,
307 std::ostream
*err
) const;
309 public: // for global_init
310 void early_expand_meta(const ConfigValues
& values
,
312 std::ostream
*oss
) const;
314 // for those want to reexpand special meta, e.g, $pid
315 bool finalize_reexpand_meta(ConfigValues
& values
,
316 const ConfigTracker
& tracker
);
318 std::list
<std::string
> get_conffile_paths(const ConfigValues
& values
,
319 const char *conf_files
,
320 std::ostream
*warnings
,
323 const std::string
& get_conf_path() const {
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.
330 std::string conf_path
;
332 std::string parse_error
;
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;
339 bool do_show_config
= false;
340 std::string do_show_config_value
;
342 std::vector
<Option
> subsys_options
;
345 std::string data_dir_option
; ///< data_dir config option, if any
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);
354 friend class test_md_config_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
));
363 inline std::ostream
& operator<<(std::ostream
& o
, const boost::blank
& ) {
364 return o
<< "INVALID_CONFIG_VALUE";
367 int ceph_resolve_file_search(const std::string
& filename_list
,
368 std::string
& result
);