If a connection comes and there is a closed session attached, remove it.
This is probably a failure of an old session to get cleaned up properly,
and in certain cases it may even be from a different client (if the addr
nonce is reused). In that case this prevents further damage, although
a complete solution would also clean up the closed connection state if
there is a fault. See #3630.
This fixes a hang that is reproduced by running the libcephfs
Caps.ReadZero test in a loop; eventually the client addr is reused and
we are linked to an ancient Session with a different client id.
Backport: bobtail
Signed-off-by: Sage Weil <sage@inktank.com>
// wire up a Session* to this connection, and add it to the session map
entity_name_t n(con->get_peer_type(), global_id);
Session *s = sessionmap.get_session(n);
+ if (s && s->is_closed()) {
+ dout(10) << " have session " << s << " but it is CLOSED, removing" << dendl;
+ con->set_priv(NULL);
+ s->put();
+ s = NULL;
+ }
if (!s) {
s = new Session;
s->inst.addr = con->get_peer_addr();