From 098fab9f631d0a2074a17cdb52811c2ced4964dd Mon Sep 17 00:00:00 2001 From: IvanGuan Date: Wed, 17 Apr 2019 10:21:54 +0800 Subject: [PATCH] client: fix fuse client hang because its bad session PipeConnection to mds. There still has a risk client will hang all the time and which happened in my enviroment a few days ago. Well konw, the start of mds will go through four stages at least(replay, reconnect, rejoin, active). According to current logic, we recived replay mdsmap and marked down pipe will return directly and if we miss the next reconnect mdsmap the client may hang all the time becuase we lost the opportunity due to old_inc equal to new_inc. So we shuold judge if we have lost MDSMap::reconnect by comparing newstate and oldstate. Fixes: http://tracker.ceph.com/issues/39305 Signed-off-by: Guan yunfei (cherry picked from commit 51c9f5cf9af61fe317259ac79a503ef8a7139622) Conflicts: src/client/Client.cc - mimic has "kick_maxsize_requests(session); wake_inode_waiters(session);" where master has just "wake_up_session_caps(session, true) --- src/client/Client.cc | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 5115555ae216..c37b28781905 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -2717,24 +2717,26 @@ 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->get_connection(session->inst); send_reconnect(session); - } else if (newstate >= MDSMap::STATE_ACTIVE) { - if (oldstate < MDSMap::STATE_ACTIVE) { - // kick new requests - kick_requests(session); - kick_flushing_caps(session); - signal_context_list(session->waiting_for_open); - kick_maxsize_requests(session); - wake_inode_waiters(session); + } else if (newstate > MDSMap::STATE_RECONNECT) { + if (oldstate < MDSMap::STATE_RECONNECT) { + ldout(cct, 1) << "we may miss the MDSMap::RECONNECT, close mds session ... " << dendl; + _closed_mds_session(session); + continue; + } + if (newstate >= MDSMap::STATE_ACTIVE) { + if (oldstate < MDSMap::STATE_ACTIVE) { + // kick new requests + kick_requests(session); + kick_flushing_caps(session); + signal_context_list(session->waiting_for_open); + kick_maxsize_requests(session); + wake_inode_waiters(session); + } + connect_mds_targets(mds); } - connect_mds_targets(mds); } else if (newstate == MDSMap::STATE_NULL && mds >= mdsmap->get_max_mds()) { _closed_mds_session(session); -- 2.47.3