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