mirror of
https://github.com/haproxy/haproxy.git
synced 2026-04-27 00:57:03 -04:00
BUG/MEDIUM: stream: Fix a possible freeze during a forced shut on a stream
When a forced shutdown is performed on a stream, it is possible to freeze it infinitly because it is performed in an unexpected way from process_stream() point of view, especially when the stream is waiting for a server connection. The events sequence is a bit complex but at the end the stream remains blocked in turn-around state and no event are trriggered to unblock it. By trying to fix the issue, we considered it was safer to rethink the feature. The idea is to quickly shutdown a stream to release resources. For instance to be able to delete a server. So, instead of scheduling a shutdown, it is more efficient to trigger an error and detach the stream from the server, if neecessary. The same code than the one used to deal with connection errors in back_handle_st_cer() is used. This patch must be slowly backported as far as 2.6.
This commit is contained in:
parent
b351f06ff1
commit
51611a5b70
1 changed files with 19 additions and 2 deletions
21
src/stream.c
21
src/stream.c
|
|
@ -2845,11 +2845,28 @@ void stream_shutdown_self(struct stream *stream, int why)
|
|||
if (stream->scb->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))
|
||||
return;
|
||||
|
||||
sc_schedule_shutdown(stream->scb);
|
||||
sc_schedule_abort(stream->scb);
|
||||
stream->task->nice = 1024;
|
||||
if (!(stream->flags & SF_ERR_MASK))
|
||||
stream->flags |= why;
|
||||
|
||||
if (objt_server(stream->target)) {
|
||||
if (stream->flags & SF_CURR_SESS) {
|
||||
stream->flags &= ~SF_CURR_SESS;
|
||||
_HA_ATOMIC_DEC(&__objt_server(stream->target)->cur_sess);
|
||||
}
|
||||
|
||||
sess_change_server(stream, NULL);
|
||||
if (may_dequeue_tasks(objt_server(stream->target), stream->be))
|
||||
process_srv_queue(objt_server(stream->target));
|
||||
}
|
||||
|
||||
/* shutw is enough to stop a connecting socket */
|
||||
stream->scb->flags |= SC_FL_ERROR | SC_FL_NOLINGER;
|
||||
sc_shutdown(stream->scb);
|
||||
|
||||
stream->scb->state = SC_ST_CLO;
|
||||
if (stream->srv_error)
|
||||
stream->srv_error(stream, stream->scb);
|
||||
}
|
||||
|
||||
/* dumps an error message for type <type> at ptr <ptr> related to stream <s>,
|
||||
|
|
|
|||
Loading…
Reference in a new issue