]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: init: always fail when setrlimit fails
authorWilliam Dauchy <w.dauchy@criteo.com>
Sun, 27 Oct 2019 19:08:11 +0000 (20:08 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 29 Oct 2019 16:42:27 +0000 (17:42 +0100)
this patch introduces a strict-limits parameter which enforces the
setrlimit setting instead of a warning. This option can be forcingly
disable with the "no" keyword.
The general aim of this patch is to avoid bad surprises on a production
environment where you change the maxconn for example, a new fd limit is
calculated, but cannot be set because of sysfs setting. In that case you
might want to have an explicit failure to be aware of it before seeing
your traffic going down. During a global rollout it is also useful to
explictly fail as most progressive rollout would simply check the
general health check of the process.

As discussed, plan to use the strict by default mode starting from v2.3.

Signed-off-by: William Dauchy <w.dauchy@criteo.com>
doc/configuration.txt
include/types/global.h
src/cfgparse-global.c
src/cfgparse.c
src/haproxy.c

index adba26802713befedd95088380ea38e969a9de05..e1257accf553bb26620f89bc5be03b4d1e303e5f 100644 (file)
@@ -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 <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
 -----------------------
 
index df6614eb162a63770e635dfa43937498f84c7a88..d5dbc7f90dc5b7aa249b5bb2a9e3b60eb34a8628 100644 (file)
@@ -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 {
index b117ebc7c27083be70bccba277ce6b2a15fa5eb0..dd37559a53a5a5db789f31d70447d5f495b57bcb 100644 (file)
@@ -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;
index 0cad16ba8e97d6a38a78cec7b771846f4e2d1537..eaad6c2cde936d72dd81e02a6d17b7122db9c488 100644 (file)
@@ -2149,10 +2149,10 @@ next_line:
 
                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;
                }
 
index a7f294d6a0fc6d2aeaeabca11ffaa349df6178ac..cf23c396fcf241b24375b4ce2eb866add7f343f5 100644 (file)
@@ -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);
-
-                       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;
+                       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. "
+                                          "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)) {