]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[BUG] checks: don't abort when second poll returns an error
authorWilly Tarreau <w@1wt.eu>
Tue, 16 Mar 2010 20:14:41 +0000 (21:14 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 16 Mar 2010 21:57:27 +0000 (22:57 +0100)
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

index cba49f8b23e407085cc61b2e06d308ed575d9c24..f808db0ba65b319f4ca965fd10b1d8a74beff2d3 100644 (file)
@@ -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);