From: Sage Weil Date: Mon, 29 Dec 2014 19:33:00 +0000 (-0800) Subject: common: add 'enable experimental data corrupting features' X-Git-Tag: v0.92~88^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8a559720fb23f081aec0c22648f127b816376b08;p=ceph.git common: add 'enable experimental data corrupting features' Signed-off-by: Sage Weil --- diff --git a/src/common/ceph_context.cc b/src/common/ceph_context.cc index 1ef517b10b6..1c939b45d0a 100644 --- a/src/common/ceph_context.cc +++ b/src/common/ceph_context.cc @@ -155,6 +155,55 @@ public: }; +// cct config watcher +class CephContextObs : public md_config_obs_t { + CephContext *cct; + +public: + CephContextObs(CephContext *cct) : cct(cct) {} + + const char** get_tracked_conf_keys() const { + static const char *KEYS[] = { + "enable_experimental_unrecoverable_data_corrupting_features", + NULL + }; + return KEYS; + } + + void handle_conf_change(const md_config_t *conf, + const std::set &changed) { + ceph_spin_lock(&cct->_feature_lock); + get_str_set(conf->enable_experimental_unrecoverable_data_corrupting_features, + cct->_experimental_features); + ceph_spin_unlock(&cct->_feature_lock); + } +}; + +bool CephContext::check_experimental_feature_enabled(std::string feat) +{ + ceph_spin_lock(&_feature_lock); + bool enabled = _experimental_features.count(feat); + ceph_spin_unlock(&_feature_lock); + + if (enabled) { + lderr(this) << "WARNING: experimental feature '" << feat << "' is enabled" << dendl; + lderr(this) << "Please be aware that this feature is experimental, untested," << dendl; + lderr(this) << "unsupported, and may result in data corruption, data loss," << dendl; + lderr(this) << "and/or irreparable damage to your cluster. Do not use" << dendl; + lderr(this) << "feature with important data." << dendl; + } else { + lderr(this) << "*** experimental feature '" << feat << "' is not enabled ***" << dendl; + lderr(this) << "This feature is marked as experimental, which means it" << dendl; + lderr(this) << " - is untested" << dendl; + lderr(this) << " - is unsupported" << dendl; + lderr(this) << " - may corrupt your data" << dendl; + lderr(this) << " - may break your cluster is an unrecoverable fashion" << dendl; + lderr(this) << "To enable this feature, add this to your ceph.conf:" << dendl; + lderr(this) << " enable experimental unrecoverable data corrupting features = " << feat << dendl; + } + return enabled; +} + // perfcounter hooks class CephContextHook : public AdminSocketHook { @@ -311,6 +360,7 @@ CephContext::CephContext(uint32_t module_type_) { ceph_spin_init(&_service_thread_lock); ceph_spin_init(&_associated_objs_lock); + ceph_spin_init(&_feature_lock); _log = new ceph::log::Log(&_conf->subsys); _log->start(); @@ -318,6 +368,9 @@ CephContext::CephContext(uint32_t module_type_) _log_obs = new LogObs(_log); _conf->add_observer(_log_obs); + _cct_obs = new CephContextObs(this); + _conf->add_observer(_cct_obs); + _perf_counters_collection = new PerfCountersCollection(this); _admin_socket = new AdminSocket(this); _heartbeat_map = new HeartbeatMap(this); @@ -385,6 +438,10 @@ CephContext::~CephContext() delete _log_obs; _log_obs = NULL; + _conf->remove_observer(_cct_obs); + delete _cct_obs; + _cct_obs = NULL; + _log->stop(); delete _log; _log = NULL; @@ -392,6 +449,7 @@ CephContext::~CephContext() delete _conf; ceph_spin_destroy(&_service_thread_lock); ceph_spin_destroy(&_associated_objs_lock); + ceph_spin_destroy(&_feature_lock); delete _crypto_none; delete _crypto_aes; diff --git a/src/common/ceph_context.h b/src/common/ceph_context.h index 7241c85583d..c332bdfa70b 100644 --- a/src/common/ceph_context.h +++ b/src/common/ceph_context.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "include/buffer.h" #include "include/atomic.h" @@ -30,6 +31,7 @@ class PerfCountersCollection; class md_config_obs_t; struct md_config_t; class CephContextHook; +class CephContextObs; class CryptoNone; class CryptoAES; class CryptoHandler; @@ -123,6 +125,9 @@ public: */ CryptoHandler *get_crypto_handler(int type); + /// check if experimental feature is enable, and emit appropriate warnings + bool check_experimental_feature_enabled(std::string feature); + private: CephContext(const CephContext &rhs); CephContext &operator=(const CephContext &rhs); @@ -160,6 +165,13 @@ private: // crypto CryptoNone *_crypto_none; CryptoAES *_crypto_aes; + + // experimental + CephContextObs *_cct_obs; + ceph_spinlock_t _feature_lock; + std::set _experimental_features; + + friend class CephContextObs; }; #endif diff --git a/src/common/config_opts.h b/src/common/config_opts.h index ff269670154..23f62ab6161 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -61,6 +61,8 @@ OPTION(mon_cluster_log_file, OPT_STR, "default=/var/log/ceph/$cluster.$channel.log cluster=/var/log/ceph/$cluster.log") OPTION(mon_cluster_log_file_level, OPT_STR, "info") +OPTION(enable_experimental_unrecoverable_data_corrupting_features, OPT_STR, "") + DEFAULT_SUBSYS(0, 5) SUBSYS(lockdep, 0, 1) SUBSYS(context, 0, 1) diff --git a/src/test/common/test_context.cc b/src/test/common/test_context.cc index cb513051af8..0d0d2aaac5f 100644 --- a/src/test/common/test_context.cc +++ b/src/test/common/test_context.cc @@ -24,6 +24,7 @@ #include "include/msgr.h" #include "common/ceph_context.h" #include "common/config.h" +#include "log/Log.h" TEST(CephContext, do_command) { @@ -52,6 +53,38 @@ TEST(CephContext, do_command) cct->put(); } +TEST(CephContext, experimental_features) +{ + CephContext *cct = (new CephContext(CEPH_ENTITY_TYPE_CLIENT))->get(); + + ASSERT_FALSE(cct->check_experimental_feature_enabled("foo")); + ASSERT_FALSE(cct->check_experimental_feature_enabled("bar")); + ASSERT_FALSE(cct->check_experimental_feature_enabled("baz")); + + cct->_conf->set_val("enable_experimental_unrecoverable_data_corrupting_features", + "foo,bar"); + cct->_conf->apply_changes(&cout); + ASSERT_TRUE(cct->check_experimental_feature_enabled("foo")); + ASSERT_TRUE(cct->check_experimental_feature_enabled("bar")); + ASSERT_FALSE(cct->check_experimental_feature_enabled("baz")); + + cct->_conf->set_val("enable_experimental_unrecoverable_data_corrupting_features", + "foo bar"); + cct->_conf->apply_changes(&cout); + ASSERT_TRUE(cct->check_experimental_feature_enabled("foo")); + ASSERT_TRUE(cct->check_experimental_feature_enabled("bar")); + ASSERT_FALSE(cct->check_experimental_feature_enabled("baz")); + + cct->_conf->set_val("enable_experimental_unrecoverable_data_corrupting_features", + "baz foo"); + cct->_conf->apply_changes(&cout); + ASSERT_TRUE(cct->check_experimental_feature_enabled("foo")); + ASSERT_FALSE(cct->check_experimental_feature_enabled("bar")); + ASSERT_TRUE(cct->check_experimental_feature_enabled("baz")); + + cct->_log->flush(); +} + /* * Local Variables: * compile-command: "cd ../.. ;