drbd: More random to the connect logic
authorPhilipp Reisner <philipp.reisner@linbit.com>
Wed, 1 Aug 2012 12:53:39 +0000 (14:53 +0200)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Fri, 9 Nov 2012 13:05:46 +0000 (14:05 +0100)
Since the listening socket is open all the time, it was possible to
get into stable "initial packet S crossed" loops.

* when both sides realize in the drbd_socket_okay() call at the end
  of the loop that the other side closed the main socket you had
  the chance to get into a stable loop with repeated "packet S crossed"
  messages.

* when both sides do not realize with the drbd_socket_okay() call at the end
  of the loop that the other side closed the main socket you had
  the chance to get into a stable loop with alternating "packet S crossed"
  "packet M crossed" messages.

In order to break out these stable loops randomize the behaviour if
such a crossing of P_INITIAL_DATA or P_INITIAL_META packets is detected.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
drivers/block/drbd/drbd_receiver.c

index 1567e9bb9bde2a9c7db6552ff5b3daea0ec73621..26c30fd64ecfb154b7c99e4dee8c3b746ad5fc47 100644 (file)
@@ -949,20 +949,25 @@ retry:
                                if (sock.socket) {
                                        conn_warn(tconn, "initial packet S crossed\n");
                                        sock_release(sock.socket);
+                                       sock.socket = s;
+                                       goto randomize;
                                }
                                sock.socket = s;
                                break;
                        case P_INITIAL_META:
+                               set_bit(DISCARD_CONCURRENT, &tconn->flags);
                                if (msock.socket) {
                                        conn_warn(tconn, "initial packet M crossed\n");
                                        sock_release(msock.socket);
+                                       msock.socket = s;
+                                       goto randomize;
                                }
                                msock.socket = s;
-                               set_bit(DISCARD_CONCURRENT, &tconn->flags);
                                break;
                        default:
                                conn_warn(tconn, "Error receiving initial packet\n");
                                sock_release(s);
+randomize:
                                if (random32() & 1)
                                        goto retry;
                        }