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