1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2016 John Spray <john.spray@redhat.com>
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.
14 #include "DaemonState.h"
16 #define dout_context g_ceph_context
17 #define dout_subsys ceph_subsys_mgr
19 #define dout_prefix *_dout << "mgr " << __func__ << " "
21 void DaemonStateIndex::insert(DaemonStatePtr dm
)
23 Mutex::Locker
l(lock
);
25 if (all
.count(dm
->key
)) {
29 by_server
[dm
->hostname
][dm
->key
] = dm
;
33 void DaemonStateIndex::_erase(const DaemonKey
& dmk
)
35 assert(lock
.is_locked_by_me());
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
);
49 DaemonStateCollection
DaemonStateIndex::get_by_service(
50 const std::string
& svc
) const
52 Mutex::Locker
l(lock
);
54 DaemonStateCollection result
;
56 for (const auto &i
: all
) {
57 if (i
.first
.first
== svc
) {
58 result
[i
.first
] = i
.second
;
65 DaemonStateCollection
DaemonStateIndex::get_by_server(
66 const std::string
&hostname
) const
68 Mutex::Locker
l(lock
);
70 if (by_server
.count(hostname
)) {
71 return by_server
.at(hostname
);
77 bool DaemonStateIndex::exists(const DaemonKey
&key
) const
79 Mutex::Locker
l(lock
);
81 return all
.count(key
) > 0;
84 DaemonStatePtr
DaemonStateIndex::get(const DaemonKey
&key
)
86 Mutex::Locker
l(lock
);
91 void DaemonStateIndex::cull(const std::string
& svc_name
,
92 const std::set
<std::string
>& names_exist
)
94 std::vector
<string
> victims
;
96 Mutex::Locker
l(lock
);
97 auto begin
= all
.lower_bound({svc_name
, ""});
99 for (auto &i
= begin
; i
!= end
; ++i
) {
100 const auto& daemon_key
= i
->first
;
101 if (daemon_key
.first
!= svc_name
)
103 if (names_exist
.count(daemon_key
.second
) == 0) {
104 victims
.push_back(daemon_key
.second
);
108 for (auto &i
: victims
) {
109 dout(4) << "Removing data for " << i
<< dendl
;
110 _erase({svc_name
, i
});
114 void DaemonPerfCounters::update(MMgrReport
*report
)
116 dout(20) << "loading " << report
->declare_types
.size() << " new types, "
117 << report
->undeclare_types
.size() << " old types, had "
118 << types
.size() << " types, got "
119 << report
->packed
.length() << " bytes of data" << dendl
;
121 // Load any newly declared types
122 for (const auto &t
: report
->declare_types
) {
123 types
.insert(std::make_pair(t
.path
, t
));
124 declared_types
.insert(t
.path
);
126 // Remove any old types
127 for (const auto &t
: report
->undeclare_types
) {
128 declared_types
.erase(t
);
131 const auto now
= ceph_clock_now();
133 // Parse packed data according to declared set of types
134 bufferlist::iterator p
= report
->packed
.begin();
136 for (const auto &t_path
: declared_types
) {
137 const auto &t
= types
.at(t_path
);
139 uint64_t avgcount
= 0;
140 uint64_t avgcount2
= 0;
143 if (t
.type
& PERFCOUNTER_LONGRUNAVG
) {
144 ::decode(avgcount
, p
);
145 ::decode(avgcount2
, p
);
147 // TODO: interface for insertion of avgs
148 instances
[t_path
].push(now
, val
);
153 uint64_t PerfCounterInstance::get_current() const
155 return buffer
.front().v
;
158 void PerfCounterInstance::push(utime_t t
, uint64_t const &v
)
160 buffer
.push_back({t
, v
});