From 659d7bc4e375fad842dfa666287a13d1d5023852 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 16 Mar 2010 21:14:41 +0100 Subject: [PATCH] [BUG] checks: don't abort when second poll returns an error Now that the response may be fragmented, we may receive early notifications of aborts in return of poll(), as indicated below, which currently cause an early error detection : 21:11:21.036600 epoll_wait(3, {{EPOLLIN, {u32=7, u64=7}}}, 8, 993) = 1 21:11:21.054361 gettimeofday({1268770281, 54467}, NULL) = 0 21:11:21.054540 recv(7, "H"..., 8030, 0) = 1 21:11:21.054694 recv(7, 0x967e759, 8029, 0) = -1 EAGAIN (Resource temporarily unavailable) 21:11:21.054843 epoll_wait(3, {{EPOLLIN|EPOLLERR|EPOLLHUP, {u32=7, u64=7}}}, 8, 975) = 1 21:11:21.060274 gettimeofday({1268770281, 60386}, NULL) = 0 21:11:21.060454 close(7) = 0 Just as in stream_sock, we must not believe poll() without attempting to receive, which fixes the issue : 21:11:59.402207 recv(7, "H"..., 8030, 0) = 1 21:11:59.402362 recv(7, 0x8b5c759, 8029, 0) = -1 EAGAIN (Resource temporarily unavailable) 21:11:59.402511 epoll_wait(3, {{EPOLLIN|EPOLLERR|EPOLLHUP, {u32=7, u64=7}}}, 8, 974) = 1 21:11:59.407242 gettimeofday({1268770319, 407353}, NULL) = 0 21:11:59.407425 recv(7, "TTP/1.0 200 OK\r\n"..., 8029, 0) = 16 21:11:59.407606 recv(7, 0x8b5c769, 8013, 0) = -1 ECONNRESET (Connection reset by peer) 21:11:59.407753 shutdown(7, 2 /* send and receive */) = -1 ENOTCONN (Transport endpoint is not connected) --- src/checks.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/checks.c b/src/checks.c index cba49f8b2..f808db0ba 100644 --- a/src/checks.c +++ b/src/checks.c @@ -866,9 +866,7 @@ static int event_srv_chk_r(int fd) struct server *s = t->context; char *desc; - if (unlikely((s->result & SRV_CHK_ERROR) || - (fdtab[fd].state == FD_STERROR) || - (fdtab[fd].ev & FD_POLL_ERR))) { + if (unlikely((s->result & SRV_CHK_ERROR) || (fdtab[fd].state == FD_STERROR))) { /* in case of TCP only, this tells us if the connection failed */ if (!(s->result & SRV_CHK_ERROR)) set_server_check_status(s, HCHK_STATUS_SOCKERR, NULL);