class MOSDMap : public Message {
- static const int HEAD_VERSION = 3;
+ static const int HEAD_VERSION = 4;
+ static const int COMPAT_VERSION = 3;
public:
uuid_d fsid;
map<epoch_t, bufferlist> incremental_maps;
epoch_t oldest_map =0, newest_map = 0;
+ // if we are fetching maps from the mon and have to jump a gap
+ // (client's next needed map is older than mon's oldest) we can
+ // share removed snaps from the gap here.
+ mempool::osdmap::map<int64_t,OSDMap::snap_interval_set_t> gap_removed_snaps;
+
epoch_t get_first() const {
epoch_t e = 0;
map<epoch_t, bufferlist>::const_iterator i = maps.begin();
}
- MOSDMap() : Message(CEPH_MSG_OSD_MAP, HEAD_VERSION) { }
+ MOSDMap() : Message(CEPH_MSG_OSD_MAP, HEAD_VERSION, COMPAT_VERSION) { }
MOSDMap(const uuid_d &f)
- : Message(CEPH_MSG_OSD_MAP, HEAD_VERSION),
+ : Message(CEPH_MSG_OSD_MAP, HEAD_VERSION, COMPAT_VERSION),
fsid(f),
oldest_map(0), newest_map(0) { }
private:
oldest_map = 0;
newest_map = 0;
}
+ if (header.version >= 4) {
+ ::decode(gap_removed_snaps, p);
+ }
}
void encode_payload(uint64_t features) override {
header.version = HEAD_VERSION;
+ header.compat_version = COMPAT_VERSION;
::encode(fsid, payload);
if ((features & CEPH_FEATURE_PGID64) == 0 ||
(features & CEPH_FEATURE_PGPOOL3) == 0 ||
header.version = 1; // old old_client version
else if ((features & CEPH_FEATURE_OSDENC) == 0)
header.version = 2; // old pg_pool_t
+ header.compat_version = 0;
// reencode maps using old format
//
::encode(oldest_map, payload);
::encode(newest_map, payload);
}
+ if (header.version >= 4) {
+ ::encode(gap_removed_snaps, payload);
+ }
}
const char *get_type_name() const override { return "osdmap"; }
out << "osd_map(" << get_first() << ".." << get_last();
if (oldest_map || newest_map)
out << " src has " << oldest_map << ".." << newest_map;
+ if (!gap_removed_snaps.empty())
+ out << " +gap_removed_snaps";
out << ")";
}
};
}
if (first < get_first_committed()) {
+ MOSDMap *m = new MOSDMap(osdmap.get_fsid());
+ m->oldest_map = get_first_committed();
+ m->newest_map = osdmap.get_epoch();
+
+ // share removed snaps during the gap
+ get_removed_snaps_range(first, m->oldest_map, &m->gap_removed_snaps);
+
first = get_first_committed();
bufferlist bl;
int err = get_version_full(first, bl);
assert(err == 0);
assert(bl.length());
-
dout(20) << "send_incremental starting with base full "
<< first << " " << bl.length() << " bytes" << dendl;
-
- MOSDMap *m = new MOSDMap(osdmap.get_fsid());
- m->oldest_map = get_first_committed();
- m->newest_map = osdmap.get_epoch();
m->maps[first] = bl;
if (req) {
}
}
+void OSDMonitor::get_removed_snaps_range(
+ epoch_t start, epoch_t end,
+ mempool::osdmap::map<int64_t,OSDMap::snap_interval_set_t> *gap_removed_snaps)
+{
+ // we only care about pools that exist now.
+ for (auto& p : osdmap.get_pools()) {
+ auto& t = (*gap_removed_snaps)[p.first];
+ for (epoch_t epoch = start; epoch < end; ++epoch) {
+ string k = make_snap_epoch_key(p.first, epoch);
+ bufferlist v;
+ mon->store->get(OSD_SNAP_PREFIX, k, v);
+ if (v.length()) {
+ auto q = v.begin();
+ OSDMap::snap_interval_set_t snaps;
+ ::decode(snaps, q);
+ t.union_of(snaps);
+ }
+ }
+ dout(10) << __func__ << " " << p.first << " " << t << dendl;
+ }
+}
+
int OSDMonitor::get_version(version_t ver, bufferlist& bl)
{
if (inc_osd_cache.lookup(ver, &bl)) {
send_incremental(op, start);
}
+ void get_removed_snaps_range(
+ epoch_t start, epoch_t end,
+ mempool::osdmap::map<int64_t,OSDMap::snap_interval_set_t> *gap_removed_snaps);
+
int get_version(version_t ver, bufferlist& bl) override;
int get_version_full(version_t ver, bufferlist& bl) override;