From: Willy Tarreau Date: Fri, 22 Jul 2011 14:56:33 +0000 (+0200) Subject: [BUG] stream_sock: disable listener when system resources are exhausted X-Git-Tag: v1.5-dev8~181 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=100298749bb45789fd1d7bc8c1c7f3ac3f6d504d;p=thirdparty%2Fhaproxy.git [BUG] stream_sock: disable listener when system resources are exhausted When an accept() returns -1 ENFILE du to system limits, it leaves the connection pending in the backlog and epoll() comes back immediately afterwards trying to make it accept it again. This causes haproxy to remain at 100% CPU until something makes an accept() possible again. Now upon such resource shortage, we mark the listener FULL so that we only enable it again once at least one connection has been released. In fact we only do that if there are some active connections on this proxy, so that it has a chance to be marked not full again. This makes haproxy remain idle when all resources are used, which helps a lot releasing those resource as fast as possible. Backport to 1.4 might be desirable but difficult and tricky. --- diff --git a/src/stream_sock.c b/src/stream_sock.c index d4752845da..dc04d35b41 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -1221,12 +1221,20 @@ int stream_sock_accept(int fd) send_log(p, LOG_EMERG, "Proxy %s reached system FD limit at %d. Please check system tunables.\n", p->id, maxfd); + if (l->nbconn) { + EV_FD_CLR(l->fd, DIR_RD); + l->state = LI_FULL; + } return 0; case EMFILE: if (p) send_log(p, LOG_EMERG, "Proxy %s reached process FD limit at %d. Please check 'ulimit-n' and restart.\n", p->id, maxfd); + if (l->nbconn) { + EV_FD_CLR(l->fd, DIR_RD); + l->state = LI_FULL; + } return 0; case ENOBUFS: case ENOMEM: @@ -1234,6 +1242,10 @@ int stream_sock_accept(int fd) send_log(p, LOG_EMERG, "Proxy %s reached system memory limit at %d sockets. Please check system tunables.\n", p->id, maxfd); + if (l->nbconn) { + EV_FD_CLR(l->fd, DIR_RD); + l->state = LI_FULL; + } return 0; default: return 0;