ctx.send_notify(q.from.osd, {q.query.from, q.query.to,
q.query.epoch_sent,
map_epoch, empty,
- PastIntervals{}});
+ PastIntervals{},
+ PG_FEATURE_CRIMSON_ALL});
}
}
}
pool,
name),
osdmap,
+ PG_FEATURE_CRIMSON_ALL,
this,
this),
scrubber(*this),
q.query.epoch_sent,
osdmap->get_epoch(),
empty,
- PastIntervals()};
+ PastIntervals(),
+ PG_FEATURE_CLASSIC_ALL};
m = new MOSDPGNotify2(spg_t{pgid.pgid, q.query.from},
std::move(notify));
}
p,
_pool,
curmap,
+ PG_FEATURE_CLASSIC_ALL,
this,
this),
pool(recovery_state.get_pgpool()),
spg_t spgid,
const PGPool &_pool,
OSDMapRef curmap,
+ pg_feature_vec_t supported_pg_acting_features,
DoutPrefixProvider *dpp,
PeeringListener *pl)
: state_history(*pl),
pg_whoami(pg_whoami),
info(spgid),
pg_log(cct),
+ local_pg_acting_features(supported_pg_acting_features),
+ pg_acting_features(local_pg_acting_features),
last_require_osd_release(curmap->require_osd_release),
missing_loc(spgid, this, dpp, cct),
machine(this, cct, spgid, dpp, pl, &state_history)
}
}
+ if (is_acting(from)) {
+ pg_acting_features &= notify.pg_features;
+ }
+
// was this a new info? if so, update peers!
if (p == peer_info.end())
update_heartbeat_peers();
// initialize features
acting_features = CEPH_FEATURES_SUPPORTED_DEFAULT;
upacting_features = CEPH_FEATURES_SUPPORTED_DEFAULT;
+ pg_acting_features = local_pg_acting_features;
for (auto p = acting.begin(); p != acting.end(); ++p) {
if (*p == CRUSH_ITEM_NONE)
continue;
query.query_epoch,
get_osdmap_epoch(),
notify_info.second,
- past_intervals));
+ past_intervals,
+ local_pg_acting_features));
} else {
update_history(query.query.history);
fulfill_log(query.from, query.query, query.query_epoch);
ps->get_osdmap_epoch(),
ps->get_osdmap_epoch(),
ps->info,
- ps->past_intervals));
+ ps->past_intervals,
+ ps->local_pg_acting_features));
}
ps->update_heartbeat_peers();
ps->get_osdmap_epoch(),
ps->get_osdmap_epoch(),
ps->info,
- ps->past_intervals));
+ ps->past_intervals,
+ ps->local_pg_acting_features));
}
return discard_event();
}
ps->get_osdmap_epoch(),
ps->get_osdmap_epoch(),
ps->info,
- ps->past_intervals));
+ ps->past_intervals,
+ ps->local_pg_acting_features));
}
return discard_event();
}
psdout(20) << "Common peer features: " << hex << ps->get_min_peer_features() << dec << dendl;
psdout(20) << "Common acting features: " << hex << ps->get_min_acting_features() << dec << dendl;
psdout(20) << "Common upacting features: " << hex << ps->get_min_upacting_features() << dec << dendl;
+ psdout(20) << "Common pg_acting_features: " << hex << ps->get_pg_acting_features() << dec << dendl;
post_event(GotInfo());
}
}
std::set<pg_shard_t> peer_log_requested; ///< logs i've requested (and start stamps)
std::set<pg_shard_t> peer_missing_requested; ///< missing sets requested
+ /// not constexpr because classic/crimson might differ
+ const pg_feature_vec_t local_pg_acting_features;
+
+ /**
+ * acting_pg_features
+ *
+ * PG specific features common to entire acting set. Valid only on primary
+ * after activation.
+ */
+ pg_feature_vec_t pg_acting_features;
+
+
/// features supported by all peers
uint64_t peer_features = CEPH_FEATURES_SUPPORTED_DEFAULT;
/// features supported by acting set
spg_t spgid,
const PGPool &pool,
OSDMapRef curmap,
+ pg_feature_vec_t supported_pg_acting_features,
DoutPrefixProvider *dpp,
PeeringListener *pl);
/// Get feature vector common to up/acting set
uint64_t get_min_upacting_features() const { return upacting_features; }
+ /// Get pg features common to acting set
+ pg_feature_vec_t get_pg_acting_features() const { return pg_acting_features; }
// Flush control interface
private:
// -- pg_notify_t --
void pg_notify_t::encode(ceph::buffer::list &bl) const
{
- ENCODE_START(3, 2, bl);
+ ENCODE_START(4, 2, bl);
encode(query_epoch, bl);
encode(epoch_sent, bl);
encode(info, bl);
encode(to, bl);
encode(from, bl);
encode(past_intervals, bl);
+ encode(pg_features, bl);
ENCODE_FINISH(bl);
}
if (struct_v >= 3) {
decode(past_intervals, bl);
}
+ if (struct_v >= 4) {
+ decode(pg_features, bl);
+ }
DECODE_FINISH(bl);
}
{
o.push_back(new pg_notify_t);
o.push_back(new pg_notify_t(shard_id_t(3), shard_id_t::NO_SHARD, 1, 1,
- pg_info_t(spg_t(pg_t(0,10), shard_id_t(-1))), PastIntervals()));
+ pg_info_t(spg_t(pg_t(0,10), shard_id_t(-1))), PastIntervals(),
+ PG_FEATURE_CLASSIC_ALL));
o.push_back(new pg_notify_t(shard_id_t(0), shard_id_t(2), 3, 10,
- pg_info_t(spg_t(pg_t(10,10), shard_id_t(2))), PastIntervals()));
+ pg_info_t(spg_t(pg_t(10,10), shard_id_t(2))), PastIntervals(),
+ PG_FEATURE_CLASSIC_ALL));
}
ostream &operator<<(ostream &lhs, const pg_notify_t ¬ify)
#include "librados/ListObjectImpl.h"
#include "compressor/Compressor.h"
#include "osd_perf_counters.h"
+#include "pg_features.h"
#define CEPH_OSD_ONDISK_MAGIC "ceph osd volume v026"
shard_id_t to;
shard_id_t from;
PastIntervals past_intervals;
+ pg_feature_vec_t pg_features = PG_FEATURE_NONE;
pg_notify_t() :
query_epoch(0), epoch_sent(0), to(shard_id_t::NO_SHARD),
from(shard_id_t::NO_SHARD) {}
epoch_t query_epoch,
epoch_t epoch_sent,
const pg_info_t &info,
- const PastIntervals& pi)
+ const PastIntervals& pi,
+ pg_feature_vec_t pg_features)
: query_epoch(query_epoch),
epoch_sent(epoch_sent),
info(info), to(to), from(from),
- past_intervals(pi) {
+ past_intervals(pi), pg_features(pg_features) {
ceph_assert(from == info.pgid.shard);
}
void encode(ceph::buffer::list &bl) const;
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+/* This feature set defines a set of features supported by OSDs once a PG has
+ * gone active.
+ * Mechanically, pretty much the same as include/ceph_features.h */
+
+using pg_feature_vec_t = uint64_t;
+static constexpr pg_feature_vec_t PG_FEATURE_INCARNATION_1 = 0ull;
+
+#define DEFINE_PG_FEATURE(bit, incarnation, name) \
+ static constexpr pg_feature_vec_t PG_FEATURE_##name = (1ull << bit); \
+ static constexpr pg_feature_vec_t PG_FEATUREMASK_##name = \
+ (1ull << bit) | PG_FEATURE_INCARNATION_##incarnation;
+
+#define PG_HAVE_FEATURE(x, name) \
+ (((x) & (PG_FEATUREMASK_##name)) == (PG_FEATUREMASK_##name))
+
+static constexpr pg_feature_vec_t PG_FEATURE_NONE = 0ull;
+static constexpr pg_feature_vec_t PG_FEATURE_CLASSIC_ALL = 0ull;
+static constexpr pg_feature_vec_t PG_FEATURE_CRIMSON_ALL = 0ull;