From 06288a9d10281e4a3cfdc6e69a3e1427b160571c Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 20 Jun 2012 20:33:41 -0700 Subject: [PATCH] mon: track intersection of quorum member features When we form a quorum, also note the intersection of the quorum members' feature bits. This will inform decisions about what encodings we use. This is an imperfect strategy because the quorum may change, and we may have a mon with old code join in and not understand what is going on. However, it does ensure that a majority of the members run new code, so in the absence of other failures we can make progress. Signed-off-by: Sage Weil --- src/mon/Elector.cc | 14 ++++++++++---- src/mon/Elector.h | 5 +++-- src/mon/Monitor.cc | 9 ++++++--- src/mon/Monitor.h | 7 ++++++- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/mon/Elector.cc b/src/mon/Elector.cc index 7c7bb5c2c71e0..515e21a5afa31 100644 --- a/src/mon/Elector.cc +++ b/src/mon/Elector.cc @@ -73,7 +73,7 @@ void Elector::start() bump_epoch(epoch+1); // odd == election cycle start_stamp = ceph_clock_now(g_ceph_context); electing_me = true; - acked_me.insert(mon->rank); + acked_me[mon->rank] = CEPH_FEATURES_ALL; leader_acked = -1; // bcast to everyone else @@ -145,7 +145,13 @@ void Elector::victory() { leader_acked = -1; electing_me = false; - set quorum = acked_me; + + unsigned features = CEPH_FEATURES_ALL; + set quorum; + for (map::iterator p = acked_me.begin(); p != acked_me.end(); ++p) { + quorum.insert(p->first); + features &= p->second; + } cancel_timer(); @@ -163,7 +169,7 @@ void Elector::victory() } // tell monitor - mon->win_election(epoch, quorum); + mon->win_election(epoch, quorum, features); } @@ -237,7 +243,7 @@ void Elector::handle_ack(MMonElection *m) if (electing_me) { // thanks - acked_me.insert(from); + acked_me[from] = m->get_connection()->get_features(); dout(5) << " so far i have " << acked_me << dendl; // is that _everyone_? diff --git a/src/mon/Elector.h b/src/mon/Elector.h index 3f3b508f45b6b..377cb97ac13e3 100644 --- a/src/mon/Elector.h +++ b/src/mon/Elector.h @@ -110,9 +110,10 @@ class Elector { /** * Set containing all those that acked our proposal to become the Leader. * - * If we are acked by everyone in the MonMap, we will declare victory. + * If we are acked by everyone in the MonMap, we will declare + * victory. Also note each peer's feature set. */ - set acked_me; + map acked_me; /** * @} */ diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index f50820d16afe2..6861010508e88 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -927,7 +927,7 @@ void Monitor::win_standalone_election() assert(rank == 0); set q; q.insert(rank); - win_election(1, q); + win_election(1, q, CEPH_FEATURES_ALL); } const utime_t& Monitor::get_leader_since() const @@ -941,7 +941,7 @@ epoch_t Monitor::get_epoch() return elector.get_epoch(); } -void Monitor::win_election(epoch_t epoch, set& active) +void Monitor::win_election(epoch_t epoch, set& active, unsigned features) { if (!is_electing()) reset(); @@ -950,8 +950,11 @@ void Monitor::win_election(epoch_t epoch, set& active) leader_since = ceph_clock_now(g_ceph_context); leader = rank; quorum = active; + quorum_features = features; outside_quorum.clear(); - dout(10) << "win_election, epoch " << epoch << " quorum is " << quorum << dendl; + dout(10) << "win_election, epoch " << epoch << " quorum is " << quorum + << " features are " << quorum_features + << dendl; clog.info() << "mon." << name << "@" << rank << " won leader election with quorum " << quorum << "\n"; diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h index 7c594c3289666..2d7f8818c56d4 100644 --- a/src/mon/Monitor.h +++ b/src/mon/Monitor.h @@ -177,6 +177,7 @@ private: set quorum; // current active set of monitors (if !starting) utime_t leader_since; // when this monitor became the leader, if it is the leader utime_t exited_quorum; // time detected as not in quorum; 0 if in + unsigned quorum_features; ///< intersection of quorum member feature bits set outside_quorum; entity_inst_t slurp_source; @@ -212,12 +213,16 @@ public: q.insert(monmap->get_name(*p)); return q; } + unsigned get_quorum_features() const { + return quorum_features; + } void bootstrap(); void reset(); void start_election(); void win_standalone_election(); - void win_election(epoch_t epoch, set& q); // end election (called by Elector) + void win_election(epoch_t epoch, set& q, + unsigned features); // end election (called by Elector) void lose_election(epoch_t epoch, set& q, int l); // end election (called by Elector) void finish_election(); -- 2.39.5