From: John Spray Date: Thu, 16 Mar 2017 16:37:18 +0000 (+0000) Subject: mds: hook up autoclose to blacklisting eviction X-Git-Tag: v12.1.0~10^2~27^2~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=dd08483bd028219d8ae8ec79d3f6da5883090718;p=ceph.git mds: hook up autoclose to blacklisting eviction Signed-off-by: John Spray --- diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 18a67801d6b..edbe9e51f1f 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -185,6 +185,7 @@ Server::Server(MDSRank *m) : is_full(false), reconnect_done(NULL), failed_reconnects(0), + reconnect_evicting(false), terminating_sessions(false) { } @@ -725,10 +726,16 @@ void Server::find_idle_sessions() return; } - while (1) { - Session *session = mds->sessionmap.get_oldest_session(Session::STATE_STALE); - if (!session) - break; + // Collect a list of sessions exceeding the autoclose threshold + std::vector to_evict; + const auto sessions_p = mds->sessionmap.by_state.find(Session::STATE_STALE); + if (sessions_p == mds->sessionmap.by_state.end() || sessions_p->second->empty()) { + return; + } + const auto &stale_sessions = sessions_p->second; + assert(stale_sessions != nullptr); + + for (const auto &session: *stale_sessions) { if (session->is_importing()) { dout(10) << "stopping at importing session " << session->info.inst << dendl; break; @@ -739,13 +746,25 @@ void Server::find_idle_sessions() << session->last_cap_renew << ")" << dendl; break; } - + + to_evict.push_back(session); + } + + for (const auto &session: to_evict) { utime_t age = now; age -= session->last_cap_renew; mds->clog->info() << "closing stale session " << session->info.inst << " after " << age; - dout(10) << "autoclosing stale session " << session->info.inst << " last " << session->last_cap_renew << dendl; - kill_session(session, NULL); + dout(10) << "autoclosing stale session " << session->info.inst << " last " + << session->last_cap_renew << dendl; + + if (g_conf->mds_session_blacklist_on_timeout) { + std::stringstream ss; + mds->kill_session(session->info.inst.name.num(), false, true, + ss, nullptr); + } else { + kill_session(session, NULL); + } } } @@ -755,6 +774,8 @@ void Server::find_idle_sessions() */ void Server::kill_session(Session *session, Context *on_safe) { + assert(mds->mds_lock.is_locked_by_me()); + if ((session->is_opening() || session->is_open() || session->is_stale()) && @@ -980,22 +1001,48 @@ void Server::reconnect_gather_finish() void Server::reconnect_tick() { + if (reconnect_evicting) { + dout(4) << "reconnect_tick: waiting for evictions" << dendl; + return; + } + utime_t reconnect_end = reconnect_start; reconnect_end += g_conf->mds_reconnect_timeout; if (ceph_clock_now() >= reconnect_end && !client_reconnect_gather.empty()) { dout(10) << "reconnect timed out" << dendl; + + // If we're doing blacklist evictions, use this to wait for them before + // proceeding to reconnect_gather_finish + MDSGatherBuilder gather(g_ceph_context); + for (set::iterator p = client_reconnect_gather.begin(); p != client_reconnect_gather.end(); ++p) { Session *session = mds->sessionmap.get_session(entity_name_t::CLIENT(p->v)); assert(session); dout(1) << "reconnect gave up on " << session->info.inst << dendl; - kill_session(session, NULL); + + if (g_conf->mds_session_blacklist_on_timeout) { + std::stringstream ss; + mds->kill_session(session->info.inst.name.num(), false, true, ss, gather.new_sub()); + } else { + kill_session(session, NULL); + } + failed_reconnects++; } client_reconnect_gather.clear(); - reconnect_gather_finish(); + + if (gather.has_subs()) { + dout(1) << "reconnect will complete once clients are evicted" << dendl; + gather.set_finisher(new MDSInternalContextWrapper(mds, new FunctionContext( + [this](int r){reconnect_gather_finish();}))); + gather.activate(); + reconnect_evicting = true; + } else { + reconnect_gather_finish(); + } } } diff --git a/src/mds/Server.h b/src/mds/Server.h index 84947856ed2..6aca16e3121 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -80,6 +80,8 @@ private: // State for while in reconnect MDSInternalContext *reconnect_done; int failed_reconnects; + bool reconnect_evicting; // true if I am waiting for evictions to complete + // before proceeding to reconnect_gather_finish friend class MDSContinuation; friend class ServerContext;