From: Sage Weil Date: Fri, 4 Sep 2009 16:39:07 +0000 (-0700) Subject: mon: fast assignment of client ids X-Git-Tag: v0.14~34 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=421e7ab9b6a6f5d32926451f89270b5cf32cb2f1;p=ceph.git mon: fast assignment of client ids --- diff --git a/src/config.cc b/src/config.cc index 16cb435a115..901b8b92c19 100644 --- a/src/config.cc +++ b/src/config.cc @@ -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), diff --git a/src/config.h b/src/config.h index e37029be005..940df11fc21 100644 --- a/src/config.h +++ b/src/config.h @@ -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; diff --git a/src/mon/ClientMonitor.cc b/src/mon/ClientMonitor.cc index 49c514491d7..689011b389c 100644 --- a/src/mon/ClientMonitor.cc +++ b/src/mon/ClientMonitor.cc @@ -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! diff --git a/src/mon/ClientMonitor.h b/src/mon/ClientMonitor.h index 270d812311d..de4b7f29f8a 100644 --- a/src/mon/ClientMonitor.h +++ b/src/mon/ClientMonitor.h @@ -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 diff --git a/src/mon/PaxosService.cc b/src/mon/PaxosService.cc index 90d77c9fcc8..0567ce94822 100644 --- a/src/mon/PaxosService.cc +++ b/src/mon/PaxosService.cc @@ -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(); } diff --git a/src/mon/PaxosService.h b/src/mon/PaxosService.h index 68178e561b4..d9d75ba1019 100644 --- a/src/mon/PaxosService.h +++ b/src/mon/PaxosService.h @@ -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() {}