// Trigger callbacks on any config observers that were waiting for
// it to become safe to start threads.
- _conf->set_val("internal_safe_to_start_threads", "true");
+ _conf->set_safe_to_start_threads();
_conf->call_all_observers();
// start admin socket
{
Mutex::Locker l(lock);
- if (internal_safe_to_start_threads)
+ if (safe_to_start_threads)
return -ENOSYS;
if (!cluster.size() && !conf_files) {
void md_config_t::parse_env()
{
Mutex::Locker l(lock);
- if (internal_safe_to_start_threads)
+ if (safe_to_start_threads)
return;
if (getenv("CEPH_KEYRING")) {
set_val_or_die("keyring", getenv("CEPH_KEYRING"));
int md_config_t::parse_argv(std::vector<const char*>& args)
{
Mutex::Locker l(lock);
- if (internal_safe_to_start_threads) {
+ if (safe_to_start_threads) {
return -ENOSYS;
}
_apply_changes(oss);
}
-bool md_config_t::_internal_field(const string& s)
-{
- if (s == "internal_safe_to_start_threads")
- return true;
- return false;
-}
-
void md_config_t::_apply_changes(std::ostream *oss)
{
/* Maps observers to the configuration options that they care about which
pair < obs_map_t::iterator, obs_map_t::iterator >
range(observers.equal_range(key));
if ((oss) &&
- (!_get_val(key.c_str(), &bufptr, sizeof(buf))) &&
- !_internal_field(key)) {
+ !_get_val(key.c_str(), &bufptr, sizeof(buf))) {
(*oss) << key << " = '" << buf << "' ";
if (range.first == range.second) {
(*oss) << "(not observed, change may require restart) ";
}
}
+void md_config_t::set_safe_to_start_threads()
+{
+ safe_to_start_threads = true;
+}
+
+void md_config_t::_clear_safe_to_start_threads()
+{
+ safe_to_start_threads = false;
+}
+
int md_config_t::injectargs(const std::string& s, std::ostream *oss)
{
int ret;
const auto &opt_iter = schema.find(k);
if (opt_iter != schema.end()) {
const Option &opt = opt_iter->second;
- if ((!opt.is_safe()) && internal_safe_to_start_threads) {
+ if ((!opt.is_safe()) && safe_to_start_threads) {
// If threads have been started and the option is not thread safe
if (observers.find(opt.name) == observers.end()) {
// And there is no observer to safely change it...
*
* 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
+ * md_config_t::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
bool _internal_field(const string& k);
void call_all_observers();
+ void set_safe_to_start_threads();
+ void _clear_safe_to_start_threads(); // this is only used by the unit test
+
// Called by the Ceph daemons to make configuration changes at runtime
int injectargs(const std::string &s, std::ostream *oss);
std::deque<std::string> parse_errors;
private:
+ // This will be set to true when it is safe to start threads.
+ // Once it is true, it will never change.
+ bool safe_to_start_threads = false;
+
obs_map_t observers;
changed_set_t changed;
OPTION(event_tracing, OPT_BOOL) // true if LTTng-UST tracepoints should be enabled
-// This will be set to true when it is safe to start threads.
-// Once it is true, it will never change.
-OPTION(internal_safe_to_start_threads, OPT_BOOL)
-
OPTION(debug_deliberately_leak_memory, OPT_BOOL)
OPTION(rgw_swift_custom_header, OPT_STR) // option to enable swift custom headers
.set_default(false)
.set_description(""),
- Option("internal_safe_to_start_threads", Option::TYPE_BOOL, Option::LEVEL_ADVANCED)
- .set_default(false)
- .set_description(""),
-
Option("debug_deliberately_leak_memory", Option::TYPE_BOOL, Option::LEVEL_DEV)
.set_default(false)
.set_description(""),
TEST(DaemonConfig, Substitution) {
int ret;
- ret = g_ceph_context->_conf->set_val("internal_safe_to_start_threads", "false");
- ASSERT_EQ(0, ret);
+ g_conf->_clear_safe_to_start_threads();
ret = g_ceph_context->_conf->set_val("host", "foo");
ASSERT_EQ(0, ret);
ret = g_ceph_context->_conf->set_val("public_network", "bar$host.baz", false);
TEST(DaemonConfig, SubstitutionTrailing) {
int ret;
- ret = g_ceph_context->_conf->set_val("internal_safe_to_start_threads", "false");
- ASSERT_EQ(0, ret);
+ g_conf->_clear_safe_to_start_threads();
ret = g_ceph_context->_conf->set_val("host", "foo");
ASSERT_EQ(0, ret);
ret = g_ceph_context->_conf->set_val("public_network", "bar$host", false);
TEST(DaemonConfig, SubstitutionBraces) {
int ret;
- ret = g_ceph_context->_conf->set_val("internal_safe_to_start_threads", "false");
- ASSERT_EQ(0, ret);
+ g_conf->_clear_safe_to_start_threads();
ret = g_ceph_context->_conf->set_val("host", "foo");
ASSERT_EQ(0, ret);
ret = g_ceph_context->_conf->set_val("public_network", "bar${host}baz", false);
}
TEST(DaemonConfig, SubstitutionBracesTrailing) {
int ret;
- ret = g_ceph_context->_conf->set_val("internal_safe_to_start_threads", "false");
- ASSERT_EQ(0, ret);
+ g_conf->_clear_safe_to_start_threads();
ret = g_ceph_context->_conf->set_val("host", "foo");
ASSERT_EQ(0, ret);
ret = g_ceph_context->_conf->set_val("public_network", "bar${host}", false);
}
TEST(DaemonConfig, ArgV) {
- ASSERT_EQ(0, g_ceph_context->_conf->set_val("internal_safe_to_start_threads",
- "false"));
+ g_conf->_clear_safe_to_start_threads();
int ret;
const char *argv[] = { "foo", "--log-graylog-port", "22",
ASSERT_EQ(0, ret);
ASSERT_EQ(string("22"), string(buf));
- ASSERT_EQ(0, g_ceph_context->_conf->set_val("internal_safe_to_start_threads",
- "true"));
+ g_conf->set_safe_to_start_threads();
}
TEST(DaemonConfig, InjectArgs) {
TEST(DaemonConfig, ThreadSafety1) {
int ret;
- // Verify that we can't change this, since internal_safe_to_start_threads has
+ // Verify that we can't change this, since safe_to_start_threads has
// been set.
ret = g_ceph_context->_conf->set_val("osd_data", "");
ASSERT_EQ(-ENOSYS, ret);
- ASSERT_EQ(0, g_ceph_context->_conf->set_val("internal_safe_to_start_threads",
- "false"));
+ g_conf->_clear_safe_to_start_threads();
// Ok, now we can change this. Since this is just a test, and there are no
// OSD threads running, we know changing osd_data won't actually blow up the
ASSERT_EQ(0, ret);
ASSERT_EQ(string("/tmp/crazydata"), string(buf));
- ASSERT_EQ(0, g_ceph_context->_conf->set_val("internal_safe_to_start_threads",
- "false"));
+ g_conf->_clear_safe_to_start_threads();
ASSERT_EQ(0, ret);
}