1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
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.
22 #include <string_view>
26 #include "include/types.h"
27 #include "include/ceph_features.h"
28 #include "include/health.h"
29 #include "include/CompatSet.h"
30 #include "include/common_fwd.h"
32 #include "common/Clock.h"
33 #include "common/Formatter.h"
34 #include "common/ceph_releases.h"
35 #include "common/config.h"
37 #include "mds/mdstypes.h"
38 #include "mds/cephfs_features.h"
40 #define MDS_FEATURE_INCOMPAT_BASE CompatSet::Feature(1, "base v0.20")
41 #define MDS_FEATURE_INCOMPAT_CLIENTRANGES CompatSet::Feature(2, "client writeable ranges")
42 #define MDS_FEATURE_INCOMPAT_FILELAYOUT CompatSet::Feature(3, "default file layouts on dirs")
43 #define MDS_FEATURE_INCOMPAT_DIRINODE CompatSet::Feature(4, "dir inode in separate object")
44 #define MDS_FEATURE_INCOMPAT_ENCODING CompatSet::Feature(5, "mds uses versioned encoding")
45 #define MDS_FEATURE_INCOMPAT_OMAPDIRFRAG CompatSet::Feature(6, "dirfrag is stored in omap")
46 #define MDS_FEATURE_INCOMPAT_INLINE CompatSet::Feature(7, "mds uses inline data")
47 #define MDS_FEATURE_INCOMPAT_NOANCHOR CompatSet::Feature(8, "no anchor table")
48 #define MDS_FEATURE_INCOMPAT_FILE_LAYOUT_V2 CompatSet::Feature(9, "file layout v2")
49 #define MDS_FEATURE_INCOMPAT_SNAPREALM_V2 CompatSet::Feature(10, "snaprealm v2")
51 #define MDS_FS_NAME_DEFAULT "cephfs"
53 class health_check_map_t
;
57 /* These states are the union of the set of possible states of an MDS daemon,
58 * and the set of possible states of an MDS rank. See
59 * doc/cephfs/mds-states.rst for state descriptions,
60 * doc/cephfs/mds-state-diagram.svg for a visual state diagram, and
61 * doc/cephfs/mds-state-diagram.dot to update mds-state-diagram.svg.
64 // States of an MDS daemon not currently holding a rank
65 // ====================================================
66 STATE_NULL
= CEPH_MDS_STATE_NULL
, // null value for fns returning this type.
67 STATE_BOOT
= CEPH_MDS_STATE_BOOT
, // up, boot announcement. destiny unknown.
68 STATE_STANDBY
= CEPH_MDS_STATE_STANDBY
, // up, idle. waiting for assignment by monitor.
69 STATE_STANDBY_REPLAY
= CEPH_MDS_STATE_STANDBY_REPLAY
, // up, replaying active node, ready to take over.
71 // States of an MDS rank, and of any MDS daemon holding that rank
72 // ==============================================================
73 STATE_STOPPED
= CEPH_MDS_STATE_STOPPED
, // down, once existed, but no subtrees. empty log. may not be held by a daemon.
75 STATE_CREATING
= CEPH_MDS_STATE_CREATING
, // up, creating MDS instance (new journal, idalloc..).
76 STATE_STARTING
= CEPH_MDS_STATE_STARTING
, // up, starting prior stopped MDS instance.
78 STATE_REPLAY
= CEPH_MDS_STATE_REPLAY
, // up, starting prior failed instance. scanning journal.
79 STATE_RESOLVE
= CEPH_MDS_STATE_RESOLVE
, // up, disambiguating distributed operations (import, rename, etc.)
80 STATE_RECONNECT
= CEPH_MDS_STATE_RECONNECT
, // up, reconnect to clients
81 STATE_REJOIN
= CEPH_MDS_STATE_REJOIN
, // up, replayed journal, rejoining distributed cache
82 STATE_CLIENTREPLAY
= CEPH_MDS_STATE_CLIENTREPLAY
, // up, active
83 STATE_ACTIVE
= CEPH_MDS_STATE_ACTIVE
, // up, active
84 STATE_STOPPING
= CEPH_MDS_STATE_STOPPING
, // up, exporting metadata (-> standby or out)
85 STATE_DNE
= CEPH_MDS_STATE_DNE
, // down, rank does not exist
87 // State which a daemon may send to MDSMonitor in its beacon
88 // to indicate that offline repair is required. Daemon must stop
89 // immediately after indicating this state.
90 STATE_DAMAGED
= CEPH_MDS_STATE_DAMAGED
93 * In addition to explicit states, an MDS rank implicitly in state:
94 * - STOPPED if it is not currently associated with an MDS daemon gid but it
95 * is in MDSMap::stopped
96 * - FAILED if it is not currently associated with an MDS daemon gid but it
97 * is in MDSMap::failed
98 * - DNE if it is not currently associated with an MDS daemon gid and it is
99 * missing from both MDSMap::failed and MDSMap::stopped
106 TRANSIENT_UNAVAILABLE
= 1,
107 STUCK_UNAVAILABLE
= 2
112 enum mds_flags
: uint64_t {
116 mds_info_t() = default;
118 bool laggy() const { return !(laggy_since
== utime_t()); }
119 void clear_laggy() { laggy_since
= utime_t(); }
121 bool is_degraded() const {
122 return STATE_REPLAY
<= state
&& state
<= STATE_CLIENTREPLAY
;
125 void freeze() { flags
|= mds_flags::FROZEN
; }
126 void unfreeze() { flags
&= ~mds_flags::FROZEN
; }
127 bool is_frozen() const { return flags
&mds_flags::FROZEN
; }
129 const entity_addrvec_t
& get_addrs() const {
133 void encode(ceph::buffer::list
& bl
, uint64_t features
) const {
134 if ((features
& CEPH_FEATURE_MDSENC
) == 0 ) encode_unversioned(bl
);
135 else encode_versioned(bl
, features
);
137 void decode(ceph::buffer::list::const_iterator
& p
);
138 void dump(ceph::Formatter
*f
) const;
139 void dump(std::ostream
&) const;
141 // The long form name for use in cluster log messages`
142 std::string
human_name() const;
144 static void generate_test_instances(std::list
<mds_info_t
*>& ls
);
146 mds_gid_t global_id
= MDS_GID_NONE
;
148 mds_rank_t rank
= MDS_RANK_NONE
;
150 MDSMap::DaemonState state
= STATE_STANDBY
;
151 version_t state_seq
= 0;
152 entity_addrvec_t addrs
;
154 std::set
<mds_rank_t
> export_targets
;
155 fs_cluster_id_t join_fscid
= FS_CLUSTER_ID_NONE
;
156 uint64_t mds_features
= 0;
160 void encode_versioned(ceph::buffer::list
& bl
, uint64_t features
) const;
161 void encode_unversioned(ceph::buffer::list
& bl
) const;
164 friend class MDSMonitor
;
165 friend class Filesystem
;
168 static CompatSet
get_compat_set_all();
169 static CompatSet
get_compat_set_default();
170 static CompatSet
get_compat_set_base(); // pre v0.20
172 static MDSMap
create_null_mdsmap() {
174 /* Use the largest epoch so it's always bigger than whatever the MDS has. */
175 null_map
.epoch
= std::numeric_limits
<decltype(epoch
)>::max();
179 bool get_inline_data_enabled() const { return inline_data_enabled
; }
180 void set_inline_data_enabled(bool enabled
) { inline_data_enabled
= enabled
; }
182 utime_t
get_session_timeout() const {
183 return utime_t(session_timeout
,0);
185 void set_session_timeout(uint32_t t
) {
189 utime_t
get_session_autoclose() const {
190 return utime_t(session_autoclose
, 0);
192 void set_session_autoclose(uint32_t t
) {
193 session_autoclose
= t
;
196 uint64_t get_max_filesize() const { return max_file_size
; }
197 void set_max_filesize(uint64_t m
) { max_file_size
= m
; }
199 void set_min_compat_client(ceph_release_t version
);
201 void add_required_client_feature(size_t bit
) {
202 required_client_features
.insert(bit
);
204 void remove_required_client_feature(size_t bit
) {
205 required_client_features
.erase(bit
);
207 const auto& get_required_client_features() const {
208 return required_client_features
;
211 int get_flags() const { return flags
; }
212 bool test_flag(int f
) const { return flags
& f
; }
213 void set_flag(int f
) { flags
|= f
; }
214 void clear_flag(int f
) { flags
&= ~f
; }
216 std::string_view
get_fs_name() const {return fs_name
;}
218 void set_snaps_allowed() {
219 set_flag(CEPH_MDSMAP_ALLOW_SNAPS
);
220 ever_allowed_features
|= CEPH_MDSMAP_ALLOW_SNAPS
;
221 explicitly_allowed_features
|= CEPH_MDSMAP_ALLOW_SNAPS
;
223 void clear_snaps_allowed() { clear_flag(CEPH_MDSMAP_ALLOW_SNAPS
); }
224 bool allows_snaps() const { return test_flag(CEPH_MDSMAP_ALLOW_SNAPS
); }
225 bool was_snaps_ever_allowed() const { return ever_allowed_features
& CEPH_MDSMAP_ALLOW_SNAPS
; }
227 void set_standby_replay_allowed() {
228 set_flag(CEPH_MDSMAP_ALLOW_STANDBY_REPLAY
);
229 ever_allowed_features
|= CEPH_MDSMAP_ALLOW_STANDBY_REPLAY
;
230 explicitly_allowed_features
|= CEPH_MDSMAP_ALLOW_STANDBY_REPLAY
;
232 void clear_standby_replay_allowed() { clear_flag(CEPH_MDSMAP_ALLOW_STANDBY_REPLAY
); }
233 bool allows_standby_replay() const { return test_flag(CEPH_MDSMAP_ALLOW_STANDBY_REPLAY
); }
234 bool was_standby_replay_ever_allowed() const { return ever_allowed_features
& CEPH_MDSMAP_ALLOW_STANDBY_REPLAY
; }
236 void set_multimds_snaps_allowed() {
237 set_flag(CEPH_MDSMAP_ALLOW_MULTIMDS_SNAPS
);
238 ever_allowed_features
|= CEPH_MDSMAP_ALLOW_MULTIMDS_SNAPS
;
239 explicitly_allowed_features
|= CEPH_MDSMAP_ALLOW_MULTIMDS_SNAPS
;
241 void clear_multimds_snaps_allowed() { clear_flag(CEPH_MDSMAP_ALLOW_MULTIMDS_SNAPS
); }
242 bool allows_multimds_snaps() const { return test_flag(CEPH_MDSMAP_ALLOW_MULTIMDS_SNAPS
); }
244 epoch_t
get_epoch() const { return epoch
; }
245 void inc_epoch() { epoch
++; }
247 bool get_enabled() const { return enabled
; }
249 const utime_t
& get_created() const { return created
; }
250 void set_created(utime_t ct
) { modified
= created
= ct
; }
251 const utime_t
& get_modified() const { return modified
; }
252 void set_modified(utime_t mt
) { modified
= mt
; }
254 epoch_t
get_last_failure() const { return last_failure
; }
255 epoch_t
get_last_failure_osd_epoch() const { return last_failure_osd_epoch
; }
257 mds_rank_t
get_max_mds() const { return max_mds
; }
258 void set_max_mds(mds_rank_t m
) { max_mds
= m
; }
259 void set_old_max_mds() { old_max_mds
= max_mds
; }
260 mds_rank_t
get_old_max_mds() const { return old_max_mds
; }
262 mds_rank_t
get_standby_count_wanted(mds_rank_t standby_daemon_count
) const {
263 ceph_assert(standby_daemon_count
>= 0);
264 std::set
<mds_rank_t
> s
;
265 get_standby_replay_mds_set(s
);
266 mds_rank_t standbys_avail
= (mds_rank_t
)s
.size()+standby_daemon_count
;
267 mds_rank_t wanted
= std::max(0, standby_count_wanted
);
268 return wanted
> standbys_avail
? wanted
- standbys_avail
: 0;
270 void set_standby_count_wanted(mds_rank_t n
) { standby_count_wanted
= n
; }
271 bool check_health(mds_rank_t standby_daemon_count
);
273 const std::string
get_balancer() const { return balancer
; }
274 void set_balancer(std::string val
) { balancer
.assign(val
); }
276 mds_rank_t
get_tableserver() const { return tableserver
; }
277 mds_rank_t
get_root() const { return root
; }
279 const std::vector
<int64_t> &get_data_pools() const { return data_pools
; }
280 int64_t get_first_data_pool() const { return *data_pools
.begin(); }
281 int64_t get_metadata_pool() const { return metadata_pool
; }
282 bool is_data_pool(int64_t poolid
) const {
283 auto p
= std::find(data_pools
.begin(), data_pools
.end(), poolid
);
284 if (p
== data_pools
.end())
289 bool pool_in_use(int64_t poolid
) const {
290 return get_enabled() && (is_data_pool(poolid
) || metadata_pool
== poolid
);
293 const auto& get_mds_info() const { return mds_info
; }
294 const auto& get_mds_info_gid(mds_gid_t gid
) const {
295 return mds_info
.at(gid
);
297 const mds_info_t
& get_mds_info(mds_rank_t m
) const {
298 ceph_assert(up
.count(m
) && mds_info
.count(up
.at(m
)));
299 return mds_info
.at(up
.at(m
));
301 mds_gid_t
find_mds_gid_by_name(std::string_view s
) const;
304 unsigned get_num_in_mds() const {
307 unsigned get_num_up_mds() const {
310 mds_rank_t
get_last_in_mds() const {
311 auto p
= in
.rbegin();
312 return p
== in
.rend() ? MDS_RANK_NONE
: *p
;
314 int get_num_failed_mds() const {
315 return failed
.size();
317 unsigned get_num_standby_replay_mds() const {
319 for (auto& i
: mds_info
) {
320 if (i
.second
.state
== MDSMap::STATE_STANDBY_REPLAY
) {
326 unsigned get_num_mds(int state
) const;
328 void add_data_pool(int64_t poolid
) {
329 data_pools
.push_back(poolid
);
331 int remove_data_pool(int64_t poolid
) {
332 std::vector
<int64_t>::iterator p
= std::find(data_pools
.begin(), data_pools
.end(), poolid
);
333 if (p
== data_pools
.end())
334 return -CEPHFS_ENOENT
;
340 void get_mds_set(std::set
<mds_rank_t
>& s
) const {
343 void get_up_mds_set(std::set
<mds_rank_t
>& s
) const;
344 void get_active_mds_set(std::set
<mds_rank_t
>& s
) const {
345 get_mds_set(s
, MDSMap::STATE_ACTIVE
);
347 void get_standby_replay_mds_set(std::set
<mds_rank_t
>& s
) const {
348 get_mds_set(s
, MDSMap::STATE_STANDBY_REPLAY
);
350 void get_failed_mds_set(std::set
<mds_rank_t
>& s
) const {
353 void get_damaged_mds_set(std::set
<mds_rank_t
>& s
) const {
358 uint64_t get_up_features();
361 * Get MDS ranks which are in but not up.
363 void get_down_mds_set(std::set
<mds_rank_t
> *s
) const
365 ceph_assert(s
!= NULL
);
366 s
->insert(failed
.begin(), failed
.end());
367 s
->insert(damaged
.begin(), damaged
.end());
370 int get_failed() const {
371 if (!failed
.empty()) return *failed
.begin();
374 void get_stopped_mds_set(std::set
<mds_rank_t
>& s
) const {
377 void get_recovery_mds_set(std::set
<mds_rank_t
>& s
) const;
379 void get_mds_set_lower_bound(std::set
<mds_rank_t
>& s
, DaemonState first
) const;
380 void get_mds_set(std::set
<mds_rank_t
>& s
, DaemonState state
) const;
382 void get_health(std::list
<std::pair
<health_status_t
,std::string
> >& summary
,
383 std::list
<std::pair
<health_status_t
,std::string
> > *detail
) const;
385 void get_health_checks(health_check_map_t
*checks
) const;
388 * Return indication of whether cluster is available. This is a
389 * heuristic for clients to see if they should bother waiting to talk to
390 * MDSs, or whether they should error out at startup/mount.
392 * A TRANSIENT_UNAVAILABLE result indicates that the cluster is in a
393 * transition state like replaying, or is potentially about the fail over.
394 * Clients should wait for an updated map before making a final decision
395 * about whether the filesystem is mountable.
397 * A STUCK_UNAVAILABLE result indicates that we can't see a way that
398 * the cluster is about to recover on its own, so it'll probably require
399 * administrator intervention: clients should probably not bother trying
402 availability_t
is_cluster_available() const;
405 * Return whether this MDSMap is suitable for resizing based on the state
408 bool is_resizeable() const {
409 return !is_degraded() &&
410 get_num_mds(CEPH_MDS_STATE_CREATING
) == 0 &&
411 get_num_mds(CEPH_MDS_STATE_STARTING
) == 0 &&
412 get_num_mds(CEPH_MDS_STATE_STOPPING
) == 0;
416 bool is_down(mds_rank_t m
) const { return up
.count(m
) == 0; }
417 bool is_up(mds_rank_t m
) const { return up
.count(m
); }
418 bool is_in(mds_rank_t m
) const { return up
.count(m
) || failed
.count(m
); }
419 bool is_out(mds_rank_t m
) const { return !is_in(m
); }
421 bool is_failed(mds_rank_t m
) const { return failed
.count(m
); }
422 bool is_stopped(mds_rank_t m
) const { return stopped
.count(m
); }
424 bool is_dne(mds_rank_t m
) const { return in
.count(m
) == 0; }
425 bool is_dne_gid(mds_gid_t gid
) const { return mds_info
.count(gid
) == 0; }
428 * Get MDS daemon status by GID
430 auto get_state_gid(mds_gid_t gid
) const {
431 auto it
= mds_info
.find(gid
);
432 if (it
== mds_info
.end())
434 return it
->second
.state
;
438 * Get MDS rank state if the rank is up, else STATE_NULL
440 auto get_state(mds_rank_t m
) const {
441 auto it
= up
.find(m
);
444 return get_state_gid(it
->second
);
447 const auto& get_info(mds_rank_t m
) const {
448 return mds_info
.at(up
.at(m
));
450 const auto& get_info_gid(mds_gid_t gid
) const {
451 return mds_info
.at(gid
);
454 bool is_boot(mds_rank_t m
) const { return get_state(m
) == STATE_BOOT
; }
455 bool is_creating(mds_rank_t m
) const { return get_state(m
) == STATE_CREATING
; }
456 bool is_starting(mds_rank_t m
) const { return get_state(m
) == STATE_STARTING
; }
457 bool is_replay(mds_rank_t m
) const { return get_state(m
) == STATE_REPLAY
; }
458 bool is_resolve(mds_rank_t m
) const { return get_state(m
) == STATE_RESOLVE
; }
459 bool is_reconnect(mds_rank_t m
) const { return get_state(m
) == STATE_RECONNECT
; }
460 bool is_rejoin(mds_rank_t m
) const { return get_state(m
) == STATE_REJOIN
; }
461 bool is_clientreplay(mds_rank_t m
) const { return get_state(m
) == STATE_CLIENTREPLAY
; }
462 bool is_active(mds_rank_t m
) const { return get_state(m
) == STATE_ACTIVE
; }
463 bool is_stopping(mds_rank_t m
) const { return get_state(m
) == STATE_STOPPING
; }
464 bool is_active_or_stopping(mds_rank_t m
) const {
465 return is_active(m
) || is_stopping(m
);
467 bool is_clientreplay_or_active_or_stopping(mds_rank_t m
) const {
468 return is_clientreplay(m
) || is_active(m
) || is_stopping(m
);
471 mds_gid_t
get_standby_replay(mds_rank_t r
) const;
472 bool has_standby_replay(mds_rank_t r
) const {
473 return get_standby_replay(r
) != MDS_GID_NONE
;
476 bool is_followable(mds_rank_t r
) const {
477 if (auto it1
= up
.find(r
); it1
!= up
.end()) {
478 if (auto it2
= mds_info
.find(it1
->second
); it2
!= mds_info
.end()) {
479 auto& info
= it2
->second
;
480 if (!info
.is_degraded() && !has_standby_replay(r
)) {
488 bool is_laggy_gid(mds_gid_t gid
) const {
489 auto it
= mds_info
.find(gid
);
490 return it
== mds_info
.end() ? false : it
->second
.laggy();
493 // degraded = some recovery in process. fixes active membership and
495 bool is_degraded() const;
496 bool is_any_failed() const {
497 return !failed
.empty();
499 bool is_any_damaged() const {
500 return !damaged
.empty();
502 bool is_resolving() const {
504 get_num_mds(STATE_RESOLVE
) > 0 &&
505 get_num_mds(STATE_REPLAY
) == 0 &&
506 failed
.empty() && damaged
.empty();
508 bool is_rejoining() const {
509 // nodes are rejoining cache state
511 get_num_mds(STATE_REJOIN
) > 0 &&
512 get_num_mds(STATE_REPLAY
) == 0 &&
513 get_num_mds(STATE_RECONNECT
) == 0 &&
514 get_num_mds(STATE_RESOLVE
) == 0 &&
515 failed
.empty() && damaged
.empty();
517 bool is_stopped() const {
522 * Get whether a rank is 'up', i.e. has
523 * an MDS daemon's entity_inst_t associated
526 bool have_inst(mds_rank_t m
) const {
531 * Get the MDS daemon entity_inst_t for a rank
534 entity_addrvec_t
get_addrs(mds_rank_t m
) const {
535 return mds_info
.at(up
.at(m
)).get_addrs();
538 mds_rank_t
get_rank_gid(mds_gid_t gid
) const {
539 if (mds_info
.count(gid
)) {
540 return mds_info
.at(gid
).rank
;
542 return MDS_RANK_NONE
;
547 * Get MDS rank incarnation if the rank is up, else -1
549 mds_gid_t
get_incarnation(mds_rank_t m
) const {
550 std::map
<mds_rank_t
, mds_gid_t
>::const_iterator u
= up
.find(m
);
553 return (mds_gid_t
)get_inc_gid(u
->second
);
556 int get_inc_gid(mds_gid_t gid
) const {
557 auto mds_info_entry
= mds_info
.find(gid
);
558 if (mds_info_entry
!= mds_info
.end())
559 return mds_info_entry
->second
.inc
;
562 void encode(ceph::buffer::list
& bl
, uint64_t features
) const;
563 void decode(ceph::buffer::list::const_iterator
& p
);
564 void decode(const ceph::buffer::list
& bl
) {
565 auto p
= bl
.cbegin();
568 void sanitize(const std::function
<bool(int64_t pool
)>& pool_exists
);
570 void print(std::ostream
& out
) const;
571 void print_summary(ceph::Formatter
*f
, std::ostream
*out
) const;
573 void dump(ceph::Formatter
*f
) const;
574 static void generate_test_instances(std::list
<MDSMap
*>& ls
);
576 static bool state_transition_valid(DaemonState prev
, DaemonState next
);
582 bool enabled
= false;
583 std::string fs_name
= MDS_FS_NAME_DEFAULT
;
584 uint32_t flags
= CEPH_MDSMAP_DEFAULTS
; // flags
585 epoch_t last_failure
= 0; // mds epoch of last failure
586 epoch_t last_failure_osd_epoch
= 0; // osd epoch of last failure; any mds entering replay needs
587 // at least this osdmap to ensure the blocklist propagates.
591 mds_rank_t tableserver
= 0; // which MDS has snaptable
592 mds_rank_t root
= 0; // which MDS has root directory
594 __u32 session_timeout
= 60;
595 __u32 session_autoclose
= 300;
596 uint64_t max_file_size
= 1ULL<<40; /* 1TB */
598 feature_bitset_t required_client_features
;
600 std::vector
<int64_t> data_pools
; // file data pools available to clients (via an ioctl). first is the default.
601 int64_t cas_pool
= -1; // where CAS objects go
602 int64_t metadata_pool
= -1; // where fs metadata objects go
605 * in: the set of logical mds #'s that define the cluster. this is the set
606 * of mds's the metadata may be distributed over.
607 * up: map from logical mds #'s to the addrs filling those roles.
608 * failed: subset of @in that are failed.
609 * stopped: set of nodes that have been initialized, but are not active.
611 * @up + @failed = @in. @in * @stopped = {}.
614 mds_rank_t max_mds
= 1; /* The maximum number of active MDSes. Also, the maximum rank. */
615 mds_rank_t old_max_mds
= 0; /* Value to restore when MDS cluster is marked up */
616 mds_rank_t standby_count_wanted
= -1;
617 std::string balancer
; /* The name/version of the mantle balancer (i.e. the rados obj name) */
619 std::set
<mds_rank_t
> in
; // currently defined cluster
621 // which ranks are failed, stopped, damaged (i.e. not held by a daemon)
622 std::set
<mds_rank_t
> failed
, stopped
, damaged
;
623 std::map
<mds_rank_t
, mds_gid_t
> up
; // who is in those roles
624 std::map
<mds_gid_t
, mds_info_t
> mds_info
;
626 uint8_t ever_allowed_features
= 0; //< bitmap of features the cluster has allowed
627 uint8_t explicitly_allowed_features
= 0; //< bitmap of features explicitly enabled
629 bool inline_data_enabled
= false;
631 uint64_t cached_up_features
= 0;
634 WRITE_CLASS_ENCODER_FEATURES(MDSMap::mds_info_t
)
635 WRITE_CLASS_ENCODER_FEATURES(MDSMap
)
637 inline std::ostream
& operator<<(std::ostream
&out
, const MDSMap
&m
) {
638 m
.print_summary(NULL
, &out
);
642 inline std::ostream
& operator<<(std::ostream
& o
, const MDSMap::mds_info_t
& info
) {