From b9c3751e9e375c679bada1fab228b52420cf7a4b Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Sun, 13 May 2018 21:27:51 -0700 Subject: [PATCH] mds: handle imported session race Thanks to Yan Zheng for identifying and reviewing the fix. Fixes: http://tracker.ceph.com/issues/24087 Signed-off-by: Patrick Donnelly --- src/mds/MDSRank.cc | 22 +++++++++++++++++++++- src/mds/SessionMap.h | 6 +++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index da618b1889644..93a0f4839f29a 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -901,9 +901,29 @@ Session *MDSRank::get_session(Message *m) { Session *session = static_cast(m->get_connection()->get_priv()); if (session) { + session->put(); // do not carry ref dout(20) << "get_session have " << session << " " << session->info.inst << " state " << session->get_state_name() << dendl; - session->put(); // not carry ref + // Check if we've imported an open session since (new sessions start closed) + if (session->is_closed()) { + Session *imported_session = sessionmap.get_session(session->info.inst.name); + if (imported_session && imported_session != session) { + dout(10) << __func__ << " replacing connection bootstrap session " << session << " with imported session " << imported_session << dendl; + imported_session->info.auth_name = session->info.auth_name; + //assert(session->info.auth_name == imported_session->info.auth_name); + assert(session->info.inst == imported_session->info.inst); + imported_session->connection = session->connection; + // send out any queued messages + while (!session->preopen_out_queue.empty()) { + imported_session->connection->send_message(session->preopen_out_queue.front()); + session->preopen_out_queue.pop_front(); + } + imported_session->auth_caps = session->auth_caps; + assert(session->get_nref() == 1); + imported_session->connection->set_priv(imported_session->get()); + session = imported_session; + } + } } else { dout(20) << "get_session dne for " << m->get_source_inst() << dendl; } diff --git a/src/mds/SessionMap.h b/src/mds/SessionMap.h index 499b171eecc87..b9714eeb01044 100644 --- a/src/mds/SessionMap.h +++ b/src/mds/SessionMap.h @@ -330,7 +330,11 @@ public: num_trim_flushes_warnings(0), num_trim_requests_warnings(0) { } ~Session() override { - assert(!item_session_list.is_on_list()); + if (state == STATE_CLOSED) { + item_session_list.remove_myself(); + } else { + assert(!item_session_list.is_on_list()); + } while (!preopen_out_queue.empty()) { preopen_out_queue.front()->put(); preopen_out_queue.pop_front(); -- 2.39.5