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