From: Yan, Zheng Date: Fri, 10 Jan 2014 01:55:50 +0000 (+0800) Subject: mds: avoid sending duplicated discovers during recovery X-Git-Tag: v0.78~223^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F1182%2Fhead;p=ceph.git mds: avoid sending duplicated discovers during recovery If MDS just entered the rejoin state, it should not kick discovers because the discovers were just sent. Similarly, if MDS just entered the clientreplay state, it should not call MDS::handle_mds_recovery() because MDS::recovery_done() has already recovered the table server. Also make MDCache::handle_mds_recovery() not wake the discover waiters up. Because the MDCache::kick_discovers re-sends the discovers, their replies will wake the discover waiter up. Signed-off-by: Yan, Zheng --- diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index eb20c06085a0..167a85e75f8e 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -2777,6 +2777,10 @@ void MDCache::handle_mds_recovery(int who) { dout(7) << "handle_mds_recovery mds." << who << dendl; + // exclude all discover waiters. kick_discovers() will do the job + static const uint64_t i_mask = CInode::WAIT_ANY_MASK & ~CInode::WAIT_DIR; + static const uint64_t d_mask = CDir::WAIT_ANY_MASK & ~CDir::WAIT_DENTRY; + list waiters; // wake up any waiters in their subtrees @@ -2797,7 +2801,7 @@ void MDCache::handle_mds_recovery(int who) while (!q.empty()) { CDir *d = q.front(); q.pop_front(); - d->take_waiting(CDir::WAIT_ANY_MASK, waiters); + d->take_waiting(d_mask, waiters); // inode waiters too for (CDir::map_t::iterator p = d->items.begin(); @@ -2806,7 +2810,7 @@ void MDCache::handle_mds_recovery(int who) CDentry *dn = p->second; CDentry::linkage_t *dnl = dn->get_linkage(); if (dnl->is_primary()) { - dnl->get_inode()->take_waiting(CInode::WAIT_ANY_MASK, waiters); + dnl->get_inode()->take_waiting(i_mask, waiters); // recurse? list ls; @@ -9904,8 +9908,11 @@ void MDCache::kick_discovers(int who) { for (map::iterator p = discovers.begin(); p != discovers.end(); - ++p) + ++p) { + if (p->second.mds != who) + continue; _send_discover(p->second); + } } diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc index b8ae455a60d0..a2e7228cbcda 100644 --- a/src/mds/MDS.cc +++ b/src/mds/MDS.cc @@ -1037,28 +1037,31 @@ void MDS::handle_mds_map(MMDSMap *m) if (g_conf->mds_dump_cache_after_rejoin && oldmap->is_rejoining() && !mdsmap->is_rejoining()) mdcache->dump_cache(); // for DEBUG only - - // ACTIVE|CLIENTREPLAY|REJOIN => we can discover from them. - set olddis, dis; - oldmap->get_mds_set(olddis, MDSMap::STATE_ACTIVE); - oldmap->get_mds_set(olddis, MDSMap::STATE_CLIENTREPLAY); - oldmap->get_mds_set(olddis, MDSMap::STATE_REJOIN); - mdsmap->get_mds_set(dis, MDSMap::STATE_ACTIVE); - mdsmap->get_mds_set(dis, MDSMap::STATE_CLIENTREPLAY); - mdsmap->get_mds_set(dis, MDSMap::STATE_REJOIN); - for (set::iterator p = dis.begin(); p != dis.end(); ++p) - if (*p != whoami && // not me - olddis.count(*p) == 0) { // newly so? - mdcache->kick_discovers(*p); - mdcache->kick_open_ino_peers(*p); - } + + if (oldstate >= MDSMap::STATE_REJOIN) { + // ACTIVE|CLIENTREPLAY|REJOIN => we can discover from them. + set olddis, dis; + oldmap->get_mds_set(olddis, MDSMap::STATE_ACTIVE); + oldmap->get_mds_set(olddis, MDSMap::STATE_CLIENTREPLAY); + oldmap->get_mds_set(olddis, MDSMap::STATE_REJOIN); + mdsmap->get_mds_set(dis, MDSMap::STATE_ACTIVE); + mdsmap->get_mds_set(dis, MDSMap::STATE_CLIENTREPLAY); + mdsmap->get_mds_set(dis, MDSMap::STATE_REJOIN); + for (set::iterator p = dis.begin(); p != dis.end(); ++p) + if (*p != whoami && // not me + olddis.count(*p) == 0) { // newly so? + mdcache->kick_discovers(*p); + mdcache->kick_open_ino_peers(*p); + } + } } if (oldmap->is_degraded() && !mdsmap->is_degraded() && state >= MDSMap::STATE_ACTIVE) dout(1) << "cluster recovered." << dendl; // did someone go active? - if (is_clientreplay() || is_active() || is_stopping()) { + if (oldstate >= MDSMap::STATE_CLIENTREPLAY && + (is_clientreplay() || is_active() || is_stopping())) { set oldactive, active; oldmap->get_mds_set(oldactive, MDSMap::STATE_ACTIVE); oldmap->get_mds_set(oldactive, MDSMap::STATE_CLIENTREPLAY);