summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2012-08-01 14:53:39 +0200
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-09 14:05:46 +0100
commit80c6eed49d5da3ba97cff4dc316ff051486cd1fc (patch)
tree07fa8b9e16aa3913aef1698a57203b049def33c7 /drivers
parent92f14951c044198306f098e76c56a944cf88867a (diff)
drbd: More random to the connect logic
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/drbd/drbd_receiver.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 1567e9bb9bd..26c30fd64ec 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -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;
}