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 Message {
25 static const int HEAD_VERSION = 3;
29 map<epoch_t, bufferlist> maps;
30 map<epoch_t, bufferlist> incremental_maps;
31 epoch_t oldest_map =0, newest_map = 0;
33 epoch_t get_first() const {
35 map<epoch_t, bufferlist>::const_iterator i = maps.begin();
36 if (i != maps.end()) e = i->first;
37 i = incremental_maps.begin();
38 if (i != incremental_maps.end() &&
39 (e == 0 || i->first < e)) e = i->first;
42 epoch_t get_last() const {
44 map<epoch_t, bufferlist>::const_reverse_iterator i = maps.rbegin();
45 if (i != maps.rend()) e = i->first;
46 i = incremental_maps.rbegin();
47 if (i != incremental_maps.rend() &&
48 (e == 0 || i->first > e)) e = i->first;
51 epoch_t get_oldest() {
54 epoch_t get_newest() {
59 MOSDMap() : Message(CEPH_MSG_OSD_MAP, HEAD_VERSION) { }
60 MOSDMap(const uuid_d &f)
61 : Message(CEPH_MSG_OSD_MAP, HEAD_VERSION),
63 oldest_map(0), newest_map(0) { }
65 ~MOSDMap() override {}
69 void decode_payload() override {
70 bufferlist::iterator p = payload.begin();
72 ::decode(incremental_maps, p);
74 if (header.version >= 2) {
75 ::decode(oldest_map, p);
76 ::decode(newest_map, p);
82 void encode_payload(uint64_t features) override {
83 header.version = HEAD_VERSION;
84 ::encode(fsid, payload);
85 if ((features & CEPH_FEATURE_PGID64) == 0 ||
86 (features & CEPH_FEATURE_PGPOOL3) == 0 ||
87 (features & CEPH_FEATURE_OSDENC) == 0 ||
88 (features & CEPH_FEATURE_OSDMAP_ENC) == 0 ||
89 (features & CEPH_FEATURE_MSG_ADDR2) == 0 ||
90 !HAVE_FEATURE(features, SERVER_LUMINOUS)) {
91 if ((features & CEPH_FEATURE_PGID64) == 0 ||
92 (features & CEPH_FEATURE_PGPOOL3) == 0)
93 header.version = 1; // old old_client version
94 else if ((features & CEPH_FEATURE_OSDENC) == 0)
95 header.version = 2; // old pg_pool_t
97 // reencode maps using old format
99 // FIXME: this can probably be done more efficiently higher up
100 // the stack, or maybe replaced with something that only
101 // includes the pools the client cares about.
102 for (map<epoch_t,bufferlist>::iterator p = incremental_maps.begin();
103 p != incremental_maps.end();
105 OSDMap::Incremental inc;
106 bufferlist::iterator q = p->second.begin();
109 if (inc.fullmap.length()) {
110 // embedded full map?
112 m.decode(inc.fullmap);
114 m.encode(inc.fullmap, features | CEPH_FEATURE_RESERVED);
116 if (inc.crush.length()) {
117 // embedded crush map
119 auto p = inc.crush.begin();
122 c.encode(inc.crush, features);
124 inc.encode(p->second, features | CEPH_FEATURE_RESERVED);
126 for (map<epoch_t,bufferlist>::iterator p = maps.begin();
132 m.encode(p->second, features | CEPH_FEATURE_RESERVED);
135 ::encode(incremental_maps, payload);
136 ::encode(maps, payload);
137 if (header.version >= 2) {
138 ::encode(oldest_map, payload);
139 ::encode(newest_map, payload);
143 const char *get_type_name() const override { return "osdmap"; }
144 void print(ostream& out) const override {
145 out << "osd_map(" << get_first() << ".." << get_last();
146 if (oldest_map || newest_map)
147 out << " src has " << oldest_map << ".." << newest_map;