As signal handling is reset during restart it is possible
for a child process to exit while sig_reaper() is not registered
as the handler for SIGCHLD and thus the worker is not reaped.

Also:
* !replace_workers_task will always be true for the master
  process so this test can be removed
* Initialised sig_reaper before workers are forked so that
  it will reap them in they case where they exit very early on

Signed-off-by: Simon Horman <[email protected]>
---
 src/haproxy.c |   35 ++++++++++++++++++++++-------------
 1 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/src/haproxy.c b/src/haproxy.c
index 7f58a43..4ae8920 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -1428,6 +1428,28 @@ static void create_processes(int argc, char **argv, FILE 
*pidfile)
                }
        }
 
+       if (global.mode & MODE_MASTER_WORKER) {
+               replace_workers_task = task_new();
+               if (unlikely(replace_workers_task == NULL)) {
+                       send_log(NULL, LOG_ERR,
+                                "Cannot create reaper task.\n");
+                       protocol_unbind_all();
+                       exit(1); /* there has been an error */
+               }
+
+               replace_workers_task->process = task_replace_workers;
+               replace_workers_task->expire = TICK_ETERNITY;
+
+               send_log(NULL, LOG_INFO,
+                        "Register sig_reaper.\n");
+               signal_register_fct(SIGCHLD, sig_reaper, SIGCHLD);
+
+               /* Reap any children that died while master restart
+                * was in progress
+                */
+               sig_reaper(NULL);
+       }
+
        /* the father launches the required number of processes */
        for (proc = 0; proc < global.nbproc; proc++) {
                /* In the case of replacing_workers a worker may still exist */
@@ -1453,20 +1475,7 @@ static void create_processes(int argc, char **argv, FILE 
*pidfile)
                        exit(0);
 
                is_master = 1;
-               if (!replace_workers_task) {
-                       replace_workers_task = task_new();
-                       if (unlikely(replace_workers_task == NULL)) {
-                               send_log(NULL, LOG_ERR,
-                                        "Cannot create reaper task.\n");
-                               protocol_unbind_all();
-                               exit(1); /* there has been an error */
-                       }
-
-                       replace_workers_task->process = task_replace_workers;
-                       replace_workers_task->expire = TICK_ETERNITY;
 
-                       signal_register_fct(SIGCHLD, sig_reaper, SIGCHLD);
-               }
        } else { /* Child */
                is_master = 0;
                close_log();
-- 
1.7.2.3


Reply via email to