From b52b081109bb565613de7e6223dda029cb27e4fe Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 29 Jan 2019 13:05:32 -0600 Subject: [PATCH] mon: maintain quorum_min_mon_release Pre-nautilus mons will appear as release 0. Signed-off-by: Sage Weil --- src/messages/MMonElection.h | 11 +++++++++-- src/mon/Elector.cc | 15 +++++++++++++-- src/mon/Elector.h | 3 ++- src/mon/Monitor.cc | 9 ++++++++- src/mon/Monitor.h | 6 +++++- 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/messages/MMonElection.h b/src/messages/MMonElection.h index 20ccbd834f429..0114ea12e7715 100644 --- a/src/messages/MMonElection.h +++ b/src/messages/MMonElection.h @@ -25,7 +25,7 @@ public: friend factory; private: - static constexpr int HEAD_VERSION = 7; + static constexpr int HEAD_VERSION = 8; static constexpr int COMPAT_VERSION = 5; public: @@ -50,6 +50,7 @@ public: set quorum; uint64_t quorum_features; mon_feature_t mon_features; + uint8_t mon_release = 0; bufferlist sharing_bl; map metadata; @@ -75,7 +76,8 @@ private: 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 { @@ -99,6 +101,7 @@ public: encode(sharing_bl, payload); encode(mon_features, payload); encode(metadata, payload); + encode(mon_release, payload); } void decode_payload() override { auto p = payload.cbegin(); @@ -118,6 +121,10 @@ public: 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); } }; diff --git a/src/mon/Elector.cc b/src/mon/Elector.cc index ae97dd6caba09..0e464e6d5a831 100644 --- a/src/mon/Elector.cc +++ b/src/mon/Elector.cc @@ -95,6 +95,7 @@ void Elector::start() } 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; @@ -105,6 +106,7 @@ void Elector::start() 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); } @@ -125,6 +127,7 @@ void Elector::defer(int who) 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); @@ -195,6 +198,7 @@ void Elector::victory() mon_feature_t mon_features = ceph::features::mon::get_supported(); set quorum; map metadata; + int min_mon_release = -1; for (map::iterator p = acked_me.begin(); p != acked_me.end(); ++p) { @@ -202,6 +206,9 @@ void Elector::victory() 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(); @@ -220,12 +227,14 @@ void Elector::victory() 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); } @@ -336,6 +345,7 @@ void Elector::handle_ack(MonOpRequestRef op) // 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::const_iterator p = acked_me.begin(); @@ -388,7 +398,7 @@ void Elector::handle_victory(MonOpRequestRef op) // 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(); @@ -419,6 +429,7 @@ void Elector::nak_old_peer(MonOpRequestRef op) 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); } diff --git a/src/mon/Elector.h b/src/mon/Elector.h index 6d311f8eacdd3..9ba52217e2674 100644 --- a/src/mon/Elector.h +++ b/src/mon/Elector.h @@ -47,8 +47,9 @@ class Elector { * 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 metadata; }; diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index c25d08fb36748..7d8cf5b58ba11 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -2071,6 +2071,7 @@ void Monitor::win_standalone_election() win_election(elector.get_epoch(), q, CEPH_FEATURES_ALL, ceph::features::mon::get_supported(), + ceph_release(), metadata); } @@ -2099,11 +2100,13 @@ void Monitor::_finish_svc_election() void Monitor::win_election(epoch_t epoch, set& active, uint64_t features, const mon_feature_t& mon_features, + int min_mon_release, const map& 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; @@ -2113,6 +2116,7 @@ void Monitor::win_election(epoch_t epoch, set& active, uint64_t features, quorum = active; quorum_con_features = features; quorum_mon_features = mon_features; + quorum_min_mon_release = min_mon_release; pending_metadata = metadata; outside_quorum.clear(); @@ -2183,7 +2187,8 @@ void Monitor::win_election(epoch_t epoch, set& active, uint64_t features, void Monitor::lose_election(epoch_t epoch, set &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(); @@ -2193,9 +2198,11 @@ void Monitor::lose_election(epoch_t epoch, set &q, int l, 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(); diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h index 80d7b7ad11d86..672a1e136e3d8 100644 --- a/src/mon/Monitor.h +++ b/src/mon/Monitor.h @@ -263,6 +263,8 @@ private: */ mon_feature_t quorum_mon_features; + int quorum_min_mon_release = -1; + set outside_quorum; /** @@ -614,10 +616,12 @@ public: void win_election(epoch_t epoch, set& q, uint64_t features, const mon_feature_t& mon_features, + int min_mon_release, const map& metadata); void lose_election(epoch_t epoch, set& 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(); -- 2.39.5