diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2011-08-04 04:33:08 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-05-09 09:15:46 -0400 |
commit | 1e86ac48af137a3cfd48cba727e7abe132dfc8de (patch) | |
tree | 0ba3f9c72f8a7fb2972b8df5ac11d352db48f97a | |
parent | 80f9fd55a66a6843373330901564ef2d9c7fb050 (diff) |
drbd: Bugfix for the connection behavior
If we get into the C_BROKEN_PIPE cstate once, the state engine set the
thi->t_state of the receiver thread to restarting. But with the while loop
in drbdd_init() a new connection gets established. After the call into
drbdd() returns immediately since the thi->t_state is not RUNNING. The
restart of drbd_init() then resets thi->t_state to RUNNING.
I.e. after entering C_BROKEN_PIPE once, the next successful established
connection gets wasted.
The two parts of the fix:
* Do not cause the thread to restart if we detect the issue
with the sockets while we are in C_WF_CONNECTION.
* Make sure that all actions that would have set us to C_BROKEN_PIPE
happen before the state change to C_WF_REPORT_PARAMS.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 2 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 10 |
2 files changed, 6 insertions, 6 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 56569a803331..8658dac2853a 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -1318,7 +1318,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, | |||
1318 | drbd_thread_stop_nowait(&mdev->receiver); | 1318 | drbd_thread_stop_nowait(&mdev->receiver); |
1319 | 1319 | ||
1320 | /* Upon network failure, we need to restart the receiver. */ | 1320 | /* Upon network failure, we need to restart the receiver. */ |
1321 | if (os.conn > C_TEAR_DOWN && | 1321 | if (os.conn > C_WF_CONNECTION && |
1322 | ns.conn <= C_TEAR_DOWN && ns.conn >= C_TIMEOUT) | 1322 | ns.conn <= C_TEAR_DOWN && ns.conn >= C_TIMEOUT) |
1323 | drbd_thread_restart_nowait(&mdev->receiver); | 1323 | drbd_thread_restart_nowait(&mdev->receiver); |
1324 | 1324 | ||
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index bb92671d1f16..aa6c52c80e2e 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -888,17 +888,12 @@ retry: | |||
888 | } | 888 | } |
889 | } | 889 | } |
890 | 890 | ||
891 | if (drbd_request_state(mdev, NS(conn, C_WF_REPORT_PARAMS)) < SS_SUCCESS) | ||
892 | return 0; | ||
893 | |||
894 | sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10; | 891 | sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10; |
895 | sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; | 892 | sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; |
896 | 893 | ||
897 | atomic_set(&mdev->packet_seq, 0); | 894 | atomic_set(&mdev->packet_seq, 0); |
898 | mdev->peer_seq = 0; | 895 | mdev->peer_seq = 0; |
899 | 896 | ||
900 | drbd_thread_start(&mdev->asender); | ||
901 | |||
902 | if (drbd_send_protocol(mdev) == -1) | 897 | if (drbd_send_protocol(mdev) == -1) |
903 | return -1; | 898 | return -1; |
904 | drbd_send_sync_param(mdev, &mdev->sync_conf); | 899 | drbd_send_sync_param(mdev, &mdev->sync_conf); |
@@ -907,6 +902,11 @@ retry: | |||
907 | drbd_send_state(mdev); | 902 | drbd_send_state(mdev); |
908 | clear_bit(USE_DEGR_WFC_T, &mdev->flags); | 903 | clear_bit(USE_DEGR_WFC_T, &mdev->flags); |
909 | clear_bit(RESIZE_PENDING, &mdev->flags); | 904 | clear_bit(RESIZE_PENDING, &mdev->flags); |
905 | |||
906 | if (drbd_request_state(mdev, NS(conn, C_WF_REPORT_PARAMS)) < SS_SUCCESS) | ||
907 | return 0; | ||
908 | |||
909 | drbd_thread_start(&mdev->asender); | ||
910 | mod_timer(&mdev->request_timer, jiffies + HZ); /* just start it here. */ | 910 | mod_timer(&mdev->request_timer, jiffies + HZ); /* just start it here. */ |
911 | 911 | ||
912 | return 1; | 912 | return 1; |