From 45b8893966394c1eb0ff86f180ab9481bb5528a4 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 12 Nov 2012 12:00:09 +0100 Subject: [PATCH] MINOR: splice: disable it when the system returns EBADF At least on a heavily patched 2.6.35.9, we can see splice() fail with EBADF : recv(6, "789.123456789.123456789.12345678"..., 1049, 0) = 1049 send(5, "HTTP/1.1 200\r\nContent-length: 10"..., 8030, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE) = 8030 gettimeofday({1352717854, 515601}, NULL) = 0 epoll_wait(0x3, 0x40221008, 0x7, 0) = 0 gettimeofday({1352717854, 515793}, NULL) = 0 pipe([7, 8]) = 0 splice(0x6, 0, 0x8, 0, 0xfe12c, 0x3) = -1 EBADF (Bad file descriptor) close(6) = 0 This clearly is a kernel issue since all FDs are valid here, so let's simply disable splice() on the connection when this happens so that the session correctly recovers from that issue using recv(). --- src/raw_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raw_sock.c b/src/raw_sock.c index b7c9f2b73..368b9f083 100644 --- a/src/raw_sock.c +++ b/src/raw_sock.c @@ -129,7 +129,7 @@ int raw_sock_to_pipe(struct connection *conn, struct pipe *pipe, unsigned int co __conn_data_poll_recv(conn); /* we know for sure that it's EAGAIN */ break; } - else if (errno == ENOSYS || errno == EINVAL) { + else if (errno == ENOSYS || errno == EINVAL || errno == EBADF) { /* splice not supported on this end, disable it. * We can safely return -1 since there is no * chance that any data has been piped yet.