]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: fix fuse client hang because its pipe to mds is not ok 24172/head
authorIvanGuan <yunfei.guan@xtaotech.com>
Fri, 4 Jan 2019 04:22:27 +0000 (12:22 +0800)
committerIvanGuan <yunfei.guan@xtaotech.com>
Fri, 4 Jan 2019 04:22:27 +0000 (12:22 +0800)
If fuse client session had been killed by mds and the mds daemon restart
or hot-standby switch happens right away but the client did not receive
any message from monitor due to network or other whatever reason untill
the mds become active again.Thus cause client didn't do closed_mds_session
lead the seession still is STATE_OPEN but client can't send any message to
mds because its pipe is not ok.So we should close the stale session so that
it can be reopened again.

Fixes: http://tracker.ceph.com/issues/36079
Signed-off-by: Guan yunfei <yunfei.guan@xtaotech.com>
src/client/Client.cc
src/mds/MDSMap.h

index d5ac1f2f1d7925b027b5241d2b646f0457930136..df1764add371f2b4c19abb25d91b61c8b9bab295 100644 (file)
@@ -2614,13 +2614,14 @@ void Client::handle_fs_map_user(MFSMapUser *m)
 
 void Client::handle_mds_map(MMDSMap* m)
 {
+  mds_gid_t old_inc, new_inc;
   if (m->get_epoch() <= mdsmap->get_epoch()) {
     ldout(cct, 1) << __func__ << " epoch " << m->get_epoch()
                   << " is identical to or older than our "
                   << mdsmap->get_epoch() << dendl;
     m->put();
     return;
-  }  
+  }
 
   ldout(cct, 1) << __func__ << " epoch " << m->get_epoch() << dendl;
 
@@ -2666,6 +2667,13 @@ void Client::handle_mds_map(MMDSMap* m)
     if (!mdsmap->is_up(mds)) {
       session->con->mark_down();
     } else if (mdsmap->get_addrs(mds) != session->addrs) {
+      old_inc = oldmap->get_incarnation(mds);
+      new_inc = mdsmap->get_incarnation(mds);
+      if (old_inc != new_inc) {
+        ldout(cct, 1) << "mds incarnation changed from "
+                     << old_inc << " to " << new_inc << dendl;
+        oldstate = MDSMap::STATE_NULL;
+      }
       session->con->mark_down();
       session->addrs = mdsmap->get_addrs(mds);
       // When new MDS starts to take over, notify kernel to trim unused entries
@@ -2676,6 +2684,11 @@ void Client::handle_mds_map(MMDSMap* m)
       continue;  // no change
     
     session->mds_state = newstate;
+    if (old_inc != new_inc && newstate > MDSMap::STATE_RECONNECT) {
+      // missed reconnect close the session so that it can be reopened
+      _closed_mds_session(session);
+      continue;
+    }
     if (newstate == MDSMap::STATE_RECONNECT) {
       session->con = messenger->connect_to_mds(session->addrs);
       send_reconnect(session);
index 37a26e60028b16937ebb90974a60d6bdd7b5b8e1..85894aeffc460fa5d0a3cd3086aedf6dc5ecc04c 100644 (file)
@@ -616,6 +616,16 @@ public:
     }
   }
 
+  /**
+   * Get MDS rank incarnation if the rank is up, else -1
+   */
+  mds_gid_t get_incarnation(mds_rank_t m) const {
+    std::map<mds_rank_t, mds_gid_t>::const_iterator u = up.find(m);
+    if (u == up.end())
+      return MDS_GID_NONE;
+    return (mds_gid_t)get_inc_gid(u->second);
+  }
+
   int get_inc_gid(mds_gid_t gid) const {
     auto mds_info_entry = mds_info.find(gid);
     if (mds_info_entry != mds_info.end())