]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: maintain quorum_min_mon_release
authorSage Weil <sage@redhat.com>
Tue, 29 Jan 2019 19:05:32 +0000 (13:05 -0600)
committerSage Weil <sage@redhat.com>
Tue, 12 Feb 2019 18:40:36 +0000 (12:40 -0600)
Pre-nautilus mons will appear as release 0.

Signed-off-by: Sage Weil <sage@redhat.com>
src/messages/MMonElection.h
src/mon/Elector.cc
src/mon/Elector.h
src/mon/Monitor.cc
src/mon/Monitor.h

index 20ccbd834f4295cb2187f964990db6c9ab6f8a17..0114ea12e7715ee39ed41607530a93148b2e9098 100644 (file)
@@ -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<int32_t> quorum;
   uint64_t quorum_features;
   mon_feature_t mon_features;
+  uint8_t mon_release = 0;
   bufferlist sharing_bl;
   map<string,string> 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);
   }
   
 };
index ae97dd6caba094e495c295fe8e903c8d1c8a973d..0e464e6d5a831a286a612d2855e225707a70bd49 100644 (file)
@@ -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<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) {
@@ -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<int, elector_info_t>::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);
 }
index 6d311f8eacdd3119ff2e8d3f933f0a2b0a56e21e..9ba52217e2674925f187070ad76154feb6ed0a26 100644 (file)
@@ -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<string,string> metadata;
   };
 
index c25d08fb3674854fda35aff894135f07c201d6d2..7d8cf5b58ba11e40619aab87646e14e9630729b7 100644 (file)
@@ -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<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;
@@ -2113,6 +2116,7 @@ void Monitor::win_election(epoch_t epoch, set<int>& 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<int>& active, uint64_t features,
 
 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();
@@ -2193,9 +2198,11 @@ void Monitor::lose_election(epoch_t epoch, set<int> &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();
index 80d7b7ad11d86e358ae583ea4aa74a079a6a245e..672a1e136e3d8ef0d202010c180bf8459ce74bab 100644 (file)
@@ -263,6 +263,8 @@ private:
    */
   mon_feature_t quorum_mon_features;
 
+  int quorum_min_mon_release = -1;
+
   set<string> outside_quorum;
 
   /**
@@ -614,10 +616,12 @@ public:
   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();