diff --git a/doc/configuration.txt b/doc/configuration.txt index adba26802..e1257accf 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -629,6 +629,7 @@ The following keywords are supported in the "global" section : - wurfl-information-list - wurfl-information-list-separator - wurfl-cache-size + - strict-limits * Performance tuning - busy-polling @@ -1405,6 +1406,14 @@ wurfl-cache-size Please note that this option is only available when haproxy has been compiled with USE_WURFL=1. +strict-limits + Makes process fail at startup when a setrlimit fails. Haproxy is tries to set + the best setrlimit according to what has been calculated. If it fails, it + will emit a warning. Use this option if you want an explicit failure of + haproxy when those limits fail. This option is disabled by default. If it has + been enabled, it may still be forcibly disabled by prefixing it with the "no" + keyword. + 3.2. Performance tuning ----------------------- diff --git a/include/types/global.h b/include/types/global.h index df6614eb1..d5dbc7f90 100644 --- a/include/types/global.h +++ b/include/types/global.h @@ -72,8 +72,8 @@ #define GTUNE_BUSY_POLLING (1<<11) #define GTUNE_LISTENER_MQ (1<<12) #define GTUNE_SET_DUMPABLE (1<<13) - #define GTUNE_USE_EVPORTS (1<<14) +#define GTUNE_STRICT_LIMITS (1<<15) /* SSL server verify mode */ enum { diff --git a/src/cfgparse-global.c b/src/cfgparse-global.c index b117ebc7c..dd37559a5 100644 --- a/src/cfgparse-global.c +++ b/src/cfgparse-global.c @@ -1172,6 +1172,14 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm) env++; } } + else if (!strcmp(args[0], "strict-limits")) { /* "no strict-limits" or "strict-limits" */ + if (alertif_too_many_args(0, file, linenum, args, &err_code)) + goto out; + if (kwm == KWM_NO) + global.tune.options &= ~GTUNE_STRICT_LIMITS; + else + global.tune.options |= GTUNE_STRICT_LIMITS; + } else { struct cfg_kw_list *kwl; int index; diff --git a/src/cfgparse.c b/src/cfgparse.c index 0cad16ba8..eaad6c2cd 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -2149,10 +2149,10 @@ int readcfgfile(const char *file) if (kwm != KWM_STD && strcmp(args[0], "option") != 0 && strcmp(args[0], "log") != 0 && strcmp(args[0], "busy-polling") != 0 && - strcmp(args[0], "set-dumpable") != 0) { + strcmp(args[0], "set-dumpable") != 0 && strcmp(args[0], "strict-limits") != 0) { ha_alert("parsing [%s:%d]: negation/default currently " - "supported only for options, log, busy-polling and " - "set-dumpable.\n", file, linenum); + "supported only for options, log, busy-polling, " + "set-dumpable and strict-limits.\n", file, linenum); err_code |= ERR_ALERT | ERR_FATAL; } diff --git a/src/haproxy.c b/src/haproxy.c index a7f294d6a..cf23c396f 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -2829,14 +2829,24 @@ int main(int argc, char **argv) limit.rlim_max = MAX(rlim_fd_max_at_boot, limit.rlim_cur); if (setrlimit(RLIMIT_NOFILE, &limit) == -1) { - /* try to set it to the max possible at least */ getrlimit(RLIMIT_NOFILE, &limit); - limit.rlim_cur = limit.rlim_max; - if (setrlimit(RLIMIT_NOFILE, &limit) != -1) - getrlimit(RLIMIT_NOFILE, &limit); + if (global.tune.options & GTUNE_STRICT_LIMITS) { + ha_alert("[%s.main()] Cannot raise FD limit to %d, limit is %d.\n", + argv[0], global.rlimit_nofile, (int)limit.rlim_cur); + if (!(global.mode & MODE_MWORKER)) + exit(1); + } + else { + /* try to set it to the max possible at least */ + limit.rlim_cur = limit.rlim_max; + if (setrlimit(RLIMIT_NOFILE, &limit) != -1) + getrlimit(RLIMIT_NOFILE, &limit); - ha_warning("[%s.main()] Cannot raise FD limit to %d, limit is %d.\n", argv[0], global.rlimit_nofile, (int)limit.rlim_cur); - global.rlimit_nofile = limit.rlim_cur; + ha_warning("[%s.main()] Cannot raise FD limit to %d, limit is %d. " + "This will fail in >= v2.3\n", + argv[0], global.rlimit_nofile, (int)limit.rlim_cur); + global.rlimit_nofile = limit.rlim_cur; + } } } @@ -2845,13 +2855,29 @@ int main(int argc, char **argv) global.rlimit_memmax * 1048576ULL; #ifdef RLIMIT_AS if (setrlimit(RLIMIT_AS, &limit) == -1) { - ha_warning("[%s.main()] Cannot fix MEM limit to %d megs.\n", - argv[0], global.rlimit_memmax); + if (global.tune.options & GTUNE_STRICT_LIMITS) { + ha_alert("[%s.main()] Cannot fix MEM limit to %d megs.\n", + argv[0], global.rlimit_memmax); + if (!(global.mode & MODE_MWORKER)) + exit(1); + } + else + ha_warning("[%s.main()] Cannot fix MEM limit to %d megs." + "This will fail in >= v2.3\n", + argv[0], global.rlimit_memmax); } #else if (setrlimit(RLIMIT_DATA, &limit) == -1) { - ha_warning("[%s.main()] Cannot fix MEM limit to %d megs.\n", - argv[0], global.rlimit_memmax); + if (global.tune.options & GTUNE_STRICT_LIMITS) { + ha_alert("[%s.main()] Cannot fix MEM limit to %d megs.\n", + argv[0], global.rlimit_memmax); + if (!(global.mode & MODE_MWORKER)) + exit(1); + } + else + ha_warning("[%s.main()] Cannot fix MEM limit to %d megs.", + "This will fail in >= v2.3\n", + argv[0], global.rlimit_memmax); } #endif } @@ -3050,13 +3076,31 @@ int main(int argc, char **argv) limit.rlim_cur = limit.rlim_max = RLIM_INFINITY; #if defined(RLIMIT_FSIZE) - if (setrlimit(RLIMIT_FSIZE, &limit) == -1) - ha_warning("[%s.main()] Failed to set the raise the maximum file size.\n", argv[0]); + if (setrlimit(RLIMIT_FSIZE, &limit) == -1) { + if (global.tune.options & GTUNE_STRICT_LIMITS) { + ha_alert("[%s.main()] Failed to set the raise the maximum " + "file size.\n", argv[0]); + if (!(global.mode & MODE_MWORKER)) + exit(1); + } + else + ha_warning("[%s.main()] Failed to set the raise the maximum " + "file size. This will fail in >= v2.3\n", argv[0]); + } #endif #if defined(RLIMIT_CORE) - if (setrlimit(RLIMIT_CORE, &limit) == -1) - ha_warning("[%s.main()] Failed to set the raise the core dump size.\n", argv[0]); + if (setrlimit(RLIMIT_CORE, &limit) == -1) { + if (global.tune.options & GTUNE_STRICT_LIMITS) { + ha_alert("[%s.main()] Failed to set the raise the core " + "dump size.\n", argv[0]); + if (!(global.mode & MODE_MWORKER)) + exit(1); + } + else + ha_warning("[%s.main()] Failed to set the raise the core " + "dump size. This will fail in >= v2.3\n", argv[0]); + } #endif #if defined(USE_PRCTL) @@ -3069,8 +3113,20 @@ int main(int argc, char **argv) limit.rlim_cur = limit.rlim_max = 0; getrlimit(RLIMIT_NOFILE, &limit); if (limit.rlim_cur < global.maxsock) { - ha_warning("[%s.main()] FD limit (%d) too low for maxconn=%d/maxsock=%d. Please raise 'ulimit-n' to %d or more to avoid any trouble.\n", - argv[0], (int)limit.rlim_cur, global.maxconn, global.maxsock, global.maxsock); + if (global.tune.options & GTUNE_STRICT_LIMITS) { + ha_alert("[%s.main()] FD limit (%d) too low for maxconn=%d/maxsock=%d. " + "Please raise 'ulimit-n' to %d or more to avoid any trouble.\n", + argv[0], (int)limit.rlim_cur, global.maxconn, global.maxsock, + global.maxsock); + if (!(global.mode & MODE_MWORKER)) + exit(1); + } + else + ha_alert("[%s.main()] FD limit (%d) too low for maxconn=%d/maxsock=%d. " + "Please raise 'ulimit-n' to %d or more to avoid any trouble." + "This will fail in >= v2.3\n", + argv[0], (int)limit.rlim_cur, global.maxconn, global.maxsock, + global.maxsock); } if (global.mode & (MODE_DAEMON | MODE_MWORKER | MODE_MWORKER_WAIT)) {