]>
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_MOSDMAP_H | |
17 | #define CEPH_MOSDMAP_H | |
18 | ||
19 | #include "msg/Message.h" | |
20 | #include "osd/OSDMap.h" | |
21 | #include "include/ceph_features.h" | |
22 | ||
f67539c2 | 23 | class MOSDMap final : public Message { |
11fdf7f2 TL |
24 | private: |
25 | static constexpr int HEAD_VERSION = 4; | |
26 | static constexpr int COMPAT_VERSION = 3; | |
7c673cae | 27 | |
9f95a23c | 28 | public: |
7c673cae | 29 | uuid_d fsid; |
28e407b8 | 30 | uint64_t encode_features = 0; |
9f95a23c TL |
31 | std::map<epoch_t, ceph::buffer::list> maps; |
32 | std::map<epoch_t, ceph::buffer::list> incremental_maps; | |
1e59de90 TL |
33 | /** |
34 | * cluster_osdmap_trim_lower_bound | |
35 | * | |
36 | * Encodes a lower bound on the monitor's osdmap trim bound. Recipients | |
37 | * can safely trim up to this bound. The sender stores maps back to | |
38 | * cluster_osdmap_trim_lower_bound. | |
39 | * | |
40 | * This field was formerly named oldest_map and encoded the oldest map | |
41 | * stored by the sender. The primary usage of this field, however, was to | |
42 | * allow the recipient to trim. The secondary usage was to inform the | |
43 | * recipient of how many maps the sender stored in case it needed to request | |
44 | * more. For both purposes, it should be safe for an older OSD to interpret | |
45 | * this field as oldest_map, and it should be safe for a new osd to interpret | |
46 | * the oldest_map field sent by an older osd as | |
47 | * cluster_osdmap_trim_lower_bound. | |
48 | * See bug https://tracker.ceph.com/issues/49689 | |
49 | */ | |
50 | epoch_t cluster_osdmap_trim_lower_bound = 0; | |
51 | epoch_t newest_map = 0; | |
7c673cae FG |
52 | |
53 | epoch_t get_first() const { | |
54 | epoch_t e = 0; | |
9f95a23c TL |
55 | auto i = maps.cbegin(); |
56 | if (i != maps.cend()) e = i->first; | |
7c673cae FG |
57 | i = incremental_maps.begin(); |
58 | if (i != incremental_maps.end() && | |
59 | (e == 0 || i->first < e)) e = i->first; | |
60 | return e; | |
61 | } | |
62 | epoch_t get_last() const { | |
63 | epoch_t e = 0; | |
9f95a23c TL |
64 | auto i = maps.crbegin(); |
65 | if (i != maps.crend()) e = i->first; | |
7c673cae FG |
66 | i = incremental_maps.rbegin(); |
67 | if (i != incremental_maps.rend() && | |
68 | (e == 0 || i->first > e)) e = i->first; | |
69 | return e; | |
70 | } | |
7c673cae | 71 | |
9f95a23c | 72 | MOSDMap() : Message{CEPH_MSG_OSD_MAP, HEAD_VERSION, COMPAT_VERSION} { } |
28e407b8 | 73 | MOSDMap(const uuid_d &f, const uint64_t features) |
9f95a23c | 74 | : Message{CEPH_MSG_OSD_MAP, HEAD_VERSION, COMPAT_VERSION}, |
28e407b8 | 75 | fsid(f), encode_features(features), |
1e59de90 | 76 | cluster_osdmap_trim_lower_bound(0), newest_map(0) { } |
7c673cae | 77 | private: |
f67539c2 | 78 | ~MOSDMap() final {} |
7c673cae FG |
79 | public: |
80 | // marshalling | |
81 | void decode_payload() override { | |
9f95a23c | 82 | using ceph::decode; |
11fdf7f2 TL |
83 | auto p = payload.cbegin(); |
84 | decode(fsid, p); | |
85 | decode(incremental_maps, p); | |
86 | decode(maps, p); | |
7c673cae | 87 | if (header.version >= 2) { |
1e59de90 | 88 | decode(cluster_osdmap_trim_lower_bound, p); |
11fdf7f2 | 89 | decode(newest_map, p); |
7c673cae | 90 | } else { |
1e59de90 | 91 | cluster_osdmap_trim_lower_bound = 0; |
7c673cae FG |
92 | newest_map = 0; |
93 | } | |
11fdf7f2 | 94 | if (header.version >= 4) { |
9f95a23c TL |
95 | // removed in octopus |
96 | mempool::osdmap::map<int64_t,snap_interval_set_t> gap_removed_snaps; | |
11fdf7f2 TL |
97 | decode(gap_removed_snaps, p); |
98 | } | |
7c673cae FG |
99 | } |
100 | void encode_payload(uint64_t features) override { | |
11fdf7f2 | 101 | using ceph::encode; |
7c673cae | 102 | header.version = HEAD_VERSION; |
11fdf7f2 TL |
103 | header.compat_version = COMPAT_VERSION; |
104 | encode(fsid, payload); | |
28e407b8 AA |
105 | if (OSDMap::get_significant_features(encode_features) != |
106 | OSDMap::get_significant_features(features)) { | |
7c673cae | 107 | if ((features & CEPH_FEATURE_PGID64) == 0 || |
11fdf7f2 | 108 | (features & CEPH_FEATURE_PGPOOL3) == 0) { |
7c673cae | 109 | header.version = 1; // old old_client version |
11fdf7f2 TL |
110 | header.compat_version = 1; |
111 | } else if ((features & CEPH_FEATURE_OSDENC) == 0) { | |
7c673cae | 112 | header.version = 2; // old pg_pool_t |
11fdf7f2 TL |
113 | header.compat_version = 2; |
114 | } | |
7c673cae FG |
115 | |
116 | // reencode maps using old format | |
117 | // | |
118 | // FIXME: this can probably be done more efficiently higher up | |
119 | // the stack, or maybe replaced with something that only | |
120 | // includes the pools the client cares about. | |
9f95a23c | 121 | for (auto p = incremental_maps.begin(); p != incremental_maps.end(); ++p) { |
7c673cae | 122 | OSDMap::Incremental inc; |
11fdf7f2 | 123 | auto q = p->second.cbegin(); |
7c673cae | 124 | inc.decode(q); |
28e407b8 AA |
125 | // always encode with subset of osdmaps canonical features |
126 | uint64_t f = inc.encode_features & features; | |
7c673cae FG |
127 | p->second.clear(); |
128 | if (inc.fullmap.length()) { | |
9f95a23c | 129 | // embedded full std::map? |
7c673cae FG |
130 | OSDMap m; |
131 | m.decode(inc.fullmap); | |
132 | inc.fullmap.clear(); | |
28e407b8 | 133 | m.encode(inc.fullmap, f | CEPH_FEATURE_RESERVED); |
7c673cae | 134 | } |
3efd9988 | 135 | if (inc.crush.length()) { |
9f95a23c | 136 | // embedded crush std::map |
3efd9988 | 137 | CrushWrapper c; |
11fdf7f2 | 138 | auto p = inc.crush.cbegin(); |
3efd9988 FG |
139 | c.decode(p); |
140 | inc.crush.clear(); | |
28e407b8 | 141 | c.encode(inc.crush, f); |
3efd9988 | 142 | } |
28e407b8 | 143 | inc.encode(p->second, f | CEPH_FEATURE_RESERVED); |
7c673cae | 144 | } |
9f95a23c | 145 | for (auto p = maps.begin(); p != maps.end(); ++p) { |
7c673cae FG |
146 | OSDMap m; |
147 | m.decode(p->second); | |
28e407b8 AA |
148 | // always encode with subset of osdmaps canonical features |
149 | uint64_t f = m.get_encoding_features() & features; | |
7c673cae | 150 | p->second.clear(); |
28e407b8 | 151 | m.encode(p->second, f | CEPH_FEATURE_RESERVED); |
7c673cae FG |
152 | } |
153 | } | |
11fdf7f2 TL |
154 | encode(incremental_maps, payload); |
155 | encode(maps, payload); | |
7c673cae | 156 | if (header.version >= 2) { |
1e59de90 | 157 | encode(cluster_osdmap_trim_lower_bound, payload); |
11fdf7f2 TL |
158 | encode(newest_map, payload); |
159 | } | |
160 | if (header.version >= 4) { | |
9f95a23c | 161 | encode((uint32_t)0, payload); |
7c673cae FG |
162 | } |
163 | } | |
164 | ||
11fdf7f2 | 165 | std::string_view get_type_name() const override { return "osdmap"; } |
9f95a23c | 166 | void print(std::ostream& out) const override { |
7c673cae | 167 | out << "osd_map(" << get_first() << ".." << get_last(); |
1e59de90 TL |
168 | if (cluster_osdmap_trim_lower_bound || newest_map) |
169 | out << " src has " << cluster_osdmap_trim_lower_bound | |
170 | << ".." << newest_map; | |
7c673cae FG |
171 | out << ")"; |
172 | } | |
9f95a23c TL |
173 | private: |
174 | template<class T, typename... Args> | |
175 | friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args); | |
7c673cae FG |
176 | }; |
177 | ||
178 | #endif |