X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fcommon%2Fconfig.h;fp=src%2Fceph%2Fsrc%2Fcommon%2Fconfig.h;h=1e573f5e11b28832ee77b3cb3b1fb5cd29a1d573;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/common/config.h b/src/ceph/src/common/config.h new file mode 100644 index 0000000..1e573f5 --- /dev/null +++ b/src/ceph/src/common/config.h @@ -0,0 +1,359 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_CONFIG_H +#define CEPH_CONFIG_H + +#include "common/ConfUtils.h" +#include "common/entity_name.h" +#include "common/code_environment.h" +#include "common/Mutex.h" +#include "log/SubsystemMap.h" +#include "common/config_obs.h" +#include "common/options.h" + +#define OSD_REP_PRIMARY 0 +#define OSD_REP_SPLAY 1 +#define OSD_REP_CHAIN 2 + +class CephContext; + +extern const char *CEPH_CONF_FILE_DEFAULT; + +#define LOG_TO_STDERR_NONE 0 +#define LOG_TO_STDERR_SOME 1 +#define LOG_TO_STDERR_ALL 2 + +/** This class represents the current Ceph configuration. + * + * For Ceph daemons, this is the daemon configuration. Log levels, caching + * settings, btrfs settings, and so forth can all be found here. For libcephfs + * and librados users, this is the configuration associated with their context. + * + * For information about how this class is loaded from a configuration file, + * see common/ConfUtils. + * + * ACCESS + * + * There are 3 ways to read the ceph context-- the old way and two new ways. + * In the old way, code would simply read the public variables of the + * configuration, without taking a lock. In the new way #1, code registers a + * configuration obserever which receives callbacks when a value changes. These + * callbacks take place under the md_config_t lock. Alternatively one can use + * get_val(const char *name) method to safely get a copy of the value. + * + * To prevent serious problems resulting from thread-safety issues, we disallow + * changing std::string configuration values after + * md_config_t::internal_safe_to_start_threads becomes true. You can still + * change integer or floating point values, and the option declared with + * SAFE_OPTION macro. Notice the latter options can not be read directly + * (conf->foo), one should use either observers or get_val() method + * (conf->get_val("foo")). + * + * FIXME: really we shouldn't allow changing integer or floating point values + * while another thread is reading them, either. + */ +struct md_config_t { +public: + typedef boost::variant member_ptr_t; + + /* Maps configuration options to the observer listening for them. */ + typedef std::multimap obs_map_t; + + /* Set of configuration options that have changed since the last + * apply_changes */ + typedef std::set < std::string > changed_set_t; + + /* + * Mapping from legacy config option names to class members + */ + std::map legacy_values; + + /** + * The configuration schema, in the form of Option objects describing + * possible settings. + */ + std::map schema; + + /** + * The current values of all settings described by the schema + */ + std::map values; + + typedef enum { + OPT_INT, OPT_LONGLONG, OPT_STR, OPT_DOUBLE, OPT_FLOAT, OPT_BOOL, + OPT_ADDR, OPT_U32, OPT_U64, OPT_UUID + } opt_type_t; + + // Create a new md_config_t structure. + md_config_t(bool is_daemon=false); + ~md_config_t(); + + // Adds a new observer to this configuration. You can do this at any time, + // but it will only receive notifications for the changes that happen after + // you attach it, obviously. + // + // Most developers will probably attach their observers after global_init, + // but before anyone can call injectargs. + // + // The caller is responsible for allocating observers. + void add_observer(md_config_obs_t* observer_); + + // Remove an observer from this configuration. + // This doesn't delete the observer! If you allocated it with new(), + // you need to delete it yourself. + // This function will assert if you try to delete an observer that isn't + // there. + void remove_observer(md_config_obs_t* observer_); + + // Parse a config file + int parse_config_files(const char *conf_files, + std::ostream *warnings, int flags); + + // Absorb config settings from the environment + void parse_env(); + + // Absorb config settings from argv + int parse_argv(std::vector& args); + + // Expand all metavariables. Make any pending observer callbacks. + void apply_changes(std::ostream *oss); + void _apply_changes(std::ostream *oss); + bool _internal_field(const string& k); + void call_all_observers(); + + // Called by the Ceph daemons to make configuration changes at runtime + int injectargs(const std::string &s, std::ostream *oss); + + // Set a configuration value, or crash + // Metavariables will be expanded. + void set_val_or_die(const std::string &key, const std::string &val, + bool meta=true); + + // Set a configuration value. + // Metavariables will be expanded. + int set_val(const std::string &key, const char *val, bool meta=true, + std::stringstream *err_ss=nullptr); + int set_val(const std::string &key, const string& s, bool meta=true, + std::stringstream *err_ss=nullptr) { + return set_val(key, s.c_str(), meta, err_ss); + } + + // Get a configuration value. + // No metavariables will be returned (they will have already been expanded) + int get_val(const std::string &key, char **buf, int len) const; + int _get_val(const std::string &key, char **buf, int len) const; + Option::value_t get_val_generic(const std::string &key) const; + template T get_val(const std::string &key) const; + + void get_all_keys(std::vector *keys) const; + + // Return a list of all the sections that the current entity is a member of. + void get_my_sections(std::vector §ions) const; + + // Return a list of all sections + int get_all_sections(std::vector §ions) const; + + // Get a value from the configuration file that we read earlier. + // Metavariables will be expanded if emeta is true. + int get_val_from_conf_file(const std::vector §ions, + std::string const &key, std::string &out, bool emeta) const; + + /// dump all config values to a stream + void show_config(std::ostream& out); + /// dump all config values to a formatter + void show_config(Formatter *f); + + /// obtain a diff between our config values and another md_config_t values + void diff(const md_config_t *other, + map > *diff, set *unknown); + + /// obtain a diff between config values and another md_config_t + /// values for a specific setting. + void diff(const md_config_t *other, + map> *diff, set *unknown, + const string& setting); + + /// print/log warnings/errors from parsing the config + void complain_about_parse_errors(CephContext *cct); + +private: + void validate_schema(); + void validate_default_settings(); + + int _get_val(const std::string &key, std::string *value) const; + Option::value_t _get_val(const std::string &key) const; + void _show_config(std::ostream *out, Formatter *f); + + void _get_my_sections(std::vector §ions) const; + + int _get_val_from_conf_file(const std::vector §ions, + const std::string &key, std::string &out, bool emeta) const; + + int parse_option(std::vector& args, + std::vector::iterator& i, + std::ostream *oss); + int parse_injectargs(std::vector& args, + std::ostream *oss); + int parse_config_files_impl(const std::list &conf_files, + std::ostream *warnings); + + int set_val_impl(const std::string &val, const Option &opt, + std::string *error_message); + + template + void assign_member(member_ptr_t ptr, const Option::value_t &val); + + + void update_legacy_val(const Option &opt, + md_config_t::member_ptr_t member); + + void init_subsys(); + + bool expand_meta(std::string &val, + std::ostream *oss) const; + + void diff_helper(const md_config_t* other, + map>* diff, + set* unknown, const string& setting = string{}); + +public: // for global_init + bool early_expand_meta(std::string &val, + std::ostream *oss) const { + Mutex::Locker l(lock); + return expand_meta(val, oss); + } +private: + bool expand_meta(std::string &val, + const Option *opt, + std::list stack, + std::ostream *oss) const; + + /// expand all metavariables in config structure. + void expand_all_meta(); + + // The configuration file we read, or NULL if we haven't read one. + ConfFile cf; +public: + std::deque parse_errors; +private: + + obs_map_t observers; + changed_set_t changed; + +public: + ceph::logging::SubsystemMap subsys; + + EntityName name; + string data_dir_option; ///< data_dir config option, if any + + /// cluster name + string cluster; + +// This macro block defines C members of the md_config_t struct +// corresponding to the definitions in legacy_config_opts.h. +// These C members are consumed by code that was written before +// the new options.cc infrastructure: all newer code should +// be consume options via explicit get() rather than C members. +#define OPTION_OPT_INT(name) int64_t name; +#define OPTION_OPT_LONGLONG(name) int64_t name; +#define OPTION_OPT_STR(name) std::string name; +#define OPTION_OPT_DOUBLE(name) double name; +#define OPTION_OPT_FLOAT(name) double name; +#define OPTION_OPT_BOOL(name) bool name; +#define OPTION_OPT_ADDR(name) entity_addr_t name; +#define OPTION_OPT_U32(name) uint64_t name; +#define OPTION_OPT_U64(name) uint64_t name; +#define OPTION_OPT_UUID(name) uuid_d name; +#define OPTION(name, ty) \ + public: \ + OPTION_##ty(name) +#define SAFE_OPTION(name, ty) \ + protected: \ + OPTION_##ty(name) +#include "common/legacy_config_opts.h" +#undef OPTION_OPT_INT +#undef OPTION_OPT_LONGLONG +#undef OPTION_OPT_STR +#undef OPTION_OPT_DOUBLE +#undef OPTION_OPT_FLOAT +#undef OPTION_OPT_BOOL +#undef OPTION_OPT_ADDR +#undef OPTION_OPT_U32 +#undef OPTION_OPT_U64 +#undef OPTION_OPT_UUID +#undef OPTION +#undef SAFE_OPTION + +public: + unsigned get_osd_pool_default_min_size() const { + return osd_pool_default_min_size ? + MIN(osd_pool_default_min_size, osd_pool_default_size) : + osd_pool_default_size - osd_pool_default_size / 2; + } + + /** A lock that protects the md_config_t internals. It is + * recursive, for simplicity. + * It is best if this lock comes first in the lock hierarchy. We will + * hold this lock when calling configuration observers. */ + mutable Mutex lock; + + friend class test_md_config_t; +}; + +template +struct get_typed_value_visitor : public boost::static_visitor { + template, int>::type = 0> + T operator()(U & val) { + return std::move(val); + } + template::value, int>::type = 0> + T operator()(U &val) { + assert("wrong type or option does not exist" == nullptr); + } +}; + +template T md_config_t::get_val(const std::string &key) const { + Option::value_t generic_val = this->get_val_generic(key); + get_typed_value_visitor gtv; + return boost::apply_visitor(gtv, generic_val); +} + +inline std::ostream& operator<<(std::ostream& o, const boost::blank& ) { + return o << "INVALID_CONFIG_VALUE"; +} + +int ceph_resolve_file_search(const std::string& filename_list, + std::string& result); + +enum config_subsys_id { + ceph_subsys_, // default +#define SUBSYS(name, log, gather) \ + ceph_subsys_##name, +#define DEFAULT_SUBSYS(log, gather) +#include "common/subsys.h" +#undef SUBSYS +#undef DEFAULT_SUBSYS + ceph_subsys_max +}; + +#endif