]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: don't send resolve message between active MDS
authorYan, Zheng <zheng.z.yan@intel.com>
Thu, 14 Mar 2013 04:27:51 +0000 (12:27 +0800)
committerGreg Farnum <greg@inktank.com>
Mon, 1 Apr 2013 16:17:19 +0000 (09:17 -0700)
When MDS cluster is resolving, current behavior is sending subtree resolve
message to all other MDS and waiting for all other MDS' resolve message.
The problem is that active MDS can have diffent subtree map due to rename.
Besides gathering active MDS's resolve messages are also racy. The only
function for these messages is disambiguate other MDS' import. We can
replace it by import finish notification.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Reviewed-by: Greg Farnum <greg@inktank.com>
src/mds/MDCache.cc
src/mds/Migrator.cc
src/mds/Migrator.h

index d3a15981a12483c823c65bbbf67472477e910d84..e360465c2cbb4c2fa16ff6bf1705c4a2c7ccbb6c 100644 (file)
@@ -2521,7 +2521,8 @@ void MDCache::send_subtree_resolves()
        ++p) {
     if (*p == mds->whoami)
       continue;
-    resolves[*p] = new MMDSResolve;
+    if (mds->is_resolve() || mds->mdsmap->is_resolve(*p))
+      resolves[*p] = new MMDSResolve;
   }
 
   // known
@@ -2841,7 +2842,7 @@ void MDCache::handle_resolve(MMDSResolve *m)
          migrator->import_reverse(dir);
        } else {
          dout(7) << "ambiguous import succeeded on " << *dir << dendl;
-         migrator->import_finish(dir);
+         migrator->import_finish(dir, true);
        }
        my_ambiguous_imports.erase(p);  // no longer ambiguous.
       }
@@ -3436,7 +3437,12 @@ void MDCache::rejoin_send_rejoins()
        ++p) {
     CDir *dir = p->first;
     assert(dir->is_subtree_root());
-    assert(!dir->is_ambiguous_dir_auth());
+    if (dir->is_ambiguous_dir_auth()) {
+      // exporter is recovering, importer is survivor.
+      assert(rejoins.count(dir->authority().first));
+      assert(!rejoins.count(dir->authority().second));
+      continue;
+    }
 
     // my subtree?
     if (dir->is_auth())
index b485ab11a9d0c830ea4af8cde85f40cc6694b755..604a78c908dd111498eb8d8b394c1ffc8ea8d29f 100644 (file)
@@ -2088,6 +2088,23 @@ void Migrator::import_reverse(CDir *dir)
   }
 }
 
+void Migrator::import_notify_finish(CDir *dir, set<CDir*>& bounds)
+{
+  dout(7) << "import_notify_finish " << *dir << dendl;
+
+  for (set<int>::iterator p = import_bystanders[dir].begin();
+       p != import_bystanders[dir].end();
+       ++p) {
+    MExportDirNotify *notify =
+      new MExportDirNotify(dir->dirfrag(), false,
+                          pair<int,int>(import_peer[dir->dirfrag()], mds->get_nodeid()),
+                          pair<int,int>(mds->get_nodeid(), CDIR_AUTH_UNKNOWN));
+    for (set<CDir*>::iterator i = bounds.begin(); i != bounds.end(); i++)
+      notify->get_bounds().push_back((*i)->dirfrag());
+    mds->send_message_mds(notify, *p);
+  }
+}
+
 void Migrator::import_notify_abort(CDir *dir, set<CDir*>& bounds)
 {
   dout(7) << "import_notify_abort " << *dir << dendl;
@@ -2183,11 +2200,11 @@ void Migrator::handle_export_finish(MExportDirFinish *m)
   CDir *dir = cache->get_dirfrag(m->get_dirfrag());
   assert(dir);
   dout(7) << "handle_export_finish on " << *dir << dendl;
-  import_finish(dir);
+  import_finish(dir, false);
   m->put();
 }
 
-void Migrator::import_finish(CDir *dir
+void Migrator::import_finish(CDir *dir, bool notify)
 {
   dout(7) << "import_finish on " << *dir << dendl;
 
@@ -2205,6 +2222,10 @@ void Migrator::import_finish(CDir *dir)
   // remove pins
   set<CDir*> bounds;
   cache->get_subtree_bounds(dir, bounds);
+
+  if (notify)
+    import_notify_finish(dir, bounds);
+
   import_remove_pins(dir, bounds);
 
   map<CInode*, map<client_t,Capability::Export> > cap_imports;
index 7988f325ff13269b582dd467202c9ab55022cd30..2889a74f49183ad5ce296f0fc77106d3a52b220a 100644 (file)
@@ -273,12 +273,13 @@ protected:
   void import_reverse_unfreeze(CDir *dir);
   void import_reverse_final(CDir *dir);
   void import_notify_abort(CDir *dir, set<CDir*>& bounds);
+  void import_notify_finish(CDir *dir, set<CDir*>& bounds);
   void import_logged_start(dirfrag_t df, CDir *dir, int from,
                           map<client_t,entity_inst_t> &imported_client_map,
                           map<client_t,uint64_t>& sseqmap);
   void handle_export_finish(MExportDirFinish *m);
 public:
-  void import_finish(CDir *dir);
+  void import_finish(CDir *dir, bool notify);
 protected:
 
   void handle_export_caps(MExportCaps *m);