]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/config.h
update sources to v12.1.2
[ceph.git] / ceph / src / common / config.h
CommitLineData
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
7c673cae
FG
18#include "common/ConfUtils.h"
19#include "common/entity_name.h"
c07f9fc5 20#include "common/code_environment.h"
7c673cae
FG
21#include "common/Mutex.h"
22#include "log/SubsystemMap.h"
23#include "common/config_obs.h"
c07f9fc5 24#include "common/options.h"
7c673cae
FG
25
26#define OSD_REP_PRIMARY 0
27#define OSD_REP_SPLAY 1
28#define OSD_REP_CHAIN 2
29
30class CephContext;
31
32extern const char *CEPH_CONF_FILE_DEFAULT;
33
34#define LOG_TO_STDERR_NONE 0
35#define LOG_TO_STDERR_SOME 1
36#define LOG_TO_STDERR_ALL 2
37
38/** This class represents the current Ceph configuration.
39 *
40 * For Ceph daemons, this is the daemon configuration. Log levels, caching
41 * settings, btrfs settings, and so forth can all be found here. For libcephfs
42 * and librados users, this is the configuration associated with their context.
43 *
44 * For information about how this class is loaded from a configuration file,
45 * see common/ConfUtils.
46 *
47 * ACCESS
48 *
49 * There are 3 ways to read the ceph context-- the old way and two new ways.
50 * In the old way, code would simply read the public variables of the
51 * configuration, without taking a lock. In the new way #1, code registers a
52 * configuration obserever which receives callbacks when a value changes. These
53 * callbacks take place under the md_config_t lock. Alternatively one can use
54 * get_val(const char *name) method to safely get a copy of the value.
55 *
56 * To prevent serious problems resulting from thread-safety issues, we disallow
57 * changing std::string configuration values after
58 * md_config_t::internal_safe_to_start_threads becomes true. You can still
59 * change integer or floating point values, and the option declared with
60 * SAFE_OPTION macro. Notice the latter options can not be read directly
61 * (conf->foo), one should use either observers or get_val() method
62 * (conf->get_val("foo")).
63 *
64 * FIXME: really we shouldn't allow changing integer or floating point values
65 * while another thread is reading them, either.
66 */
67struct md_config_t {
68public:
c07f9fc5
FG
69 typedef boost::variant<int64_t md_config_t::*,
70 uint64_t md_config_t::*,
71 std::string md_config_t::*,
72 double md_config_t::*,
73 bool md_config_t::*,
74 entity_addr_t md_config_t::*,
75 uuid_d md_config_t::*> member_ptr_t;
76
7c673cae
FG
77 /* Maps configuration options to the observer listening for them. */
78 typedef std::multimap <std::string, md_config_obs_t*> obs_map_t;
79
80 /* Set of configuration options that have changed since the last
81 * apply_changes */
82 typedef std::set < std::string > changed_set_t;
83
c07f9fc5
FG
84 /*
85 * Mapping from legacy config option names to class members
86 */
87 std::map<std::string, md_config_t::member_ptr_t> legacy_values;
88
89 /**
90 * The configuration schema, in the form of Option objects describing
91 * possible settings.
92 */
93 std::map<std::string, const Option &> schema;
94
95 /**
96 * The current values of all settings described by the schema
97 */
98 std::map<std::string, Option::value_t> values;
7c673cae
FG
99
100 typedef enum {
101 OPT_INT, OPT_LONGLONG, OPT_STR, OPT_DOUBLE, OPT_FLOAT, OPT_BOOL,
102 OPT_ADDR, OPT_U32, OPT_U64, OPT_UUID
103 } opt_type_t;
104
7c673cae 105 // Create a new md_config_t structure.
c07f9fc5 106 md_config_t(bool is_daemon=false);
7c673cae
FG
107 ~md_config_t();
108
109 // Adds a new observer to this configuration. You can do this at any time,
110 // but it will only receive notifications for the changes that happen after
111 // you attach it, obviously.
112 //
113 // Most developers will probably attach their observers after global_init,
114 // but before anyone can call injectargs.
115 //
116 // The caller is responsible for allocating observers.
117 void add_observer(md_config_obs_t* observer_);
118
119 // Remove an observer from this configuration.
120 // This doesn't delete the observer! If you allocated it with new(),
121 // you need to delete it yourself.
122 // This function will assert if you try to delete an observer that isn't
123 // there.
124 void remove_observer(md_config_obs_t* observer_);
125
126 // Parse a config file
127 int parse_config_files(const char *conf_files,
128 std::ostream *warnings, int flags);
129
130 // Absorb config settings from the environment
131 void parse_env();
132
133 // Absorb config settings from argv
134 int parse_argv(std::vector<const char*>& args);
135
136 // Expand all metavariables. Make any pending observer callbacks.
137 void apply_changes(std::ostream *oss);
138 void _apply_changes(std::ostream *oss);
139 bool _internal_field(const string& k);
140 void call_all_observers();
141
142 // Called by the Ceph daemons to make configuration changes at runtime
143 int injectargs(const std::string &s, std::ostream *oss);
144
145 // Set a configuration value, or crash
146 // Metavariables will be expanded.
c07f9fc5
FG
147 void set_val_or_die(const std::string &key, const std::string &val,
148 bool meta=true);
7c673cae
FG
149
150 // Set a configuration value.
151 // Metavariables will be expanded.
c07f9fc5
FG
152 int set_val(const std::string &key, const char *val, bool meta=true,
153 std::stringstream *err_ss=nullptr);
154 int set_val(const std::string &key, const string& s, bool meta=true,
155 std::stringstream *err_ss=nullptr) {
156 return set_val(key, s.c_str(), meta, err_ss);
7c673cae
FG
157 }
158
159 // Get a configuration value.
160 // No metavariables will be returned (they will have already been expanded)
c07f9fc5
FG
161 int get_val(const std::string &key, char **buf, int len) const;
162 int _get_val(const std::string &key, char **buf, int len) const;
163 Option::value_t get_val_generic(const std::string &key) const;
164 template<typename T> T get_val(const std::string &key) const;
7c673cae
FG
165
166 void get_all_keys(std::vector<std::string> *keys) const;
167
168 // Return a list of all the sections that the current entity is a member of.
169 void get_my_sections(std::vector <std::string> &sections) const;
170
171 // Return a list of all sections
172 int get_all_sections(std::vector <std::string> &sections) const;
173
174 // Get a value from the configuration file that we read earlier.
175 // Metavariables will be expanded if emeta is true.
176 int get_val_from_conf_file(const std::vector <std::string> &sections,
c07f9fc5 177 std::string const &key, std::string &out, bool emeta) const;
7c673cae
FG
178
179 /// dump all config values to a stream
180 void show_config(std::ostream& out);
181 /// dump all config values to a formatter
182 void show_config(Formatter *f);
183
184 /// obtain a diff between our config values and another md_config_t values
185 void diff(const md_config_t *other,
186 map<string,pair<string,string> > *diff, set<string> *unknown);
187
31f18b77
FG
188 /// obtain a diff between config values and another md_config_t
189 /// values for a specific setting.
190 void diff(const md_config_t *other,
191 map<string,pair<string,string>> *diff, set<string> *unknown,
192 const string& setting);
193
7c673cae
FG
194 /// print/log warnings/errors from parsing the config
195 void complain_about_parse_errors(CephContext *cct);
196
197private:
c07f9fc5 198 void validate_schema();
7c673cae
FG
199 void validate_default_settings();
200
c07f9fc5
FG
201 int _get_val(const std::string &key, std::string *value) const;
202 Option::value_t _get_val(const std::string &key) const;
7c673cae
FG
203 void _show_config(std::ostream *out, Formatter *f);
204
205 void _get_my_sections(std::vector <std::string> &sections) const;
206
207 int _get_val_from_conf_file(const std::vector <std::string> &sections,
c07f9fc5 208 const std::string &key, std::string &out, bool emeta) const;
7c673cae
FG
209
210 int parse_option(std::vector<const char*>& args,
211 std::vector<const char*>::iterator& i,
212 std::ostream *oss);
213 int parse_injectargs(std::vector<const char*>& args,
214 std::ostream *oss);
215 int parse_config_files_impl(const std::list<std::string> &conf_files,
216 std::ostream *warnings);
217
c07f9fc5 218 int set_val_impl(const std::string &val, const Option &opt,
7c673cae 219 std::string *error_message);
c07f9fc5
FG
220
221 template <typename T>
222 void assign_member(member_ptr_t ptr, const Option::value_t &val);
223
224
225 void update_legacy_val(const Option &opt,
226 md_config_t::member_ptr_t member);
7c673cae
FG
227
228 void init_subsys();
229
230 bool expand_meta(std::string &val,
231 std::ostream *oss) const;
31f18b77
FG
232
233 void diff_helper(const md_config_t* other,
234 map<string, pair<string, string>>* diff,
235 set<string>* unknown, const string& setting = string{});
236
7c673cae
FG
237public: // for global_init
238 bool early_expand_meta(std::string &val,
239 std::ostream *oss) const {
240 Mutex::Locker l(lock);
241 return expand_meta(val, oss);
242 }
243private:
244 bool expand_meta(std::string &val,
c07f9fc5
FG
245 const Option *opt,
246 std::list<const Option*> stack,
7c673cae
FG
247 std::ostream *oss) const;
248
249 /// expand all metavariables in config structure.
250 void expand_all_meta();
251
252 // The configuration file we read, or NULL if we haven't read one.
253 ConfFile cf;
254public:
255 std::deque<std::string> parse_errors;
256private:
257
258 obs_map_t observers;
259 changed_set_t changed;
260
261public:
262 ceph::logging::SubsystemMap subsys;
263
264 EntityName name;
265 string data_dir_option; ///< data_dir config option, if any
266
267 /// cluster name
268 string cluster;
269
c07f9fc5
FG
270// This macro block defines C members of the md_config_t struct
271// corresponding to the definitions in legacy_config_opts.h.
272// These C members are consumed by code that was written before
273// the new options.cc infrastructure: all newer code should
274// be consume options via explicit get() rather than C members.
275#define OPTION_OPT_INT(name) int64_t name;
276#define OPTION_OPT_LONGLONG(name) int64_t name;
277#define OPTION_OPT_STR(name) std::string name;
278#define OPTION_OPT_DOUBLE(name) double name;
279#define OPTION_OPT_FLOAT(name) double name;
280#define OPTION_OPT_BOOL(name) bool name;
281#define OPTION_OPT_ADDR(name) entity_addr_t name;
282#define OPTION_OPT_U32(name) uint64_t name;
283#define OPTION_OPT_U64(name) uint64_t name;
284#define OPTION_OPT_UUID(name) uuid_d name;
285#define OPTION(name, ty) \
7c673cae 286 public: \
c07f9fc5
FG
287 OPTION_##ty(name)
288#define SAFE_OPTION(name, ty) \
7c673cae 289 protected: \
c07f9fc5
FG
290 OPTION_##ty(name)
291#include "common/legacy_config_opts.h"
7c673cae
FG
292#undef OPTION_OPT_INT
293#undef OPTION_OPT_LONGLONG
294#undef OPTION_OPT_STR
295#undef OPTION_OPT_DOUBLE
296#undef OPTION_OPT_FLOAT
297#undef OPTION_OPT_BOOL
298#undef OPTION_OPT_ADDR
299#undef OPTION_OPT_U32
300#undef OPTION_OPT_U64
301#undef OPTION_OPT_UUID
302#undef OPTION
7c673cae 303#undef SAFE_OPTION
7c673cae 304
c07f9fc5 305public:
7c673cae
FG
306 unsigned get_osd_pool_default_min_size() const {
307 return osd_pool_default_min_size ?
308 MIN(osd_pool_default_min_size, osd_pool_default_size) :
309 osd_pool_default_size - osd_pool_default_size / 2;
310 }
311
312 /** A lock that protects the md_config_t internals. It is
313 * recursive, for simplicity.
314 * It is best if this lock comes first in the lock hierarchy. We will
315 * hold this lock when calling configuration observers. */
316 mutable Mutex lock;
317
318 friend class test_md_config_t;
7c673cae
FG
319};
320
321template<typename T>
322struct get_typed_value_visitor : public boost::static_visitor<T> {
323 template<typename U,
324 typename boost::enable_if<boost::is_same<T, U>, int>::type = 0>
325 T operator()(U & val) {
326 return std::move(val);
327 }
328 template<typename U,
329 typename boost::enable_if_c<!boost::is_same<T, U>::value, int>::type = 0>
330 T operator()(U &val) {
331 assert("wrong type or option does not exist" == nullptr);
332 }
333};
334
c07f9fc5
FG
335template<typename T> T md_config_t::get_val(const std::string &key) const {
336 Option::value_t generic_val = this->get_val_generic(key);
7c673cae
FG
337 get_typed_value_visitor<T> gtv;
338 return boost::apply_visitor(gtv, generic_val);
339}
340
c07f9fc5 341inline std::ostream& operator<<(std::ostream& o, const boost::blank& ) {
7c673cae
FG
342 return o << "INVALID_CONFIG_VALUE";
343}
344
345int ceph_resolve_file_search(const std::string& filename_list,
346 std::string& result);
347
7c673cae
FG
348enum config_subsys_id {
349 ceph_subsys_, // default
7c673cae
FG
350#define SUBSYS(name, log, gather) \
351 ceph_subsys_##name,
352#define DEFAULT_SUBSYS(log, gather)
c07f9fc5 353#include "common/subsys.h"
7c673cae 354#undef SUBSYS
7c673cae
FG
355#undef DEFAULT_SUBSYS
356 ceph_subsys_max
357};
358
359#endif