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;