From f6975aa9202c27c50d4272e0fc37067700a28c0f Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 15 Nov 2018 14:33:05 +0100 Subject: [PATCH] BUG/MEDIUM: stream-int: make failed splice_in always subscribe to recv As part of the changes that went into 1.9-dev2 regarding the polling modifications, the changes consecutive to the removal of the wait_list from the conn_streams (commit 71384551a) made si_cs_recv() occasionally return without subscribing to receive events, causing spliced transfers to randomly fail if the client was at least as fast as the server. This may remain unnoticed on most deployments since servers are usually close to haproxy with higher bandwidth than clients have, resulting in buffers always being full. In order to reproduce his effect, it is better to do it on the local machine and to transfer very large objects (hundreds of gigs) over a single connection, to see it suddenly stall after a few tens of gigs. Now with this fix it's fine even after 3 TB over a single connection. No backport is needed. --- src/stream_interface.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/stream_interface.c b/src/stream_interface.c index b82f68cd8..a37a9f6ed 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -652,7 +652,7 @@ int si_cs_send(struct conn_stream *cs) * in the normal buffer. */ if (!co_data(oc)) - return did_send; + goto end; /* when we're here, we already know that there is no spliced * data left, and that there are sendable buffered data. @@ -699,6 +699,7 @@ int si_cs_send(struct conn_stream *cs) */ } } + end: /* We couldn't send all of our data, let the mux know we'd like to send more */ if (!channel_is_empty(oc)) conn->mux->subscribe(cs, SUB_CAN_SEND, &si->wait_event);