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(const std::string
&hostname
) const
67 Mutex::Locker
l(lock
);
69 if (by_server
.count(hostname
)) {
70 return by_server
.at(hostname
);
76 bool DaemonStateIndex::exists(const DaemonKey
&key
) const
78 Mutex::Locker
l(lock
);
80 return all
.count(key
) > 0;
83 DaemonStatePtr
DaemonStateIndex::get(const DaemonKey
&key
)
85 Mutex::Locker
l(lock
);
90 void DaemonStateIndex::cull(const std::string
& svc_name
,
91 const std::set
<std::string
>& names_exist
)
93 std::vector
<string
> victims
;
95 Mutex::Locker
l(lock
);
96 auto begin
= all
.lower_bound({svc_name
, ""});
98 for (auto &i
= begin
; i
!= end
; ++i
) {
99 const auto& daemon_key
= i
->first
;
100 if (daemon_key
.first
!= svc_name
)
102 if (names_exist
.count(daemon_key
.second
) == 0) {
103 victims
.push_back(daemon_key
.second
);
107 for (auto &i
: victims
) {
108 dout(4) << "Removing data for " << i
<< dendl
;
109 _erase({svc_name
, i
});
113 void DaemonPerfCounters::update(MMgrReport
*report
)
115 dout(20) << "loading " << report
->declare_types
.size() << " new types, "
116 << report
->undeclare_types
.size() << " old types, had "
117 << types
.size() << " types, got "
118 << report
->packed
.length() << " bytes of data" << dendl
;
120 // Load any newly declared types
121 for (const auto &t
: report
->declare_types
) {
122 types
.insert(std::make_pair(t
.path
, t
));
123 declared_types
.insert(t
.path
);
125 // Remove any old types
126 for (const auto &t
: report
->undeclare_types
) {
127 declared_types
.erase(t
);
130 const auto now
= ceph_clock_now();
132 // Parse packed data according to declared set of types
133 bufferlist::iterator p
= report
->packed
.begin();
135 for (const auto &t_path
: declared_types
) {
136 const auto &t
= types
.at(t_path
);
138 uint64_t avgcount
= 0;
139 uint64_t avgcount2
= 0;
142 if (t
.type
& PERFCOUNTER_LONGRUNAVG
) {
143 ::decode(avgcount
, p
);
144 ::decode(avgcount2
, p
);
146 // TODO: interface for insertion of avgs
147 instances
[t_path
].push(now
, val
);
152 uint64_t PerfCounterInstance::get_current() const
154 return buffer
.front().v
;
157 void PerfCounterInstance::push(utime_t t
, uint64_t const &v
)
159 buffer
.push_back({t
, v
});