diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2012-08-01 08:53:39 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-09 08:05:46 -0500 |
commit | 80c6eed49d5da3ba97cff4dc316ff051486cd1fc (patch) | |
tree | 07fa8b9e16aa3913aef1698a57203b049def33c7 /drivers/block/drbd | |
parent | 92f14951c044198306f098e76c56a944cf88867a (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/block/drbd')
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 1567e9bb9bde..26c30fd64ecf 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -949,20 +949,25 @@ retry: | |||
949 | if (sock.socket) { | 949 | if (sock.socket) { |
950 | conn_warn(tconn, "initial packet S crossed\n"); | 950 | conn_warn(tconn, "initial packet S crossed\n"); |
951 | sock_release(sock.socket); | 951 | sock_release(sock.socket); |
952 | sock.socket = s; | ||
953 | goto randomize; | ||
952 | } | 954 | } |
953 | sock.socket = s; | 955 | sock.socket = s; |
954 | break; | 956 | break; |
955 | case P_INITIAL_META: | 957 | case P_INITIAL_META: |
958 | set_bit(DISCARD_CONCURRENT, &tconn->flags); | ||
956 | if (msock.socket) { | 959 | if (msock.socket) { |
957 | conn_warn(tconn, "initial packet M crossed\n"); | 960 | conn_warn(tconn, "initial packet M crossed\n"); |
958 | sock_release(msock.socket); | 961 | sock_release(msock.socket); |
962 | msock.socket = s; | ||
963 | goto randomize; | ||
959 | } | 964 | } |
960 | msock.socket = s; | 965 | msock.socket = s; |
961 | set_bit(DISCARD_CONCURRENT, &tconn->flags); | ||
962 | break; | 966 | break; |
963 | default: | 967 | default: |
964 | conn_warn(tconn, "Error receiving initial packet\n"); | 968 | conn_warn(tconn, "Error receiving initial packet\n"); |
965 | sock_release(s); | 969 | sock_release(s); |
970 | randomize: | ||
966 | if (random32() & 1) | 971 | if (random32() & 1) |
967 | goto retry; | 972 | goto retry; |
968 | } | 973 | } |