]> git.proxmox.com Git - ceph.git/blob - ceph/src/messages/MOSDMap.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / messages / MOSDMap.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
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
23 class MOSDMap : public MessageInstance<MOSDMap> {
24 public:
25 friend factory;
26 private:
27 static constexpr int HEAD_VERSION = 4;
28 static constexpr int COMPAT_VERSION = 3;
29
30 public:
31 uuid_d fsid;
32 uint64_t encode_features = 0;
33 map<epoch_t, bufferlist> maps;
34 map<epoch_t, bufferlist> incremental_maps;
35 epoch_t oldest_map =0, newest_map = 0;
36
37 // if we are fetching maps from the mon and have to jump a gap
38 // (client's next needed map is older than mon's oldest) we can
39 // share removed snaps from the gap here.
40 mempool::osdmap::map<int64_t,OSDMap::snap_interval_set_t> gap_removed_snaps;
41
42 epoch_t get_first() const {
43 epoch_t e = 0;
44 map<epoch_t, bufferlist>::const_iterator i = maps.begin();
45 if (i != maps.end()) e = i->first;
46 i = incremental_maps.begin();
47 if (i != incremental_maps.end() &&
48 (e == 0 || i->first < e)) e = i->first;
49 return e;
50 }
51 epoch_t get_last() const {
52 epoch_t e = 0;
53 map<epoch_t, bufferlist>::const_reverse_iterator i = maps.rbegin();
54 if (i != maps.rend()) e = i->first;
55 i = incremental_maps.rbegin();
56 if (i != incremental_maps.rend() &&
57 (e == 0 || i->first > e)) e = i->first;
58 return e;
59 }
60 epoch_t get_oldest() {
61 return oldest_map;
62 }
63 epoch_t get_newest() {
64 return newest_map;
65 }
66
67
68 MOSDMap() : MessageInstance(CEPH_MSG_OSD_MAP, HEAD_VERSION, COMPAT_VERSION) { }
69 MOSDMap(const uuid_d &f, const uint64_t features)
70 : MessageInstance(CEPH_MSG_OSD_MAP, HEAD_VERSION, COMPAT_VERSION),
71 fsid(f), encode_features(features),
72 oldest_map(0), newest_map(0) { }
73 private:
74 ~MOSDMap() override {}
75 public:
76 // marshalling
77 void decode_payload() override {
78 auto p = payload.cbegin();
79 decode(fsid, p);
80 decode(incremental_maps, p);
81 decode(maps, p);
82 if (header.version >= 2) {
83 decode(oldest_map, p);
84 decode(newest_map, p);
85 } else {
86 oldest_map = 0;
87 newest_map = 0;
88 }
89 if (header.version >= 4) {
90 decode(gap_removed_snaps, p);
91 }
92 }
93 void encode_payload(uint64_t features) override {
94 using ceph::encode;
95 header.version = HEAD_VERSION;
96 header.compat_version = COMPAT_VERSION;
97 encode(fsid, payload);
98 if (OSDMap::get_significant_features(encode_features) !=
99 OSDMap::get_significant_features(features)) {
100 if ((features & CEPH_FEATURE_PGID64) == 0 ||
101 (features & CEPH_FEATURE_PGPOOL3) == 0) {
102 header.version = 1; // old old_client version
103 header.compat_version = 1;
104 } else if ((features & CEPH_FEATURE_OSDENC) == 0) {
105 header.version = 2; // old pg_pool_t
106 header.compat_version = 2;
107 }
108
109 // reencode maps using old format
110 //
111 // FIXME: this can probably be done more efficiently higher up
112 // the stack, or maybe replaced with something that only
113 // includes the pools the client cares about.
114 for (map<epoch_t,bufferlist>::iterator p = incremental_maps.begin();
115 p != incremental_maps.end();
116 ++p) {
117 OSDMap::Incremental inc;
118 auto q = p->second.cbegin();
119 inc.decode(q);
120 // always encode with subset of osdmaps canonical features
121 uint64_t f = inc.encode_features & features;
122 p->second.clear();
123 if (inc.fullmap.length()) {
124 // embedded full map?
125 OSDMap m;
126 m.decode(inc.fullmap);
127 inc.fullmap.clear();
128 m.encode(inc.fullmap, f | CEPH_FEATURE_RESERVED);
129 }
130 if (inc.crush.length()) {
131 // embedded crush map
132 CrushWrapper c;
133 auto p = inc.crush.cbegin();
134 c.decode(p);
135 inc.crush.clear();
136 c.encode(inc.crush, f);
137 }
138 inc.encode(p->second, f | CEPH_FEATURE_RESERVED);
139 }
140 for (map<epoch_t,bufferlist>::iterator p = maps.begin();
141 p != maps.end();
142 ++p) {
143 OSDMap m;
144 m.decode(p->second);
145 // always encode with subset of osdmaps canonical features
146 uint64_t f = m.get_encoding_features() & features;
147 p->second.clear();
148 m.encode(p->second, f | CEPH_FEATURE_RESERVED);
149 }
150 }
151 encode(incremental_maps, payload);
152 encode(maps, payload);
153 if (header.version >= 2) {
154 encode(oldest_map, payload);
155 encode(newest_map, payload);
156 }
157 if (header.version >= 4) {
158 encode(gap_removed_snaps, payload);
159 }
160 }
161
162 std::string_view get_type_name() const override { return "osdmap"; }
163 void print(ostream& out) const override {
164 out << "osd_map(" << get_first() << ".." << get_last();
165 if (oldest_map || newest_map)
166 out << " src has " << oldest_map << ".." << newest_map;
167 if (!gap_removed_snaps.empty())
168 out << " +gap_removed_snaps";
169 out << ")";
170 }
171 };
172
173 #endif