From 5b6037aeb43aff90111fdae08807ddda290bc570 Mon Sep 17 00:00:00 2001 From: Mykola Golub Date: Thu, 13 Dec 2018 13:12:14 +0200 Subject: [PATCH] mgr: fix crash due to multiple sessions from daemons with same name Don't assume perf counter instances are stable. If there are multiple sessions from daemons reporting the same name (e.g. rgws), the instances are cleared in DaemonServer::handle_open. If the daemons have different counter names (for counters like "objecter-0x55b6f4f1a630.op_active") it will throw out_of_range in DaemonPerfCounters::update when accessing the instance removed by another session. The regression was introduced when adding avgcount support. Fixes: https://tracker.ceph.com/issues/36244 Signed-off-by: Mykola Golub --- src/mgr/DaemonState.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/mgr/DaemonState.cc b/src/mgr/DaemonState.cc index 2d8d32b2459aa..b13685a1561b6 100644 --- a/src/mgr/DaemonState.cc +++ b/src/mgr/DaemonState.cc @@ -279,8 +279,6 @@ void DaemonPerfCounters::update(MMgrReport *report) for (const auto &t : report->declare_types) { types.insert(std::make_pair(t.path, t)); session->declared_types.insert(t.path); - instances.insert(std::pair( - t.path, PerfCounterInstance(t.type))); } // Remove any old types for (const auto &t : report->undeclare_types) { @@ -294,6 +292,13 @@ void DaemonPerfCounters::update(MMgrReport *report) DECODE_START(1, p); for (const auto &t_path : session->declared_types) { const auto &t = types.at(t_path); + auto instances_it = instances.find(t_path); + // Always check the instance exists, as we don't prevent yet + // multiple sessions from daemons with the same name, and one + // session clearing stats created by another on open. + if (instances_it == instances.end()) { + instances_it = instances.insert({t_path, t.type}).first; + } uint64_t val = 0; uint64_t avgcount = 0; uint64_t avgcount2 = 0; @@ -302,9 +307,9 @@ void DaemonPerfCounters::update(MMgrReport *report) if (t.type & PERFCOUNTER_LONGRUNAVG) { decode(avgcount, p); decode(avgcount2, p); - instances.at(t_path).push_avg(now, val, avgcount); + instances_it->second.push_avg(now, val, avgcount); } else { - instances.at(t_path).push(now, val); + instances_it->second.push(now, val); } } DECODE_FINISH(p); -- 2.39.5