]> git.proxmox.com Git - ceph.git/blob - ceph/src/mgr/DaemonState.h
update sources to 12.2.7
[ceph.git] / ceph / src / mgr / DaemonState.h
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 #ifndef DAEMON_STATE_H_
15 #define DAEMON_STATE_H_
16
17 #include <map>
18 #include <string>
19 #include <memory>
20 #include <set>
21 #include <boost/circular_buffer.hpp>
22
23 #include "common/RWLock.h"
24
25 #include "msg/msg_types.h"
26
27 // For PerfCounterType
28 #include "messages/MMgrReport.h"
29
30
31 // Unique reference to a daemon within a cluster
32 typedef std::pair<std::string, std::string> DaemonKey;
33
34 // An instance of a performance counter type, within
35 // a particular daemon.
36 class PerfCounterInstance
37 {
38 class DataPoint
39 {
40 public:
41 utime_t t;
42 uint64_t v;
43 DataPoint(utime_t t_, uint64_t v_)
44 : t(t_), v(v_)
45 {}
46 };
47
48 class AvgDataPoint
49 {
50 public:
51 utime_t t;
52 uint64_t s;
53 uint64_t c;
54 AvgDataPoint(utime_t t_, uint64_t s_, uint64_t c_)
55 : t(t_), s(s_), c(c_)
56 {}
57 };
58
59 boost::circular_buffer<DataPoint> buffer;
60 boost::circular_buffer<AvgDataPoint> avg_buffer;
61
62 uint64_t get_current() const;
63
64 public:
65 const boost::circular_buffer<DataPoint> & get_data() const
66 {
67 return buffer;
68 }
69 const boost::circular_buffer<AvgDataPoint> & get_data_avg() const
70 {
71 return avg_buffer;
72 }
73 void push(utime_t t, uint64_t const &v);
74 void push_avg(utime_t t, uint64_t const &s, uint64_t const &c);
75
76 PerfCounterInstance(enum perfcounter_type_d type)
77 {
78 if (type & PERFCOUNTER_LONGRUNAVG)
79 avg_buffer = boost::circular_buffer<AvgDataPoint>(20);
80 else
81 buffer = boost::circular_buffer<DataPoint>(20);
82 };
83 };
84
85
86 typedef std::map<std::string, PerfCounterType> PerfCounterTypes;
87
88 // Performance counters for one daemon
89 class DaemonPerfCounters
90 {
91 public:
92 // The record of perf stat types, shared between daemons
93 PerfCounterTypes &types;
94
95 DaemonPerfCounters(PerfCounterTypes &types_)
96 : types(types_)
97 {}
98
99 std::map<std::string, PerfCounterInstance> instances;
100
101 void update(MMgrReport *report);
102
103 void clear()
104 {
105 instances.clear();
106 }
107 };
108
109 // The state that we store about one daemon
110 class DaemonState
111 {
112 public:
113 Mutex lock = {"DaemonState::lock"};
114
115 DaemonKey key;
116
117 // The hostname where daemon was last seen running (extracted
118 // from the metadata)
119 std::string hostname;
120
121 // The metadata (hostname, version, etc) sent from the daemon
122 std::map<std::string, std::string> metadata;
123
124 // TODO: this can be generalized to other daemons
125 std::vector<OSDHealthMetric> osd_health_metrics;
126
127 // Ephemeral state
128 bool service_daemon = false;
129 utime_t service_status_stamp;
130 std::map<std::string, std::string> service_status;
131 utime_t last_service_beacon;
132
133 // The perf counters received in MMgrReport messages
134 DaemonPerfCounters perf_counters;
135
136 DaemonState(PerfCounterTypes &types_)
137 : perf_counters(types_)
138 {
139 }
140 };
141
142 typedef std::shared_ptr<DaemonState> DaemonStatePtr;
143 typedef std::map<DaemonKey, DaemonStatePtr> DaemonStateCollection;
144
145
146
147
148 /**
149 * Fuse the collection of per-daemon metadata from Ceph into
150 * a view that can be queried by service type, ID or also
151 * by server (aka fqdn).
152 */
153 class DaemonStateIndex
154 {
155 private:
156 mutable RWLock lock = {"DaemonStateIndex", true, true, true};
157
158 std::map<std::string, DaemonStateCollection> by_server;
159 DaemonStateCollection all;
160 std::set<DaemonKey> updating;
161
162 void _erase(const DaemonKey& dmk);
163
164 public:
165 DaemonStateIndex() {}
166
167 // FIXME: shouldn't really be public, maybe construct DaemonState
168 // objects internally to avoid this.
169 PerfCounterTypes types;
170
171 void insert(DaemonStatePtr dm);
172 bool exists(const DaemonKey &key) const;
173 DaemonStatePtr get(const DaemonKey &key);
174
175 // Note that these return by value rather than reference to avoid
176 // callers needing to stay in lock while using result. Callers must
177 // still take the individual DaemonState::lock on each entry though.
178 DaemonStateCollection get_by_server(const std::string &hostname) const;
179 DaemonStateCollection get_by_service(const std::string &svc_name) const;
180 DaemonStateCollection get_all() const {return all;}
181
182 template<typename Callback, typename...Args>
183 auto with_daemons_by_server(Callback&& cb, Args&&... args) const ->
184 decltype(cb(by_server, std::forward<Args>(args)...)) {
185 RWLock::RLocker l(lock);
186
187 return std::forward<Callback>(cb)(by_server, std::forward<Args>(args)...);
188 }
189
190 void notify_updating(const DaemonKey &k) {
191 RWLock::WLocker l(lock);
192 updating.insert(k);
193 }
194 void clear_updating(const DaemonKey &k) {
195 RWLock::WLocker l(lock);
196 updating.erase(k);
197 }
198 bool is_updating(const DaemonKey &k) {
199 RWLock::RLocker l(lock);
200 return updating.count(k) > 0;
201 }
202
203 /**
204 * Remove state for all daemons of this type whose names are
205 * not present in `names_exist`. Use this function when you have
206 * a cluster map and want to ensure that anything absent in the map
207 * is also absent in this class.
208 */
209 void cull(const std::string& svc_name,
210 const std::set<std::string>& names_exist);
211 };
212
213 #endif
214