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>
This commit is contained in:
Philipp Reisner 2012-08-01 14:53:39 +02:00
parent 92f14951c0
commit 80c6eed49d

View File

@ -949,20 +949,25 @@ static int conn_connect(struct drbd_tconn *tconn)
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;
}