]>
git.proxmox.com Git - ceph.git/blob - 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
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.
16 #ifndef CEPH_MOSDMAP_H
17 #define CEPH_MOSDMAP_H
19 #include "msg/Message.h"
20 #include "osd/OSDMap.h"
21 #include "include/ceph_features.h"
23 class MOSDMap
: public MessageInstance
<MOSDMap
> {
27 static constexpr int HEAD_VERSION
= 4;
28 static constexpr int COMPAT_VERSION
= 3;
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;
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
;
42 epoch_t
get_first() const {
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
;
51 epoch_t
get_last() const {
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
;
60 epoch_t
get_oldest() {
63 epoch_t
get_newest() {
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) { }
74 ~MOSDMap() override
{}
77 void decode_payload() override
{
78 auto p
= payload
.cbegin();
80 decode(incremental_maps
, p
);
82 if (header
.version
>= 2) {
83 decode(oldest_map
, p
);
84 decode(newest_map
, p
);
89 if (header
.version
>= 4) {
90 decode(gap_removed_snaps
, p
);
93 void encode_payload(uint64_t features
) override
{
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;
109 // reencode maps using old format
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();
117 OSDMap::Incremental inc
;
118 auto q
= p
->second
.cbegin();
120 // always encode with subset of osdmaps canonical features
121 uint64_t f
= inc
.encode_features
& features
;
123 if (inc
.fullmap
.length()) {
124 // embedded full map?
126 m
.decode(inc
.fullmap
);
128 m
.encode(inc
.fullmap
, f
| CEPH_FEATURE_RESERVED
);
130 if (inc
.crush
.length()) {
131 // embedded crush map
133 auto p
= inc
.crush
.cbegin();
136 c
.encode(inc
.crush
, f
);
138 inc
.encode(p
->second
, f
| CEPH_FEATURE_RESERVED
);
140 for (map
<epoch_t
,bufferlist
>::iterator p
= maps
.begin();
145 // always encode with subset of osdmaps canonical features
146 uint64_t f
= m
.get_encoding_features() & features
;
148 m
.encode(p
->second
, f
| CEPH_FEATURE_RESERVED
);
151 encode(incremental_maps
, payload
);
152 encode(maps
, payload
);
153 if (header
.version
>= 2) {
154 encode(oldest_map
, payload
);
155 encode(newest_map
, payload
);
157 if (header
.version
>= 4) {
158 encode(gap_removed_snaps
, payload
);
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";