return keys;
}
-void Client::handle_conf_change(const struct md_config_t *conf,
+void Client::handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed)
{
Mutex::Locker lock(client_lock);
int test_dentry_handling(bool can_invalidate);
const char** get_tracked_conf_keys() const override;
- void handle_conf_change(const struct md_config_t *conf,
+ void handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed) override;
uint32_t get_deleg_timeout() { return deleg_timeout; }
int set_deleg_timeout(uint32_t timeout);
#include "include/assert.h"
#include "lockdep.h"
-#include "common/ceph_context.h"
+#include <string>
#include <pthread.h>
using namespace ceph;
+class CephContext;
class PerfCounters;
enum {
#ifndef CEPH_COMMON_PLUGINREGISTRY_H
#define CEPH_COMMON_PLUGINREGISTRY_H
+#include <map>
#include "common/Mutex.h"
class CephContext;
}
void TracepointProvider::handle_conf_change(
- const struct md_config_t *conf, const std::set<std::string> &changed) {
+ const md_config_t *conf, const std::set<std::string> &changed) {
if (changed.count(m_config_keys[0])) {
verify_config(conf);
}
}
-void TracepointProvider::verify_config(const struct md_config_t *conf) {
+void TracepointProvider::verify_config(const md_config_t *conf) {
Mutex::Locker locker(m_lock);
if (m_handle) {
return;
#ifndef CEPH_TRACEPOINT_PROVIDER_H
#define CEPH_TRACEPOINT_PROVIDER_H
+#include "common/ceph_context.h"
#include "common/config_obs.h"
#include "common/Mutex.h"
#include <dlfcn.h>
-struct md_config_t;
-
class TracepointProvider : public md_config_obs_t {
public:
struct Traits {
const char** get_tracked_conf_keys() const override {
return m_config_keys;
}
- void handle_conf_change(const struct md_config_t *conf,
+ void handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed) override;
private:
Mutex m_lock;
void* m_handle = nullptr;
- void verify_config(const struct md_config_t *conf);
+ void verify_config(const md_config_t *conf);
};
#endif // CEPH_TRACEPOINT_PROVIDER_H
delete[] _conf_keys;
}
-void ThreadPool::handle_conf_change(const struct md_config_t *conf,
+void ThreadPool::handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed)
{
if (changed.count(_thread_num_option)) {
#include "Cond.h"
#include "include/unordered_map.h"
+#include "common/config_obs.h"
#include "common/HeartbeatMap.h"
#include <atomic>
const char **get_tracked_conf_keys() const override {
return _conf_keys;
}
- void handle_conf_change(const struct md_config_t *conf,
+ void handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed) override;
public:
#include "auth/Crypto.h"
#include "include/str_list.h"
+#include "common/config.h"
+#include "common/config_obs.h"
#include "common/PluginRegistry.h"
#include "common/valgrind.h"
#include "include/spinlock.h"
#include "common/cmdparse.h"
#include "common/code_environment.h"
+#include "common/config_fwd.h"
#include "include/spinlock.h"
class CephContextServiceThread;
class PerfCountersCollection;
class PerfCounters;
-class md_config_obs_t;
-struct md_config_t;
class CephContextHook;
class CephContextObs;
class CryptoHandler;
*
*/
+#include "common/ceph_context.h"
#include "common/config.h"
#include "ceph_crypto.h"
#include "common/ceph_argparse.h"
#include "common/common_init.h"
#include "common/config.h"
+#include "common/config_obs.h"
#include "include/str_list.h"
#include "include/stringify.h"
#include "osd/osd_types.h"
return 0;
}
-md_config_t::md_config_t(bool is_daemon)
+namespace ceph::internal {
+
+template<LockPolicy lp>
+md_config_impl<lp>::md_config_impl(bool is_daemon)
: is_daemon(is_daemon),
- cluster(""),
- lock("md_config_t", true, false)
+ cluster("")
{
// Load the compile-time list of Option into
// a map so that we can resolve keys quickly.
// members if present.
legacy_values = {
#define OPTION(name, type) \
- {std::string(STRINGIFY(name)), &md_config_t::name},
+ {std::string(STRINGIFY(name)), &md_config_impl::name},
#define SAFE_OPTION(name, type) OPTION(name, type)
#include "common/legacy_config_opts.h"
#undef OPTION
update_legacy_vals();
}
-md_config_t::~md_config_t()
+template<LockPolicy lp>
+md_config_impl<lp>::~md_config_impl()
{
}
* Sanity check schema. Assert out on failures, to ensure any bad changes
* cannot possibly pass any testing and make it into a release.
*/
-void md_config_t::validate_schema()
+template<LockPolicy lp>
+void md_config_impl<lp>::validate_schema()
{
for (const auto &i : schema) {
const auto &opt = i.second;
}
}
-const Option *md_config_t::find_option(const string& name) const
+template<LockPolicy lp>
+const Option *md_config_impl<lp>::find_option(const string& name) const
{
auto p = schema.find(name);
if (p != schema.end()) {
return nullptr;
}
-void md_config_t::set_val_default(const string& name, const std::string& val)
+template<LockPolicy lp>
+void md_config_impl<lp>::set_val_default(const string& name, const std::string& val)
{
- Mutex::Locker l(lock);
+ auto locker = lock();
const Option *o = find_option(name);
assert(o);
string err;
assert(r >= 0);
}
-int md_config_t::set_mon_vals(CephContext *cct,
+template<LockPolicy lp>
+int md_config_impl<lp>::set_mon_vals(CephContext *cct,
const map<string,string>& kv,
config_callback config_cb)
{
- Mutex::Locker l(lock);
+ auto locker = lock();
ignored_mon_values.clear();
if (!config_cb) {
return 0;
}
-void md_config_t::add_observer(md_config_obs_t* observer_)
+template<LockPolicy lp>
+void md_config_impl<lp>::add_observer(md_config_obs_impl<lp>* observer_)
{
- Mutex::Locker l(lock);
+ auto locker = lock();
const char **keys = observer_->get_tracked_conf_keys();
for (const char ** k = keys; *k; ++k) {
- obs_map_t::value_type val(*k, observer_);
- observers.insert(val);
+ observers.emplace(*k, observer_);
}
}
-void md_config_t::remove_observer(md_config_obs_t* observer_)
+template<LockPolicy lp>
+void md_config_impl<lp>::remove_observer(md_config_obs_impl<lp>* observer_)
{
- Mutex::Locker l(lock);
+ auto locker = lock();
bool found_obs = false;
- for (obs_map_t::iterator o = observers.begin(); o != observers.end(); ) {
+ for (auto o = observers.begin(); o != observers.end(); ) {
if (o->second == observer_) {
observers.erase(o++);
found_obs = true;
assert(found_obs);
}
-int md_config_t::parse_config_files(const char *conf_files_str,
+template<LockPolicy lp>
+int md_config_impl<lp>::parse_config_files(const char *conf_files_str,
std::ostream *warnings,
int flags)
{
- Mutex::Locker l(lock);
+ auto locker = lock();
if (safe_to_start_threads)
return -ENOSYS;
return 0;
}
-void md_config_t::parse_env(const char *args_var)
+template<LockPolicy lp>
+void md_config_impl<lp>::parse_env(const char *args_var)
{
if (safe_to_start_threads)
return;
args_var = "CEPH_ARGS";
}
if (getenv("CEPH_KEYRING")) {
- Mutex::Locker l(lock);
+ auto locker = lock();
string k = getenv("CEPH_KEYRING");
values["keyring"][CONF_ENV] = Option::value_t(k);
}
if (const char *dir = getenv("CEPH_LIB")) {
- Mutex::Locker l(lock);
+ auto locker = lock();
for (auto name : { "erasure_code_dir", "plugin_dir", "osd_class_dir" }) {
std::string err;
const Option *o = find_option(name);
}
}
-void md_config_t::show_config(std::ostream& out)
+template<LockPolicy lp>
+void md_config_impl<lp>::show_config(std::ostream& out)
{
- Mutex::Locker l(lock);
+ auto locker = lock();
_show_config(&out, NULL);
}
-void md_config_t::show_config(Formatter *f)
+template<LockPolicy lp>
+void md_config_impl<lp>::show_config(Formatter *f)
{
- Mutex::Locker l(lock);
+ auto locker = lock();
_show_config(NULL, f);
}
-void md_config_t::config_options(Formatter *f)
+template<LockPolicy lp>
+void md_config_impl<lp>::config_options(Formatter *f)
{
- Mutex::Locker l(lock);
+ auto locker = lock();
f->open_array_section("options");
for (const auto& i: schema) {
f->dump_object("option", i.second);
f->close_section();
}
-void md_config_t::_show_config(std::ostream *out, Formatter *f)
+template<LockPolicy lp>
+void md_config_impl<lp>::_show_config(std::ostream *out, Formatter *f)
{
if (out) {
*out << "name = " << name << std::endl;
}
}
-int md_config_t::parse_argv(std::vector<const char*>& args, int level)
+template<LockPolicy lp>
+int md_config_impl<lp>::parse_argv(std::vector<const char*>& args, int level)
{
- Mutex::Locker l(lock);
+ auto locker = lock();
if (safe_to_start_threads) {
return -ENOSYS;
}
return 0;
}
-void md_config_t::do_argv_commands()
+template<LockPolicy lp>
+void md_config_impl<lp>::do_argv_commands()
{
- Mutex::Locker l(lock);
+ auto locker = lock();
if (do_show_config) {
_show_config(&cout, NULL);
}
}
-int md_config_t::parse_option(std::vector<const char*>& args,
+template<LockPolicy lp>
+int md_config_impl<lp>::parse_option(std::vector<const char*>& args,
std::vector<const char*>::iterator& i,
ostream *oss,
int level)
return ret >= 0 ? 0 : ret;
}
-int md_config_t::parse_injectargs(std::vector<const char*>& args,
+template<LockPolicy lp>
+int md_config_impl<lp>::parse_injectargs(std::vector<const char*>& args,
std::ostream *oss)
{
assert(lock.is_locked());
return ret;
}
-void md_config_t::apply_changes(std::ostream *oss)
+template<LockPolicy lp>
+void md_config_impl<lp>::apply_changes(std::ostream *oss)
{
- Mutex::Locker l(lock);
+ auto locker = lock();
/*
* apply changes until the cluster name is assigned
*/
_apply_changes(oss);
}
-void md_config_t::_apply_changes(std::ostream *oss)
+template<LockPolicy lp>
+void md_config_impl<lp>::_apply_changes(std::ostream *oss)
{
/* Maps observers to the configuration options that they care about which
* have changed. */
for (changed_set_t::const_iterator c = changed.begin();
c != changed.end(); ++c) {
const std::string &key(*c);
- pair < obs_map_t::iterator, obs_map_t::iterator >
- range(observers.equal_range(key));
+ auto [first, last] = observers.equal_range(key);
if ((oss) && !conf_stringify(_get_val(key), &val)) {
(*oss) << key << " = '" << val << "' ";
- if (range.first == range.second) {
+ if (first == last) {
(*oss) << "(not observed, change may require restart) ";
}
}
- for (obs_map_t::iterator r = range.first; r != range.second; ++r) {
+ for (auto r = first; r != last; ++r) {
rev_obs_map_t::value_type robs_val(r->second, empty_set);
pair < rev_obs_map_t::iterator, bool > robs_ret(robs.insert(robs_val));
std::set <std::string> &keys(robs_ret.first->second);
}
-void md_config_t::call_all_observers()
+template<LockPolicy lp>
+void md_config_impl<lp>::call_all_observers()
{
std::map<md_config_obs_t*,std::set<std::string> > obs;
// Have the scope of the lock extend to the scope of
// An alternative might be to pass a std::unique_lock to
// handle_conf_change and have a version of get_var that can take it
// by reference and lock as appropriate.
- Mutex::Locker l(lock);
+ auto locker = lock();
{
for (auto r = observers.begin(); r != observers.end(); ++r) {
obs[r->second].insert(r->first);
}
}
-void md_config_t::set_safe_to_start_threads()
+template<LockPolicy lp>
+void md_config_impl<lp>::set_safe_to_start_threads()
{
safe_to_start_threads = true;
}
-void md_config_t::_clear_safe_to_start_threads()
+template<LockPolicy lp>
+void md_config_impl<lp>::_clear_safe_to_start_threads()
{
safe_to_start_threads = false;
}
-int md_config_t::injectargs(const std::string& s, std::ostream *oss)
+template<LockPolicy lp>
+int md_config_impl<lp>::injectargs(const std::string& s, std::ostream *oss)
{
int ret;
- Mutex::Locker l(lock);
+ auto locker = lock();
char b[s.length()+1];
strcpy(b, s.c_str());
std::vector<const char*> nargs;
return ret;
}
-void md_config_t::set_val_or_die(const std::string &key,
+template<LockPolicy lp>
+void md_config_impl<lp>::set_val_or_die(const std::string &key,
const std::string &val)
{
std::stringstream err;
assert(ret == 0);
}
-int md_config_t::set_val(const std::string &key, const char *val,
+template<LockPolicy lp>
+int md_config_impl<lp>::set_val(const std::string &key, const char *val,
std::stringstream *err_ss)
{
- Mutex::Locker l(lock);
+ auto locker = lock();
if (key.empty()) {
if (err_ss) *err_ss << "No key specified";
return -EINVAL;
return -ENOENT;
}
-int md_config_t::rm_val(const std::string& key)
+template<LockPolicy lp>
+int md_config_impl<lp>::rm_val(const std::string& key)
{
- Mutex::Locker l(lock);
+ auto locker = lock();
return _rm_val(key, CONF_OVERRIDE);
}
-void md_config_t::get_defaults_bl(bufferlist *bl)
+template<LockPolicy lp>
+void md_config_impl<lp>::get_defaults_bl(bufferlist *bl)
{
- Mutex::Locker l(lock);
+ auto locker = lock();
if (defaults_bl.length() == 0) {
uint32_t n = 0;
bufferlist bl;
*bl = defaults_bl;
}
-void md_config_t::get_config_bl(
+template<LockPolicy lp>
+void md_config_impl<lp>::get_config_bl(
uint64_t have_version,
bufferlist *bl,
uint64_t *got_version)
{
- Mutex::Locker l(lock);
+ auto locker = lock();
if (values_bl.length() == 0) {
uint32_t n = 0;
bufferlist bl;
}
}
-int md_config_t::get_val(const std::string &key, char **buf, int len) const
+template<LockPolicy lp>
+int md_config_impl<lp>::get_val(const std::string &key, char **buf, int len) const
{
- Mutex::Locker l(lock);
+ auto locker = lock();
string k(ConfFile::normalize_key_name(key));
return _get_val_cstr(k, buf, len);
}
-int md_config_t::get_val(
+template<LockPolicy lp>
+int md_config_impl<lp>::get_val(
const std::string &key,
std::string *val) const
{
return conf_stringify(get_val_generic(key), val);
}
-Option::value_t md_config_t::get_val_generic(const std::string &key) const
+template<LockPolicy lp>
+Option::value_t md_config_impl<lp>::get_val_generic(const std::string &key) const
{
- Mutex::Locker l(lock);
+ auto locker = lock();
string k(ConfFile::normalize_key_name(key));
return _get_val(k);
}
-Option::value_t md_config_t::_get_val(
+template<LockPolicy lp>
+Option::value_t md_config_impl<lp>::_get_val(
const std::string &key,
expand_stack_t *stack,
std::ostream *err) const
return _get_val(*o, stack, err);
}
-Option::value_t md_config_t::_get_val(
+template<LockPolicy lp>
+Option::value_t md_config_impl<lp>::_get_val(
const Option& o,
expand_stack_t *stack,
std::ostream *err) const
return _expand_meta(_get_val_default(o), &o, stack, err);
}
-Option::value_t md_config_t::_get_val_nometa(const Option& o) const
+template<LockPolicy lp>
+Option::value_t md_config_impl<lp>::_get_val_nometa(const Option& o) const
{
auto p = values.find(o.name);
if (p != values.end() && !p->second.empty()) {
return _get_val_default(o);
}
-const Option::value_t& md_config_t::_get_val_default(const Option& o) const
+template<LockPolicy lp>
+const Option::value_t& md_config_impl<lp>::_get_val_default(const Option& o) const
{
bool has_daemon_default = !boost::get<boost::blank>(&o.daemon_value);
if (is_daemon && has_daemon_default) {
}
}
-void md_config_t::early_expand_meta(
+template<LockPolicy lp>
+void md_config_impl<lp>::early_expand_meta(
std::string &val,
std::ostream *err) const
{
- Mutex::Locker l(lock);
+ auto locker = lock();
expand_stack_t stack;
Option::value_t v = _expand_meta(Option::value_t(val), nullptr, &stack, err);
conf_stringify(v, &val);
}
-void md_config_t::finalize_reexpand_meta()
+template<LockPolicy lp>
+void md_config_impl<lp>::finalize_reexpand_meta()
{
- Mutex::Locker l(lock);
+ auto locker = lock();
for (auto &i : may_reexpand_meta) {
set_val(i.first, i.second);
}
_apply_changes(NULL);
}
-Option::value_t md_config_t::_expand_meta(
+template<LockPolicy lp>
+Option::value_t md_config_impl<lp>::_expand_meta(
const Option::value_t& in,
const Option *o,
expand_stack_t *stack,
return Option::value_t(out);
}
-int md_config_t::_get_val_cstr(
+template<LockPolicy lp>
+int md_config_impl<lp>::_get_val_cstr(
const std::string &key, char **buf, int len) const
{
assert(lock.is_locked());
return -ENOENT;
}
-void md_config_t::get_all_keys(std::vector<std::string> *keys) const {
+template<LockPolicy lp>
+void md_config_impl<lp>::get_all_keys(std::vector<std::string> *keys) const {
const std::string negative_flag_prefix("no_");
keys->clear();
* looking. The lowest priority section is the one we look in only if all
* others had nothing. This should always be the global section.
*/
-void md_config_t::get_my_sections(std::vector <std::string> §ions) const
+template<LockPolicy lp>
+void md_config_impl<lp>::get_my_sections(std::vector <std::string> §ions) const
{
- Mutex::Locker l(lock);
+ auto locker = lock();
_get_my_sections(sections);
}
-void md_config_t::_get_my_sections(std::vector <std::string> §ions) const
+template<LockPolicy lp>
+void md_config_impl<lp>::_get_my_sections(std::vector <std::string> §ions) const
{
assert(lock.is_locked());
sections.push_back(name.to_str());
}
// Return a list of all sections
-int md_config_t::get_all_sections(std::vector <std::string> §ions) const
+template<LockPolicy lp>
+int md_config_impl<lp>::get_all_sections(std::vector <std::string> §ions) const
{
- Mutex::Locker l(lock);
+ auto locker = lock();
for (ConfFile::const_section_iter_t s = cf.sections_begin();
s != cf.sections_end(); ++s) {
sections.push_back(s->first);
return 0;
}
-int md_config_t::get_val_from_conf_file(
+template<LockPolicy lp>
+int md_config_impl<lp>::get_val_from_conf_file(
const std::vector <std::string> §ions,
const std::string &key,
std::string &out,
bool emeta) const
{
- Mutex::Locker l(lock);
+ auto locker = lock();
int r = _get_val_from_conf_file(sections, key, out);
if (r < 0) {
return r;
return 0;
}
-int md_config_t::_get_val_from_conf_file(
+template<LockPolicy lp>
+int md_config_impl<lp>::_get_val_from_conf_file(
const std::vector <std::string> §ions,
const std::string &key,
std::string &out) const
return -ENOENT;
}
-int md_config_t::_set_val(
+template<LockPolicy lp>
+int md_config_impl<lp>::_set_val(
const std::string &raw_val,
const Option &opt,
int level,
return 1;
}
-void md_config_t::_refresh(const Option& opt)
+template<LockPolicy lp>
+void md_config_impl<lp>::_refresh(const Option& opt)
{
// Apply the value to its legacy field, if it has one
auto legacy_ptr_iter = legacy_values.find(std::string(opt.name));
}
}
-int md_config_t::_rm_val(const std::string& key, int level)
+template<LockPolicy lp>
+int md_config_impl<lp>::_rm_val(const std::string& key, int level)
{
if (schema.count(key) == 0) {
return -EINVAL;
/**
* Handles assigning from a variant-of-types to a variant-of-pointers-to-types
*/
+template<class Config>
class assign_visitor : public boost::static_visitor<>
{
- md_config_t *conf;
+ Config *conf;
Option::value_t val;
public:
- assign_visitor(md_config_t *conf_, Option::value_t val_)
+ assign_visitor(Config *conf_, Option::value_t val_)
: conf(conf_), val(val_)
{}
template <typename T>
- void operator()( T md_config_t::* ptr) const
+ void operator()(T Config::* ptr) const
{
- T *member = const_cast<T *>(&(conf->*(boost::get<const T md_config_t::*>(ptr))));
+ T *member = const_cast<T *>(&(conf->*(boost::get<const T Config::*>(ptr))));
*member = boost::get<T>(val);
}
- void operator()(uint64_t md_config_t::* ptr) const
+ void operator()(uint64_t Config::* ptr) const
{
using T = uint64_t;
- auto member = const_cast<T*>(&(conf->*(boost::get<const T md_config_t::*>(ptr))));
+ auto member = const_cast<T*>(&(conf->*(boost::get<const T Config::*>(ptr))));
*member = boost::apply_visitor(get_size_visitor<T>{}, val);
}
- void operator()(int64_t md_config_t::* ptr) const
+ void operator()(int64_t Config::* ptr) const
{
using T = int64_t;
- auto member = const_cast<T*>(&(conf->*(boost::get<const T md_config_t::*>(ptr))));
+ auto member = const_cast<T*>(&(conf->*(boost::get<const T Config::*>(ptr))));
*member = boost::apply_visitor(get_size_visitor<T>{}, val);
}
};
} // anonymous namespace
-void md_config_t::update_legacy_vals()
+template<LockPolicy lp>
+void md_config_impl<lp>::update_legacy_vals()
{
for (const auto &i : legacy_values) {
const auto &name = i.first;
}
}
-void md_config_t::update_legacy_val(const Option &opt,
- md_config_t::member_ptr_t member_ptr)
+template<LockPolicy lp>
+void md_config_impl<lp>::update_legacy_val(const Option &opt,
+ md_config_impl::member_ptr_t member_ptr)
{
Option::value_t v = _get_val(opt);
boost::apply_visitor(assign_visitor(this, v), member_ptr);
}
}
-void md_config_t::diff(
+template<LockPolicy lp>
+void md_config_impl<lp>::diff(
Formatter *f,
string name) const
{
- Mutex::Locker l(lock);
+ auto locker = lock();
for (auto& i : values) {
if (i.second.size() == 1 &&
i.second.begin()->first == CONF_DEFAULT) {
}
}
-void md_config_t::complain_about_parse_errors(CephContext *cct)
+template<LockPolicy lp>
+void md_config_impl<lp>::complain_about_parse_errors(CephContext *cct)
{
::complain_about_parse_errors(cct, &parse_errors);
}
+// explicit instantiate the only md_config_impl type we need
+template class md_config_impl<internal::LockPolicy::MUTEX>;
+
+} // namespace ceph::internal
#include "common/code_environment.h"
#include "common/Mutex.h"
#include "log/SubsystemMap.h"
-#include "common/config_obs.h"
#include "common/options.h"
#include "common/subsys_types.h"
+#include "config_fwd.h"
class CephContext;
extern const char *ceph_conf_level_name(int level);
+namespace ceph::internal {
+// empty helper class except when the template argument is policy_mutex
+template<LockPolicy lp>
+class LockMutex {
+ struct Locker {};
+public:
+ Locker operator()() const {
+ return Locker{};
+ }
+ bool is_locked() const {
+ return true;
+ }
+};
+
+template<>
+class LockMutex<LockPolicy::MUTEX> {
+ mutable Mutex mutex{"md_config_t", true, false};
+public:
+ auto operator()() const {
+ return Mutex::Locker{mutex};
+ }
+ bool is_locked() const {
+ return mutex.is_locked();
+ }
+};
+
/** This class represents the current Ceph configuration.
*
* For Ceph daemons, this is the daemon configuration. Log levels, caching
* FIXME: really we shouldn't allow changing integer or floating point values
* while another thread is reading them, either.
*/
-struct md_config_t {
+template<LockPolicy lock_policy>
+struct md_config_impl {
public:
typedef boost::variant<int64_t md_config_t::*,
uint64_t md_config_t::*,
const bool is_daemon;
/* Maps configuration options to the observer listening for them. */
- typedef std::multimap <std::string, md_config_obs_t*> obs_map_t;
+ typedef std::multimap <std::string, md_config_obs_impl<lock_policy>*> obs_map_t;
/* Set of configuration options that have changed since the last
* apply_changes */
/*
* Mapping from legacy config option names to class members
*/
- std::map<std::string, md_config_t::member_ptr_t> legacy_values;
+ std::map<std::string, md_config_impl::member_ptr_t> legacy_values;
/**
* The configuration schema, in the form of Option objects describing
} opt_type_t;
// Create a new md_config_t structure.
- explicit md_config_t(bool is_daemon=false);
- ~md_config_t();
+ explicit md_config_impl(bool is_daemon=false);
+ ~md_config_impl();
// 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
// but before anyone can call injectargs.
//
// The caller is responsible for allocating observers.
- void add_observer(md_config_obs_t* observer_);
+ void add_observer(md_config_obs_impl<lock_policy>* 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_);
+ void remove_observer(md_config_obs_impl<lock_policy>* observer_);
// Parse a config file
int parse_config_files(const char *conf_files,
void update_legacy_vals();
void update_legacy_val(const Option &opt,
- md_config_t::member_ptr_t member);
+ md_config_impl::member_ptr_t member);
Option::value_t _expand_meta(
const Option::value_t& in,
* 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;
+ LockMutex<lock_policy> lock;
friend class test_md_config_t;
};
+template<LockPolicy lp>
template<typename T>
-const T md_config_t::get_val(const std::string &key) const {
+const T md_config_impl<lp>::get_val(const std::string &key) const {
return boost::get<T>(this->get_val_generic(key));
}
+} // namespace ceph::internal
+
inline std::ostream& operator<<(std::ostream& o, const boost::blank& ) {
return o << "INVALID_CONFIG_VALUE";
}
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+
+#pragma once
+
+namespace ceph::internal {
+
+enum class LockPolicy {
+ SINGLE,
+ MUTEX,
+};
+
+template<LockPolicy lp> struct md_config_impl;
+template<LockPolicy lp> class md_config_obs_impl;
+}
+
+using md_config_t =
+ ceph::internal::md_config_impl<ceph::internal::LockPolicy::MUTEX>;
+using md_config_obs_t =
+ ceph::internal::md_config_obs_impl<ceph::internal::LockPolicy::MUTEX>;
#include <set>
#include <string>
-#include <list>
-struct md_config_t;
+#include "common/config_fwd.h"
+
+namespace ceph::internal {
/** @brief Base class for configuration observers.
* Use this as a base class for your object if it has to respond to configuration changes,
* Subscribe for configuration changes by calling the md_config_t::add_observer() method
* and unsubscribe using md_config_t::remove_observer().
*/
-class md_config_obs_t {
+template<LockPolicy lp>
+class md_config_obs_impl {
public:
- virtual ~md_config_obs_t() {}
+ virtual ~md_config_obs_impl() {}
/** @brief Get a table of strings specifying the configuration keys in which the object is interested.
* This is called when the object is subscribed to configuration changes with add_observer().
* The returned table should not be freed until the observer is removed with remove_observer().
* Note that it is not possible to change the set of tracked keys without re-subscribing. */
virtual const char** get_tracked_conf_keys() const = 0;
/// React to a configuration change.
- virtual void handle_conf_change(const struct md_config_t *conf,
+ virtual void handle_conf_change(const md_config_impl<lp>* conf,
const std::set <std::string> &changed) = 0;
/// Unused for now
- virtual void handle_subsys_change(const struct md_config_t *conf,
+ virtual void handle_subsys_change(const md_config_impl<lp>* conf,
const std::set<int>& changed) { }
};
-
-class NoopConfigObserver : public md_config_obs_t {
- std::list<std::string> options;
- const char **ptrs = 0;
-
-public:
- NoopConfigObserver(std::list<std::string> l) : options(l) {
- ptrs = new const char*[options.size() + 1];
- unsigned j = 0;
- for (auto& i : options) {
- ptrs[j++] = i.c_str();
- }
- ptrs[j] = 0;
- }
- ~NoopConfigObserver() {
- delete[] ptrs;
- }
-
- const char** get_tracked_conf_keys() const override {
- return ptrs;
- }
- void handle_conf_change(const struct md_config_t *conf,
- const std::set <std::string> &changed) override {
- }
-};
+}
#endif
#include <type_traits>
#include "global/global_context.h"
+#include "common/ceph_context.h"
#include "common/config.h"
#include "common/likely.h"
#include "common/Clock.h"
#include "common/perf_histogram.h"
#include "include/utime.h"
#include "common/Mutex.h"
+#include "common/ceph_context.h"
#include "common/ceph_time.h"
class CephContext;
#include "common/pick_address.h"
#include "include/ipaddr.h"
#include "include/str_list.h"
+#include "common/config_obs.h"
#include "common/debug.h"
#include "common/errno.h"
const char** get_tracked_conf_keys() const override {
return (const char **)keys;
}
- void handle_conf_change(const struct md_config_t *conf,
+ void handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed) override {
// do nothing.
}
#include "acconfig.h"
#include "ceph_ver.h"
+#include "common/ceph_context.h"
#include "CompressionPluginLZ4.h"
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
#include "acconfig.h"
#include "ceph_ver.h"
+#include "common/ceph_context.h"
#include "CompressionPluginSnappy.h"
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
#include "acconfig.h"
#include "ceph_ver.h"
+#include "common/ceph_context.h"
#include "CompressionPluginZlib.h"
// -----------------------------------------------------------------------------
#include "acconfig.h"
#include "ceph_ver.h"
+#include "common/ceph_context.h"
#include "CompressionPluginZstd.h"
// -----------------------------------------------------------------------------
#ifndef CEPH_GLOBAL_CONTEXT_H
#define CEPH_GLOBAL_CONTEXT_H
+#include "common/config_fwd.h"
+
class CephContext;
-struct md_config_t;
extern CephContext *g_ceph_context;
extern md_config_t *g_conf;
#ifndef CEPH_COMMON_PIDFILE_H
#define CEPH_COMMON_PIDFILE_H
-struct md_config_t;
+#include "common/config_fwd.h"
// Write a pidfile with the current pid, using the configuration in the
// provided conf structure.
#ifndef CEPH_LIBRADOS_RADOSCLIENT_H
#define CEPH_LIBRADOS_RADOSCLIENT_H
+#include "common/config_fwd.h"
#include "common/Cond.h"
#include "common/Mutex.h"
#include "common/RWLock.h"
struct Context;
class CephContext;
struct Connection;
-struct md_config_t;
class Message;
class MLog;
class Messenger;
return KEYS;
}
-void MDSDaemon::handle_conf_change(const struct md_config_t *conf,
+void MDSDaemon::handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed)
{
// We may be called within mds_lock (via `tell`) or outwith the
// config observer bits
const char** get_tracked_conf_keys() const override;
- void handle_conf_change(const struct md_config_t *conf,
- const std::set <std::string> &changed) override;
+ void handle_conf_change(const md_config_t *conf,
+ const std::set <std::string> &changed) override;
protected:
// tick and other timer fun
Context *tick_event = nullptr;
void handle_write_error(int err);
- void handle_conf_change(const struct md_config_t *conf,
+ void handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed)
{
mdcache->migrator->handle_conf_change(conf, changed, *mdsmap);
in->auth_unpin(this);
}
-void Migrator::handle_conf_change(const struct md_config_t *conf,
+void Migrator::handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed,
const MDSMap &mds_map)
{
inject_session_race = g_conf->get_val<bool>("mds_inject_migrator_session_race");
}
- void handle_conf_change(const struct md_config_t *conf,
+ void handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed,
const MDSMap &mds_map);
}
}
-void PurgeQueue::handle_conf_change(const struct md_config_t *conf,
+void PurgeQueue::handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed,
const MDSMap &mds_map)
{
void update_op_limit(const MDSMap &mds_map);
- void handle_conf_change(const struct md_config_t *conf,
+ void handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed,
const MDSMap &mds_map);
return KEYS;
}
-void DaemonServer::handle_conf_change(const struct md_config_t *conf,
- const std::set <std::string> &changed)
+void DaemonServer::handle_conf_change(const md_config_t *conf,
+ const std::set <std::string> &changed)
{
// We may be called within lock (via MCommand `config set`) or outwith the
// lock (via admin socket `config set`), so handle either case.
void _send_configure(ConnectionRef c);
virtual const char** get_tracked_conf_keys() const override;
- virtual void handle_conf_change(const struct md_config_t *conf,
+ virtual void handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed) override;
};
}
void MgrStandby::handle_conf_change(
- const struct md_config_t *conf,
+ const md_config_t *conf,
const std::set <std::string> &changed)
{
if (changed.count("clog_to_monitors") ||
public:
// config observer bits
const char** get_tracked_conf_keys() const override;
- void handle_conf_change(const struct md_config_t *conf,
- const std::set <std::string> &changed) override;
+ void handle_conf_change(const md_config_t *conf,
+ const std::set <std::string> &changed) override;
protected:
MonClient monc;
#pragma once
+#include <map>
+#include <memory>
+#include <string>
+#include <boost/optional.hpp>
+#include "common/Mutex.h"
#include "Python.h"
#include "Gil.h"
-#include <string>
-#include "common/Mutex.h"
-#include <memory>
-#include <boost/optional.hpp>
class MonClient;
return graylogs[channel];
}
-void LogMonitor::handle_conf_change(const struct md_config_t *conf,
+void LogMonitor::handle_conf_change(const md_config_t *conf,
const std::set<std::string> &changed)
{
if (changed.count("mon_cluster_log_to_syslog") ||
#include "include/types.h"
#include "PaxosService.h"
+#include "common/config_fwd.h"
#include "common/LogEntry.h"
#include "include/str_map.h"
};
return KEYS;
}
- void handle_conf_change(const struct md_config_t *conf,
+ void handle_conf_change(const md_config_t *conf,
const std::set<std::string> &changed) override;
};
#endif
return KEYS;
}
-void Monitor::handle_conf_change(const struct md_config_t *conf,
+void Monitor::handle_conf_change(const md_config_t *conf,
const std::set<std::string> &changed)
{
sanitize_options();
#include "Session.h"
#include "MonCommand.h"
+
+#include "common/config_obs.h"
#include "common/LogClient.h"
#include "auth/cephx/CephxKeyServer.h"
#include "auth/AuthMethodList.h"
// config observer
const char** get_tracked_conf_keys() const override;
- void handle_conf_change(const struct md_config_t *conf,
+ void handle_conf_change(const md_config_t *conf,
const std::set<std::string> &changed) override;
void update_log_clients();
return KEYS;
}
-void BlueStore::handle_conf_change(const struct md_config_t *conf,
+void BlueStore::handle_conf_change(const md_config_t *conf,
const std::set<std::string> &changed)
{
if (changed.count("bluestore_csum_type")) {
public:
// config observer
const char** get_tracked_conf_keys() const override;
- void handle_conf_change(const struct md_config_t *conf,
- const std::set<std::string> &changed) override;
+ void handle_conf_change(const md_config_t *conf,
+ const std::set<std::string> &changed) override;
//handler for discard event
void handle_discard(interval_set<uint64_t>& to_release);
#include <memory>
#include <errno.h>
#include <cstdio>
+#include "common/config_obs.h"
#include "common/hobject.h"
#include "common/Mutex.h"
#include "common/Cond.h"
using std::deque;
#include "Journal.h"
+#include "common/config_fwd.h"
#include "common/Cond.h"
#include "common/Mutex.h"
#include "common/Thread.h"
int set_throttle_params();
const char** get_tracked_conf_keys() const override;
void handle_conf_change(
- const struct md_config_t *conf,
+ const md_config_t *conf,
const std::set <std::string> &changed) override {
for (const char **i = get_tracked_conf_keys();
*i;
return KEYS;
}
-void FileStore::handle_conf_change(const struct md_config_t *conf,
+void FileStore::handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed)
{
if (changed.count("filestore_max_inline_xattr_size") ||
const SequencerPosition &spos);
const char** get_tracked_conf_keys() const override;
- void handle_conf_change(const struct md_config_t *conf,
+ void handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed) override;
int set_throttle_params();
float m_filestore_commit_timeout;
return KEYS;
}
-void OSD::handle_conf_change(const struct md_config_t *conf,
+void OSD::handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed)
{
if (changed.count("osd_max_backfills")) {
public:
// config observer bits
const char** get_tracked_conf_keys() const override;
- void handle_conf_change(const struct md_config_t *conf,
+ void handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed) override;
void update_log_config();
void check_config();
}
-void Objecter::handle_conf_change(const struct md_config_t *conf,
+void Objecter::handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed)
{
if (changed.count("crush_location")) {
#include "common/admin_socket.h"
#include "common/ceph_time.h"
#include "common/ceph_timer.h"
+#include "common/config_obs.h"
#include "common/shunique_lock.h"
#include "common/zipkin_trace.h"
#include "common/Finisher.h"
public:
// config observer bits
const char** get_tracked_conf_keys() const override;
- void handle_conf_change(const struct md_config_t *conf,
+ void handle_conf_change(const md_config_t *conf,
const std::set <std::string> &changed) override;
public:
{}
void test_expand_meta() {
- Mutex::Locker l(lock);
+ auto locker = lock();
// successfull meta expansion $run_dir and ${run_dir}
{
ostringstream oss;
#include <signal.h>
#include <stdlib.h>
#include "gtest/gtest.h"
+#include "common/ceph_context.h"
#include "common/config.h"
#include "compressor/Compressor.h"
#include "compressor/CompressionPlugin.h"
#include "gtest/gtest.h"
#include "common/ceph_argparse.h"
+#include "common/ceph_context.h"
#include "common/config.h"
#include "global/global_context.h"
#include "include/cephfs/libcephfs.h"
#include "global/global_context.h"
#include "global/global_init.h"
#include "common/ceph_argparse.h"
+#include "common/ceph_context.h"
#include "common/config.h"
#include "common/Clock.h"
#include "include/utime.h"
#include "global/global_context.h"
#include "global/global_init.h"
#include "common/ceph_argparse.h"
+#include "common/ceph_context.h"
#include "common/config.h"
#include "common/Clock.h"
#include "include/utime.h"
#include "global/global_context.h"
#include "global/global_init.h"
#include "common/errno.h"
+#include "common/ceph_context.h"
#include "common/ceph_argparse.h"
#include "common/config.h"
#include "erasure-code/ErasureCodePlugin.h"
#include <algorithm>
#include <atomic>
#include <iostream>
+#include <list>
#include <random>
#include <string>
#include <set>
#include <gtest/gtest.h>
#include "acconfig.h"
+#include "common/config_obs.h"
#include "include/Context.h"
-
#include "msg/async/Event.h"
#include "msg/async/Stack.h"
#if GTEST_HAS_PARAM_TEST
+class NoopConfigObserver : public md_config_obs_t {
+ std::list<std::string> options;
+ const char **ptrs = 0;
+
+public:
+ NoopConfigObserver(std::list<std::string> l) : options(l) {
+ ptrs = new const char*[options.size() + 1];
+ unsigned j = 0;
+ for (auto& i : options) {
+ ptrs[j++] = i.c_str();
+ }
+ ptrs[j] = 0;
+ }
+ ~NoopConfigObserver() {
+ delete[] ptrs;
+ }
+
+ const char** get_tracked_conf_keys() const override {
+ return ptrs;
+ }
+ void handle_conf_change(const md_config_t *conf,
+ const std::set <std::string> &changed) override {
+ }
+};
+
class NetworkWorkerTest : public ::testing::TestWithParam<const char*> {
public:
std::shared_ptr<NetworkStack> stack;
#include <stack>
#include <boost/scoped_ptr.hpp>
#include <gtest/gtest.h>
+#include "common/config_fwd.h"
class ObjectStore;
-struct md_config_t;
class StoreTestFixture : virtual public ::testing::Test {
const std::string type;
}
template <typename I>
-void ImageSyncThrottler<I>::handle_conf_change(const struct md_config_t *conf,
+void ImageSyncThrottler<I>::handle_conf_change(const md_config_t *conf,
const set<string> &changed) {
if (changed.count("rbd_mirror_concurrent_image_syncs")) {
set_max_concurrent_syncs(conf->get_val<uint64_t>("rbd_mirror_concurrent_image_syncs"));
std::set<std::string> m_inflight_ops;
const char **get_tracked_conf_keys() const override;
- void handle_conf_change(const struct md_config_t *conf,
+ void handle_conf_change(const md_config_t *conf,
const std::set<std::string> &changed) override;
};