]> git.proxmox.com Git - ceph.git/blob - ceph/src/mgr/DaemonState.cc
290fde6513453ebccdc2e1df74ecf17447128120
[ceph.git] / ceph / src / mgr / DaemonState.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2016 John Spray <john.spray@redhat.com>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 */
13
14 #include "DaemonState.h"
15
16 #define dout_context g_ceph_context
17 #define dout_subsys ceph_subsys_mgr
18 #undef dout_prefix
19 #define dout_prefix *_dout << "mgr " << __func__ << " "
20
21 void DaemonStateIndex::insert(DaemonStatePtr dm)
22 {
23 Mutex::Locker l(lock);
24
25 if (all.count(dm->key)) {
26 _erase(dm->key);
27 }
28
29 by_server[dm->hostname][dm->key] = dm;
30 all[dm->key] = dm;
31 }
32
33 void DaemonStateIndex::_erase(const DaemonKey& dmk)
34 {
35 assert(lock.is_locked_by_me());
36
37 const auto to_erase = all.find(dmk);
38 assert(to_erase != all.end());
39 const auto dm = to_erase->second;
40 auto &server_collection = by_server[dm->hostname];
41 server_collection.erase(dm->key);
42 if (server_collection.empty()) {
43 by_server.erase(dm->hostname);
44 }
45
46 all.erase(to_erase);
47 }
48
49 DaemonStateCollection DaemonStateIndex::get_by_type(uint8_t type) const
50 {
51 Mutex::Locker l(lock);
52
53 DaemonStateCollection result;
54
55 for (const auto &i : all) {
56 if (i.first.first == type) {
57 result[i.first] = i.second;
58 }
59 }
60
61 return result;
62 }
63
64 DaemonStateCollection DaemonStateIndex::get_by_server(const std::string &hostname) const
65 {
66 Mutex::Locker l(lock);
67
68 if (by_server.count(hostname)) {
69 return by_server.at(hostname);
70 } else {
71 return {};
72 }
73 }
74
75 bool DaemonStateIndex::exists(const DaemonKey &key) const
76 {
77 Mutex::Locker l(lock);
78
79 return all.count(key) > 0;
80 }
81
82 DaemonStatePtr DaemonStateIndex::get(const DaemonKey &key)
83 {
84 Mutex::Locker l(lock);
85
86 return all.at(key);
87 }
88
89 void DaemonStateIndex::cull(entity_type_t daemon_type,
90 const std::set<std::string>& names_exist)
91 {
92 std::vector<string> victims;
93
94 Mutex::Locker l(lock);
95 auto begin = all.lower_bound({daemon_type, ""});
96 auto end = all.end();
97 for (auto &i = begin; i != end; ++i) {
98 const auto& daemon_key = i->first;
99 if (daemon_key.first != daemon_type)
100 break;
101 if (names_exist.count(daemon_key.second) == 0) {
102 victims.push_back(daemon_key.second);
103 }
104 }
105
106 for (auto &i : victims) {
107 dout(4) << "Removing data for " << i << dendl;
108 _erase({daemon_type, i});
109 }
110 }
111
112 void DaemonPerfCounters::update(MMgrReport *report)
113 {
114 dout(20) << "loading " << report->declare_types.size() << " new types, "
115 << report->undeclare_types.size() << " old types, had "
116 << types.size() << " types, got "
117 << report->packed.length() << " bytes of data" << dendl;
118
119 // Load any newly declared types
120 for (const auto &t : report->declare_types) {
121 types.insert(std::make_pair(t.path, t));
122 declared_types.insert(t.path);
123 }
124 // Remove any old types
125 for (const auto &t : report->undeclare_types) {
126 declared_types.erase(t);
127 }
128
129 const auto now = ceph_clock_now();
130
131 // Parse packed data according to declared set of types
132 bufferlist::iterator p = report->packed.begin();
133 DECODE_START(1, p);
134 for (const auto &t_path : declared_types) {
135 const auto &t = types.at(t_path);
136 uint64_t val = 0;
137 uint64_t avgcount = 0;
138 uint64_t avgcount2 = 0;
139
140 ::decode(val, p);
141 if (t.type & PERFCOUNTER_LONGRUNAVG) {
142 ::decode(avgcount, p);
143 ::decode(avgcount2, p);
144 }
145 // TODO: interface for insertion of avgs
146 instances[t_path].push(now, val);
147 }
148 DECODE_FINISH(p);
149 }
150
151 uint64_t PerfCounterInstance::get_current() const
152 {
153 return buffer.front().v;
154 }
155
156 void PerfCounterInstance::push(utime_t t, uint64_t const &v)
157 {
158 buffer.push_back({t, v});
159 }
160