]>
git.proxmox.com Git - ceph.git/blob - ceph/src/mon/MgrStatMonitor.cc
df92265d30797404c02534e89d51826704a4ed04
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "MgrStatMonitor.h"
5 #include "mon/OSDMonitor.h"
7 #include "mon/PGMonitor.h"
8 #include "messages/MGetPoolStats.h"
9 #include "messages/MGetPoolStatsReply.h"
10 #include "messages/MMonMgrReport.h"
11 #include "messages/MStatfs.h"
12 #include "messages/MStatfsReply.h"
14 class MgrPGStatService
: public MonPGStatService
{
17 MgrPGStatService(PGMapDigest
& d
) : digest(d
) {}
19 const pool_stat_t
* get_pool_stat(int poolid
) const override
{
20 auto i
= digest
.pg_pool_sum
.find(poolid
);
21 if (i
!= digest
.pg_pool_sum
.end()) {
27 ceph_statfs
get_statfs() const override
{
28 return digest
.get_statfs();
31 void print_summary(Formatter
*f
, ostream
*out
) const override
{
32 digest
.print_summary(f
, out
);
34 void dump_info(Formatter
*f
) const override
{
37 void dump_fs_stats(stringstream
*ss
,
39 bool verbose
) const override
{
40 digest
.dump_fs_stats(ss
, f
, verbose
);
42 void dump_pool_stats(const OSDMap
& osdm
, stringstream
*ss
, Formatter
*f
,
43 bool verbose
) const override
{
44 digest
.dump_pool_stats_full(osdm
, ss
, f
, verbose
);
49 #define dout_subsys ceph_subsys_mon
51 #define dout_prefix _prefix(_dout, mon)
52 static ostream
& _prefix(std::ostream
*_dout
, Monitor
*mon
) {
53 return *_dout
<< "mon." << mon
->name
<< "@" << mon
->rank
54 << "(" << mon
->get_state_name()
58 MgrStatMonitor::MgrStatMonitor(Monitor
*mn
, Paxos
*p
, const string
& service_name
)
59 : PaxosService(mn
, p
, service_name
),
60 pgservice(new MgrPGStatService(digest
))
64 MgrStatMonitor::~MgrStatMonitor() = default;
66 MonPGStatService
*MgrStatMonitor::get_pg_stat_service()
68 return pgservice
.get();
71 void MgrStatMonitor::create_initial()
77 void MgrStatMonitor::update_from_paxos(bool *need_bootstrap
)
79 version
= get_last_committed();
80 dout(10) << " " << version
<< dendl
;
82 get_version(version
, bl
);
87 ::decode(health_summary
, p
);
88 ::decode(health_detail
, p
);
92 void MgrStatMonitor::create_pending()
94 dout(10) << " " << version
<< dendl
;
95 pending_digest
= digest
;
96 pending_health_summary
= health_summary
;
97 pending_health_detail
= health_detail
;
100 void MgrStatMonitor::encode_pending(MonitorDBStore::TransactionRef t
)
103 if (version
< mon
->pgmon()->get_last_committed()) {
104 // fast-forward to pgmon version to ensure clients don't see a
105 // jump back in time for MGetPoolStats and MStatFs.
106 version
= mon
->pgmon()->get_last_committed() + 1;
108 dout(10) << " " << version
<< dendl
;
110 ::encode(pending_digest
, bl
, mon
->get_quorum_con_features());
111 ::encode(pending_health_summary
, bl
);
112 ::encode(pending_health_detail
, bl
);
113 put_version(t
, version
, bl
);
114 put_last_committed(t
, version
);
117 version_t
MgrStatMonitor::get_trim_to()
119 // we don't actually need *any* old states, but keep a few.
126 void MgrStatMonitor::on_active()
130 void MgrStatMonitor::get_health(list
<pair
<health_status_t
,string
> >& summary
,
131 list
<pair
<health_status_t
,string
> > *detail
,
132 CephContext
*cct
) const
134 summary
.insert(summary
.end(), health_summary
.begin(), health_summary
.end());
136 detail
->insert(detail
->end(), health_detail
.begin(), health_detail
.end());
140 void MgrStatMonitor::tick()
144 void MgrStatMonitor::print_summary(Formatter
*f
, std::ostream
*ss
) const
146 pgservice
->print_summary(f
, ss
);
149 bool MgrStatMonitor::preprocess_query(MonOpRequestRef op
)
151 auto m
= static_cast<PaxosServiceMessage
*>(op
->get_req());
152 switch (m
->get_type()) {
153 case CEPH_MSG_STATFS
:
154 return preprocess_statfs(op
);
155 case MSG_MON_MGR_REPORT
:
156 return preprocess_report(op
);
157 case MSG_GETPOOLSTATS
:
158 return preprocess_getpoolstats(op
);
161 derr
<< "Unhandled message type " << m
->get_type() << dendl
;
166 bool MgrStatMonitor::prepare_update(MonOpRequestRef op
)
168 auto m
= static_cast<PaxosServiceMessage
*>(op
->get_req());
169 switch (m
->get_type()) {
170 case MSG_MON_MGR_REPORT
:
171 return prepare_report(op
);
174 derr
<< "Unhandled message type " << m
->get_type() << dendl
;
179 bool MgrStatMonitor::preprocess_report(MonOpRequestRef op
)
184 bool MgrStatMonitor::prepare_report(MonOpRequestRef op
)
186 auto m
= static_cast<MMonMgrReport
*>(op
->get_req());
187 bufferlist bl
= m
->get_data();
189 ::decode(pending_digest
, p
);
190 dout(10) << __func__
<< " " << pending_digest
<< dendl
;
191 pending_health_summary
.swap(m
->health_summary
);
192 pending_health_detail
.swap(m
->health_detail
);
196 bool MgrStatMonitor::preprocess_getpoolstats(MonOpRequestRef op
)
198 op
->mark_pgmon_event(__func__
);
199 auto m
= static_cast<MGetPoolStats
*>(op
->get_req());
200 auto session
= m
->get_session();
203 if (!session
->is_capable("pg", MON_CAP_R
)) {
204 dout(0) << "MGetPoolStats received from entity with insufficient caps "
205 << session
->caps
<< dendl
;
208 if (m
->fsid
!= mon
->monmap
->fsid
) {
209 dout(0) << __func__
<< " on fsid "
210 << m
->fsid
<< " != " << mon
->monmap
->fsid
<< dendl
;
214 if (mon
->pgservice
== get_pg_stat_service()) {
215 ver
= get_last_committed();
217 ver
= mon
->pgmon()->get_last_committed();
219 auto reply
= new MGetPoolStatsReply(m
->fsid
, m
->get_tid(), ver
);
220 for (const auto& pool_name
: m
->pools
) {
221 const auto pool_id
= mon
->osdmon()->osdmap
.lookup_pg_pool_name(pool_name
);
222 if (pool_id
== -ENOENT
)
224 auto pool_stat
= mon
->pgservice
->get_pool_stat(pool_id
);
227 reply
->pool_stats
[pool_name
] = *pool_stat
;
229 mon
->send_reply(op
, reply
);
233 bool MgrStatMonitor::preprocess_statfs(MonOpRequestRef op
)
235 op
->mark_pgmon_event(__func__
);
236 auto statfs
= static_cast<MStatfs
*>(op
->get_req());
237 auto session
= statfs
->get_session();
240 if (!session
->is_capable("pg", MON_CAP_R
)) {
241 dout(0) << "MStatfs received from entity with insufficient privileges "
242 << session
->caps
<< dendl
;
245 if (statfs
->fsid
!= mon
->monmap
->fsid
) {
246 dout(0) << __func__
<< " on fsid " << statfs
->fsid
247 << " != " << mon
->monmap
->fsid
<< dendl
;
250 dout(10) << __func__
<< " " << *statfs
251 << " from " << statfs
->get_orig_source() << dendl
;
253 if (mon
->pgservice
== get_pg_stat_service()) {
254 ver
= get_last_committed();
256 ver
= mon
->pgmon()->get_last_committed();
258 auto reply
= new MStatfsReply(statfs
->fsid
, statfs
->get_tid(), ver
);
259 reply
->h
.st
= mon
->pgservice
->get_statfs();
260 mon
->send_reply(op
, reply
);