]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
msg/async/ProtocolV2: respect policy.resetcheck on cookie==0
authorSage Weil <sage@redhat.com>
Thu, 31 Jan 2019 22:52:09 +0000 (16:52 -0600)
committerSage Weil <sage@redhat.com>
Sun, 3 Feb 2019 16:43:40 +0000 (10:43 -0600)
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 <sage@redhat.com>
src/msg/async/ProtocolV2.cc

index b7d413e84788897d36d330a01ca50571c308cb88..16ed5163b5a50dafbb4bb8e347a6d5a64a509cc2 100644 (file)
@@ -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()) {