]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: take probed peer's monmap if it has ever joined a quorum
authorSage Weil <sage@inktank.com>
Thu, 17 May 2012 18:08:38 +0000 (11:08 -0700)
committerSage Weil <sage@inktank.com>
Fri, 18 May 2012 23:23:56 +0000 (16:23 -0700)
If we probe a peer and their monmap has actually been part of a started
cluster/quorum, and ours hasn't, take theirs.  Comparing versions isn't
sufficient.

Signed-off-by: Sage Weil <sage@inktank.com>
src/mon/Monitor.cc

index 3172f5cc8296c649110c7af376c2961a011b0734..3a741d61f1bcb923c38ceb113c7a4bf156563ca7 100644 (file)
@@ -568,17 +568,24 @@ void Monitor::handle_probe_reply(MMonProbe *m)
     return;
   }
 
-  // newer map?
-  MonMap *newmap = new MonMap;
-  newmap->decode(m->monmap_bl);
-  if (newmap->get_epoch() > monmap->get_epoch()) {
-    dout(10) << " got new monmap epoch " << newmap->get_epoch()
-            << " > my " << monmap->get_epoch() << dendl;
-    monmap->decode(m->monmap_bl);
-    m->put();
-
-    bootstrap();
-    return;
+  // newer map, or they've joined a quorum and we haven't?
+  bufferlist mybl;
+  monmap->encode(mybl, m->get_connection()->get_features());
+  // make sure it's actually different; the checks below err toward
+  // taking the other guy's map, which could cause us to loop.
+  if (!mybl.contents_equal(m->monmap_bl)) {
+    MonMap *newmap = new MonMap;
+    newmap->decode(m->monmap_bl);
+    if (m->has_ever_joined && (newmap->get_epoch() > monmap->get_epoch() ||
+                              !has_ever_joined)) {
+      dout(10) << " got newer/committed monmap epoch " << newmap->get_epoch()
+              << ", mine was " << monmap->get_epoch() << dendl;
+      monmap->decode(m->monmap_bl);
+      m->put();
+
+      bootstrap();
+      return;
+    }
   }
 
   // rename peer?