You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

57 lines
2.6 KiB

commit f87ea7d2fdcfa3ccd5d605b3ce96642d28f20f6b
Author: Willy Tarreau <w@1wt.eu>
Date: Fri Aug 24 14:31:53 2018 +0200
BUG/MEDIUM: unix: provide a ->drain() function
Right now conn_sock_drain() calls the protocol's ->drain() function if
it exists, otherwise it simply tries to disable polling for receiving
on the connection. This doesn't work well anymore since we've implemented
the muxes in 1.8, and it has a side effect with keep-alive backend
connections established over unix sockets. What happens is that if
during the idle time after a request, a connection reports some data,
si_idle_conn_null_cb() is called, which will call conn_sock_drain().
This one sees there's no drain() on unix sockets and will simply disable
polling for data on the connection. But it doesn't do anything on the
conn_stream. Thus while leaving the conn_fd_handler, the mux's polling
is updated and recomputed based on the conn_stream's polling state,
which is still enabled, and nothing changes, so we see the process
use 100% CPU in this case because the FD remains active in the cache.
There are several issues that need to be addressed here. The first and
most important is that we cannot expect some protocols to simply stop
reading data when asked to drain pending data. So this patch make the
unix sockets rely on tcp_drain() since the functions are the same. This
solution is appropriate for backporting, but a better one is desired for
the long term. The second issue is that si_idle_conn_null_cb() shouldn't
drain the connection but the conn_stream.
At the moment we don't have any way to drain a conn_stream, though a flag
on rcv_buf() will do it well. Until we support muxes on the server side
it is not a problem so this part can be addressed later.
This fix must be backported to 1.8.
(cherry picked from commit fe5d2ac65fd58a8320e8dc725219c1bce5839592)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index f2374be6..0b3a57b8 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -42,6 +42,7 @@
#include <proto/listener.h>
#include <proto/log.h>
#include <proto/protocol.h>
+#include <proto/proto_tcp.h>
#include <proto/task.h>
static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen);
@@ -71,6 +72,7 @@ static struct protocol proto_unix = {
.disable_all = disable_all_listeners,
.get_src = uxst_get_src,
.get_dst = uxst_get_dst,
+ .drain = tcp_drain,
.pause = uxst_pause_listener,
.add = uxst_add_listener,
.listeners = LIST_HEAD_INIT(proto_unix.listeners),