]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr: fix crash due to multiple sessions from daemons with same name 25864/head
authorMykola Golub <mgolub@suse.com>
Thu, 13 Dec 2018 11:12:14 +0000 (13:12 +0200)
committerAshish Singh <assingh@redhat.com>
Wed, 9 Jan 2019 12:25:48 +0000 (17:55 +0530)
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 <mgolub@suse.com>
(cherry picked from commit 5b6037aeb43aff90111fdae08807ddda290bc570)

src/mgr/DaemonState.cc

index aeb80060c34c625c734348cca190dc02afc34259..1f41f2ad49457d5c0376773935b96144e1196349 100644 (file)
@@ -141,8 +141,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<std::string, PerfCounterInstance>(
-                     t.path, PerfCounterInstance(t.type)));
   }
   // Remove any old types
   for (const auto &t : report->undeclare_types) {
@@ -156,6 +154,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;
@@ -164,9 +169,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);