]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: mworker: wait mode use standard init code path
authorWilliam Lallemand <wlallemand@haproxy.com>
Wed, 21 Nov 2018 14:48:31 +0000 (15:48 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 21 Nov 2018 16:05:30 +0000 (17:05 +0100)
The mworker waitpid mode (which is used when a reload failed to apply
the new configuration) was still using a specific initialisation path.
That's a problem since we use a polling loop in the master now, the
master proxy is not initialized and the master CLI is not activated.

This patch removes the initialisation code of the wait mode and
introduce the MODE_MWORKER_WAIT in order to use the same init path as
the MODE_MWORKER with some exceptions. It allows to use the master proxy
and the master CLI during the waitpid mode.

include/types/global.h
src/haproxy.c

index effc51c2c6e7ec35ffae89f20c644401a4f67619..02b9c26ae181e7b320455033640d9dd206ee7647 100644 (file)
@@ -47,6 +47,7 @@
 #define        MODE_STARTING   0x20
 #define        MODE_FOREGROUND 0x40
 #define        MODE_MWORKER    0x80    /* Master Worker */
+#define        MODE_MWORKER_WAIT       0x100    /* Master Worker wait mode */
 
 /* list of last checks to perform, depending on config options */
 #define LSTCHK_CAP_BIND        0x00000001      /* check that we can bind to any port */
index 225dc6933397ff1f4b37bee37279d100ee851e30..78356213b0d03d4e1e225274ddc194b7ad26e1ec 100644 (file)
@@ -753,14 +753,6 @@ static void mworker_reload()
                next_argv[next_argc++] = NULL;
        }
 
-       if (getenv("HAPROXY_MWORKER_WAIT_ONLY") == NULL) {
-               struct per_thread_deinit_fct *ptdf;
-
-               list_for_each_entry(ptdf, &per_thread_deinit_list, list)
-                       ptdf->fct();
-               deinit_pollers(); /* we don't want to leak the poller fd */
-       }
-
        ha_warning("Reexecuting Master process\n");
        execvp(next_argv[0], next_argv);
 
@@ -895,40 +887,6 @@ static void mworker_loop()
        run_thread_poll_loop((int []){0});
 }
 
-/*
- * This function initialize haproxy for the master wait mode, it won't fork any
- * new process and won't parse the configuration
- */
-static int mworker_wait_mode()
-{
-
-       global.maxsock = 10; /* reserve 10 fds ; will be incremented by socket eaters */
-
-       if (!(global.tune.options & GTUNE_USE_KQUEUE))
-               disable_poller("kqueue");
-
-       if (!(global.tune.options & GTUNE_USE_EPOLL))
-               disable_poller("epoll");
-
-       if (!(global.tune.options & GTUNE_USE_POLL))
-               disable_poller("poll");
-
-       if (!(global.tune.options & GTUNE_USE_SELECT))
-               disable_poller("select");
-
-       if (global.tune.maxpollevents <= 0)
-               global.tune.maxpollevents = MAX_POLL_EVENTS;
-
-       init_pollers();
-
-
-       mworker_loop();
-
-       /* should never be there */
-
-       return -1;
-}
-
 /*
  * Reexec the process in failure mode, instead of exiting
  */
@@ -1681,11 +1639,10 @@ static void init(int argc, char **argv)
        global.mode |= (arg_mode & (MODE_DAEMON | MODE_MWORKER | MODE_FOREGROUND | MODE_VERBOSE
                                    | MODE_QUIET | MODE_CHECK | MODE_DEBUG));
 
