]>
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 | ||
16 | #ifndef CEPH_FSMAP_H | |
17 | #define CEPH_FSMAP_H | |
18 | ||
94b18763 | 19 | #include <map> |
11fdf7f2 | 20 | #include <memory> |
94b18763 FG |
21 | #include <set> |
22 | #include <string> | |
11fdf7f2 | 23 | #include <string_view> |
94b18763 | 24 | |
7c673cae FG |
25 | #include <errno.h> |
26 | ||
27 | #include "include/types.h" | |
28 | #include "common/Clock.h" | |
7c673cae FG |
29 | #include "mds/MDSMap.h" |
30 | ||
7c673cae FG |
31 | #include "include/CompatSet.h" |
32 | #include "include/ceph_features.h" | |
9f95a23c | 33 | #include "include/common_fwd.h" |
7c673cae FG |
34 | #include "common/Formatter.h" |
35 | #include "mds/mdstypes.h" | |
36 | ||
224ce89b | 37 | class health_check_map_t; |
7c673cae | 38 | |
f67539c2 TL |
39 | struct ClusterInfo { |
40 | ClusterInfo() = default; | |
41 | ClusterInfo(std::string_view client_name, std::string_view cluster_name, | |
42 | std::string_view fs_name) | |
43 | : client_name(client_name), | |
44 | cluster_name(cluster_name), | |
45 | fs_name(fs_name) { | |
46 | } | |
47 | ||
48 | std::string client_name; | |
49 | std::string cluster_name; | |
50 | std::string fs_name; | |
51 | ||
52 | bool operator==(const ClusterInfo &cluster_info) const { | |
53 | return client_name == cluster_info.client_name && | |
54 | cluster_name == cluster_info.cluster_name && | |
55 | fs_name == cluster_info.fs_name; | |
56 | } | |
57 | ||
58 | void dump(ceph::Formatter *f) const; | |
59 | void print(std::ostream& out) const; | |
60 | ||
61 | void encode(ceph::buffer::list &bl) const; | |
62 | void decode(ceph::buffer::list::const_iterator &iter); | |
63 | }; | |
64 | ||
65 | inline std::ostream& operator<<(std::ostream& out, const ClusterInfo &cluster_info) { | |
66 | out << "{client_name=" << cluster_info.client_name << ", cluster_name=" | |
67 | << cluster_info.cluster_name << ", fs_name=" << cluster_info.fs_name << "}"; | |
68 | return out; | |
69 | } | |
70 | ||
71 | struct Peer { | |
72 | Peer() = default; | |
73 | Peer(std::string_view uuid) | |
74 | : uuid(uuid) { | |
75 | } | |
76 | Peer(std::string_view uuid, | |
77 | const ClusterInfo &remote) | |
78 | : uuid(uuid), | |
79 | remote(remote) { | |
80 | } | |
81 | ||
82 | std::string uuid; | |
83 | ClusterInfo remote; | |
84 | ||
85 | bool operator==(const Peer &rhs) const { | |
86 | return uuid == rhs.uuid; | |
87 | } | |
88 | ||
89 | bool operator<(const Peer &rhs) const { | |
90 | return uuid < rhs.uuid; | |
91 | } | |
92 | ||
93 | void dump(ceph::Formatter *f) const; | |
94 | void print(std::ostream& out) const; | |
95 | ||
96 | void encode(ceph::buffer::list &bl) const; | |
97 | void decode(ceph::buffer::list::const_iterator &iter); | |
98 | }; | |
99 | ||
100 | typedef std::set<Peer> Peers; | |
101 | inline std::ostream& operator<<(std::ostream& out, const Peer &peer) { | |
102 | out << "{uuid=" << peer.uuid << ", remote_cluster=" << peer.remote << "}"; | |
103 | return out; | |
104 | } | |
105 | ||
106 | struct MirrorInfo { | |
107 | MirrorInfo() = default; | |
108 | ||
109 | bool is_mirrored() const { | |
110 | return mirrored; | |
111 | } | |
112 | void enable_mirroring() { | |
113 | mirrored = true; | |
114 | } | |
115 | void disable_mirroring() { | |
116 | peers.clear(); | |
117 | mirrored = false; | |
118 | } | |
119 | ||
120 | // uuid variant check | |
121 | bool has_peer(std::string_view uuid) const { | |
122 | return peers.find(Peer(uuid)) != peers.end(); | |
123 | } | |
124 | // client_name/cluster_name/fs_name variant check | |
125 | bool has_peer(std::string_view client_name, | |
126 | std::string_view cluster_name, | |
127 | std::string_view fs_name) const { | |
128 | ClusterInfo cluster_info(client_name, cluster_name, fs_name); | |
129 | for (auto &peer : peers) { | |
130 | if (peer.remote == cluster_info) { | |
131 | return true; | |
132 | } | |
133 | } | |
134 | return false; | |
135 | } | |
136 | bool has_peers() const { | |
137 | return !peers.empty(); | |
138 | } | |
139 | ||
140 | void peer_add(std::string_view uuid, | |
141 | std::string_view client_name, | |
142 | std::string_view cluster_name, | |
143 | std::string_view fs_name) { | |
144 | peers.emplace(Peer(uuid, ClusterInfo(client_name, cluster_name, fs_name))); | |
145 | } | |
146 | void peer_remove(std::string_view uuid) { | |
147 | peers.erase(uuid); | |
148 | } | |
149 | ||
150 | bool mirrored = false; | |
151 | Peers peers; | |
152 | ||
153 | void dump(ceph::Formatter *f) const; | |
154 | void print(std::ostream& out) const; | |
155 | ||
156 | void encode(ceph::buffer::list &bl) const; | |
157 | void decode(ceph::buffer::list::const_iterator &iter); | |
158 | }; | |
159 | ||
160 | inline std::ostream& operator<<(std::ostream& out, const MirrorInfo &mirror_info) { | |
161 | out << "{peers=" << mirror_info.peers << "}"; | |
162 | return out; | |
163 | } | |
164 | ||
165 | WRITE_CLASS_ENCODER(ClusterInfo) | |
166 | WRITE_CLASS_ENCODER(Peer) | |
167 | WRITE_CLASS_ENCODER(MirrorInfo) | |
168 | ||
7c673cae FG |
169 | /** |
170 | * The MDSMap and any additional fields describing a particular | |
171 | * filesystem (a unique fs_cluster_id_t). | |
172 | */ | |
173 | class Filesystem | |
174 | { | |
1adf2230 | 175 | public: |
11fdf7f2 TL |
176 | using ref = std::shared_ptr<Filesystem>; |
177 | using const_ref = std::shared_ptr<Filesystem const>; | |
178 | ||
179 | template<typename... Args> | |
180 | static ref create(Args&&... args) | |
181 | { | |
182 | return std::make_shared<Filesystem>(std::forward<Args>(args)...); | |
183 | } | |
184 | ||
f67539c2 TL |
185 | void encode(ceph::buffer::list& bl, uint64_t features) const; |
186 | void decode(ceph::buffer::list::const_iterator& p); | |
7c673cae | 187 | |
f67539c2 | 188 | void dump(ceph::Formatter *f) const; |
7c673cae FG |
189 | void print(std::ostream& out) const; |
190 | ||
522d829b TL |
191 | bool is_upgradeable() const { |
192 | return !mds_map.allows_standby_replay() && mds_map.get_num_in_mds() <= 1; | |
193 | } | |
194 | ||
7c673cae FG |
195 | /** |
196 | * Return true if a daemon is already assigned as | |
197 | * STANDBY_REPLAY for the gid `who` | |
198 | */ | |
199 | bool has_standby_replay(mds_gid_t who) const | |
11fdf7f2 TL |
200 | { |
201 | return get_standby_replay(who) != MDS_GID_NONE; | |
202 | } | |
9f95a23c | 203 | mds_gid_t get_standby_replay(mds_gid_t who) const; |
11fdf7f2 TL |
204 | bool is_standby_replay(mds_gid_t who) const |
205 | { | |
206 | auto p = mds_map.mds_info.find(who); | |
207 | if (p != mds_map.mds_info.end() && | |
208 | p->second.state == MDSMap::STATE_STANDBY_REPLAY) { | |
209 | return true; | |
210 | } | |
7c673cae FG |
211 | return false; |
212 | } | |
1adf2230 AA |
213 | |
214 | fs_cluster_id_t fscid = FS_CLUSTER_ID_NONE; | |
215 | MDSMap mds_map; | |
f67539c2 | 216 | MirrorInfo mirror_info; |
7c673cae FG |
217 | }; |
218 | WRITE_CLASS_ENCODER_FEATURES(Filesystem) | |
219 | ||
220 | class FSMap { | |
7c673cae | 221 | public: |
7c673cae | 222 | friend class MDSMonitor; |
28e407b8 | 223 | friend class PaxosFSMap; |
9f95a23c | 224 | using mds_info_t = MDSMap::mds_info_t; |
7c673cae | 225 | |
522d829b TL |
226 | static const version_t STRUCT_VERSION = 7; |
227 | static const version_t STRUCT_VERSION_TRIM_TO = 7; | |
228 | ||
229 | FSMap() : default_compat(MDSMap::get_compat_set_default()) {} | |
7c673cae FG |
230 | |
231 | FSMap(const FSMap &rhs) | |
232 | : | |
233 | epoch(rhs.epoch), | |
234 | next_filesystem_id(rhs.next_filesystem_id), | |
235 | legacy_client_fscid(rhs.legacy_client_fscid), | |
522d829b | 236 | default_compat(rhs.default_compat), |
7c673cae FG |
237 | enable_multiple(rhs.enable_multiple), |
238 | ever_enabled_multiple(rhs.ever_enabled_multiple), | |
239 | mds_roles(rhs.mds_roles), | |
240 | standby_daemons(rhs.standby_daemons), | |
522d829b TL |
241 | standby_epochs(rhs.standby_epochs), |
242 | struct_version(rhs.struct_version) | |
7c673cae | 243 | { |
b32b8144 | 244 | filesystems.clear(); |
7c673cae FG |
245 | for (const auto &i : rhs.filesystems) { |
246 | const auto &fs = i.second; | |
247 | filesystems[fs->fscid] = std::make_shared<Filesystem>(*fs); | |
248 | } | |
249 | } | |
250 | ||
9f95a23c | 251 | FSMap &operator=(const FSMap &rhs); |
7c673cae | 252 | |
522d829b | 253 | const CompatSet &get_default_compat() const {return default_compat;} |
7c673cae | 254 | |
f67539c2 TL |
255 | void filter(const std::vector<string>& allowed) |
256 | { | |
257 | if (allowed.empty()) { | |
258 | return; | |
259 | } | |
260 | ||
261 | for (auto &f : filesystems) { | |
262 | string_view fs_name = f.second->mds_map.get_fs_name(); | |
263 | if (std::find(allowed.begin(), allowed.end(), fs_name) == allowed.end()) { | |
264 | filesystems.erase(f.first); | |
265 | } | |
266 | } | |
267 | ||
268 | for (auto r : mds_roles) { | |
269 | string_view fs_name = fs_name_from_gid(r.first); | |
270 | if (std::find(allowed.begin(), allowed.end(), fs_name) == allowed.end()) { | |
271 | mds_roles.erase(r.first); | |
272 | } | |
273 | } | |
274 | } | |
275 | ||
7c673cae FG |
276 | void set_enable_multiple(const bool v) |
277 | { | |
278 | enable_multiple = v; | |
279 | if (true == v) { | |
280 | ever_enabled_multiple = true; | |
281 | } | |
282 | } | |
283 | ||
284 | bool get_enable_multiple() const | |
285 | { | |
286 | return enable_multiple; | |
287 | } | |
288 | ||
289 | void set_legacy_client_fscid(fs_cluster_id_t fscid) | |
290 | { | |
11fdf7f2 | 291 | ceph_assert(fscid == FS_CLUSTER_ID_NONE || filesystems.count(fscid)); |
7c673cae FG |
292 | legacy_client_fscid = fscid; |
293 | } | |
294 | ||
295 | fs_cluster_id_t get_legacy_client_fscid() const | |
296 | { | |
297 | return legacy_client_fscid; | |
298 | } | |
299 | ||
11fdf7f2 TL |
300 | size_t get_num_standby() const { |
301 | return standby_daemons.size(); | |
302 | } | |
303 | ||
9f95a23c | 304 | bool is_any_degraded() const; |
11fdf7f2 | 305 | |
7c673cae FG |
306 | /** |
307 | * Get state of all daemons (for all filesystems, including all standbys) | |
308 | */ | |
9f95a23c | 309 | std::map<mds_gid_t, mds_info_t> get_mds_info() const; |
7c673cae | 310 | |
522d829b | 311 | const mds_info_t* get_available_standby(const Filesystem& fs) const; |
11fdf7f2 | 312 | |
7c673cae FG |
313 | /** |
314 | * Resolve daemon name to GID | |
315 | */ | |
9f95a23c | 316 | mds_gid_t find_mds_gid_by_name(std::string_view s) const; |
7c673cae FG |
317 | |
318 | /** | |
319 | * Resolve daemon name to status | |
320 | */ | |
9f95a23c | 321 | const mds_info_t* find_by_name(std::string_view name) const; |
7c673cae FG |
322 | |
323 | /** | |
324 | * Does a daemon exist with this GID? | |
325 | */ | |
f67539c2 TL |
326 | bool gid_exists(mds_gid_t gid, |
327 | const std::vector<string>& in = {}) const | |
7c673cae | 328 | { |
f67539c2 TL |
329 | try { |
330 | string_view m = fs_name_from_gid(gid); | |
331 | return in.empty() || std::find(in.begin(), in.end(), m) != in.end(); | |
332 | } catch (const std::out_of_range&) { | |
333 | return false; | |
334 | } | |
7c673cae FG |
335 | } |
336 | ||
337 | /** | |
338 | * Does a daemon with this GID exist, *and* have an MDS rank assigned? | |
339 | */ | |
340 | bool gid_has_rank(mds_gid_t gid) const | |
341 | { | |
342 | return gid_exists(gid) && mds_roles.at(gid) != FS_CLUSTER_ID_NONE; | |
343 | } | |
344 | ||
f67539c2 TL |
345 | /** |
346 | * Which filesystem owns this GID? | |
347 | */ | |
348 | fs_cluster_id_t fscid_from_gid(mds_gid_t gid) const { | |
349 | if (!gid_exists(gid)) { | |
350 | return FS_CLUSTER_ID_NONE; | |
351 | } | |
9f95a23c TL |
352 | return mds_roles.at(gid); |
353 | } | |
354 | ||
7c673cae FG |
355 | /** |
356 | * Insert a new MDS daemon, as a standby | |
357 | */ | |
f67539c2 | 358 | void insert(const MDSMap::mds_info_t &new_info); |
7c673cae FG |
359 | |
360 | /** | |
361 | * Assign an MDS cluster standby replay rank to a standby daemon | |
362 | */ | |
363 | void assign_standby_replay( | |
364 | const mds_gid_t standby_gid, | |
365 | const fs_cluster_id_t leader_ns, | |
366 | const mds_rank_t leader_rank); | |
367 | ||
368 | /** | |
369 | * Assign an MDS cluster rank to a standby daemon | |
370 | */ | |
371 | void promote( | |
372 | mds_gid_t standby_gid, | |
11fdf7f2 | 373 | Filesystem& filesystem, |
7c673cae FG |
374 | mds_rank_t assigned_rank); |
375 | ||
376 | /** | |
377 | * A daemon reports that it is STATE_STOPPED: remove it, | |
378 | * and the rank it held. | |
379 | * | |
380 | * @returns a list of any additional GIDs that were removed from the map | |
381 | * as a side effect (like standby replays) | |
382 | */ | |
9f95a23c | 383 | std::vector<mds_gid_t> stop(mds_gid_t who); |
7c673cae FG |
384 | |
385 | /** | |
386 | * The rank held by 'who', if any, is to be relinquished, and | |
387 | * the state for the daemon GID is to be forgotten. | |
388 | */ | |
f67539c2 | 389 | void erase(mds_gid_t who, epoch_t blocklist_epoch); |
7c673cae FG |
390 | |
391 | /** | |
392 | * Update to indicate that the rank held by 'who' is damaged | |
393 | */ | |
f67539c2 | 394 | void damaged(mds_gid_t who, epoch_t blocklist_epoch); |
7c673cae FG |
395 | |
396 | /** | |
397 | * Update to indicate that the rank `rank` is to be removed | |
398 | * from the damaged list of the filesystem `fscid` | |
399 | */ | |
400 | bool undamaged(const fs_cluster_id_t fscid, const mds_rank_t rank); | |
401 | ||
402 | /** | |
403 | * Initialize a Filesystem and assign a fscid. Update legacy_client_fscid | |
404 | * to point to the new filesystem if it's the only one. | |
405 | * | |
406 | * Caller must already have validated all arguments vs. the existing | |
407 | * FSMap and OSDMap contents. | |
408 | */ | |
11fdf7f2 TL |
409 | Filesystem::ref create_filesystem( |
410 | std::string_view name, int64_t metadata_pool, | |
522d829b TL |
411 | int64_t data_pool, uint64_t features, |
412 | fs_cluster_id_t fscid); | |
7c673cae FG |
413 | |
414 | /** | |
415 | * Remove the filesystem (it must exist). Caller should already | |
416 | * have failed out any MDSs that were assigned to the filesystem. | |
417 | */ | |
9f95a23c | 418 | void erase_filesystem(fs_cluster_id_t fscid); |
7c673cae FG |
419 | |
420 | /** | |
421 | * Reset all the state information (not configuration information) | |
422 | * in a particular filesystem. Caller must have verified that | |
423 | * the filesystem already exists. | |
424 | */ | |
425 | void reset_filesystem(fs_cluster_id_t fscid); | |
426 | ||
427 | /** | |
428 | * Mutator helper for Filesystem objects: expose a non-const | |
429 | * Filesystem pointer to `fn` and update epochs appropriately. | |
430 | */ | |
11fdf7f2 TL |
431 | template<typename T> |
432 | void modify_filesystem(fs_cluster_id_t fscid, T&& fn) | |
7c673cae | 433 | { |
11fdf7f2 | 434 | auto& fs = filesystems.at(fscid); |
7c673cae FG |
435 | fn(fs); |
436 | fs->mds_map.epoch = epoch; | |
437 | } | |
438 | ||
439 | /** | |
440 | * Apply a mutation to the mds_info_t structure for a particular | |
441 | * daemon (identified by GID), and make appropriate updates to epochs. | |
442 | */ | |
11fdf7f2 TL |
443 | template<typename T> |
444 | void modify_daemon(mds_gid_t who, T&& fn) | |
7c673cae | 445 | { |
11fdf7f2 TL |
446 | const auto& fscid = mds_roles.at(who); |
447 | if (fscid == FS_CLUSTER_ID_NONE) { | |
448 | auto& info = standby_daemons.at(who); | |
449 | fn(info); | |
450 | ceph_assert(info.state == MDSMap::STATE_STANDBY); | |
7c673cae FG |
451 | standby_epochs[who] = epoch; |
452 | } else { | |
11fdf7f2 TL |
453 | auto& fs = filesystems.at(fscid); |
454 | auto& info = fs->mds_map.mds_info.at(who); | |
455 | fn(info); | |
7c673cae FG |
456 | fs->mds_map.epoch = epoch; |
457 | } | |
458 | } | |
459 | ||
460 | /** | |
461 | * Given that gid exists in a filesystem or as a standby, return | |
462 | * a reference to its info. | |
463 | */ | |
9f95a23c | 464 | const mds_info_t& get_info_gid(mds_gid_t gid) const |
7c673cae FG |
465 | { |
466 | auto fscid = mds_roles.at(gid); | |
467 | if (fscid == FS_CLUSTER_ID_NONE) { | |
468 | return standby_daemons.at(gid); | |
469 | } else { | |
470 | return filesystems.at(fscid)->mds_map.mds_info.at(gid); | |
471 | } | |
472 | } | |
473 | ||
f67539c2 TL |
474 | std::string_view fs_name_from_gid(mds_gid_t gid) const |
475 | { | |
476 | auto fscid = mds_roles.at(gid); | |
477 | if (fscid == FS_CLUSTER_ID_NONE or !filesystem_exists(fscid)) { | |
478 | return std::string_view(); | |
479 | } else { | |
480 | return get_filesystem(fscid)->mds_map.get_fs_name(); | |
481 | } | |
482 | } | |
483 | ||
11fdf7f2 TL |
484 | bool is_standby_replay(mds_gid_t who) const |
485 | { | |
486 | return filesystems.at(mds_roles.at(who))->is_standby_replay(who); | |
487 | } | |
488 | ||
489 | mds_gid_t get_standby_replay(mds_gid_t who) const | |
490 | { | |
491 | return filesystems.at(mds_roles.at(who))->get_standby_replay(who); | |
492 | } | |
493 | ||
11fdf7f2 | 494 | Filesystem::const_ref get_legacy_filesystem() |
7c673cae FG |
495 | { |
496 | if (legacy_client_fscid == FS_CLUSTER_ID_NONE) { | |
497 | return nullptr; | |
498 | } else { | |
499 | return filesystems.at(legacy_client_fscid); | |
500 | } | |
501 | } | |
502 | ||
503 | /** | |
504 | * A daemon has informed us of its offload targets | |
505 | */ | |
11fdf7f2 | 506 | void update_export_targets(mds_gid_t who, const std::set<mds_rank_t> &targets) |
7c673cae FG |
507 | { |
508 | auto fscid = mds_roles.at(who); | |
11fdf7f2 | 509 | modify_filesystem(fscid, [who, &targets](auto&& fs) { |
7c673cae FG |
510 | fs->mds_map.mds_info.at(who).export_targets = targets; |
511 | }); | |
512 | } | |
513 | ||
514 | epoch_t get_epoch() const { return epoch; } | |
515 | void inc_epoch() { epoch++; } | |
516 | ||
522d829b TL |
517 | version_t get_struct_version() const { return struct_version; } |
518 | bool is_struct_old() const { | |
519 | return struct_version < STRUCT_VERSION_TRIM_TO; | |
520 | } | |
521 | ||
7c673cae FG |
522 | size_t filesystem_count() const {return filesystems.size();} |
523 | bool filesystem_exists(fs_cluster_id_t fscid) const {return filesystems.count(fscid) > 0;} | |
11fdf7f2 TL |
524 | Filesystem::const_ref get_filesystem(fs_cluster_id_t fscid) const {return std::const_pointer_cast<const Filesystem>(filesystems.at(fscid));} |
525 | Filesystem::ref get_filesystem(fs_cluster_id_t fscid) {return filesystems.at(fscid);} | |
526 | Filesystem::const_ref get_filesystem(void) const {return std::const_pointer_cast<const Filesystem>(filesystems.begin()->second);} | |
9f95a23c TL |
527 | Filesystem::const_ref get_filesystem(std::string_view name) const; |
528 | ||
529 | std::vector<Filesystem::const_ref> get_filesystems(void) const; | |
7c673cae FG |
530 | |
531 | int parse_filesystem( | |
11fdf7f2 TL |
532 | std::string_view ns_str, |
533 | Filesystem::const_ref *result | |
7c673cae FG |
534 | ) const; |
535 | ||
f67539c2 TL |
536 | int parse_role( |
537 | std::string_view role_str, | |
538 | mds_role_t *role, | |
539 | std::ostream &ss, | |
540 | const std::vector<string> &filter) const; | |
541 | ||
7c673cae | 542 | int parse_role( |
11fdf7f2 | 543 | std::string_view role_str, |
7c673cae FG |
544 | mds_role_t *role, |
545 | std::ostream &ss) const; | |
546 | ||
547 | /** | |
548 | * Return true if this pool is in use by any of the filesystems | |
549 | */ | |
9f95a23c | 550 | bool pool_in_use(int64_t poolid) const; |
7c673cae | 551 | |
9f95a23c | 552 | const mds_info_t* find_replacement_for(mds_role_t role) const; |
7c673cae | 553 | |
f67539c2 TL |
554 | void get_health(std::list<std::pair<health_status_t,std::string> >& summary, |
555 | std::list<std::pair<health_status_t,std::string> > *detail) const; | |
7c673cae | 556 | |
224ce89b WB |
557 | void get_health_checks(health_check_map_t *checks) const; |
558 | ||
7c673cae FG |
559 | bool check_health(void); |
560 | ||
561 | /** | |
562 | * Assert that the FSMap, Filesystem, MDSMap, mds_info_t relations are | |
563 | * all self-consistent. | |
564 | */ | |
565 | void sanity() const; | |
566 | ||
f67539c2 TL |
567 | void encode(ceph::buffer::list& bl, uint64_t features) const; |
568 | void decode(ceph::buffer::list::const_iterator& p); | |
569 | void decode(ceph::buffer::list& bl) { | |
11fdf7f2 | 570 | auto p = bl.cbegin(); |
7c673cae FG |
571 | decode(p); |
572 | } | |
11fdf7f2 | 573 | void sanitize(const std::function<bool(int64_t pool)>& pool_exists); |
7c673cae | 574 | |
f67539c2 TL |
575 | void print(std::ostream& out) const; |
576 | void print_summary(ceph::Formatter *f, std::ostream *out) const; | |
577 | void print_daemon_summary(std::ostream& out) const; | |
578 | void print_fs_summary(std::ostream& out) const; | |
7c673cae | 579 | |
f67539c2 | 580 | void dump(ceph::Formatter *f) const; |
9f95a23c TL |
581 | static void generate_test_instances(std::list<FSMap*>& ls); |
582 | ||
583 | protected: | |
584 | epoch_t epoch = 0; | |
585 | uint64_t next_filesystem_id = FS_CLUSTER_ID_ANONYMOUS + 1; | |
586 | fs_cluster_id_t legacy_client_fscid = FS_CLUSTER_ID_NONE; | |
522d829b | 587 | CompatSet default_compat; |
f67539c2 TL |
588 | bool enable_multiple = true; |
589 | bool ever_enabled_multiple = true; // < the cluster had multiple FS enabled once | |
9f95a23c TL |
590 | |
591 | std::map<fs_cluster_id_t, Filesystem::ref> filesystems; | |
592 | ||
593 | // Remember which Filesystem an MDS daemon's info is stored in | |
594 | // (or in standby_daemons for FS_CLUSTER_ID_NONE) | |
595 | std::map<mds_gid_t, fs_cluster_id_t> mds_roles; | |
596 | ||
597 | // For MDS daemons not yet assigned to a Filesystem | |
598 | std::map<mds_gid_t, mds_info_t> standby_daemons; | |
599 | std::map<mds_gid_t, epoch_t> standby_epochs; | |
522d829b TL |
600 | |
601 | private: | |
602 | epoch_t struct_version = 0; | |
7c673cae FG |
603 | }; |
604 | WRITE_CLASS_ENCODER_FEATURES(FSMap) | |
605 | ||
f67539c2 | 606 | inline std::ostream& operator<<(std::ostream& out, const FSMap& m) { |
7c673cae FG |
607 | m.print_summary(NULL, &out); |
608 | return out; | |
609 | } | |
610 | ||
611 | #endif |