From: Sage Weil Date: Thu, 31 Jan 2019 22:52:09 +0000 (-0600) Subject: msg/async/ProtocolV2: respect policy.resetcheck on cookie==0 X-Git-Tag: v14.1.0~219^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F26256%2Fhead;p=ceph.git msg/async/ProtocolV2: respect policy.resetcheck on cookie==0 It's possible the accepting end knows the cookie but the connecting end does not if the fault happens before it receives server_ident. If the next connection attempt is in the other direction, we need to avoid a reset or the queued messages at the first site will get lost. Fixes: http://tracker.ceph.com/issues/38118 Signed-off-by: Sage Weil --- diff --git a/src/msg/async/ProtocolV2.cc b/src/msg/async/ProtocolV2.cc index b7d413e84788..16ed5163b5a5 100644 --- a/src/msg/async/ProtocolV2.cc +++ b/src/msg/async/ProtocolV2.cc @@ -2701,15 +2701,29 @@ CtPtr ProtocolV2::handle_reconnect(char *payload, uint32_t length) { return WRITE(bl, "session retry", read_frame); } - if (!exproto->cookie) { - // server connection was reseted, reset client - ldout(cct, 5) << __func__ << " no cookie set, reseting client" << dendl; - return WRITE(bl, "session reset", read_frame); - } else if (exproto->cookie != reconnect.cookie()) { - ldout(cct, 5) << __func__ << " cookie mismatch sc=" << exproto->cookie - << " cc=" << reconnect.cookie() << ", reseting client" - << dendl; - return WRITE(bl, "session reset", read_frame); + if (connection->policy.resetcheck) { + if (!exproto->cookie) { + // server connection was reseted, reset client + ldout(cct, 5) << __func__ << " no cookie set, reseting client" << dendl; + return WRITE(bl, "session reset", read_frame); + } else if (exproto->cookie != reconnect.cookie()) { + ldout(cct, 5) << __func__ << " cookie mismatch sc=" << exproto->cookie + << " cc=" << reconnect.cookie() << ", reseting client" + << dendl; + return WRITE(bl, "session reset", read_frame); + } + } else { + if (exproto->cookie == 0) { + // this happens when: + // - a connects to b + // - a sends client_ident + // - b gets client_ident, sends server_ident and sets cookie X + // - connection fault + // - b reconnects to a with cookie X, connect_seq=1 + // - a has cookie==0 + ldout(cct, 5) << __func__ << " no cookie set, setting" << dendl; + exproto->cookie = reconnect.cookie(); + } } if (exproto->peer_global_seq > reconnect.global_seq()) {