]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
monclient: refactor MonMap into MonClient
authorSage Weil <sage@newdream.net>
Fri, 26 Jun 2009 20:49:12 +0000 (13:49 -0700)
committerSage Weil <sage@newdream.net>
Fri, 26 Jun 2009 22:10:27 +0000 (15:10 -0700)
15 files changed:
src/ceph.cc
src/cfuse.cc
src/client/Client.cc
src/client/Client.h
src/cmds.cc
src/config.cc
src/config.h
src/cosd.cc
src/csyn.cc
src/dumpjournal.cc
src/librados.cc
src/mon/MonClient.cc
src/mon/MonClient.h
src/mon/MonMap.h
src/testmsgr.cc

index 19df388c39e5fd41806e47bd229cac0718af7b5c..8b9415333c6d88d1d76a0063ab7844517f0d2f56 100644 (file)
@@ -45,8 +45,8 @@ extern "C" {
 Mutex lock("ceph.cc lock");
 Cond cond;
 Messenger *messenger = 0;
-MonMap monmap;
 SafeTimer timer(lock);
+MonClient mc;
 
 const char *outfile = 0;
 
@@ -106,8 +106,8 @@ void handle_notify(MMonObserveNotify *notify)
          << (notify->is_latest ? " (latest)" : "")
          << dendl;
   
-  if (ceph_fsid_compare(&notify->fsid, &monmap.fsid)) {
-    dout(0) << notify->get_source_inst() << " notify fsid " << notify->fsid << " != " << monmap.fsid << dendl;
+  if (ceph_fsid_compare(&notify->fsid, &mc.monmap.fsid)) {
+    dout(0) << notify->get_source_inst() << " notify fsid " << notify->fsid << " != " << mc.monmap.fsid << dendl;
     delete notify;
     return;
   }
@@ -230,14 +230,14 @@ static void send_observe_requests(bool newmon)
   if (is_timeout)
     return;
 
-  int mon = monmap.pick_mon(newmon);
+  int mon = mc.monmap.pick_mon(newmon);
   bool sent = false;
   for (int i=0; i<PAXOS_NUM; i++) {
     if (registered.count(i))
       continue;
-    MMonObserve *m = new MMonObserve(monmap.fsid, i, map_ver[i]);
+    MMonObserve *m = new MMonObserve(mc.monmap.fsid, i, map_ver[i]);
     dout(1) << "mon" << mon << " <- observe " << get_paxos_name(i) << dendl;
-    messenger->send_message(m, monmap.get_inst(mon));
+    messenger->send_message(m, mc.monmap.get_inst(mon));
     sent = true;
   }
 
@@ -280,15 +280,15 @@ Context *event = 0;
 
 void get_status(bool newmon)
 {
-  int mon = monmap.pick_mon(newmon);
+  int mon = mc.monmap.pick_mon(newmon);
 
   vector<string> vcmd(2);
   vcmd[0] = prefix[which];
   vcmd[1] = "stat";
   
-  MMonCommand *m = new MMonCommand(monmap.fsid, last_seen_version);
+  MMonCommand *m = new MMonCommand(mc.monmap.fsid, last_seen_version);
   m->cmd.swap(vcmd);
-  messenger->send_message(m, monmap.get_inst(mon));
+  messenger->send_message(m, mc.monmap.get_inst(mon));
 
   event = new C_Refresh;
   timer.add_event_after(.2, event);
@@ -375,20 +375,20 @@ void send_command();
 
 struct C_Resend : public Context {
   void finish(int) {
-    monmap.pick_mon(true);  // pick a new mon
+    mc.monmap.pick_mon(true);  // pick a new mon
     if (!reply)
       send_command();
   }
 };
 void send_command()
 {
-  MMonCommand *m = new MMonCommand(monmap.fsid, last_seen_version);
+  MMonCommand *m = new MMonCommand(mc.monmap.fsid, last_seen_version);
   m->cmd = pending_cmd;
   m->get_data() = pending_bl;
 
-  int mon = monmap.pick_mon();
+  int mon = mc.monmap.pick_mon();
   generic_dout(0) << "mon" << mon << " <- " << pending_cmd << dendl;
-  messenger->send_message(m, monmap.get_inst(mon));
+  messenger->send_message(m, mc.monmap.get_inst(mon));
 
   resend_event = new C_Resend;
   timer.add_event_after(15.0, resend_event);
@@ -618,8 +618,7 @@ int main(int argc, const char **argv, const char *envp[])
   }
 
   // get monmap
-  MonClient mc(&monmap, NULL);
-  if (!mc.get_monmap())
+  if (mc.build_initial_monmap() < 0)
     return -1;
   
   // start up network
index 119abddc4f4e026428c4c73e027bc75917406236..4a6b0102bf8301f7341f37433ce703d639d71597 100644 (file)
@@ -63,9 +63,8 @@ int main(int argc, const char **argv, const char *envp[]) {
   }
 
   // get monmap
-  MonMap monmap;
-  MonClient mc(&monmap, NULL);
-  if (!mc.get_monmap())
+  MonClient mc;
+  if (mc.build_initial_monmap() < 0)
     return -1;
 
   // start up network
@@ -73,7 +72,7 @@ int main(int argc, const char **argv, const char *envp[]) {
   rank.bind();
   cout << "bound to " << rank.get_rank_addr() << ", mounting ceph" << std::endl;
 
-  Client *client = new Client(rank.register_entity(entity_name_t::CLIENT()), &monmap);
+  Client *client = new Client(rank.register_entity(entity_name_t::CLIENT()), &mc);
 
   rank.start();
 
index bd231da743e104f2db9b396f370b6afd2f8d8090..900dca1a456de234bd5ceffdc267c6fe41ebe3b6 100644 (file)
@@ -101,11 +101,13 @@ void client_flush_set_callback(void *p, inodeno_t ino)
 
 // cons/des
 
-Client::Client(Messenger *m, MonMap *mm) : timer(client_lock), client_lock("Client::client_lock")
+Client::Client(Messenger *m, MonClient *mc) : timer(client_lock), client_lock("Client::client_lock")
 {
   // which client am i?
   whoami = m->get_myname().num();
-  monmap = mm;
+
+  monclient = mc;
+  monclient->set_messenger(m);
   
   tick_event = 0;
 
@@ -128,12 +130,10 @@ Client::Client(Messenger *m, MonMap *mm) : timer(client_lock), client_lock("Clie
   // set up messengers
   messenger = m;
 
-  monclient = new MonClient(monmap, messenger);
-
   // osd interfaces
   osdmap = new OSDMap;     // initially blank.. see mount()
   mdsmap = new MDSMap;
-  objecter = new Objecter(messenger, monmap, osdmap, client_lock);
+  objecter = new Objecter(messenger, &monclient->monmap, osdmap, client_lock);
   objecter->set_client_incarnation(0);  // client always 0, for now.
   objectcacher = new ObjectCacher(objecter, client_lock, 
                                  0,                            // all ack callback
@@ -158,7 +158,6 @@ Client::~Client()
   if (mdsmap) { delete mdsmap; mdsmap = 0; }
 
   unlink_dispatcher(monclient);
-  delete monclient;
 
   if (messenger)
     messenger->destroy();
@@ -247,8 +246,6 @@ void Client::init()
   messenger->set_dispatcher(this);
   link_dispatcher(monclient);
 
-  objecter->init();
-
   tick();
 
   // do logger crap only once per process.
@@ -809,9 +806,9 @@ MClientReply *Client::make_request(MClientRequest *req,
 
       if (!mdsmap->is_active(mds)) {
        dout(10) << "no address for mds" << mds << ", requesting new mdsmap" << dendl;
-       int mon = monmap->pick_mon();
-       messenger->send_message(new MMDSGetMap(monmap->fsid, mdsmap->get_epoch()+1),
-                               monmap->get_inst(mon));
+       int mon = monclient->monmap.pick_mon();
+       messenger->send_message(new MMDSGetMap(monclient->monmap.fsid, mdsmap->get_epoch()+1),
+                               monclient->monmap.get_inst(mon));
        waiting_for_mdsmap.push_back(&cond);
        cond.Wait(client_lock);
 
@@ -2291,6 +2288,7 @@ int Client::mount()
   ticket = monclient->get_ticket();
 
   objecter->signed_ticket = signed_ticket;
+  objecter->init();
 
   mounted = true;
   
index 93b269f80717068ffb438db424241a829e7f6c07..bea621056f205e1de85676232fdb08202a441a9f 100644 (file)
@@ -602,7 +602,6 @@ public:
   MonClient *monclient;
   Messenger *messenger;  
   int whoami;
-  MonMap *monmap;
 
   ceph_client_ticket ticket;
   bufferlist signed_ticket;
@@ -844,7 +843,7 @@ protected:
   bool dispatch_impl(Message *m);
 
  public:
-  Client(Messenger *m, MonMap *mm);
+  Client(Messenger *m, MonClient *mc);
   ~Client();
   void tear_down_cache();   
 
index 457f30a3a7bee00e14e35c44ee6048c8ffe97009..aaa453fafd4ca8ba5b44855f157dc57c51298a19 100644 (file)
@@ -63,16 +63,14 @@ int main(int argc, const char **argv)
   if (g_conf.clock_tare) g_clock.tare();
 
   // get monmap
-  MonMap monmap;
-  MonClient mc(&monmap, NULL);
-  if (!mc.get_monmap())
+  MonClient mc;
+  if (mc.build_initial_monmap() < 0)
     return -1;
 
   SimpleMessenger rank;
   rank.bind();
   cout << "starting mds." << g_conf.id
        << " at " << rank.get_rank_addr() 
-       << " fsid " << monmap.get_fsid()
        << std::endl;
 
   Messenger *m = rank.register_entity(entity_name_t::MDS(-1));
@@ -88,7 +86,7 @@ int main(int argc, const char **argv)
   rank.start();
   
   // start mds
-  MDS *mds = new MDS(g_conf.id, m, &monmap);
+  MDS *mds = new MDS(g_conf.id, m, &mc.monmap);
   mds->init();
   
   rank.wait();
index bed319bbe984923199d99a69176b5e9668850bd1..7944164c3521e287bc522c21bc8d58d7cae8763e 100644 (file)
@@ -214,6 +214,20 @@ bool parse_ip_port(const char *s, entity_addr_t& a, const char **end)
   return true;
 }
 
+bool parse_ip_port_vec(const char *s, vector<entity_addr_t>& vec)
+{
+  const char *p = s;
+  const char *end = p + strlen(p);
+  while (p < end) {
+    entity_addr_t a;
+    if (!parse_ip_port(p, a, &p))
+      return false;
+    vec.push_back(a);
+  }
+  return true;
+}
+
+
 
 
 void parse_config_option_string(string& s)
index a326de07308a1ce8165247178fc0055edafd7b35..cc3a46b06c15bd314220c4ae83197d7e81e6874b 100644 (file)
@@ -371,6 +371,7 @@ void parse_config_options(std::vector<const char*>& args);
 void parse_config_option_string(string& s);
 
 extern bool parse_ip_port(const char *s, entity_addr_t& addr, const char **end=0);
+extern bool parse_ip_port_vec(const char *s, vector<entity_addr_t>& vec);
 
 void generic_server_usage();
 void generic_client_usage();
index 0f60346e4ea39af4d938e2028cf3543afa2d4467..6c49a468dc9fe014a723d136e4deb127019f3eec 100644 (file)
@@ -80,18 +80,19 @@ int main(int argc, const char **argv)
   _dout_create_courtesy_output_symlink("osd", whoami);
 
   // get monmap
-  MonMap monmap;
-  MonClient mc(&monmap, NULL);
-  if (!mc.get_monmap())
+  MonClient mc;
+  if (mc.build_initial_monmap() < 0)
+    return -1;
+  if (mc.get_monmap() < 0)
     return -1;
 
   if (mkfs) {
-    int err = OSD::mkfs(g_conf.osd_data, g_conf.osd_journal, monmap.fsid, whoami);
+    int err = OSD::mkfs(g_conf.osd_data, g_conf.osd_journal, mc.monmap.fsid, whoami);
     if (err < 0) {
       cerr << "error creating empty object store in " << g_conf.osd_data << ": " << strerror(-err) << std::endl;
       exit(1);
     }
-    cout << "created object store for osd" << whoami << " fsid " << monmap.fsid << " on " << g_conf.osd_data << std::endl;
+    cout << "created object store for osd" << whoami << " fsid " << mc.monmap.fsid << " on " << g_conf.osd_data << std::endl;
     exit(0);
   }
 
@@ -115,8 +116,8 @@ int main(int argc, const char **argv)
     cerr << "OSD magic " << magic << " != my " << CEPH_OSD_ONDISK_MAGIC << std::endl;
     exit(1);
   }
-  if (ceph_fsid_compare(&fsid, &monmap.fsid)) {
-    cerr << "OSD fsid " << fsid << " != monmap fsid " << monmap.fsid << std::endl;
+  if (ceph_fsid_compare(&fsid, &mc.monmap.fsid)) {
+    cerr << "OSD fsid " << fsid << " != monmap fsid " << mc.monmap.fsid << std::endl;
     exit(1);
   }
 
@@ -128,7 +129,7 @@ int main(int argc, const char **argv)
        << " at " << rank.get_rank_addr() 
        << " osd_data " << g_conf.osd_data
        << " " << ((g_conf.osd_journal && g_conf.osd_journal[0]) ? g_conf.osd_journal:"(no journal)")
-       << " fsid " << monmap.fsid
+       << " fsid " << mc.monmap.fsid
        << std::endl;
 
   g_timer.shutdown();
@@ -154,7 +155,7 @@ int main(int argc, const char **argv)
   rank.start();
 
   // start osd
-  OSD *osd = new OSD(whoami, m, hbm, &monmap, g_conf.osd_data, g_conf.osd_journal);
+  OSD *osd = new OSD(whoami, m, hbm, &mc.monmap, g_conf.osd_data, g_conf.osd_journal);
   if (osd->init() < 0) {
     cout << "error initializing osd" << std::endl;
     return 1;
index e7b93c76344e655b8a63d4210526fc3e5790758d..1db9ca82bbd598e6d8bd8071d162d36a74242f63 100644 (file)
@@ -50,9 +50,8 @@ int main(int argc, const char **argv, char *envp[])
   if (g_conf.clock_tare) g_clock.tare();
 
   // get monmap
-  MonMap monmap;
-  MonClient mc(&monmap, NULL);
-  if (!mc.get_monmap())
+  MonClient mc;
+  if (mc.build_initial_monmap() < 0)
     return -1;
 
   // start up network
@@ -69,7 +68,7 @@ int main(int argc, const char **argv, char *envp[])
 
   cout << "mounting and starting " << g_conf.num_client << " syn client(s)" << std::endl;
   for (int i=0; i<g_conf.num_client; i++) {
-    Client *client = new Client(rank.register_entity(entity_name_t(entity_name_t::TYPE_CLIENT,-1)), &monmap);
+    Client *client = new Client(rank.register_entity(entity_name_t(entity_name_t::TYPE_CLIENT,-1)), &mc);
     SyntheticClient *syn = new SyntheticClient(client);
     clients.push_back(client);
     synclients.push_back(syn);
index 9c7f9f9293659f62d6a40ce85339112c4faaa8b5..7c39b37ce1922d415960357298a04d0857872c21 100644 (file)
@@ -82,9 +82,8 @@ int main(int argc, const char **argv, const char *envp[])
   int mds = 0;
 
   // get monmap
-  MonMap monmap;
-  MonClient mc(&monmap, NULL);
-  if (!mc.get_monmap())
+  MonClient mc;
+  if (mc.build_initial_monmap() < 0)
     return -1;
   
   // start up network
@@ -98,7 +97,7 @@ int main(int argc, const char **argv, const char *envp[])
   inodeno_t ino = MDS_INO_LOG_OFFSET + mds;
   unsigned pg_pool = CEPH_METADATA_RULE;
 
-  objecter = new Objecter(messenger, &monmap, &osdmap, lock);
+  objecter = new Objecter(messenger, &mc.monmap, &osdmap, lock);
   journaler = new Journaler(ino, pg_pool, CEPH_FS_ONDISK_MAGIC, objecter, 0, 0,  &lock);
 
   objecter->set_client_incarnation(0);
index 1c7093b06f3f51474dfaa7494ad8e779e185312a..78059c6a8c14d25e88cf279951b04f4ceb231995 100644 (file)
@@ -52,7 +52,6 @@ using namespace std;
 
 class RadosClient : public Dispatcher
 {
-  MonMap monmap;
   OSDMap osdmap;
   Messenger *messenger;
   MonClient monclient;
@@ -68,7 +67,7 @@ class RadosClient : public Dispatcher
 
  
 public:
-  RadosClient() : messenger(NULL), monclient(&monmap, NULL), lock("radosclient") {}
+  RadosClient() : messenger(NULL), lock("radosclient") {}
   ~RadosClient();
   bool init();
   void shutdown();
@@ -266,13 +265,11 @@ public:
 bool RadosClient::init()
 {
   // get monmap
-  if (!monclient.get_monmap())
+  if (monclient.build_initial_monmap() < 0)
     return false;
 
   rank.bind();
-  dout(1) << "starting at " << rank.get_rank_addr() 
-         << " fsid " << monmap.get_fsid()
-         << dendl;
+  dout(1) << "starting at " << rank.get_rank_addr() << dendl;
 
   messenger = rank.register_entity(entity_name_t::CLIENT(-1));
   assert_warn(messenger);
@@ -290,7 +287,7 @@ bool RadosClient::init()
 
   monclient.link_dispatcher(this);
 
-  objecter = new Objecter(messenger, &monmap, &osdmap, lock);
+  objecter = new Objecter(messenger, &monclient.monmap, &osdmap, lock);
   if (!objecter)
     return false;
 
index dfc822839431406c90aa21bcbb6561ad6d9e73bf..fc0852b5d10543d6fc660d9dd69b6281df7cc290 100644 (file)
 #undef dout_prefix
 #define dout_prefix *_dout << dbeginl << "monclient: "
 
-Mutex monmap_lock("monmap_lock");
-Cond monmap_cond;
-bufferlist monmap_bl;
 
-int MonClient::probe_mon(MonMap *pmonmap) 
+/*
+ * build an initial monmap with any known monitor
+ * addresses.
+ */
+int MonClient::build_initial_monmap()
 {
-  vector<entity_addr_t> monaddrs;
-
-  const char *p = g_conf.mon_host;
-  const char *end = p + strlen(p);
-  while (p < end) {
-    entity_addr_t a;
-    if (parse_ip_port(p, a, &p)) {
-      monaddrs.push_back(a);
-    } else {
-      break;
+  // file?
+  if (g_conf.monmap) {
+    const char *monmap_fn = g_conf.monmap;
+    int r = monmap.read(monmap_fn);
+    if (r >= 0)
+      return 0;
+    cerr << "unable to read monmap from " << monmap_fn << ": " << strerror(errno) << std::endl;
+  }
+
+  // -m foo?
+  if (g_conf.mon_host) {
+    vector<entity_addr_t> addrs;
+    if (parse_ip_port_vec(g_conf.mon_host, addrs)) {
+      for (unsigned i=0; i<addrs.size(); i++) {
+       entity_inst_t inst;
+       inst.name = entity_name_t::MON(i);
+       inst.addr = addrs[i];
+       monmap.add_mon(inst);
+      }
+      return 0;
     }
+    cerr << "unable to parse addrs in '" << g_conf.mon_host << "'" << std::endl;
   }
-  if (monaddrs.empty()) {
-    cerr << "couldn't parse ip:port(s) from '" << g_conf.mon_host << "'" << std::endl;
-    return -1;
+
+  // config file?
+  ConfFile a(g_conf.conf);
+  ConfFile b("ceph.conf");
+  ConfFile *c = 0;
+  
+  if (a.parse())
+    c = &a;
+  else if (b.parse())
+    c = &b;
+  if (c) {
+    static string monstr;
+    for (int i=0; i<15; i++) {
+      char monname[20];
+      char *val = 0;
+      sprintf(monname, "mon%d", i);
+      c->read(monname, "mon addr", &val, 0);
+      if (!val || !val[0])
+       break;
+      
+      entity_inst_t inst;
+      if (!parse_ip_port(val, inst.addr)) {
+       cerr << "unable to parse conf's addr for " << monname << " (" << val << ")" << std::endl;
+       continue;
+      }
+      inst.name = entity_name_t::MON(monmap.mon_inst.size());
+      monmap.add_mon(inst);
+    }
+    if (monmap.size())
+      return 0;
+    cerr << "unable to find any monitors in conf" << std::endl;
+    return -EINVAL;
   }
 
+  cerr << "please specify monitors via -m monaddr or -c ceph.conf" << std::endl;
+  return -ENOENT;
+}
+
+int MonClient::get_monmap()
+{
+  dout(10) << "get_monmap" << dendl;
+  Mutex::Locker l(monc_lock);
+  
   SimpleMessenger rank; 
 
   rank.bind();
-  dout(1) << " connecting to monitor(s) at " << monaddrs << " ..." << dendl;
   
   Messenger *msgr = rank.register_entity(entity_name_t::CLIENT(-1));
   msgr->set_dispatcher(this);
-
+  
   rank.start(true);  // do not daemonize!
   
   int attempt = 10;
   int i = 0;
-  monmap_lock.Lock();
+
   srand(getpid());
-  while (monmap_bl.length() == 0) {
-    i = rand() % monaddrs.size();
-    dout(10) << "querying " << monaddrs[i] << dendl;
-    entity_inst_t mi;
-    mi.addr = monaddrs[i];
-    mi.name = entity_name_t::MON(0);  // FIXME HRM!
-    msgr->send_message(new MMonGetMap, mi);
+  while (monmap.epoch == 0) {
+    i = rand() % monmap.mon_inst.size();
+    dout(10) << "querying " << monmap.mon_inst[i] << dendl;
+    msgr->send_message(new MMonGetMap, monmap.mon_inst[i]);
     
     if (--attempt == 0)
       break;
-
+    
     utime_t interval(1, 0);
-    monmap_cond.WaitInterval(monmap_lock, interval);
-  }
-  monmap_lock.Unlock();
-
-  if (monmap_bl.length()) {
-    pmonmap->decode(monmap_bl);
-    dout(1) << "[got monmap from " << monaddrs[i] << " fsid " << pmonmap->fsid << "]" << dendl;
+    map_cond.WaitInterval(monc_lock, interval);
   }
+  
   msgr->shutdown();
   rank.wait();
   msgr->destroy();
 
-  if (monmap_bl.length())
+  if (monmap.epoch)
     return 0;
-
-  cerr << "unable to fetch monmap from " << monaddrs << std::endl;
-  return -1; // failed
-}
-
-MonMap *MonClient::get_monmap()
-{
-  char *val = 0;
-  char monname[10];
-
-  if (g_conf.monmap) {
-    // file?
-    const char *monmap_fn = g_conf.monmap;
-    int r = pmonmap->read(monmap_fn);
-    if (r >= 0) {
-      vector<entity_inst_t>::iterator iter = pmonmap->mon_inst.begin();
-      unsigned int i;
-      const sockaddr_in *ipaddr;
-      entity_addr_t conf_addr;
-      ConfFile a(g_conf.conf);
-      ConfFile b("ceph.conf");
-      ConfFile *c = 0;
-
-      dout(1) << "[opened monmap at " << monmap_fn << " fsid " << pmonmap->fsid << "]" << dendl;
-
-      if (a.parse())
-        c = &a;
-      else if (b.parse())
-        c = &b;
-      if (c) {
-        for (i=0; i<pmonmap->mon_inst.size(); i++) {
-          ipaddr = &pmonmap->mon_inst[i].addr.ipaddr;
-          sprintf(monname, "mon%d", i);
-          if (c->read(monname, "mon addr", &val, 0)) {
-            if (parse_ip_port(val, conf_addr, NULL)) {
-              if ((ipaddr->sin_addr.s_addr != conf_addr.ipaddr.sin_addr.s_addr) ||
-                (ipaddr->sin_port != conf_addr.ipaddr.sin_port)) {
-                   cerr << "WARNING: 'mon addr' config option (" << monname << ") does not match monmap file" << std::endl
-                        << "         continuing with monmap configuration" << std::endl;
-              }
-           }
-          }
-        }
-      }
-
-      return pmonmap;
-    }
-
-    cerr << "unable to read monmap from " << monmap_fn << ": " << strerror(errno) << std::endl;
-  }
-
-  if (!g_conf.mon_host) {
-    // cluster conf?
-    ConfFile a(g_conf.conf);
-    ConfFile b("ceph.conf");
-    ConfFile *c = 0;
-
-    if (a.parse())
-      c = &a;
-    else if (b.parse())
-      c = &b;
-    if (c) {
-      static string monstr;
-      for (int i=0; i<15; i++) {
-       sprintf(monname, "mon%d", i);
-       c->read(monname, "mon addr", &val, 0);
-       if (!val || !val[0])
-         break;
-       
-       if (monstr.length())
-         monstr += ",";
-       monstr += val;
-      }
-      g_conf.mon_host = strdup(monstr.c_str());
-    }
-  }
-
-  // probe?
-  if (g_conf.mon_host &&
-      probe_mon(pmonmap) == 0)  
-    return pmonmap;
-
-  cerr << "must specify monitor address (-m monaddr) or cluster conf (-c ceph.conf) or monmap file (-M monmap)" << std::endl;
-  return NULL;
+  return -1;
 }
 
-void MonClient::handle_monmap(MMonMap *m)
-{
-  dout(10) << "handle_monmap " << *m << dendl;
-  monmap_lock.Lock();
-  monmap_bl = m->monmapbl;
-  monmap_cond.Signal();
-  monmap_lock.Unlock();
-  delete m;
-}
 
 bool MonClient::dispatch_impl(Message *m)
 {
@@ -198,6 +147,17 @@ bool MonClient::dispatch_impl(Message *m)
   return false;
 }
 
+void MonClient::handle_monmap(MMonMap *m)
+{
+  dout(10) << "handle_monmap " << *m << dendl;
+  monc_lock.Lock();
+  bufferlist::iterator p = m->monmapbl.begin();
+  ::decode(monmap, p);
+  map_cond.Signal();
+  monc_lock.Unlock();
+  delete m;
+}
+
 
 
 // -------------------
@@ -206,10 +166,10 @@ bool MonClient::dispatch_impl(Message *m)
 void MonClient::_try_mount(double timeout)
 {
   dout(10) << "_try_mount" << dendl;
-  int mon = pmonmap->pick_mon();
+  int mon = monmap.pick_mon();
   dout(2) << "sending client_mount to mon" << mon << dendl;
   messenger->set_dispatcher(this);
-  messenger->send_message(new MClientMount, pmonmap->get_inst(mon));
+  messenger->send_message(new MClientMount, monmap.get_inst(mon));
 
   // schedule timeout?
   assert(mount_timeout_event == 0);
@@ -267,8 +227,13 @@ void MonClient::handle_mount_ack(MClientMountAck* m)
 {
   dout(10) << "handle_mount_ack " << *m << dendl;
 
+  // monmap
+  bufferlist::iterator p = m->monmap_bl.begin();
+  ::decode(monmap, p);
+
+  // ticket
   signed_ticket = m->signed_ticket;
-  bufferlist::iterator p = signed_ticket.begin();
+  p = signed_ticket.begin();
   ::decode(ticket, p);
 
   messenger->reset_myname(m->get_dest());
@@ -286,9 +251,9 @@ int MonClient::unmount()
 
   // fixme: this should retry and time out too
 
-  int mon = pmonmap->pick_mon();
+  int mon = monmap.pick_mon();
   dout(2) << "sending client_unmount to mon" << mon << dendl;
-  messenger->send_message(new MClientUnmount, pmonmap->get_inst(mon));
+  messenger->send_message(new MClientUnmount, monmap.get_inst(mon));
   
   while (mounted)
     mount_cond.Wait(monc_lock);
index 97001ea235456723da66f75d6b2adec4c0988084..8def162f41ad83a5c4b916b341579ec40c024616 100644 (file)
@@ -18,6 +18,8 @@
 #include "msg/Dispatcher.h"
 #include "msg/Messenger.h"
 
+#include "MonMap.h"
+
 #include "common/Timer.h"
 
 class MonMap;
@@ -25,24 +27,26 @@ class MMonMap;
 class MClientMountAck;
 
 class MonClient : public Dispatcher {
-  MonMap *pmonmap;
-  Context *mount_timeout_event;
+public:
+  MonMap monmap;
+private:
   Messenger *messenger;
 
+  ceph_client_ticket ticket;
+  bufferlist signed_ticket;
+
+  Context *mount_timeout_event;
+
   Mutex monc_lock;
   SafeTimer timer;
   bool mounted;
   int mounters;
   bool unmounting;
-  Cond mount_cond;
+  Cond mount_cond, map_cond;
 
-  ceph_client_ticket ticket;
-  bufferlist signed_ticket;
 
-  int probe_mon(MonMap *pmonmap);
-  void handle_monmap(MMonMap *m);
   bool dispatch_impl(Message *m);
-
+  void handle_monmap(MMonMap *m);
 
  protected:
   class C_MountTimeout : public Context {
@@ -60,19 +64,40 @@ class MonClient : public Dispatcher {
   void handle_mount_ack(MClientMountAck* m);
   void handle_unmount(Message* m);
  public:
-  MonClient(MonMap *pmm, Messenger *m) : pmonmap(pmm), messenger(m),
-                                        monc_lock("mon_client"), timer(monc_lock) {
+  MonClient() : messenger(NULL),
+               monc_lock("MonClient::monc_lock"),
+               timer(monc_lock) {
     mounted = false;
     mounters = 0;
     mount_timeout_event = 0;
     unmounting = false;
   }
 
-  MonMap *get_monmap();
+  int build_initial_monmap();
+  int get_monmap();
 
   int mount(double mount_timeout);
   int unmount();
 
+  void send_mon_message(Message *m, bool new_mon=false);
+
+  entity_addr_t get_mon_addr(unsigned i) {
+    Mutex::Locker l(monc_lock);
+    if (i < monmap.size())
+      return monmap.mon_inst[i].addr;
+    return entity_addr_t();
+  }
+  entity_inst_t get_mon_inst(unsigned i) {
+    Mutex::Locker l(monc_lock);
+    if (i < monmap.size())
+      return monmap.mon_inst[i];
+    return entity_inst_t();
+  }
+  int get_num_mon() {
+    Mutex::Locker l(monc_lock);
+    return monmap.size();
+  }
+
   void set_messenger(Messenger *m) { messenger = m; }
 
   bufferlist& get_signed_ticket() { return signed_ticket; }
index 9d0a9101360bdab82dbfadc2d66f598886e5f347..126320345281375e33fd299fbcd0a9960a52f1e5 100644 (file)
@@ -29,7 +29,9 @@ class MonMap {
 
   int       last_mon;    // last mon i talked to
 
-  MonMap(int s=0) : epoch(s?1:0), mon_inst(s), last_mon(-1) { }
+  MonMap(int s=0) : epoch(s?1:0), mon_inst(s), last_mon(-1) {
+    memset(&fsid, 0, sizeof(fsid));
+  }
 
   ceph_fsid_t& get_fsid() { return fsid; }
 
index 1b0a4b21a99bff0b514a809e6a94819acef9bb17..9deaccf27169183287f8d7b1e2a882eaeb2d1834 100644 (file)
@@ -36,7 +36,6 @@ using namespace std;
 #include <fcntl.h>
 
 
-MonMap monmap;
 Messenger *messenger = 0;
 
 Mutex lock("mylock");
@@ -77,12 +76,12 @@ int main(int argc, const char **argv, const char *envp[]) {
   dout(0) << "i am mon" << whoami << dendl;
 
   // get monmap
-  MonClient mc(&monmap, NULL);
-  if (!mc.get_monmap())
+  MonClient mc;
+  if (mc.build_initial_monmap() < 0)
     return -1;
   
   // start up network
-  g_my_addr = monmap.get_inst(whoami).addr;
+  g_my_addr = mc.get_mon_addr(whoami);
   SimpleMessenger rank;
   int err = rank.bind();
   if (err < 0)
@@ -110,18 +109,18 @@ int main(int argc, const char **argv, const char *envp[]) {
       cond.Wait(lock);
     }
 
-    int t = rand() % monmap.size();
+    int t = rand() % mc.get_num_mon();
     if (t == whoami)
       continue;
     
     if (rand() % 10 == 0) {
       //cerr << "mark_down " << t << std::endl;
       dout(0) << "mark_down " << t << dendl;
-      messenger->mark_down(monmap.get_inst(t).addr);
+      messenger->mark_down(mc.get_mon_addr(t));
     } 
     //cerr << "pinging " << t << std::endl;
     dout(0) << "pinging " << t << dendl;
-    messenger->send_message(new MPing, monmap.get_inst(t));
+    messenger->send_message(new MPing, mc.get_mon_inst(t));
     cerr << isend << "\t" << ++sent << "\t" << received << "\r";
   }
   lock.Unlock();