From: Yan, Zheng Date: Tue, 30 Sep 2014 04:31:30 +0000 (+0800) Subject: mds: Add session to sessionmap when its state becomes opening X-Git-Tag: v0.88~100^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a67c2f9768e43f2b166fec74f1249c47564d79f1;p=ceph.git mds: Add session to sessionmap when its state becomes opening following sequence events may happen. - client sends reconnect message to a recovering MDS. - MDS::ms_verify_authorizer() create a session for the client, the session is in closed state. - MDS::handle_client_reconnect() sends session close message to the client. - client closes the old connection and opens a new connection - MDS::ms_verify_authorizer() is called for a new connection - MDS::ms_handle_reset() is called for the old connection - MDS::ms_handle_accept() is called for the new connection MDS::ms_handle_reset() removes client's session from the session map, this can cause null pointer dereference when handling client request. The fix is add session to sessionmap when its state becomes 'opening' and remove session from sessionmap when its state becomes 'closed' Signed-off-by: Yan, Zheng --- diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc index 5661fb51dc04..74719cdd97e1 100644 --- a/src/mds/MDS.cc +++ b/src/mds/MDS.cc @@ -2240,7 +2240,6 @@ bool MDS::ms_handle_reset(Connection *con) dout(3) << "ms_handle_reset closing connection for session " << session->info.inst << dendl; con->mark_down(); con->set_priv(NULL); - sessionmap.remove_session(session); } session->put(); } else { @@ -2266,7 +2265,6 @@ void MDS::ms_handle_remote_reset(Connection *con) dout(3) << "ms_handle_remote_reset closing connection for session " << session->info.inst << dendl; con->mark_down(); con->set_priv(NULL); - sessionmap.remove_session(session); } session->put(); } @@ -2312,7 +2310,6 @@ bool MDS::ms_verify_authorizer(Connection *con, int peer_type, dout(10) << " new session " << s << " for " << s->info.inst << " con " << con << dendl; con->set_priv(s); s->connection = con; - sessionmap.add_session(s); } else { dout(10) << " existing session " << s << " for " << s->info.inst << " existing con " << s->connection << ", new/authorizing con " << con << dendl; diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 90eca043e4b0..a8c14b1b6a28 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -233,6 +233,9 @@ void Server::handle_client_session(MClientSession *m) dout(20) << " " << i->first << ": " << i->second << dendl; } + if (session->is_closed()) + mds->sessionmap.add_session(session); + sseq = mds->sessionmap.set_state(session, Session::STATE_OPENING); mds->sessionmap.touch_session(session); pv = ++mds->sessionmap.projected; @@ -383,6 +386,7 @@ void Server::_session_logged(Session *session, uint64_t state_seq, bool open, ve mds->send_message_client(new MClientSession(CEPH_SESSION_CLOSE), session); mds->sessionmap.set_state(session, Session::STATE_CLOSED); session->clear(); + mds->sessionmap.remove_session(session); } else if (session->is_killing()) { // destroy session, close connection if (session->connection != NULL) {