-       /* Master workers wait mode */
-       if ((global.mode & MODE_MWORKER) && (getenv("HAPROXY_MWORKER_WAIT_ONLY") != NULL)) {
-
+       if (getenv("HAPROXY_MWORKER_WAIT_ONLY")) {
                unsetenv("HAPROXY_MWORKER_WAIT_ONLY");
-               mworker_wait_mode();
+               global.mode |= MODE_MWORKER_WAIT;
+               global.mode &= ~MODE_MWORKER;
        }
 
        if ((global.mode & MODE_MWORKER) && (getenv("HAPROXY_MWORKER_REEXEC") != NULL)) {
@@ -1698,44 +1655,47 @@ static void init(int argc, char **argv)
                exit(1);
        }
 
-       /* handle cfgfiles that are actually directories */
-       cfgfiles_expand_directories();
-
-       if (LIST_ISEMPTY(&cfg_cfgfiles))
-               usage(progname);
-
        global.maxsock = 10; /* reserve 10 fds ; will be incremented by socket eaters */
 
        init_default_instance();
 
-       list_for_each_entry(wl, &cfg_cfgfiles, list) {
-               int ret;
+       /* in wait mode, we don't try to read the configuration files */
+       if (!(global.mode & MODE_MWORKER_WAIT)) {
 
-               ret = readcfgfile(wl->s);
-               if (ret == -1) {
-                       ha_alert("Could not open configuration file %s : %s\n",
-                                wl->s, strerror(errno));
-                       exit(1);
+               /* handle cfgfiles that are actually directories */
+               cfgfiles_expand_directories();
+
+               if (LIST_ISEMPTY(&cfg_cfgfiles))
+                       usage(progname);
+
+
+               list_for_each_entry(wl, &cfg_cfgfiles, list) {
+                       int ret;
+
+                       ret = readcfgfile(wl->s);
+                       if (ret == -1) {
+                               ha_alert("Could not open configuration file %s : %s\n",
+                                        wl->s, strerror(errno));
+                               exit(1);
+                       }
+                       if (ret & (ERR_ABORT|ERR_FATAL))
+                               ha_alert("Error(s) found in configuration file : %s\n", wl->s);
+                       err_code |= ret;
+                       if (err_code & ERR_ABORT)
+                               exit(1);
                }
-               if (ret & (ERR_ABORT|ERR_FATAL))
-                       ha_alert("Error(s) found in configuration file : %s\n", wl->s);
-               err_code |= ret;
-               if (err_code & ERR_ABORT)
-                       exit(1);
-       }
 
-       /* do not try to resolve arguments nor to spot inconsistencies when
-        * the configuration contains fatal errors caused by files not found
-        * or failed memory allocations.
-        */
-       if (err_code & (ERR_ABORT|ERR_FATAL)) {
-               ha_alert("Fatal errors found in configuration.\n");
-               exit(1);
+               /* do not try to resolve arguments nor to spot inconsistencies when
+                * the configuration contains fatal errors caused by files not found
+                * or failed memory allocations.
+                */
+               if (err_code & (ERR_ABORT|ERR_FATAL)) {
+                       ha_alert("Fatal errors found in configuration.\n");
+                       exit(1);
+               }
        }
-
        if (global.mode & MODE_MWORKER) {
                int proc;
-               struct wordlist *it, *c;
                struct mworker_proc *tmproc;
 
                if (getenv("HAPROXY_MWORKER_REEXEC") == NULL) {
@@ -1780,6 +1740,10 @@ static void init(int argc, char **argv)
 
                        LIST_ADDQ(&proc_list, &tmproc->list);
                }
+       }
+       if (global.mode & (MODE_MWORKER|MODE_MWORKER_WAIT)) {
+               struct wordlist *it, *c;
+
                mworker_env_to_proc_list(); /* get the info of the children in the env */
 
 
@@ -2847,7 +2811,7 @@ int main(int argc, char **argv)
                exit(1);
        }
 
-       if (listeners == 0) {
+       if (!(global.mode & MODE_MWORKER_WAIT) && listeners == 0) {
                ha_alert("[%s.main()] No enabled listener found (check for 'bind' directives) ! Exiting.\n", argv[0]);
                /* Note: we don't have to send anything to the old pids because we
                 * never stopped them. */
@@ -2941,7 +2905,7 @@ int main(int argc, char **argv)
                }
        }
 
-       if (nb_oldpids)
+       if (nb_oldpids && !(global.mode & MODE_MWORKER_WAIT))
                nb_oldpids = tell_old_pids(oldpids_sig);
 
        if ((getenv("HAPROXY_MWORKER_REEXEC") == NULL)) {
@@ -2983,14 +2947,13 @@ int main(int argc, char **argv)
                           argv[0], (int)limit.rlim_cur, global.maxconn, global.maxsock, global.maxsock);
        }
 
-       if (global.mode & (MODE_DAEMON | MODE_MWORKER)) {
+       if (global.mode & (MODE_DAEMON | MODE_MWORKER | MODE_MWORKER_WAIT)) {
                struct proxy *px;
                struct peers *curpeers;
                int ret = 0;
                int proc;
                int devnullfd = -1;
 
-               children = calloc(global.nbproc, sizeof(int));
                /*
                 * if daemon + mworker: must fork here to let a master
                 * process live in background before forking children
@@ -3020,38 +2983,45 @@ int main(int argc, char **argv)
                }
 
                /* the father launches the required number of processes */
-               for (proc = 0; proc < global.nbproc; proc++) {
-                       ret = fork();
-                       if (ret < 0) {
-                               ha_alert("[%s.main()] Cannot fork.\n", argv[0]);
-                               protocol_unbind_all();
-                               exit(1); /* there has been an error */
-                       }
-                       else if (ret == 0) /* child breaks here */
-                               break;
-                       children[proc] = ret;
-                       if (pidfd >= 0 && !(global.mode & MODE_MWORKER)) {
-                               char pidstr[100];
-                               snprintf(pidstr, sizeof(pidstr), "%d\n", ret);
-                               shut_your_big_mouth_gcc(write(pidfd, pidstr, strlen(pidstr)));
-                       }
-                       if (global.mode & MODE_MWORKER) {
-                               struct mworker_proc *child;
-
-                               qfprintf(stdout, "New worker #%d (%d) forked\n", relative_pid, ret);
-                               /* find the right mworker_proc */
-                               list_for_each_entry(child, &proc_list, list) {
-                                       if (child->relative_pid == relative_pid &&
-                                           child->reloads == 0) {
-                                               child->timestamp = now.tv_sec;
-                                               child->pid = ret;
-                                               break;
+               if (!(global.mode & MODE_MWORKER_WAIT)) {
+                       children = calloc(global.nbproc, sizeof(int));
+                       for (proc = 0; proc < global.nbproc; proc++) {
+                               ret = fork();
+                               if (ret < 0) {
+                                       ha_alert("[%s.main()] Cannot fork.\n", argv[0]);
+                                       protocol_unbind_all();
+                                       exit(1); /* there has been an error */
+                               }
+                               else if (ret == 0) /* child breaks here */
+                                       break;
+                               children[proc] = ret;
+                               if (pidfd >= 0 && !(global.mode & MODE_MWORKER)) {
+                                       char pidstr[100];
+                                       snprintf(pidstr, sizeof(pidstr), "%d\n", ret);
+                                       shut_your_big_mouth_gcc(write(pidfd, pidstr, strlen(pidstr)));
+                               }
+                               if (global.mode & MODE_MWORKER) {
+                                       struct mworker_proc *child;
+
+                                       qfprintf(stdout, "New worker #%d (%d) forked\n", relative_pid, ret);
+                                       /* find the right mworker_proc */
+                                       list_for_each_entry(child, &proc_list, list) {
+                                               if (child->relative_pid == relative_pid &&
+                                                   child->reloads == 0) {
+                                                       child->timestamp = now.tv_sec;
+                                                       child->pid = ret;
+                                                       break;
+                                               }
                                        }
                                }
-                       }
 
-                       relative_pid++; /* each child will get a different one */
-                       pid_bit <<= 1;
+                               relative_pid++; /* each child will get a different one */
+                               pid_bit <<= 1;
+                       }
+               } else {
+                       /* wait mode */
+                       global.nbproc = 1;
+                       proc = 1;
                }
 
 #ifdef USE_CPU_AFFINITY
@@ -3085,7 +3055,7 @@ int main(int argc, char **argv)
                free(global.pidfile); global.pidfile = NULL;
 
                if (proc == global.nbproc) {
-                       if (global.mode & MODE_MWORKER) {
+                       if (global.mode & (MODE_MWORKER|MODE_MWORKER_WAIT)) {
 
                                if ((!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)) &&
                                        (global.mode & MODE_DAEMON)) {