If there is a fault while delivering the message, close the con. This will
clean up the Session state from memory. If the client doesn't get the
CLOSED message, they will reconnect (from their perspective, it is still
a lossless connection) and get a remote_reset event telling them that the
session is gone. The client code already handles this case properly.
Note that way back in
4ac45200f10e0409121948cea5226ca9e23bb5fb we removed
this because the client would reuse the same connection when it reopened
the session. Now the client never does that; it will mark_down the con
as soon as it is closed and open a new one for a new session... which means
the MDS will get a remote_reset and close out the old session.
Signed-off-by: Sage Weil <sage@inktank.com>
case CEPH_ENTITY_TYPE_OSD:
objecter->ms_handle_remote_reset(con);
break;
+
+ case CEPH_ENTITY_TYPE_CLIENT:
+ Session *session = static_cast<Session *>(con->get_priv());
+ if (session) {
+ if (session->is_closed()) {
+ messenger->mark_down(con);
+ sessionmap.remove_session(session);
+ }
+ session->put();
+ }
+ break;
}
}
}
if (session->is_closing()) {
+ // mark con disposable. if there is a fault, we will get a
+ // reset and clean it up. if the client hasn't received the
+ // CLOSE message yet, they will reconnect and get an
+ // ms_handle_remote_reset() and realize they had in fact closed.
+ // do this *before* sending the message to avoid a possible
+ // race.
+ mds->messenger->mark_disposable(session->connection);
+
// reset session
mds->send_message_client(new MClientSession(CEPH_SESSION_CLOSE), session);
mds->sessionmap.set_state(session, Session::STATE_CLOSED);