]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: fast assignment of client ids
authorSage Weil <sage@newdream.net>
Fri, 4 Sep 2009 16:39:07 +0000 (09:39 -0700)
committerSage Weil <sage@newdream.net>
Fri, 4 Sep 2009 17:06:42 +0000 (10:06 -0700)
src/config.cc
src/config.h
src/mon/ClientMonitor.cc
src/mon/ClientMonitor.h
src/mon/PaxosService.cc
src/mon/PaxosService.h

index 16cb435a115fe788efb743b8f2058ebc359dfd6a..901b8b92c194986e2bd65dba1fb80e25f5fc2c50 100644 (file)
@@ -359,6 +359,7 @@ static struct config_option config_optionsp[] = {
        OPTION(mon_stop_with_last_mds, 0, OPT_BOOL, false),
        OPTION(mon_allow_mds_bully, 0, OPT_BOOL, false),   // allow a booting mds to (forcibly) claim an mds # .. FIXME
        OPTION(mon_pg_create_interval, 0, OPT_FLOAT, 30.0), // no more than every 30s
+       OPTION(mon_clientid_prealloc, 0, OPT_INT, 100),   // how many clientids to prealloc
        OPTION(paxos_propose_interval, 0, OPT_DOUBLE, 1.0),  // gather updates for this long before proposing a map update
        OPTION(paxos_observer_timeout, 0, OPT_DOUBLE, 5*60), // gather updates for this long before proposing a map update
        OPTION(client_cache_size, 0, OPT_INT, 1000),
index e37029be00557018631a869dbe9a384188f9b8d1..940df11fc21e7ddacff33a2a7389c3ce6a1ed5d6 100644 (file)
@@ -137,6 +137,7 @@ struct md_config_t {
   bool mon_stop_with_last_mds;
   bool mon_allow_mds_bully;
   float mon_pg_create_interval;
+  int mon_clientid_prealloc;
 
   double paxos_propose_interval;
   double paxos_observer_timeout;
index 49c514491d711210bc3353b41de528208a6c6d2f..689011b389c9df14a1ce766b73bda5d2dcd55985 100644 (file)
@@ -63,9 +63,20 @@ bool ClientMonitor::update_from_paxos()
 
   paxos->stash_latest(paxosv, bl);
 
+  if (next_client < 0) {
+    dout(10) << "in-core next_client reset to " << client_map.next_client << dendl;
+    next_client = client_map.next_client;
+  }
+
   return true;
 }
 
+void ClientMonitor::on_election_start()
+{
+  dout(10) << "in-core next_client cleared" << dendl;
+  next_client = -1;
+}
+
 void ClientMonitor::create_pending()
 {
   pending_map = client_map;
@@ -96,34 +107,13 @@ void ClientMonitor::encode_pending(bufferlist &bl)
 
 // -------
 
-bool ClientMonitor::check_mount(MClientMount *m)
-{
-    stringstream ss;
-    // already mounted?
-    entity_addr_t addr = m->get_orig_source_addr();
-    ExportControl *ec = conf_get_export_control();
-    if (ec && (!ec->is_authorized(&addr, "/"))) {
-      dout(0) << "client is not authorized to mount" << dendl;
-      ss << "client " << addr << " is not authorized to mount";
-      mon->get_logclient()->log(LOG_SEC, ss);
-
-      string s;
-      getline(ss, s);
-      mon->messenger->send_message(new MClientMountAck(-1, -EPERM, s.c_str()),
-                                  m->get_orig_source_inst());
-      return true;
-    }
-
-    return false;
-}
-
 bool ClientMonitor::preprocess_query(PaxosServiceMessage *m)
 {
   dout(10) << "preprocess_query " << *m << " from " << m->get_orig_source_inst() << dendl;
 
   switch (m->get_type()) {
   case CEPH_MSG_CLIENT_MOUNT:
-       return check_mount((MClientMount *)m);
+    return preprocess_mount((MClientMount *)m);
     
   case MSG_MON_COMMAND:
     return preprocess_command((MMonCommand*)m);
@@ -142,18 +132,7 @@ bool ClientMonitor::prepare_update(PaxosServiceMessage *m)
   
   switch (m->get_type()) {
   case CEPH_MSG_CLIENT_MOUNT:
-    {
-      entity_addr_t addr = m->get_orig_source_addr();
-      client_t client = pending_map.next_client;
-      pending_map.next_client.v++;
-
-      dout(10) << "mount: assigned client" << client << " to " << addr << dendl;
-
-      paxos->wait_for_commit(new C_Mounted(this, client, (MClientMount*)m));
-      ss << "client" << client << " " << addr << " mounted";
-      mon->get_logclient()->log(LOG_INFO, ss);
-    }
-    return true;
+    return prepare_mount((MClientMount*)m);
 
   case MSG_MON_COMMAND:
     return prepare_command((MMonCommand*)m);
@@ -167,6 +146,91 @@ bool ClientMonitor::prepare_update(PaxosServiceMessage *m)
 }
 
 
+// MOUNT
+
+bool ClientMonitor::preprocess_mount(MClientMount *m)
+{
+  stringstream ss;
+  
+  // allowed?
+  entity_addr_t addr = m->get_orig_source_addr();
+  ExportControl *ec = conf_get_export_control();
+  if (ec && (!ec->is_authorized(&addr, "/"))) {
+    dout(0) << "client is not authorized to mount" << dendl;
+    ss << "client " << addr << " is not authorized to mount";
+    mon->get_logclient()->log(LOG_SEC, ss);
+    
+    string s;
+    getline(ss, s);
+    mon->messenger->send_message(new MClientMountAck(-1, -EPERM, s.c_str()),
+                                m->get_orig_source_inst());
+    return true;
+  }
+  
+  // fast mount?
+  if (mon->is_leader() &&
+      next_client < client_map.next_client) {
+    client_t client = next_client;
+    next_client.v++;
+
+    dout(10) << "preprocess_mount fast mount client" << client << ", in-core next is " << next_client
+            << ", paxos next is " << pending_map.next_client << dendl;
+    _mounted(client, m);
+    
+    if (next_client == pending_map.next_client) {
+      pending_map.next_client.v += g_conf.mon_clientid_prealloc;
+      propose_pending();
+    }
+
+    return true;
+  }      
+  
+  return false;
+}
+
+bool ClientMonitor::prepare_mount(MClientMount *m)
+{
+  stringstream ss;
+  entity_addr_t addr = m->get_orig_source_addr();
+
+  assert(next_client <= client_map.next_client);
+
+  client_t client = next_client;
+  next_client.v++;
+  
+  pending_map.next_client.v = next_client.v + g_conf.mon_clientid_prealloc;
+  
+  dout(10) << "mount: assigned client" << client << " to " << addr << dendl;
+  
+  paxos->wait_for_commit(new C_Mounted(this, client, (MClientMount*)m));
+  ss << "client" << client << " " << addr << " mounted";
+  mon->get_logclient()->log(LOG_INFO, ss);
+  return true;
+}
+
+void ClientMonitor::_mounted(client_t client, MClientMount *m)
+{
+  entity_inst_t to;
+  to.addr = m->get_orig_source_addr();
+  to.name = entity_name_t::CLIENT(client.v);
+
+  dout(10) << "_mounted client" << client << " at " << to << dendl;
+  
+  // reply with client ticket
+  MClientMountAck *ack = new MClientMountAck;
+  ack->client = client;
+  mon->monmap->encode(ack->monmap_bl);
+
+  mon->send_reply(m, ack, to);
+
+  // also send latest mds and osd maps
+  //mon->mdsmon()->send_latest(to);
+  //mon->osdmon()->send_latest(to);
+
+  delete m;
+}
+
+
 // COMMAND
 
 bool ClientMonitor::preprocess_command(MMonCommand *m)
@@ -224,31 +288,6 @@ bool ClientMonitor::prepare_command(MMonCommand *m)
 }
 
 
-// MOUNT
-
-
-void ClientMonitor::_mounted(client_t client, MClientMount *m)
-{
-  entity_inst_t to;
-  to.addr = m->get_orig_source_addr();
-  to.name = entity_name_t::CLIENT(client.v);
-
-  dout(10) << "_mounted client" << client << " at " << to << dendl;
-  
-  // reply with client ticket
-  MClientMountAck *ack = new MClientMountAck;
-  ack->client = client;
-  mon->monmap->encode(ack->monmap_bl);
-
-  mon->send_reply(m, ack, to);
-
-  // also send latest mds and osd maps
-  //mon->mdsmon()->send_latest(to);
-  //mon->osdmon()->send_latest(to);
-
-  delete m;
-}
-
 bool ClientMonitor::should_propose(double& delay)
 {
   return true;  // never delay!  we want fast mounts!
index 270d812311d69336fb7046daf7e13fe529e1c532..de4b7f29f8ac9eb48a6ba25bf6b324d950cb59cd 100644 (file)
@@ -57,6 +57,7 @@ public:
   };
 
   ClientMap client_map, pending_map;
+  client_t next_client;
 
 private:
   // leader
@@ -68,7 +69,8 @@ private:
 
   void committed();
 
-  bool check_mount(MClientMount *m);
+  bool preprocess_mount(MClientMount *m);
+  bool prepare_mount(MClientMount *m);
   void _mounted(client_t c, MClientMount *m);
  
   bool preprocess_query(PaxosServiceMessage *m);  // true if processed.
@@ -79,8 +81,10 @@ private:
 
   bool should_propose(double& delay);
 
+  void on_election_start();
+
  public:
-  ClientMonitor(Monitor *mn, Paxos *p) : PaxosService(mn, p) { }
+  ClientMonitor(Monitor *mn, Paxos *p) : PaxosService(mn, p), next_client(-1) { }
   
   void tick();  // check state, take actions
 
index 90d77c9fcc85c629e5710a7749ff0c58b950b0dc..0567ce94822426038ae3378c41d08eca0acbc1ec 100644 (file)
@@ -148,6 +148,8 @@ void PaxosService::election_starting()
     mon->timer.cancel_event(proposal_timer);
     proposal_timer = 0;
   }
+
+  on_election_start();
 }
 
 void PaxosService::election_finished()
@@ -181,6 +183,8 @@ void PaxosService::_active()
       have_pending = true;
     }
   }
+
+  on_active();
 }
 
 
index 68178e561b4568b445bdc673f27c92b88608c0c1..d9d75ba1019a0120a9462b1011fc847d5835ce42 100644 (file)
@@ -104,6 +104,9 @@ public:
   virtual bool prepare_update(PaxosServiceMessage *m) = 0;
   virtual bool should_propose(double &delay);
 
+  virtual void on_active() { }
+  virtual void on_election_start() { }
+
   virtual void committed() = 0;            // [leader] called after a proposed value commits
 
   virtual void tick() {}