]> git.proxmox.com Git - ceph.git/blame - ceph/src/mon/mon_types.h
update sources to v12.1.1
[ceph.git] / ceph / src / mon / mon_types.h
CommitLineData
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#ifndef CEPH_MON_TYPES_H
16#define CEPH_MON_TYPES_H
17
31f18b77
FG
18#include <map>
19
7c673cae
FG
20#include "include/utime.h"
21#include "include/util.h"
22#include "common/Formatter.h"
23#include "common/bit_str.h"
24#include "include/Context.h"
7c673cae
FG
25
26#define PAXOS_PGMAP 0 // before osd, for pg kick to behave
27#define PAXOS_MDSMAP 1
28#define PAXOS_OSDMAP 2
29#define PAXOS_LOG 3
30#define PAXOS_MONMAP 4
31#define PAXOS_AUTH 5
32#define PAXOS_MGR 6
31f18b77 33#define PAXOS_MGRSTAT 7
224ce89b
WB
34#define PAXOS_HEALTH 8
35#define PAXOS_NUM 9
7c673cae
FG
36
37inline const char *get_paxos_name(int p) {
38 switch (p) {
39 case PAXOS_MDSMAP: return "mdsmap";
40 case PAXOS_MONMAP: return "monmap";
41 case PAXOS_OSDMAP: return "osdmap";
42 case PAXOS_PGMAP: return "pgmap";
43 case PAXOS_LOG: return "logm";
44 case PAXOS_AUTH: return "auth";
45 case PAXOS_MGR: return "mgr";
31f18b77 46 case PAXOS_MGRSTAT: return "mgrstat";
224ce89b 47 case PAXOS_HEALTH: return "health";
7c673cae
FG
48 default: ceph_abort(); return 0;
49 }
50}
51
52#define CEPH_MON_ONDISK_MAGIC "ceph mon volume v012"
53
31f18b77
FG
54// map of entity_type -> features -> count
55struct FeatureMap {
56 std::map<uint32_t,std::map<uint64_t,uint64_t>> m;
57
58 void add(uint32_t type, uint64_t features) {
59 m[type][features]++;
60 }
61
62 void rm(uint32_t type, uint64_t features) {
63 auto p = m.find(type);
64 assert(p != m.end());
65 auto q = p->second.find(features);
66 assert(q != p->second.end());
67 if (--q->second == 0) {
68 p->second.erase(q);
69 if (p->second.empty()) {
70 m.erase(p);
71 }
72 }
73 }
74
75 FeatureMap& operator+=(const FeatureMap& o) {
76 for (auto& p : o.m) {
77 auto &v = m[p.first];
78 for (auto& q : p.second) {
79 v[q.first] += q.second;
80 }
81 }
82 return *this;
83 }
84
85 void encode(bufferlist& bl) const {
86 ENCODE_START(1, 1, bl);
87 ::encode(m, bl);
88 ENCODE_FINISH(bl);
89 }
90
91 void decode(bufferlist::iterator& p) {
92 DECODE_START(1, p);
93 ::decode(m, p);
94 DECODE_FINISH(p);
95 }
96
97 void dump(Formatter *f) const {
98 for (auto& p : m) {
99 f->open_object_section(ceph_entity_type_name(p.first));
100 for (auto& q : p.second) {
101 f->open_object_section("group");
102 f->dump_unsigned("features", q.first);
103 f->dump_string("release", ceph_release_name(
104 ceph_release_from_features(q.first)));
105 f->dump_unsigned("num", q.second);
106 f->close_section();
107 }
108 f->close_section();
109 }
110 }
111};
112WRITE_CLASS_ENCODER(FeatureMap)
113
7c673cae
FG
114/**
115 * leveldb store stats
116 *
117 * If we ever decide to support multiple backends for the monitor store,
118 * we should then create an abstract class 'MonitorStoreStats' of sorts
119 * and inherit it on LevelDBStoreStats. I'm sure you'll figure something
120 * out.
121 */
122struct LevelDBStoreStats {
123 uint64_t bytes_total;
124 uint64_t bytes_sst;
125 uint64_t bytes_log;
126 uint64_t bytes_misc;
127 utime_t last_update;
128
129 LevelDBStoreStats() :
130 bytes_total(0),
131 bytes_sst(0),
132 bytes_log(0),
133 bytes_misc(0)
134 {}
135
136 void dump(Formatter *f) const {
137 assert(f != NULL);
138 f->dump_int("bytes_total", bytes_total);
139 f->dump_int("bytes_sst", bytes_sst);
140 f->dump_int("bytes_log", bytes_log);
141 f->dump_int("bytes_misc", bytes_misc);
142 f->dump_stream("last_updated") << last_update;
143 }
144
145 void encode(bufferlist &bl) const {
146 ENCODE_START(1, 1, bl);
147 ::encode(bytes_total, bl);
148 ::encode(bytes_sst, bl);
149 ::encode(bytes_log, bl);
150 ::encode(bytes_misc, bl);
151 ::encode(last_update, bl);
152 ENCODE_FINISH(bl);
153 }
154
155 void decode(bufferlist::iterator &p) {
156 DECODE_START(1, p);
157 ::decode(bytes_total, p);
158 ::decode(bytes_sst, p);
159 ::decode(bytes_log, p);
160 ::decode(bytes_misc, p);
161 ::decode(last_update, p);
162 DECODE_FINISH(p);
163 }
164
165 static void generate_test_instances(list<LevelDBStoreStats*>& ls) {
166 ls.push_back(new LevelDBStoreStats);
167 ls.push_back(new LevelDBStoreStats);
168 ls.back()->bytes_total = 1024*1024;
169 ls.back()->bytes_sst = 512*1024;
170 ls.back()->bytes_log = 256*1024;
171 ls.back()->bytes_misc = 256*1024;
172 ls.back()->last_update = utime_t();
173 }
174};
175WRITE_CLASS_ENCODER(LevelDBStoreStats)
176
177// data stats
178
179struct DataStats {
180 ceph_data_stats_t fs_stats;
181 // data dir
182 utime_t last_update;
183 LevelDBStoreStats store_stats;
184
185 void dump(Formatter *f) const {
186 assert(f != NULL);
187 f->dump_int("kb_total", (fs_stats.byte_total/1024));
188 f->dump_int("kb_used", (fs_stats.byte_used/1024));
189 f->dump_int("kb_avail", (fs_stats.byte_avail/1024));
190 f->dump_int("avail_percent", fs_stats.avail_percent);
191 f->dump_stream("last_updated") << last_update;
192 f->open_object_section("store_stats");
193 store_stats.dump(f);
194 f->close_section();
195 }
196
197 void encode(bufferlist &bl) const {
198 ENCODE_START(3, 1, bl);
199 ::encode(fs_stats.byte_total, bl);
200 ::encode(fs_stats.byte_used, bl);
201 ::encode(fs_stats.byte_avail, bl);
202 ::encode(fs_stats.avail_percent, bl);
203 ::encode(last_update, bl);
204 ::encode(store_stats, bl);
205 ENCODE_FINISH(bl);
206 }
207 void decode(bufferlist::iterator &p) {
208 DECODE_START(1, p);
209 // we moved from having fields in kb to fields in byte
210 if (struct_v > 2) {
211 ::decode(fs_stats.byte_total, p);
212 ::decode(fs_stats.byte_used, p);
213 ::decode(fs_stats.byte_avail, p);
214 } else {
215 uint64_t t;
216 ::decode(t, p);
217 fs_stats.byte_total = t*1024;
218 ::decode(t, p);
219 fs_stats.byte_used = t*1024;
220 ::decode(t, p);
221 fs_stats.byte_avail = t*1024;
222 }
223 ::decode(fs_stats.avail_percent, p);
224 ::decode(last_update, p);
225 if (struct_v > 1)
226 ::decode(store_stats, p);
227
228 DECODE_FINISH(p);
229 }
230};
231WRITE_CLASS_ENCODER(DataStats)
232
233struct ScrubResult {
234 map<string,uint32_t> prefix_crc; ///< prefix -> crc
235 map<string,uint64_t> prefix_keys; ///< prefix -> key count
236
237 bool operator!=(const ScrubResult& other) {
238 return prefix_crc != other.prefix_crc || prefix_keys != other.prefix_keys;
239 }
240
241 void encode(bufferlist& bl) const {
242 ENCODE_START(1, 1, bl);
243 ::encode(prefix_crc, bl);
244 ::encode(prefix_keys, bl);
245 ENCODE_FINISH(bl);
246 }
247 void decode(bufferlist::iterator& p) {
248 DECODE_START(1, p);
249 ::decode(prefix_crc, p);
250 ::decode(prefix_keys, p);
251 DECODE_FINISH(p);
252 }
253 void dump(Formatter *f) const {
254 f->open_object_section("crc");
255 for (map<string,uint32_t>::const_iterator p = prefix_crc.begin(); p != prefix_crc.end(); ++p)
256 f->dump_unsigned(p->first.c_str(), p->second);
257 f->close_section();
258 f->open_object_section("keys");
259 for (map<string,uint64_t>::const_iterator p = prefix_keys.begin(); p != prefix_keys.end(); ++p)
260 f->dump_unsigned(p->first.c_str(), p->second);
261 f->close_section();
262 }
263 static void generate_test_instances(list<ScrubResult*>& ls) {
264 ls.push_back(new ScrubResult);
265 ls.push_back(new ScrubResult);
266 ls.back()->prefix_crc["foo"] = 123;
267 ls.back()->prefix_keys["bar"] = 456;
268 }
269};
270WRITE_CLASS_ENCODER(ScrubResult)
271
272static inline ostream& operator<<(ostream& out, const ScrubResult& r) {
273 return out << "ScrubResult(keys " << r.prefix_keys << " crc " << r.prefix_crc << ")";
274}
275
276/// for information like os, kernel, hostname, memory info, cpu model.
277typedef map<string, string> Metadata;
278
7c673cae
FG
279namespace ceph {
280 namespace features {
281 namespace mon {
282 /**
283 * Get a feature's name based on its value.
284 *
285 * @param b raw feature value
286 *
287 * @remarks
288 * Consumers should not assume this interface will never change.
289 * @remarks
290 * As the number of features increase, so may the internal representation
291 * of the raw features. When this happens, this interface will change
292 * accordingly. So should consumers of this interface.
293 */
294 static inline const char *get_feature_name(uint64_t b);
295 }
296 }
297}
298
299
300inline const char *ceph_mon_feature_name(uint64_t b)
301{
302 return ceph::features::mon::get_feature_name(b);
303};
304
305class mon_feature_t {
306
307 static const int HEAD_VERSION = 1;
308 static const int COMPAT_VERSION = 1;
309
310 // mon-specific features
311 uint64_t features;
312
313public:
314
315 explicit constexpr
316 mon_feature_t(const uint64_t f) : features(f) { }
317
318 mon_feature_t() :
319 features(0) { }
320
321 constexpr
322 mon_feature_t(const mon_feature_t &o) :
323 features(o.features) { }
324
325 mon_feature_t& operator&=(const mon_feature_t other) {
326 features &= other.features;
327 return (*this);
328 }
329
330 /**
331 * Obtain raw features
332 *
333 * @remarks
334 * Consumers should not assume this interface will never change.
335 * @remarks
336 * As the number of features increase, so may the internal representation
337 * of the raw features. When this happens, this interface will change
338 * accordingly. So should consumers of this interface.
339 */
340 uint64_t get_raw() const {
341 return features;
342 }
343
344 constexpr
345 friend mon_feature_t operator&(const mon_feature_t a,
346 const mon_feature_t b) {
347 return mon_feature_t(a.features & b.features);
348 }
349
350 mon_feature_t& operator|=(const mon_feature_t other) {
351 features |= other.features;
352 return (*this);
353 }
354
355 constexpr
356 friend mon_feature_t operator|(const mon_feature_t a,
357 const mon_feature_t b) {
358 return mon_feature_t(a.features | b.features);
359 }
360
361 constexpr
362 friend mon_feature_t operator^(const mon_feature_t a,
363 const mon_feature_t b) {
364 return mon_feature_t(a.features ^ b.features);
365 }
366
367 mon_feature_t& operator^=(const mon_feature_t other) {
368 features ^= other.features;
369 return (*this);
370 }
371
372 bool operator==(const mon_feature_t other) const {
373 return (features == other.features);
374 }
375
376 bool operator!=(const mon_feature_t other) const {
377 return (features != other.features);
378 }
379
380 bool empty() const {
381 return features == 0;
382 }
383
384 /**
385 * Set difference of our features in respect to @p other
386 *
387 * Returns all the elements in our features that are not in @p other
388 *
389 * @returns all the features not in @p other
390 */
391 mon_feature_t diff(const mon_feature_t other) const {
392 return mon_feature_t((features ^ other.features) & features);
393 }
394
395 /**
396 * Set intersection of our features and @p other
397 *
398 * Returns all the elements common to both our features and the
399 * features of @p other
400 *
401 * @returns the features common to @p other and us
402 */
403 mon_feature_t intersection(const mon_feature_t other) const {
404 return mon_feature_t((features & other.features));
405 }
406
407 /**
408 * Checks whether we have all the features in @p other
409 *
410 * Returns true if we have all the features in @p other
411 *
412 * @returns true if we contain all the features in @p other
413 * @returns false if we do not contain some of the features in @p other
414 */
415 bool contains_all(const mon_feature_t other) const {
416 mon_feature_t d = intersection(other);
417 return d == other;
418 }
419
420 /**
421 * Checks whether we contain any of the features in @p other.
422 *
423 * @returns true if we contain any of the features in @p other
424 * @returns false if we don't contain any of the features in @p other
425 */
426 bool contains_any(const mon_feature_t other) const {
427 mon_feature_t d = intersection(other);
428 return !d.empty();
429 }
430
431 void set_feature(const mon_feature_t f) {
432 features |= f.features;
433 }
434
435 void unset_feature(const mon_feature_t f) {
436 features &= ~(f.features);
437 }
438
439 void print(ostream& out) const {
440 out << "[";
441 print_bit_str(features, out, ceph::features::mon::get_feature_name);
442 out << "]";
443 }
444
445 void print_with_value(ostream& out) const {
446 out << "[";
447 print_bit_str(features, out, ceph::features::mon::get_feature_name, true);
448 out << "]";
449 }
450
451 void dump(Formatter *f, const char *sec_name = NULL) const {
452 f->open_array_section((sec_name ? sec_name : "features"));
453 dump_bit_str(features, f, ceph::features::mon::get_feature_name);
454 f->close_section();
455 }
456
457 void dump_with_value(Formatter *f, const char *sec_name = NULL) const {
458 f->open_array_section((sec_name ? sec_name : "features"));
459 dump_bit_str(features, f, ceph::features::mon::get_feature_name, true);
460 f->close_section();
461 }
462
463 void encode(bufferlist& bl) const {
464 ENCODE_START(HEAD_VERSION, COMPAT_VERSION, bl);
465 ::encode(features, bl);
466 ENCODE_FINISH(bl);
467 }
468 void decode(bufferlist::iterator& p) {
469 DECODE_START(COMPAT_VERSION, p);
470 ::decode(features, p);
471 DECODE_FINISH(p);
472 }
473};
474WRITE_CLASS_ENCODER(mon_feature_t)
475
476namespace ceph {
477 namespace features {
478 namespace mon {
479 constexpr mon_feature_t FEATURE_KRAKEN( (1ULL << 0));
480 constexpr mon_feature_t FEATURE_LUMINOUS( (1ULL << 1));
481
482 constexpr mon_feature_t FEATURE_RESERVED( (1ULL << 63));
483 constexpr mon_feature_t FEATURE_NONE( (0ULL));
484
485 /**
486 * All the features this monitor supports
487 *
488 * If there's a feature above, it should be OR'ed to this list.
489 */
490 constexpr mon_feature_t get_supported() {
491 return (
492 FEATURE_KRAKEN |
493 FEATURE_LUMINOUS |
494 FEATURE_NONE
495 );
496 }
497 /**
498 * All the features that, once set, cannot be removed.
499 *
500 * Features should only be added to this list if you want to make
501 * sure downgrades are not possible after a quorum supporting all
502 * these features has been formed.
503 *
504 * Any feature in this list will be automatically set on the monmap's
505 * features once all the monitors in the quorum support it.
506 */
507 constexpr mon_feature_t get_persistent() {
508 return (
509 FEATURE_KRAKEN |
510 FEATURE_LUMINOUS |
511 FEATURE_NONE
512 );
513 }
514
515 static inline mon_feature_t get_feature_by_name(std::string n);
516 }
517 }
518}
519
520static inline const char *ceph::features::mon::get_feature_name(uint64_t b) {
521 mon_feature_t f(b);
522
523 if (f == FEATURE_KRAKEN) {
524 return "kraken";
525 } else if (f == FEATURE_LUMINOUS) {
526 return "luminous";
527 } else if (f == FEATURE_RESERVED) {
528 return "reserved";
529 }
530 return "unknown";
531}
532
533static inline
534mon_feature_t ceph::features::mon::get_feature_by_name(std::string n) {
535
536 if (n == "kraken") {
537 return FEATURE_KRAKEN;
538 } else if (n == "luminous") {
539 return FEATURE_LUMINOUS;
540 } else if (n == "reserved") {
541 return FEATURE_RESERVED;
542 }
543 return FEATURE_NONE;
544}
545
546static inline ostream& operator<<(ostream& out, const mon_feature_t& f) {
547 out << "mon_feature_t(";
548 f.print(out);
549 out << ")";
550 return out;
551}
552
553#endif