Hi John,

On Wed, Feb 16, 2011 at 09:51:31AM +0000, John Carter wrote:
> After a bit more experimenting - I have found that number of ports which
> haproxy can listen on is set by the number of file handles per process.
> 
> On linux systems this is set at 1024 by default, hence the limit 1024,
> however this can be changed by editing :
> 
> /etc/security/limits.conf
> 
> where it is possible to change the value for the number of open file handles
> per process

But my concern is that it's exactly what haproxy is doing itself by doing
a setrlimit() upon startup. Thus I still fail to understand why it does
not work in your case.

Hmmm looking at the code I think I have an idea. It looks like the IP ranges
only reserve one socket (1 per "bind" line instead of one per port).

OK I found it. It was even worse than that. The setrlimit() is called AFTER
binding all the ports ! So it means that in your case, only the system's
limits are considered :-(

I've successfully reproduced your case and confirmed the attached patch fixes
it. I'll merge it, so feel free to apply it to your version.

Thanks for the report,
Willy

diff --git a/src/cfgparse.c b/src/cfgparse.c
index 39ac8a0..c1955f0 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1151,8 +1151,8 @@ int cfg_parse_listen(const char *file, int linenum, char 
**args, int kwm)
                                new->conf.file = file;
                                new->conf.line = linenum;
                                new = new->next;
+                               global.maxsock++;
                        }
-                       global.maxsock++;
                }
 
                /* set default values */
@@ -1348,6 +1348,7 @@ int cfg_parse_listen(const char *file, int linenum, char 
**args, int kwm)
                        new_listen->conf.file = file;
                        new_listen->conf.line = linenum;
                        new_listen = new_listen->next;
+                       global.maxsock++;
                }
 
                cur_arg = 2;
@@ -1501,7 +1502,6 @@ int cfg_parse_listen(const char *file, int linenum, char 
**args, int kwm)
                        err_code |= ERR_ALERT | ERR_FATAL;
                        goto out;
                }
-               global.maxsock++;
                goto out;
        }
        else if (!strcmp(args[0], "monitor-net")) {  /* set the range of IPs to 
ignore */
diff --git a/src/haproxy.c b/src/haproxy.c
index a92efc0..fd222cc 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -1014,6 +1014,33 @@ int main(int argc, char **argv)
         */
        signal(SIGPIPE, SIG_IGN);
 
+       /* ulimits */
+       if (!global.rlimit_nofile)
+               global.rlimit_nofile = global.maxsock;
+
+       if (global.rlimit_nofile) {
+               limit.rlim_cur = limit.rlim_max = global.rlimit_nofile;
+               if (setrlimit(RLIMIT_NOFILE, &limit) == -1) {
+                       Warning("[%s.main()] Cannot raise FD limit to %d.\n", 
argv[0], global.rlimit_nofile);
+               }
+       }
+
+       if (global.rlimit_memmax) {
+               limit.rlim_cur = limit.rlim_max =
+                       global.rlimit_memmax * 1048576 / global.nbproc;
+#ifdef RLIMIT_AS
+               if (setrlimit(RLIMIT_AS, &limit) == -1) {
+                       Warning("[%s.main()] Cannot fix MEM limit to %d 
megs.\n",
+                               argv[0], global.rlimit_memmax);
+               }
+#else
+               if (setrlimit(RLIMIT_DATA, &limit) == -1) {
+                       Warning("[%s.main()] Cannot fix MEM limit to %d 
megs.\n",
+                               argv[0], global.rlimit_memmax);
+               }
+#endif
+       }
+
        /* We will loop at most 100 times with 10 ms delay each time.
         * That's at most 1 second. We only send a signal to old pids
         * if we cannot grab at least one port.
@@ -1096,33 +1123,6 @@ int main(int argc, char **argv)
                pidfile = fdopen(pidfd, "w");
        }
 
-       /* ulimits */
-       if (!global.rlimit_nofile)
-               global.rlimit_nofile = global.maxsock;
-
-       if (global.rlimit_nofile) {
-               limit.rlim_cur = limit.rlim_max = global.rlimit_nofile;
-               if (setrlimit(RLIMIT_NOFILE, &limit) == -1) {
-                       Warning("[%s.main()] Cannot raise FD limit to %d.\n", 
argv[0], global.rlimit_nofile);
-               }
-       }
-
-       if (global.rlimit_memmax) {
-               limit.rlim_cur = limit.rlim_max =
-                       global.rlimit_memmax * 1048576 / global.nbproc;
-#ifdef RLIMIT_AS
-               if (setrlimit(RLIMIT_AS, &limit) == -1) {
-                       Warning("[%s.main()] Cannot fix MEM limit to %d 
megs.\n",
-                               argv[0], global.rlimit_memmax);
-               }
-#else
-               if (setrlimit(RLIMIT_DATA, &limit) == -1) {
-                       Warning("[%s.main()] Cannot fix MEM limit to %d 
megs.\n",
-                               argv[0], global.rlimit_memmax);
-               }
-#endif
-       }
-
 #ifdef CONFIG_HAP_CTTPROXY
        if (global.last_checks & LSTCHK_CTTPROXY) {
                int ret;

Reply via email to