From: Yan, Zheng Date: Mon, 7 Nov 2016 14:21:17 +0000 (+0800) Subject: mds: ignore 'session evict' when mds is replaying log X-Git-Tag: v10.2.6~111^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=edac06fd13f6539edb63b715b45928233731faf1;p=ceph.git mds: ignore 'session evict' when mds is replaying log Fixes: http://tracker.ceph.com/issues/17801 Signed-off-by: Yan, Zheng (cherry picked from commit 315c6a23e466e703c4ca013358c53288cca0e81f) --- diff --git a/src/mds/MDSDaemon.cc b/src/mds/MDSDaemon.cc index 0482477b7cc..8c1677b8be0 100644 --- a/src/mds/MDSDaemon.cc +++ b/src/mds/MDSDaemon.cc @@ -801,11 +801,9 @@ int MDSDaemon::_handle_command( int64_t session_id = 0; bool got = cmd_getval(cct, cmdmap, "session_id", session_id); assert(got); - const bool killed = mds_rank->kill_session(session_id); - if (!killed) { + bool killed = mds_rank->kill_session(session_id, false, ss); + if (!killed) r = -ENOENT; - ss << "session '" << session_id << "' not found"; - } } else if (prefix == "heap") { if (!ceph_using_tcmalloc()) { r = -EOPNOTSUPP; diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index 19a584a65cc..f845e286566 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -1710,18 +1710,11 @@ bool MDSRankDispatcher::handle_asok_command( assert(got_arg == true); mds_lock.Lock(); - Session *session = sessionmap.get_session(entity_name_t(CEPH_ENTITY_TYPE_CLIENT, - strtol(client_id.c_str(), 0, 10))); - if (session) { - C_SaferCond on_safe; - server->kill_session(session, &on_safe); - - mds_lock.Unlock(); - on_safe.wait(); - } else { - dout(15) << "session " << session << " not in sessionmap!" << dendl; - mds_lock.Unlock(); - } + std::stringstream ss; + bool killed = kill_session(strtol(client_id.c_str(), 0, 10), true, ss); + if (!killed) + dout(15) << ss.str() << dendl; + mds_lock.Unlock(); } else if (command == "scrub_path") { string path; vector scrubop_vec; @@ -1788,13 +1781,13 @@ protected: public: C_MDS_Send_Command_Reply(MDSRank *_mds, MCommand *_m) : MDSInternalContext(_mds), m(_m) { m->get(); } - void send (int r) { + void send (int r, const std::string& out_str) { bufferlist bl; - MDSDaemon::send_command_reply(m, mds, r, bl, ""); + MDSDaemon::send_command_reply(m, mds, r, bl, out_str); m->put(); } void finish (int r) { - send(r); + send(r, ""); } }; @@ -1805,9 +1798,15 @@ public: */ void MDSRankDispatcher::evict_sessions(const SessionFilter &filter, MCommand *m) { - std::list victims; C_MDS_Send_Command_Reply *reply = new C_MDS_Send_Command_Reply(this, m); + if (is_any_replay()) { + reply->send(-EAGAIN, "MDS is replaying log"); + delete reply; + return; + } + + std::list victims; const auto sessions = sessionmap.get_sessions(); for (const auto p : sessions) { if (!p.first.is_client()) { @@ -1824,7 +1823,7 @@ void MDSRankDispatcher::evict_sessions(const SessionFilter &filter, MCommand *m) dout(20) << __func__ << " matched " << victims.size() << " sessions" << dendl; if (victims.empty()) { - reply->send(0); + reply->send(0, ""); delete reply; return; } @@ -2420,16 +2419,29 @@ void MDSRankDispatcher::handle_osd_map() objecter->maybe_request_map(); } -bool MDSRankDispatcher::kill_session(int64_t session_id) +bool MDSRankDispatcher::kill_session(int64_t session_id, bool wait, std::stringstream& err_ss) { + if (is_any_replay()) { + err_ss << "MDS is replaying log"; + return false; + } + Session *session = sessionmap.get_session(entity_name_t(CEPH_ENTITY_TYPE_CLIENT, session_id)); + if (!session) { + err_ss << "session " << session_id << " not in sessionmap!"; + return false; + } + if (wait) { + C_SaferCond on_safe; + server->kill_session(session, &on_safe); - if (session) { - server->kill_session(session, NULL); - return true; + mds_lock.Unlock(); + on_safe.wait(); + mds_lock.Lock(); } else { - return false; + server->kill_session(session, NULL); } + return true; } void MDSRank::bcast_mds_map() @@ -2456,12 +2468,11 @@ bool MDSRankDispatcher::handle_command_legacy(std::vector args) mdcache->dump_cache(); } else if (args[0] == "session" && args[1] == "kill") { - Session *session = sessionmap.get_session(entity_name_t(CEPH_ENTITY_TYPE_CLIENT, - strtol(args[2].c_str(), 0, 10))); - if (session) - server->kill_session(session, NULL); - else - dout(15) << "session " << session << " not in sessionmap!" << dendl; + std::stringstream ss; + bool killed = kill_session(strtol(args[2].c_str(), 0, 10), false, ss); + if (!killed) + dout(15) << ss.str() << dendl; + } else if (args[0] == "issue_caps") { long inum = strtol(args[1].c_str(), 0, 10); CInode *in = mdcache->get_inode(inodeno_t(inum)); diff --git a/src/mds/MDSRank.h b/src/mds/MDSRank.h index 17e259b174b..c8022e6cac1 100644 --- a/src/mds/MDSRank.h +++ b/src/mds/MDSRank.h @@ -488,7 +488,7 @@ public: Formatter *f, std::ostream& ss); void handle_mds_map(MMDSMap *m, MDSMap *oldmap); void handle_osd_map(); - bool kill_session(int64_t session_id); + bool kill_session(int64_t session_id, bool wait, std::stringstream& ss); void update_log_config(); bool handle_command_legacy(std::vector args);