From 113e306de516d1dbe7f00a8f041e9a7cb35e0473 Mon Sep 17 00:00:00 2001 From: oliveiradan Date: Thu, 18 Aug 2016 21:51:09 -0600 Subject: [PATCH] common: *config diff get* option added Signed-off-by: Daniel Oliveira --- src/common/ceph_context.cc | 64 +++++++++++++++++++++++++-------- src/common/config.cc | 40 +++++++++++++++++++++ src/common/config.h | 6 ++++ src/test/common/test_context.cc | 7 ++++ 4 files changed, 102 insertions(+), 15 deletions(-) diff --git a/src/common/ceph_context.cc b/src/common/ceph_context.cc index 29aaa86bd115..43b88d8f1b85 100644 --- a/src/common/ceph_context.cc +++ b/src/common/ceph_context.cc @@ -417,7 +417,7 @@ void CephContext::do_command(std::string command, cmdmap_t& cmdmap, f->dump_string("error", "syntax error: 'perf reset '"); } else { if(!_perf_counters_collection->reset(var)) - f->dump_stream("error") << "Not find: " << var; + f->dump_stream("error") << "Not find: " << var; else f->dump_string("success", command + ' ' + var); } @@ -438,8 +438,8 @@ void CephContext::do_command(std::string command, cmdmap_t& cmdmap, !(cmd_getval(this, cmdmap, "val", val))) { f->dump_string("error", "syntax error: 'config set '"); } else { - // val may be multiple words - string valstr = str_join(val, " "); + // val may be multiple words + string valstr = str_join(val, " "); int r = _conf->set_val(var.c_str(), valstr.c_str()); if (r < 0) { f->dump_stream("error") << "error setting '" << var << "' to '" << valstr << "': " << cpp_strerror(r); @@ -452,17 +452,17 @@ void CephContext::do_command(std::string command, cmdmap_t& cmdmap, } else if (command == "config get") { std::string var; if (!cmd_getval(this, cmdmap, "var", var)) { - f->dump_string("error", "syntax error: 'config get '"); + f->dump_string("error", "syntax error: 'config get '"); } else { - char buf[4096]; - memset(buf, 0, sizeof(buf)); - char *tmp = buf; - int r = _conf->get_val(var.c_str(), &tmp, sizeof(buf)); - if (r < 0) { - f->dump_stream("error") << "error getting '" << var << "': " << cpp_strerror(r); - } else { - f->dump_string(var.c_str(), buf); - } + char buf[4096]; + memset(buf, 0, sizeof(buf)); + char *tmp = buf; + int r = _conf->get_val(var.c_str(), &tmp, sizeof(buf)); + if (r < 0) { + f->dump_stream("error") << "error getting '" << var << "': " << cpp_strerror(r); + } else { + f->dump_string(var.c_str(), buf); + } } } else if (command == "config diff") { md_config_t def_conf; @@ -496,7 +496,38 @@ void CephContext::do_command(std::string command, cmdmap_t& cmdmap, f->dump_string("option", *p); } f->close_section(); // unknown - } else if (command == "log flush") { + } + else if (command == "config diff get") { + std::string ceph_setting; + if (!cmd_getval(this, cmdmap, "var", ceph_setting)) { + f->dump_string("error", "syntax error: 'config diff get '"); + } + else { + md_config_t def_conf; + def_conf.set_val("cluster", _conf->cluster); + def_conf.name = _conf->name; + def_conf.set_val("host", _conf->host); + def_conf.apply_changes(NULL); + + map> diff; + def_conf.diff_setting(_conf, &diff, ceph_setting, true); + f->open_object_section("diff"); + f->open_object_section("current"); + + for (const auto& p : diff) { + f->dump_string(p.first.c_str(), p.second.second); + } + f->close_section(); //-- current + + f->open_object_section("defaults"); + for (const auto& p : diff) { + f->dump_string(p.first.c_str(), p.second.first); + } + f->close_section(); //-- defaults + f->close_section(); //-- diff + } //-- else if (!cmd_getval(this, cmdmap, "var", ceph_setting)) + } //-- else if (command == "config diff get") + else if (command == "log flush") { _log->flush(); } else if (command == "log dump") { @@ -516,7 +547,6 @@ void CephContext::do_command(std::string command, cmdmap_t& cmdmap, << "result is " << out->length() << " bytes" << dendl; } - CephContext::CephContext(uint32_t module_type_, int init_flags_) : nref(1), _conf(new md_config_t()), @@ -582,6 +612,9 @@ CephContext::CephContext(uint32_t module_type_, int init_flags_) _admin_socket->register_command("config diff", "config diff", _admin_hook, "dump diff of current config and default config"); + _admin_socket->register_command("config diff get", + "config diff get name=var,type=CephString", _admin_hook, + "dump diff get : dump diff of current and default config setting "); _admin_socket->register_command("log flush", "log flush", _admin_hook, "flush log entries to log file"); _admin_socket->register_command("log dump", "log dump", _admin_hook, "dump recent log entries to log file"); _admin_socket->register_command("log reopen", "log reopen", _admin_hook, "reopen log file"); @@ -620,6 +653,7 @@ CephContext::~CephContext() _admin_socket->unregister_command("config set"); _admin_socket->unregister_command("config get"); _admin_socket->unregister_command("config diff"); + _admin_socket->unregister_command("config diff get"); _admin_socket->unregister_command("log flush"); _admin_socket->unregister_command("log dump"); _admin_socket->unregister_command("log reopen"); diff --git a/src/common/config.cc b/src/common/config.cc index 768a552cc705..1f3c8630c76b 100644 --- a/src/common/config.cc +++ b/src/common/config.cc @@ -1373,6 +1373,46 @@ void md_config_t::diff( } } +void md_config_t::diff_setting(const md_config_t *other, + map> *diff, + const string& ceph_setting, bool show_unchanged) +{ + Mutex::Locker l(lock); + + char local_buf[4096]; + char other_buf[4096]; + for (int i = 0; i < NUM_CONFIG_OPTIONS; i++) { + config_option *opt = &config_optionsp[i]; + std::string ceph_setting_name(opt->name); + if (ceph_setting != opt->name) { + continue; + } + memset(local_buf, 0, sizeof(local_buf)); + memset(other_buf, 0, sizeof(other_buf)); + + char *other_val = other_buf; + int err = other->get_val(opt->name, &other_val, sizeof(other_buf)); + if (err < 0) { + continue; + } + + char *local_val = local_buf; + err = _get_val(opt->name, &local_val, sizeof(local_buf)); + if (err != 0) { + continue; + } + if (strcmp(local_val, other_val)) { + diff->insert(make_pair(ceph_setting, make_pair(local_val, other_val))); + } + else { + if (show_unchanged) { + diff->insert(make_pair(ceph_setting, make_pair(local_val, other_val))); + } + } + break; + } +} + void md_config_t::complain_about_parse_errors(CephContext *cct) { ::complain_about_parse_errors(cct, &parse_errors); diff --git a/src/common/config.h b/src/common/config.h index bbabc14a8870..ea4ce47b3052 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -239,6 +239,12 @@ public: 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_setting(const md_config_t*, + std::map>*, + const std::string&, bool show_unchanged = false); + /// print/log warnings/errors from parsing the config void complain_about_parse_errors(CephContext *cct); diff --git a/src/test/common/test_context.cc b/src/test/common/test_context.cc index d976758c6b7c..ee0f64606662 100644 --- a/src/test/common/test_context.cc +++ b/src/test/common/test_context.cc @@ -52,6 +52,13 @@ TEST(CephContext, do_command) EXPECT_EQ("{\n \"key\": \"value\"\n}\n", s); } + { + bufferlist out; + cct->do_command("config diff get", cmdmap, "xml", &out); + string s(out.c_str(), out.length()); + EXPECT_EQ("" + value + + "", s); + } cct->put(); } -- 2.47.3