Pre-nautilus mons will appear as release 0.
Signed-off-by: Sage Weil <sage@redhat.com>
friend factory;
private:
- static constexpr int HEAD_VERSION = 7;
+ static constexpr int HEAD_VERSION = 8;
static constexpr int COMPAT_VERSION = 5;
public:
set<int32_t> quorum;
uint64_t quorum_features;
mon_feature_t mon_features;
+ uint8_t mon_release = 0;
bufferlist sharing_bl;
map<string,string> metadata;
public:
std::string_view get_type_name() const override { return "election"; }
void print(ostream& out) const override {
- out << "election(" << fsid << " " << get_opname(op) << " " << epoch << ")";
+ out << "election(" << fsid << " " << get_opname(op)
+ << " rel " << (int)mon_release << " e" << epoch << ")";
}
void encode_payload(uint64_t features) override {
encode(sharing_bl, payload);
encode(mon_features, payload);
encode(metadata, payload);
+ encode(mon_release, payload);
}
void decode_payload() override {
auto p = payload.cbegin();
decode(mon_features, p);
if (header.version >= 7)
decode(metadata, p);
+ if (header.version >= 8)
+ decode(mon_release, p);
+ else
+ mon_release = infer_ceph_release_from_mon_features(mon_features);
}
};
}
electing_me = true;
acked_me[mon->rank].cluster_features = CEPH_FEATURES_ALL;
+ acked_me[mon->rank].mon_release = ceph_release();
acked_me[mon->rank].mon_features = ceph::features::mon::get_supported();
mon->collect_metadata(&acked_me[mon->rank].metadata);
leader_acked = -1;
MMonElection *m =
new MMonElection(MMonElection::OP_PROPOSE, epoch, mon->monmap);
m->mon_features = ceph::features::mon::get_supported();
+ m->mon_release = ceph_release();
mon->send_mon_message(m, i);
}
leader_acked = who;
MMonElection *m = new MMonElection(MMonElection::OP_ACK, epoch, mon->monmap);
m->mon_features = ceph::features::mon::get_supported();
+ m->mon_release = ceph_release();
mon->collect_metadata(&m->metadata);
mon->send_mon_message(m, who);
mon_feature_t mon_features = ceph::features::mon::get_supported();
set<int> quorum;
map<int,Metadata> metadata;
+ int min_mon_release = -1;
for (map<int, elector_info_t>::iterator p = acked_me.begin();
p != acked_me.end();
++p) {
cluster_features &= p->second.cluster_features;
mon_features &= p->second.mon_features;
metadata[p->first] = p->second.metadata;
+ if (min_mon_release < 0 || p->second.mon_release < min_mon_release) {
+ min_mon_release = p->second.mon_release;
+ }
}
cancel_timer();
m->quorum_features = cluster_features;
m->mon_features = mon_features;
m->sharing_bl = mon->get_local_commands_bl(mon_features);
+ m->mon_release = min_mon_release;
mon->send_mon_message(m, *p);
}
// tell monitor
mon->win_election(epoch, quorum,
- cluster_features, mon_features, metadata);
+ cluster_features, mon_features, min_mon_release,
+ metadata);
}
// thanks
acked_me[from].cluster_features = m->get_connection()->get_features();
acked_me[from].mon_features = m->mon_features;
+ acked_me[from].mon_release = m->mon_release;
acked_me[from].metadata = m->metadata;
dout(5) << " so far i have {";
for (map<int, elector_info_t>::const_iterator p = acked_me.begin();
// they win
mon->lose_election(epoch, m->quorum, from,
- m->quorum_features, m->mon_features);
+ m->quorum_features, m->mon_features, m->mon_release);
// cancel my timer
cancel_timer();
mon->monmap);
reply->quorum_features = required_features;
reply->mon_features = required_mon_features;
+ reply->mon_release = ceph_release();
mon->features.encode(reply->sharing_bl);
m->get_connection()->send_message(reply);
}
* a pair, which would be weird, a struct to keep them seems appropriate.
*/
struct elector_info_t {
- uint64_t cluster_features;
+ uint64_t cluster_features = 0;
mon_feature_t mon_features;
+ int mon_release = 0;
map<string,string> metadata;
};
win_election(elector.get_epoch(), q,
CEPH_FEATURES_ALL,
ceph::features::mon::get_supported(),
+ ceph_release(),
metadata);
}
void Monitor::win_election(epoch_t epoch, set<int>& active, uint64_t features,
const mon_feature_t& mon_features,
+ int min_mon_release,
const map<int,Metadata>& metadata)
{
dout(10) << __func__ << " epoch " << epoch << " quorum " << active
<< " features " << features
<< " mon_features " << mon_features
+ << " min_mon_release " << min_mon_release
<< dendl;
ceph_assert(is_electing());
state = STATE_LEADER;
quorum = active;
quorum_con_features = features;
quorum_mon_features = mon_features;
+ quorum_min_mon_release = min_mon_release;
pending_metadata = metadata;
outside_quorum.clear();
void Monitor::lose_election(epoch_t epoch, set<int> &q, int l,
uint64_t features,
- const mon_feature_t& mon_features)
+ const mon_feature_t& mon_features,
+ int min_mon_release)
{
state = STATE_PEON;
leader_since = utime_t();
outside_quorum.clear();
quorum_con_features = features;
quorum_mon_features = mon_features;
+ quorum_min_mon_release = min_mon_release;
dout(10) << "lose_election, epoch " << epoch << " leader is mon" << leader
<< " quorum is " << quorum << " features are " << quorum_con_features
<< " mon_features are " << quorum_mon_features
+ << " min_mon_release " << min_mon_release
<< dendl;
paxos->peon_init();
*/
mon_feature_t quorum_mon_features;
+ int quorum_min_mon_release = -1;
+
set<string> outside_quorum;
/**
void win_election(epoch_t epoch, set<int>& q,
uint64_t features,
const mon_feature_t& mon_features,
+ int min_mon_release,
const map<int,Metadata>& metadata);
void lose_election(epoch_t epoch, set<int>& q, int l,
uint64_t features,
- const mon_feature_t& mon_features);
+ const mon_feature_t& mon_features,
+ int min_mon_release);
// end election (called by Elector)
void finish_election();