From b86cc9a2e49a4d1b53e83f47876a42b42819efcb Mon Sep 17 00:00:00 2001 From: John Spray Date: Thu, 31 Aug 2017 12:13:23 -0400 Subject: [PATCH] mgr: runtime adjustment of perf counter threshold ceph-mgr has missed out on the `config set` command that the other daemons got recently: add it here and hook it all up to the stats period and threshold settings. Signed-off-by: John Spray (cherry picked from commit 057b73d641decb9403aba50caae9d139f3a34dd4) --- src/mgr/DaemonServer.cc | 82 ++++++++++++++++++++++++++++++++++++++--- src/mgr/DaemonServer.h | 13 ++++++- src/mgr/MgrCommands.h | 5 +++ 3 files changed, 94 insertions(+), 6 deletions(-) diff --git a/src/mgr/DaemonServer.cc b/src/mgr/DaemonServer.cc index 74c43d7ac6467..298ed4413f6ef 100644 --- a/src/mgr/DaemonServer.cc +++ b/src/mgr/DaemonServer.cc @@ -74,10 +74,13 @@ DaemonServer::DaemonServer(MonClient *monc_, g_conf->auth_cluster_required : g_conf->auth_supported), lock("DaemonServer") -{} +{ + g_conf->add_observer(this); +} DaemonServer::~DaemonServer() { delete msgr; + g_conf->remove_observer(this); } int DaemonServer::init(uint64_t gid, entity_addr_t client_addr) @@ -232,6 +235,11 @@ bool DaemonServer::ms_handle_reset(Connection *con) dout(10) << "unregistering osd." << session->osd_id << " session " << session << " con " << con << dendl; osd_cons[session->osd_id].erase(con); + + auto iter = daemon_connections.find(con); + if (iter != daemon_connections.end()) { + daemon_connections.erase(iter); + } } return false; } @@ -315,10 +323,7 @@ bool DaemonServer::handle_open(MMgrOpen *m) dout(4) << "from " << m->get_connection() << " " << key << dendl; - auto configure = new MMgrConfigure(); - configure->stats_period = g_conf->mgr_stats_period; - configure->stats_threshold = g_conf->get_val("mgr_stats_threshold"); - m->get_connection()->send_message(configure); + _send_configure(m->get_connection()); DaemonStatePtr daemon; if (daemon_state.exists(key)) { @@ -359,6 +364,15 @@ bool DaemonServer::handle_open(MMgrOpen *m) } } + if (m->get_connection()->get_peer_type() != entity_name_t::TYPE_CLIENT && + m->service_name.empty()) + { + // Store in set of the daemon/service connections, i.e. those + // connections that require an update in the event of stats + // configuration changes. + daemon_connections.insert(m->get_connection()); + } + m->put(); return true; } @@ -706,6 +720,19 @@ bool DaemonServer::handle_command(MCommand *m) return true; } + if (prefix == "config set") { + std::string key; + std::string val; + cmd_getval(cct, cmdctx->cmdmap, "key", key); + cmd_getval(cct, cmdctx->cmdmap, "value", val); + r = cct->_conf->set_val(key, val, true, &ss); + if (r == 0) { + cct->_conf->apply_changes(nullptr); + } + cmdctx->reply(0, ss); + return true; + } + // ----------- // PG commands @@ -1405,3 +1432,48 @@ void DaemonServer::got_service_map() daemon_state.cull(p.first, names); } } + + +const char** DaemonServer::get_tracked_conf_keys() const +{ + static const char *KEYS[] = { + "mgr_stats_threshold", + "mgr_stats_period", + nullptr + }; + + return KEYS; +} + +void DaemonServer::handle_conf_change(const struct md_config_t *conf, + const std::set &changed) +{ + dout(4) << "ohai" << dendl; + // We may be called within lock (via MCommand `config set`) or outwith the + // lock (via admin socket `config set`), so handle either case. + const bool initially_locked = lock.is_locked_by_me(); + if (!initially_locked) { + lock.Lock(); + } + + if (changed.count("mgr_stats_threshold") || changed.count("mgr_stats_period")) { + dout(4) << "Updating stats threshold/period on " + << daemon_connections.size() << " clients" << dendl; + // Send a fresh MMgrConfigure to all clients, so that they can follow + // the new policy for transmitting stats + for (auto &c : daemon_connections) { + _send_configure(c); + } + } +} + +void DaemonServer::_send_configure(ConnectionRef c) +{ + assert(lock.is_locked_by_me()); + + auto configure = new MMgrConfigure(); + configure->stats_period = g_conf->get_val("mgr_stats_period"); + configure->stats_threshold = g_conf->get_val("mgr_stats_threshold"); + c->send_message(configure); +} + diff --git a/src/mgr/DaemonServer.h b/src/mgr/DaemonServer.h index 6e44832021510..d29e3752f8612 100644 --- a/src/mgr/DaemonServer.h +++ b/src/mgr/DaemonServer.h @@ -42,7 +42,7 @@ struct MonCommand; * Server used in ceph-mgr to communicate with Ceph daemons like * MDSs and OSDs. */ -class DaemonServer : public Dispatcher +class DaemonServer : public Dispatcher, public md_config_obs_t { protected: boost::scoped_ptr client_byte_throttler; @@ -64,10 +64,15 @@ protected: AuthAuthorizeHandlerRegistry auth_registry; + // Connections for daemons, and clients with service names set + // (i.e. those MgrClients that are allowed to send MMgrReports) + std::set daemon_connections; + /// connections for osds ceph::unordered_map> osd_cons; ServiceMap pending_service_map; // uncommitted + epoch_t pending_service_map_dirty = 0; Mutex lock; @@ -128,6 +133,12 @@ public: bool handle_command(MCommand *m); void send_report(); void got_service_map(); + + 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, + const std::set &changed) override; }; #endif diff --git a/src/mgr/MgrCommands.h b/src/mgr/MgrCommands.h index 1818454e1fcc4..79766fafed93a 100644 --- a/src/mgr/MgrCommands.h +++ b/src/mgr/MgrCommands.h @@ -131,3 +131,8 @@ COMMAND("service dump", "dump service map", "service", "r", "cli,rest") COMMAND("service status", "dump service state", "service", "r", "cli,rest") + +COMMAND("config set " \ + "name=key,type=CephString name=value,type=CephString", + "Set a configuration option at runtime (not persistent)", + "mgr", "rw", "cli,rest") -- 2.39.5