]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: Add session to sessionmap when its state becomes opening 2610/head 2617/head
authorYan, Zheng <zyan@redhat.com>
Tue, 30 Sep 2014 04:31:30 +0000 (12:31 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 30 Sep 2014 12:58:07 +0000 (20:58 +0800)
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 <zyan@redhat.com>
src/mds/MDS.cc
src/mds/Server.cc

index 5661fb51dc043deb407f190cd0b1d5f301292b56..74719cdd97e15445464ee0af6e6fd1c9ba9a4c7e 100644 (file)
@@ -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;
index 90eca043e4b0d612980c8ca28746d0c6afc9787e..a8c14b1b6a284c4ee6a43bc32a81c7236b237164 100644 (file)
@@ -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) {