]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: limit initial quorum to mon_initial_members
authorSage Weil <sage@inktank.com>
Thu, 17 May 2012 20:27:30 +0000 (13:27 -0700)
committerSage Weil <sage@inktank.com>
Fri, 18 May 2012 23:23:57 +0000 (16:23 -0700)
This is a two-stage process.

 * If we start up, and have never joined a quorum, and initial members are
   specified, only include them in the monmap; put all others in the
   extra probe list.
 * We add missing members if necessary to make the monmap (and initial
   quorum) the right size.
 * If we probe someone that *has* participated in a successful quorum, we
   get their monmap, and restart, so this is moot.
 * We only call an election to create a new cluster if outside_quorum gets
   big enough (it will only include initial members) and if it includes us.

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

index 995807cbcaea49528632d15a4b4ef301333942f8..ca7facf1199429f29c4ba60749419a497354744b 100644 (file)
@@ -49,6 +49,7 @@
 
 #include "include/color.h"
 #include "include/ceph_fs.h"
+#include "include/str_list.h"
 
 #include "OSDMonitor.h"
 #include "MDSMonitor.h"
@@ -226,8 +227,6 @@ int Monitor::init()
 {
   lock.Lock();
 
-  rank = monmap->get_rank(messenger->get_myaddr());
-  
   dout(1) << "init fsid " << monmap->fsid << dendl;
   
   assert(!logger);
@@ -283,6 +282,54 @@ int Monitor::init()
   has_ever_joined = store->exists_bl_ss("joined");
   dout(10) << "has_ever_joined = " << (int)has_ever_joined << dendl;
 
+  if (!has_ever_joined) {
+    // impose initial quorum restrictions?
+    list<string> initial_members;
+    get_str_list(g_conf->mon_initial_members, initial_members);
+    if (initial_members.size()) {
+      dout(1) << " initial_members " << initial_members << ", filtering seed monmap" << dendl;
+
+      // remove non-initial members
+      unsigned i = 0;
+      while (i < monmap->size()) {
+       string n = monmap->get_name(i);
+       if (std::find(initial_members.begin(), initial_members.end(), n) != initial_members.end()) {
+         dout(1) << " keeping " << n << " " << monmap->get_addr(i) << dendl;
+         i++;
+         continue;
+       }
+
+       dout(1) << " removing " << monmap->get_name(i) << " " << monmap->get_addr(i) << dendl;
+       extra_probe_peers.insert(monmap->get_addr(i));
+       monmap->remove(n);
+       assert(!monmap->contains(n));
+      }
+
+      // add missing initial members
+      for (list<string>::iterator p = initial_members.begin(); p != initial_members.end(); ++p) {
+       if (!monmap->contains(*p)) {
+         entity_addr_t a;
+         a.set_family(AF_INET);
+         for (int n=1; ; n++) {
+           a.set_port(n);
+           if (!monmap->contains(a))
+             break;
+         }
+         dout(1) << " adding " << *p << " " << a << dendl;
+         monmap->add(*p, a);
+         assert(monmap->contains(*p));
+       }
+      }
+
+      dout(10) << " monmap is " << *monmap << dendl;
+    }
+
+    // (re)calc my rank, in case it changed
+    rank = monmap->get_rank(name);
+    messenger->set_myname(entity_name_t::MON(rank));
+    messenger->mark_down_all();
+  }
+
   // init paxos
   for (int i = 0; i < PAXOS_NUM; ++i) {
     paxos[i]->init();
@@ -573,6 +620,7 @@ void Monitor::handle_probe_probe(MMonProbe *m)
 void Monitor::handle_probe_reply(MMonProbe *m)
 {
   dout(10) << "handle_probe_reply " << m->get_source_inst() << *m << dendl;
+  dout(10) << " monmap is " << *monmap << dendl;
 
   if (!is_probing()) {
     m->put();