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