]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: startup: split main: add step_init_3
authorValentine Krasnobaeva <vkrasnobaeva@haproxy.com>
Mon, 7 Oct 2024 08:37:01 +0000 (10:37 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 16 Oct 2024 20:02:39 +0000 (22:02 +0200)
The first part of main(), just after calling the former init() and before
trying to bind listeners, need to be also encapsulated into a separate
step_init_3() as it is. It contains important blocks to register signals, to
apply memory and nofile limits, etc. The order of these blocks should be also
preserved (especially the signals part).

For the moment step_init_3() must be also executed for all runtime modes.

src/haproxy.c

index 8269553545e000e634bebd24b797ec0e32145e2f..d7a2fbd6134d2214cde6174fdb8ae545cfd46a09 100644 (file)
@@ -2755,6 +2755,88 @@ static void step_init_2(int argc, char** argv)
        post_mortem_add_component("haproxy", haproxy_version, cc, cflags, opts, argv[0]);
 }
 
+/* This is a third part of the late init sequence, where we register signals for
+ * process in worker and in standalone modes. We also check here, if the
+ * global.maxsock calculated in step_init_2() could be applied as the nofile limit
+ * for the process. Memory limit, if set, will be applied here as well. If some
+ * capabilities were set on the haproxy binary by administrator, we will try to
+ * put it into the process Effective capabilities set.
+ */
+static void step_init_3(void)
+{
+       struct rlimit limit;
+
+       signal_register_fct(SIGQUIT, dump, SIGQUIT);
+       signal_register_fct(SIGUSR1, sig_soft_stop, SIGUSR1);
+       signal_register_fct(SIGHUP, sig_dump_state, SIGHUP);
+       signal_register_fct(SIGUSR2, NULL, 0);
+
+       /* Always catch SIGPIPE even on platforms which define MSG_NOSIGNAL.
+        * Some recent FreeBSD setups report broken pipes, and MSG_NOSIGNAL
+        * was defined there, so let's stay on the safe side.
+        */
+       signal_register_fct(SIGPIPE, NULL, 0);
+
+       /* ulimits */
+       if (!global.rlimit_nofile)
+               global.rlimit_nofile = global.maxsock;
+
+       if (global.rlimit_nofile) {
+               limit.rlim_cur = global.rlimit_nofile;
+               limit.rlim_max = MAX(rlim_fd_max_at_boot, limit.rlim_cur);
+
+               if ((global.fd_hard_limit && limit.rlim_cur > global.fd_hard_limit) ||
+                   raise_rlim_nofile(NULL, &limit) != 0) {
+                       getrlimit(RLIMIT_NOFILE, &limit);
+                       if (global.fd_hard_limit && limit.rlim_cur > global.fd_hard_limit)
+                               limit.rlim_cur = global.fd_hard_limit;
+
+                       if (global.tune.options & GTUNE_STRICT_LIMITS) {
+                               ha_alert("[%s.main()] Cannot raise FD limit to %d, limit is %d.\n",
+                                        progname, global.rlimit_nofile, (int)limit.rlim_cur);
+                               exit(1);
+                       }
+                       else {
+                               /* try to set it to the max possible at least */
+                               limit.rlim_cur = limit.rlim_max;
+                               if (global.fd_hard_limit && limit.rlim_cur > global.fd_hard_limit)
+                                       limit.rlim_cur = global.fd_hard_limit;
+
+                               if (raise_rlim_nofile(&limit, &limit) == 0)
+                                       getrlimit(RLIMIT_NOFILE, &limit);
+
+                               ha_warning("[%s.main()] Cannot raise FD limit to %d, limit is %d.\n",
+                                          progname, global.rlimit_nofile, (int)limit.rlim_cur);
+                               global.rlimit_nofile = limit.rlim_cur;
+                       }
+               }
+       }
+
+       if (global.rlimit_memmax) {
+               limit.rlim_cur = limit.rlim_max =
+                       global.rlimit_memmax * 1048576ULL;
+               if (setrlimit(RLIMIT_DATA, &limit) == -1) {
+                       if (global.tune.options & GTUNE_STRICT_LIMITS) {
+                               ha_alert("[%s.main()] Cannot fix MEM limit to %d megs.\n",
+                                        progname, global.rlimit_memmax);
+                               exit(1);
+                       }
+                       else
+                               ha_warning("[%s.main()] Cannot fix MEM limit to %d megs.\n",
+                                          progname, global.rlimit_memmax);
+               }
+       }
+
+#if defined(USE_LINUX_CAP)
+       /* If CAP_NET_BIND_SERVICE is in binary file permitted set and process
+        * is started and run under the same non-root user, this allows
+        * binding to privileged ports.
+        */
+       if (!master)
+           prepare_caps_from_permitted_set(geteuid(), global.uid, progname);
+#endif
+}
+
 void deinit(void)
 {
        struct proxy *p = proxies_list, *p0;
@@ -3456,75 +3538,10 @@ int main(int argc, char **argv)
         */
        step_init_2(argc, argv);
 
-       signal_register_fct(SIGQUIT, dump, SIGQUIT);
-       signal_register_fct(SIGUSR1, sig_soft_stop, SIGUSR1);
-       signal_register_fct(SIGHUP, sig_dump_state, SIGHUP);
-       signal_register_fct(SIGUSR2, NULL, 0);
-
-       /* Always catch SIGPIPE even on platforms which define MSG_NOSIGNAL.
-        * Some recent FreeBSD setups report broken pipes, and MSG_NOSIGNAL
-        * was defined there, so let's stay on the safe side.
-        */
-       signal_register_fct(SIGPIPE, NULL, 0);
-
-       /* ulimits */
-       if (!global.rlimit_nofile)
-               global.rlimit_nofile = global.maxsock;
-
-       if (global.rlimit_nofile) {
-               limit.rlim_cur = global.rlimit_nofile;
-               limit.rlim_max = MAX(rlim_fd_max_at_boot, limit.rlim_cur);
-
-               if ((global.fd_hard_limit && limit.rlim_cur > global.fd_hard_limit) ||
-                   raise_rlim_nofile(NULL, &limit) != 0) {
-                       getrlimit(RLIMIT_NOFILE, &limit);
-                       if (global.fd_hard_limit && limit.rlim_cur > global.fd_hard_limit)
-                               limit.rlim_cur = global.fd_hard_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);
-                               exit(1);
-                       }
-                       else {
-                               /* try to set it to the max possible at least */
-                               limit.rlim_cur = limit.rlim_max;
-                               if (global.fd_hard_limit && limit.rlim_cur > global.fd_hard_limit)
-                                       limit.rlim_cur = global.fd_hard_limit;
-
-                               if (raise_rlim_nofile(&limit, &limit) == 0)
-                                       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.rlimit_memmax) {
-               limit.rlim_cur = limit.rlim_max =
-                       global.rlimit_memmax * 1048576ULL;
-               if (setrlimit(RLIMIT_DATA, &limit) == -1) {
-                       if (global.tune.options & GTUNE_STRICT_LIMITS) {
-                               ha_alert("[%s.main()] Cannot fix MEM limit to %d megs.\n",
-                                        argv[0], global.rlimit_memmax);
-                               exit(1);
-                       }
-                       else
-                               ha_warning("[%s.main()] Cannot fix MEM limit to %d megs.\n",
-                                          argv[0], global.rlimit_memmax);
-               }
-       }
-
-#if defined(USE_LINUX_CAP)
-       /* If CAP_NET_BIND_SERVICE is in binary file permitted set and process
-        * is started and run under the same non-root user, this allows
-        * binding to privileged ports.
+       /* Late init step: register signals for worker and standalon modes, apply
+        * nofile and memory limits, apply capabilities from binary, if any.
         */
-       if (!master)
-           prepare_caps_from_permitted_set(geteuid(), global.uid, argv[0]);
-#endif
+       step_init_3();
 
        /* Try to get the listeners FD from the previous process using
         * _getsocks on the stat socket, it must never been done in wait mode