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