]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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) 2004-2006 Sage Weil <sage@newdream.net> | |
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 | ||
15 | /* | |
16 | * Placement Group Map. Placement Groups are logical sets of objects | |
17 | * that are replicated by the same set of devices. pgid=(r,hash(o)&m) | |
18 | * where & is a bit-wise AND and m=2^k-1 | |
19 | */ | |
20 | ||
21 | #ifndef CEPH_PGMAP_H | |
22 | #define CEPH_PGMAP_H | |
23 | ||
224ce89b | 24 | #include "include/health.h" |
7c673cae FG |
25 | #include "common/debug.h" |
26 | #include "common/TextTable.h" | |
27 | #include "osd/osd_types.h" | |
31f18b77 | 28 | #include "include/mempool.h" |
224ce89b | 29 | #include "mon/health_check.h" |
7c673cae | 30 | #include <sstream> |
31f18b77 | 31 | #include "mon/PGStatService.h" |
7c673cae FG |
32 | |
33 | // FIXME: don't like including this here to get OSDMap::Incremental, maybe | |
34 | // PGMapUpdater needs its own header. | |
35 | #include "osd/OSDMap.h" | |
36 | ||
37 | namespace ceph { class Formatter; } | |
38 | ||
31f18b77 | 39 | class PGMapDigest { |
7c673cae | 40 | public: |
31f18b77 FG |
41 | MEMPOOL_CLASS_HELPERS(); |
42 | virtual ~PGMapDigest() {} | |
43 | ||
44 | mempool::pgmap::vector<uint64_t> osd_last_seq; | |
45 | ||
46 | mutable std::map<int, int64_t> avail_space_by_rule; | |
47 | ||
48 | // aggregate state, populated by PGMap child | |
49 | int64_t num_pg = 0, num_osd = 0; | |
50 | int64_t num_pg_active = 0; | |
51 | int64_t num_pg_unknown = 0; | |
52 | mempool::pgmap::unordered_map<int32_t,pool_stat_t> pg_pool_sum; | |
53 | mempool::pgmap::map<int64_t,int64_t> num_pg_by_pool; | |
54 | pool_stat_t pg_sum; | |
55 | osd_stat_t osd_sum; | |
56 | mempool::pgmap::unordered_map<int32_t,int32_t> num_pg_by_state; | |
57 | struct pg_count { | |
58 | int32_t acting = 0; | |
59 | int32_t up = 0; | |
60 | int32_t primary = 0; | |
61 | void encode(bufferlist& bl) const { | |
62 | ::encode(acting, bl); | |
63 | ::encode(up, bl); | |
64 | ::encode(primary, bl); | |
65 | } | |
66 | void decode(bufferlist::iterator& p) { | |
67 | ::decode(acting, p); | |
68 | ::decode(up, p); | |
69 | ::decode(primary, p); | |
70 | } | |
71 | }; | |
72 | mempool::pgmap::unordered_map<int32_t,pg_count> num_pg_by_osd; | |
73 | ||
74 | // recent deltas, and summation | |
75 | /** | |
76 | * keep track of last deltas for each pool, calculated using | |
77 | * @p pg_pool_sum as baseline. | |
78 | */ | |
79 | mempool::pgmap::unordered_map<uint64_t, mempool::pgmap::list< pair<pool_stat_t, utime_t> > > per_pool_sum_deltas; | |
80 | /** | |
81 | * keep track of per-pool timestamp deltas, according to last update on | |
82 | * each pool. | |
83 | */ | |
84 | mempool::pgmap::unordered_map<uint64_t, utime_t> per_pool_sum_deltas_stamps; | |
85 | /** | |
86 | * keep track of sum deltas, per-pool, taking into account any previous | |
87 | * deltas existing in @p per_pool_sum_deltas. The utime_t as second member | |
88 | * of the pair is the timestamp refering to the last update (i.e., the first | |
89 | * member of the pair) for a given pool. | |
90 | */ | |
91 | mempool::pgmap::unordered_map<uint64_t, pair<pool_stat_t,utime_t> > per_pool_sum_delta; | |
92 | ||
93 | pool_stat_t pg_sum_delta; | |
94 | utime_t stamp_delta; | |
95 | ||
96 | ||
97 | void print_summary(Formatter *f, ostream *out) const; | |
98 | void print_oneline_summary(Formatter *f, ostream *out) const; | |
99 | ||
100 | void recovery_summary(Formatter *f, list<string> *psl, | |
b32b8144 | 101 | const pool_stat_t& pool_sum) const; |
31f18b77 FG |
102 | void overall_recovery_summary(Formatter *f, list<string> *psl) const; |
103 | void pool_recovery_summary(Formatter *f, list<string> *psl, | |
104 | uint64_t poolid) const; | |
105 | void recovery_rate_summary(Formatter *f, ostream *out, | |
106 | const pool_stat_t& delta_sum, | |
107 | utime_t delta_stamp) const; | |
108 | void overall_recovery_rate_summary(Formatter *f, ostream *out) const; | |
109 | void pool_recovery_rate_summary(Formatter *f, ostream *out, | |
110 | uint64_t poolid) const; | |
111 | /** | |
112 | * Obtain a formatted/plain output for client I/O, source from stats for a | |
113 | * given @p delta_sum pool over a given @p delta_stamp period of time. | |
114 | */ | |
115 | void client_io_rate_summary(Formatter *f, ostream *out, | |
116 | const pool_stat_t& delta_sum, | |
117 | utime_t delta_stamp) const; | |
118 | /** | |
119 | * Obtain a formatted/plain output for the overall client I/O, which is | |
120 | * calculated resorting to @p pg_sum_delta and @p stamp_delta. | |
121 | */ | |
122 | void overall_client_io_rate_summary(Formatter *f, ostream *out) const; | |
123 | /** | |
124 | * Obtain a formatted/plain output for client I/O over a given pool | |
125 | * with id @p pool_id. We will then obtain pool-specific data | |
126 | * from @p per_pool_sum_delta. | |
127 | */ | |
128 | void pool_client_io_rate_summary(Formatter *f, ostream *out, | |
129 | uint64_t poolid) const; | |
130 | /** | |
131 | * Obtain a formatted/plain output for cache tier IO, source from stats for a | |
132 | * given @p delta_sum pool over a given @p delta_stamp period of time. | |
133 | */ | |
134 | void cache_io_rate_summary(Formatter *f, ostream *out, | |
135 | const pool_stat_t& delta_sum, | |
136 | utime_t delta_stamp) const; | |
137 | /** | |
138 | * Obtain a formatted/plain output for the overall cache tier IO, which is | |
139 | * calculated resorting to @p pg_sum_delta and @p stamp_delta. | |
140 | */ | |
141 | void overall_cache_io_rate_summary(Formatter *f, ostream *out) const; | |
142 | /** | |
143 | * Obtain a formatted/plain output for cache tier IO over a given pool | |
144 | * with id @p pool_id. We will then obtain pool-specific data | |
145 | * from @p per_pool_sum_delta. | |
146 | */ | |
147 | void pool_cache_io_rate_summary(Formatter *f, ostream *out, | |
148 | uint64_t poolid) const; | |
149 | ||
d2e6a577 FG |
150 | /** |
151 | * Return the number of additional bytes that can be stored in this | |
152 | * pool before the first OSD fills up, accounting for PG overhead. | |
153 | */ | |
154 | int64_t get_pool_free_space(const OSDMap &osd_map, int64_t poolid) const; | |
155 | ||
31f18b77 FG |
156 | virtual void dump_pool_stats_full(const OSDMap &osd_map, stringstream *ss, |
157 | Formatter *f, bool verbose) const; | |
158 | void dump_fs_stats(stringstream *ss, Formatter *f, bool verbose) const; | |
159 | static void dump_object_stat_sum(TextTable &tbl, Formatter *f, | |
160 | const object_stat_sum_t &sum, | |
161 | uint64_t avail, | |
162 | float raw_used_rate, | |
163 | bool verbose, const pg_pool_t *pool); | |
164 | ||
165 | size_t get_num_pg_by_osd(int osd) const { | |
166 | auto p = num_pg_by_osd.find(osd); | |
167 | if (p == num_pg_by_osd.end()) | |
168 | return 0; | |
169 | else | |
170 | return p->second.acting; | |
171 | } | |
172 | int get_num_primary_pg_by_osd(int osd) const { | |
173 | auto p = num_pg_by_osd.find(osd); | |
174 | if (p == num_pg_by_osd.end()) | |
175 | return 0; | |
176 | else | |
177 | return p->second.primary; | |
178 | } | |
179 | ||
d2e6a577 FG |
180 | ceph_statfs get_statfs(OSDMap &osdmap, |
181 | boost::optional<int64_t> data_pool) const; | |
31f18b77 FG |
182 | |
183 | int64_t get_rule_avail(int ruleno) const { | |
184 | auto i = avail_space_by_rule.find(ruleno); | |
185 | if (i != avail_space_by_rule.end()) | |
186 | return avail_space_by_rule[ruleno]; | |
187 | else | |
188 | return 0; | |
189 | } | |
190 | ||
181888fb FG |
191 | // kill me post-mimic or -nautilus |
192 | bool definitely_converted_snapsets() const { | |
193 | // false negative is okay; false positive is not! | |
194 | return | |
195 | num_pg && | |
196 | num_pg_unknown == 0 && | |
197 | pg_sum.stats.sum.num_legacy_snapsets == 0; | |
198 | } | |
199 | ||
31f18b77 FG |
200 | // kill me post-luminous: |
201 | virtual float get_fallback_full_ratio() const { | |
202 | return .95; | |
203 | } | |
204 | ||
205 | uint64_t get_last_osd_stat_seq(int osd) { | |
206 | if (osd < (int)osd_last_seq.size()) | |
207 | return osd_last_seq[osd]; | |
208 | return 0; | |
209 | } | |
210 | ||
211 | void encode(bufferlist& bl, uint64_t features) const; | |
212 | void decode(bufferlist::iterator& p); | |
213 | void dump(Formatter *f) const; | |
214 | static void generate_test_instances(list<PGMapDigest*>& ls); | |
215 | }; | |
216 | WRITE_CLASS_ENCODER(PGMapDigest::pg_count); | |
217 | WRITE_CLASS_ENCODER_FEATURES(PGMapDigest); | |
218 | ||
219 | class PGMap : public PGMapDigest { | |
220 | public: | |
221 | MEMPOOL_CLASS_HELPERS(); | |
222 | ||
7c673cae FG |
223 | // the map |
224 | version_t version; | |
225 | epoch_t last_osdmap_epoch; // last osdmap epoch i applied to the pgmap | |
226 | epoch_t last_pg_scan; // osdmap epoch | |
31f18b77 FG |
227 | mempool::pgmap::unordered_map<int32_t,osd_stat_t> osd_stat; |
228 | mempool::pgmap::unordered_map<pg_t,pg_stat_t> pg_stat; | |
229 | mempool::pgmap::set<int32_t> full_osds; // for pre-luminous only | |
230 | mempool::pgmap::set<int32_t> nearfull_osds; // for pre-luminous only | |
7c673cae FG |
231 | float full_ratio; |
232 | float nearfull_ratio; | |
233 | ||
234 | // mapping of osd to most recently reported osdmap epoch | |
31f18b77 | 235 | mempool::pgmap::unordered_map<int32_t,epoch_t> osd_epochs; |
7c673cae FG |
236 | |
237 | class Incremental { | |
238 | public: | |
31f18b77 | 239 | MEMPOOL_CLASS_HELPERS(); |
7c673cae | 240 | version_t version; |
31f18b77 | 241 | mempool::pgmap::map<pg_t,pg_stat_t> pg_stat_updates; |
7c673cae FG |
242 | epoch_t osdmap_epoch; |
243 | epoch_t pg_scan; // osdmap epoch | |
31f18b77 | 244 | mempool::pgmap::set<pg_t> pg_remove; |
7c673cae FG |
245 | float full_ratio; |
246 | float nearfull_ratio; | |
247 | utime_t stamp; | |
248 | ||
249 | private: | |
31f18b77 FG |
250 | mempool::pgmap::map<int32_t,osd_stat_t> osd_stat_updates; |
251 | mempool::pgmap::set<int32_t> osd_stat_rm; | |
7c673cae | 252 | |
31f18b77 FG |
253 | // mapping of osd to most recently reported osdmap epoch. |
254 | // 1:1 with osd_stat_updates. | |
255 | mempool::pgmap::map<int32_t,epoch_t> osd_epochs; | |
7c673cae FG |
256 | public: |
257 | ||
31f18b77 | 258 | const mempool::pgmap::map<int32_t, osd_stat_t> &get_osd_stat_updates() const { |
7c673cae FG |
259 | return osd_stat_updates; |
260 | } | |
31f18b77 | 261 | const mempool::pgmap::set<int32_t> &get_osd_stat_rm() const { |
7c673cae FG |
262 | return osd_stat_rm; |
263 | } | |
31f18b77 | 264 | const mempool::pgmap::map<int32_t, epoch_t> &get_osd_epochs() const { |
7c673cae FG |
265 | return osd_epochs; |
266 | } | |
267 | ||
31f18b77 FG |
268 | template<typename OsdStat> |
269 | void update_stat(int32_t osd, epoch_t epoch, OsdStat&& stat) { | |
270 | osd_stat_updates[osd] = std::forward<OsdStat>(stat); | |
7c673cae FG |
271 | osd_epochs[osd] = epoch; |
272 | assert(osd_epochs.size() == osd_stat_updates.size()); | |
273 | } | |
31f18b77 | 274 | void stat_osd_out(int32_t osd, epoch_t epoch) { |
7c673cae FG |
275 | // 0 the stats for the osd |
276 | osd_stat_updates[osd] = osd_stat_t(); | |
31f18b77 FG |
277 | // only fill in the epoch if the osd didn't already report htis |
278 | // epoch. that way we zero the stat but still preserve a reported | |
279 | // new epoch... | |
280 | if (!osd_epochs.count(osd)) | |
281 | osd_epochs[osd] = epoch; | |
282 | // ...and maintain our invariant. | |
283 | assert(osd_epochs.size() == osd_stat_updates.size()); | |
7c673cae | 284 | } |
31f18b77 | 285 | void stat_osd_down_up(int32_t osd, epoch_t epoch, const PGMap& pg_map) { |
7c673cae | 286 | // 0 the op_queue_age_hist for this osd |
31f18b77 | 287 | auto p = osd_stat_updates.find(osd); |
7c673cae FG |
288 | if (p != osd_stat_updates.end()) { |
289 | p->second.op_queue_age_hist.clear(); | |
290 | return; | |
291 | } | |
31f18b77 | 292 | auto q = pg_map.osd_stat.find(osd); |
7c673cae FG |
293 | if (q != pg_map.osd_stat.end()) { |
294 | osd_stat_t& t = osd_stat_updates[osd] = q->second; | |
295 | t.op_queue_age_hist.clear(); | |
31f18b77 | 296 | osd_epochs[osd] = epoch; |
7c673cae FG |
297 | } |
298 | } | |
299 | void rm_stat(int32_t osd) { | |
300 | osd_stat_rm.insert(osd); | |
301 | osd_epochs.erase(osd); | |
302 | osd_stat_updates.erase(osd); | |
303 | } | |
304 | void encode(bufferlist &bl, uint64_t features=-1) const; | |
305 | void decode(bufferlist::iterator &bl); | |
306 | void dump(Formatter *f) const; | |
307 | static void generate_test_instances(list<Incremental*>& o); | |
308 | ||
309 | Incremental() : version(0), osdmap_epoch(0), pg_scan(0), | |
310 | full_ratio(0), nearfull_ratio(0) {} | |
311 | }; | |
312 | ||
313 | ||
314 | // aggregate stats (soft state), generated by calc_stats() | |
7c673cae | 315 | mutable epoch_t min_last_epoch_clean = 0; |
31f18b77 FG |
316 | mempool::pgmap::unordered_map<int,set<pg_t> > pg_by_osd; |
317 | mempool::pgmap::unordered_map<int,int> blocked_by_sum; | |
318 | mempool::pgmap::list< pair<pool_stat_t, utime_t> > pg_sum_deltas; | |
7c673cae FG |
319 | |
320 | utime_t stamp; | |
321 | ||
31f18b77 FG |
322 | void update_global_delta( |
323 | CephContext *cct, | |
324 | const utime_t ts, const pool_stat_t& pg_sum_old); | |
325 | void update_pool_deltas( | |
326 | CephContext *cct, | |
327 | const utime_t ts, | |
328 | const mempool::pgmap::unordered_map<uint64_t, pool_stat_t>& pg_pool_sum_old); | |
7c673cae FG |
329 | void clear_delta(); |
330 | ||
331 | void deleted_pool(int64_t pool) { | |
332 | pg_pool_sum.erase(pool); | |
31f18b77 | 333 | num_pg_by_pool.erase(pool); |
7c673cae FG |
334 | per_pool_sum_deltas.erase(pool); |
335 | per_pool_sum_deltas_stamps.erase(pool); | |
336 | per_pool_sum_delta.erase(pool); | |
337 | } | |
338 | ||
339 | private: | |
31f18b77 FG |
340 | void update_delta( |
341 | CephContext *cct, | |
342 | const utime_t ts, | |
343 | const pool_stat_t& old_pool_sum, | |
344 | utime_t *last_ts, | |
345 | const pool_stat_t& current_pool_sum, | |
346 | pool_stat_t *result_pool_delta, | |
347 | utime_t *result_ts_delta, | |
348 | mempool::pgmap::list<pair<pool_stat_t,utime_t> > *delta_avg_list); | |
7c673cae FG |
349 | |
350 | void update_one_pool_delta(CephContext *cct, | |
351 | const utime_t ts, | |
352 | const uint64_t pool, | |
353 | const pool_stat_t& old_pool_sum); | |
354 | ||
355 | epoch_t calc_min_last_epoch_clean() const; | |
356 | ||
7c673cae FG |
357 | public: |
358 | ||
31f18b77 FG |
359 | mempool::pgmap::set<pg_t> creating_pgs; |
360 | mempool::pgmap::map<int,map<epoch_t,set<pg_t> > > creating_pgs_by_osd_epoch; | |
7c673cae FG |
361 | |
362 | // Bits that use to be enum StuckPG | |
363 | static const int STUCK_INACTIVE = (1<<0); | |
364 | static const int STUCK_UNCLEAN = (1<<1); | |
365 | static const int STUCK_UNDERSIZED = (1<<2); | |
366 | static const int STUCK_DEGRADED = (1<<3); | |
367 | static const int STUCK_STALE = (1<<4); | |
368 | ||
369 | PGMap() | |
370 | : version(0), | |
371 | last_osdmap_epoch(0), last_pg_scan(0), | |
372 | full_ratio(0), nearfull_ratio(0) | |
373 | {} | |
374 | ||
375 | void set_full_ratios(float full, float nearfull) { | |
376 | if (full_ratio == full && nearfull_ratio == nearfull) | |
377 | return; | |
378 | full_ratio = full; | |
379 | nearfull_ratio = nearfull; | |
380 | redo_full_sets(); | |
381 | } | |
382 | ||
383 | version_t get_version() const { | |
384 | return version; | |
385 | } | |
386 | void set_version(version_t v) { | |
387 | version = v; | |
388 | } | |
389 | epoch_t get_last_osdmap_epoch() const { | |
390 | return last_osdmap_epoch; | |
391 | } | |
392 | void set_last_osdmap_epoch(epoch_t e) { | |
393 | last_osdmap_epoch = e; | |
394 | } | |
395 | epoch_t get_last_pg_scan() const { | |
396 | return last_pg_scan; | |
397 | } | |
398 | void set_last_pg_scan(epoch_t e) { | |
399 | last_pg_scan = e; | |
400 | } | |
401 | utime_t get_stamp() const { | |
402 | return stamp; | |
403 | } | |
404 | void set_stamp(utime_t s) { | |
405 | stamp = s; | |
406 | } | |
407 | ||
7c673cae | 408 | pool_stat_t get_pg_pool_sum_stat(int64_t pool) const { |
31f18b77 | 409 | auto p = pg_pool_sum.find(pool); |
7c673cae FG |
410 | if (p != pg_pool_sum.end()) |
411 | return p->second; | |
412 | return pool_stat_t(); | |
413 | } | |
414 | ||
7c673cae FG |
415 | |
416 | void update_pg(pg_t pgid, bufferlist& bl); | |
417 | void remove_pg(pg_t pgid); | |
418 | void update_osd(int osd, bufferlist& bl); | |
419 | void remove_osd(int osd); | |
420 | ||
421 | void apply_incremental(CephContext *cct, const Incremental& inc); | |
422 | void redo_full_sets(); | |
423 | void register_nearfull_status(int osd, const osd_stat_t& s); | |
424 | void calc_stats(); | |
425 | void stat_pg_add(const pg_t &pgid, const pg_stat_t &s, | |
426 | bool sameosds=false); | |
427 | void stat_pg_sub(const pg_t &pgid, const pg_stat_t &s, | |
428 | bool sameosds=false); | |
429 | void stat_pg_update(const pg_t pgid, pg_stat_t &prev, bufferlist::iterator& blp); | |
31f18b77 FG |
430 | void stat_osd_add(int osd, const osd_stat_t &s); |
431 | void stat_osd_sub(int osd, const osd_stat_t &s); | |
7c673cae FG |
432 | |
433 | void encode(bufferlist &bl, uint64_t features=-1) const; | |
434 | void decode(bufferlist::iterator &bl); | |
435 | ||
31f18b77 FG |
436 | /// encode subset of our data to a PGMapDigest |
437 | void encode_digest(const OSDMap& osdmap, | |
438 | bufferlist& bl, uint64_t features) const; | |
439 | ||
7c673cae FG |
440 | void dirty_all(Incremental& inc); |
441 | ||
31f18b77 FG |
442 | int64_t get_rule_avail(const OSDMap& osdmap, int ruleno) const; |
443 | void get_rules_avail(const OSDMap& osdmap, | |
444 | std::map<int,int64_t> *avail_map) const; | |
7c673cae | 445 | void dump(Formatter *f) const; |
7c673cae FG |
446 | void dump_basic(Formatter *f) const; |
447 | void dump_pg_stats(Formatter *f, bool brief) const; | |
448 | void dump_pool_stats(Formatter *f) const; | |
449 | void dump_osd_stats(Formatter *f) const; | |
450 | void dump_delta(Formatter *f) const; | |
451 | void dump_filtered_pg_stats(Formatter *f, set<pg_t>& pgs) const; | |
31f18b77 FG |
452 | void dump_pool_stats_full(const OSDMap &osd_map, stringstream *ss, |
453 | Formatter *f, bool verbose) const override { | |
454 | get_rules_avail(osd_map, &avail_space_by_rule); | |
455 | PGMapDigest::dump_pool_stats_full(osd_map, ss, f, verbose); | |
456 | } | |
7c673cae | 457 | |
31f18b77 FG |
458 | void dump_pg_stats_plain( |
459 | ostream& ss, | |
460 | const mempool::pgmap::unordered_map<pg_t, pg_stat_t>& pg_stats, | |
461 | bool brief) const; | |
462 | void get_stuck_stats( | |
463 | int types, const utime_t cutoff, | |
464 | mempool::pgmap::unordered_map<pg_t, pg_stat_t>& stuck_pgs) const; | |
7c673cae FG |
465 | bool get_stuck_counts(const utime_t cutoff, map<string, int>& note) const; |
466 | void dump_stuck(Formatter *f, int types, utime_t cutoff) const; | |
467 | void dump_stuck_plain(ostream& ss, int types, utime_t cutoff) const; | |
468 | int dump_stuck_pg_stats(stringstream &ds, | |
469 | Formatter *f, | |
470 | int threshold, | |
471 | vector<string>& args) const; | |
472 | void dump(ostream& ss) const; | |
473 | void dump_basic(ostream& ss) const; | |
474 | void dump_pg_stats(ostream& ss, bool brief) const; | |
475 | void dump_pg_sum_stats(ostream& ss, bool header) const; | |
476 | void dump_pool_stats(ostream& ss, bool header) const; | |
477 | void dump_osd_stats(ostream& ss) const; | |
478 | void dump_osd_sum_stats(ostream& ss) const; | |
479 | void dump_filtered_pg_stats(ostream& ss, set<pg_t>& pgs) const; | |
480 | ||
481 | void dump_osd_perf_stats(Formatter *f) const; | |
482 | void print_osd_perf_stats(std::ostream *ss) const; | |
483 | ||
484 | void dump_osd_blocked_by_stats(Formatter *f) const; | |
485 | void print_osd_blocked_by_stats(std::ostream *ss) const; | |
486 | ||
487 | void get_filtered_pg_stats(uint32_t state, int64_t poolid, int64_t osdid, | |
488 | bool primary, set<pg_t>& pgs) const; | |
7c673cae FG |
489 | |
490 | epoch_t get_min_last_epoch_clean() const { | |
491 | if (!min_last_epoch_clean) | |
492 | min_last_epoch_clean = calc_min_last_epoch_clean(); | |
493 | return min_last_epoch_clean; | |
494 | } | |
495 | ||
31f18b77 FG |
496 | float get_fallback_full_ratio() const override { |
497 | if (full_ratio > 0) { | |
498 | return full_ratio; | |
499 | } | |
500 | return .95; | |
501 | } | |
502 | ||
503 | void get_health(CephContext *cct, | |
504 | const OSDMap& osdmap, | |
505 | list<pair<health_status_t,string> >& summary, | |
506 | list<pair<health_status_t,string> > *detail) const; | |
507 | ||
224ce89b WB |
508 | void get_health_checks( |
509 | CephContext *cct, | |
510 | const OSDMap& osdmap, | |
511 | health_check_map_t *checks) const; | |
512 | ||
7c673cae FG |
513 | static void generate_test_instances(list<PGMap*>& o); |
514 | }; | |
515 | WRITE_CLASS_ENCODER_FEATURES(PGMap::Incremental) | |
516 | WRITE_CLASS_ENCODER_FEATURES(PGMap) | |
517 | ||
31f18b77 | 518 | inline ostream& operator<<(ostream& out, const PGMapDigest& m) { |
7c673cae FG |
519 | m.print_oneline_summary(NULL, &out); |
520 | return out; | |
521 | } | |
522 | ||
523 | int process_pg_map_command( | |
524 | const string& prefix, | |
525 | const map<string,cmd_vartype>& cmdmap, | |
526 | const PGMap& pg_map, | |
527 | const OSDMap& osdmap, | |
528 | Formatter *f, | |
529 | stringstream *ss, | |
530 | bufferlist *odata); | |
531 | ||
532 | class PGMapUpdater | |
533 | { | |
534 | public: | |
535 | static void check_osd_map( | |
536 | const OSDMap::Incremental &osd_inc, | |
537 | std::set<int> *need_check_down_pg_osds, | |
538 | std::map<int,utime_t> *last_osd_report, | |
539 | PGMap *pg_map, | |
540 | PGMap::Incremental *pending_inc); | |
541 | ||
31f18b77 FG |
542 | static void check_osd_map( |
543 | CephContext *cct, | |
544 | const OSDMap &osdmap, | |
545 | const PGMap& pg_map, | |
546 | PGMap::Incremental *pending_inc); | |
7c673cae FG |
547 | /** |
548 | * check latest osdmap for new pgs to register | |
549 | */ | |
550 | static void register_new_pgs( | |
551 | const OSDMap &osd_map, | |
552 | const PGMap &pg_map, | |
553 | PGMap::Incremental *pending_inc); | |
554 | ||
555 | /** | |
556 | * recalculate creating pg mappings | |
557 | */ | |
558 | static void update_creating_pgs( | |
559 | const OSDMap &osd_map, | |
560 | const PGMap &pg_map, | |
561 | PGMap::Incremental *pending_inc); | |
562 | ||
563 | static void register_pg( | |
564 | const OSDMap &osd_map, | |
565 | pg_t pgid, epoch_t epoch, | |
566 | bool new_pool, | |
567 | const PGMap &pg_map, | |
568 | PGMap::Incremental *pending_inc); | |
569 | ||
570 | // mark pg's state stale if its acting primary osd is down | |
571 | static void check_down_pgs( | |
572 | const OSDMap &osd_map, | |
573 | const PGMap &pg_map, | |
574 | bool check_all, | |
575 | const set<int>& need_check_down_pg_osds, | |
576 | PGMap::Incremental *pending_inc); | |
577 | }; | |
578 | ||
579 | namespace reweight { | |
580 | /* Assign a lower weight to overloaded OSDs. | |
581 | * | |
582 | * The osds that will get a lower weight are those with with a utilization | |
583 | * percentage 'oload' percent greater than the average utilization. | |
584 | */ | |
585 | int by_utilization(const OSDMap &osd_map, | |
586 | const PGMap &pg_map, | |
587 | int oload, | |
588 | double max_changef, | |
589 | int max_osds, | |
590 | bool by_pg, const set<int64_t> *pools, | |
591 | bool no_increasing, | |
592 | mempool::osdmap::map<int32_t, uint32_t>* new_weights, | |
593 | std::stringstream *ss, | |
594 | std::string *out_str, | |
595 | Formatter *f); | |
596 | } | |
597 | ||
31f18b77 FG |
598 | |
599 | class PGMapStatService : virtual public PGStatService { | |
600 | protected: | |
601 | const PGMap& pgmap; | |
602 | public: | |
603 | PGMapStatService(const PGMap& o) | |
604 | : pgmap(o) {} | |
605 | ||
606 | bool is_readable() const override { return true; } | |
607 | ||
d2e6a577 | 608 | const pool_stat_t* get_pool_stat(int64_t poolid) const override { |
31f18b77 FG |
609 | auto i = pgmap.pg_pool_sum.find(poolid); |
610 | if (i != pgmap.pg_pool_sum.end()) { | |
611 | return &i->second; | |
612 | } | |
613 | return nullptr; | |
614 | } | |
615 | ||
616 | const osd_stat_t& get_osd_sum() const override { return pgmap.osd_sum; } | |
617 | ||
618 | const osd_stat_t *get_osd_stat(int osd) const override { | |
619 | auto i = pgmap.osd_stat.find(osd); | |
620 | if (i == pgmap.osd_stat.end()) { | |
621 | return nullptr; | |
622 | } | |
623 | return &i->second; | |
624 | } | |
625 | const mempool::pgmap::unordered_map<int32_t,osd_stat_t>& get_osd_stat() const override { | |
626 | return pgmap.osd_stat; | |
627 | } | |
628 | float get_full_ratio() const override { return pgmap.full_ratio; } | |
629 | float get_nearfull_ratio() const override { return pgmap.nearfull_ratio; } | |
630 | ||
631 | bool have_creating_pgs() const override { | |
632 | return !pgmap.creating_pgs.empty(); | |
633 | } | |
634 | bool is_creating_pg(pg_t pgid) const override { | |
635 | return pgmap.creating_pgs.count(pgid); | |
636 | } | |
637 | ||
638 | epoch_t get_min_last_epoch_clean() const override { | |
639 | return pgmap.get_min_last_epoch_clean(); | |
640 | } | |
641 | ||
642 | bool have_full_osds() const override { return !pgmap.full_osds.empty(); } | |
643 | bool have_nearfull_osds() const override { | |
644 | return !pgmap.nearfull_osds.empty(); | |
645 | } | |
646 | ||
647 | size_t get_num_pg_by_osd(int osd) const override { | |
648 | return pgmap.get_num_pg_by_osd(osd); | |
649 | } | |
d2e6a577 FG |
650 | ceph_statfs get_statfs(OSDMap& osd_map, |
651 | boost::optional<int64_t> data_pool) const override { | |
31f18b77 FG |
652 | ceph_statfs statfs; |
653 | statfs.kb = pgmap.osd_sum.kb; | |
654 | statfs.kb_used = pgmap.osd_sum.kb_used; | |
655 | statfs.kb_avail = pgmap.osd_sum.kb_avail; | |
656 | statfs.num_objects = pgmap.pg_sum.stats.sum.num_objects; | |
657 | return statfs; | |
658 | } | |
659 | void print_summary(Formatter *f, ostream *out) const override { | |
660 | pgmap.print_summary(f, out); | |
661 | } | |
662 | virtual void dump_info(Formatter *f) const override { | |
663 | f->dump_object("pgmap", pgmap); | |
664 | } | |
665 | void dump_fs_stats(stringstream *ss, | |
666 | Formatter *f, | |
667 | bool verbose) const override { | |
668 | pgmap.dump_fs_stats(ss, f, verbose); | |
669 | } | |
670 | void dump_pool_stats(const OSDMap& osdm, stringstream *ss, Formatter *f, | |
671 | bool verbose) const override { | |
672 | pgmap.dump_pool_stats_full(osdm, ss, f, verbose); | |
673 | } | |
674 | ||
675 | int process_pg_command(const string& prefix, | |
676 | const map<string,cmd_vartype>& cmdmap, | |
677 | const OSDMap& osdmap, | |
678 | Formatter *f, | |
679 | stringstream *ss, | |
680 | bufferlist *odata) const override { | |
681 | return process_pg_map_command(prefix, cmdmap, pgmap, osdmap, f, ss, odata); | |
682 | } | |
683 | }; | |
684 | ||
685 | ||
7c673cae | 686 | #endif |