Commit 823bd832 authored by Philipp Reisner's avatar Philipp Reisner

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: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent 7d4c782c
...@@ -987,14 +987,9 @@ static int conn_connect(struct drbd_tconn *tconn) ...@@ -987,14 +987,9 @@ static int conn_connect(struct drbd_tconn *tconn)
} }
} }
if (conn_request_state(tconn, NS(conn, C_WF_REPORT_PARAMS), CS_VERBOSE) < SS_SUCCESS)
return 0;
sock->sk->sk_sndtimeo = timeout; sock->sk->sk_sndtimeo = timeout;
sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
drbd_thread_start(&tconn->asender);
if (drbd_send_protocol(tconn) == -EOPNOTSUPP) if (drbd_send_protocol(tconn) == -EOPNOTSUPP)
return -1; return -1;
...@@ -1008,6 +1003,11 @@ static int conn_connect(struct drbd_tconn *tconn) ...@@ -1008,6 +1003,11 @@ static int conn_connect(struct drbd_tconn *tconn)
} }
rcu_read_unlock(); rcu_read_unlock();
if (conn_request_state(tconn, NS(conn, C_WF_REPORT_PARAMS), CS_VERBOSE) < SS_SUCCESS)
return 0;
drbd_thread_start(&tconn->asender);
return h; return h;
out_release_sockets: out_release_sockets:
......
...@@ -1055,7 +1055,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, ...@@ -1055,7 +1055,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
drbd_thread_stop_nowait(&mdev->tconn->receiver); drbd_thread_stop_nowait(&mdev->tconn->receiver);
/* Upon network failure, we need to restart the receiver. */ /* Upon network failure, we need to restart the receiver. */
if (os.conn > C_TEAR_DOWN && if (os.conn > C_WF_CONNECTION &&
ns.conn <= C_TEAR_DOWN && ns.conn >= C_TIMEOUT) ns.conn <= C_TEAR_DOWN && ns.conn >= C_TIMEOUT)
drbd_thread_restart_nowait(&mdev->tconn->receiver); drbd_thread_restart_nowait(&mdev->tconn->receiver);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment