[PATCH] os/unix: don't stop old workers if reload failed

kasei at kasei.im kasei at kasei.im
Fri Dec 4 04:29:51 UTC 2020


*Sorry for the format issue, resending it.
  Hello, We found sometimes nginx might failed to start new worker processes
during reconfiguring, (the number of processes exceeds NGX_MAX_PROCESSES for
example). In that case, the master process still send QUIT signal to old
workers, leads to the situation that there is no worker processes accept socket
from listening sockets.
  And we found actually there is a return code in os/win32's
ngx_start_worker_processes funcation. It skip quiting workers if there is no
worker processes be spawned. So I written this patch followed win32's
implementation and tested it. Cloud you please check this patch to see if there
is anything missed? Thanks very much.

# HG changeset patch
# User Kasei Wang <kasei at kasei.im>
# Date 1607052987 -28800
#      Fri Dec 04 11:36:27 2020 +0800
# Node ID 0711cc5f95b5fc2aad0b51328b382b5cfe08f8bb
# Parent  90cc7194e993f8d722347e9f46a00f65dffc3935
os/unix: don't stop old workers if start new worker processes
	 failed during reconfiguring.

diff -r 90cc7194e993 -r 0711cc5f95b5 src/os/unix/ngx_process_cycle.c
--- a/src/os/unix/ngx_process_cycle.c	Fri Nov 27 00:01:20 2020 +0300
+++ b/src/os/unix/ngx_process_cycle.c	Fri Dec 04 11:36:27 2020 +0800
@@ -11,7 +11,7 @@
 #include <ngx_channel.h>


-static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n,
+static ngx_int_t ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n,
     ngx_int_t type);
 static void ngx_start_cache_manager_processes(ngx_cycle_t *cycle,
     ngx_uint_t respawn);
@@ -127,8 +127,13 @@

     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

-    ngx_start_worker_processes(cycle, ccf->worker_processes,
-                               NGX_PROCESS_RESPAWN);
+    if (ngx_start_worker_processes(cycle, ccf->worker_processes,
+                               NGX_PROCESS_RESPAWN) == 0)
+    {
+        ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
+                      "start worker processes failed");
+        exit(2);
+    }
     ngx_start_cache_manager_processes(cycle, 0);

     ngx_new_binary = 0;
@@ -231,8 +236,14 @@
             ngx_cycle = cycle;
             ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
                                                    ngx_core_module);
-            ngx_start_worker_processes(cycle, ccf->worker_processes,
-                                       NGX_PROCESS_JUST_RESPAWN);
+            /* TODO: close reuseport listening sockets not handled by worker */
+            if (ngx_start_worker_processes(cycle, ccf->worker_processes,
+                                       NGX_PROCESS_JUST_RESPAWN) == 0)
+            {
+                ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
+                "start worker processes failed during reconfiguring");
+                continue;
+            }
             ngx_start_cache_manager_processes(cycle, 1);

             /* allow new processes to start */
@@ -332,7 +343,7 @@
 }


-static void
+static ngx_int_t
 ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
 {
     ngx_int_t      i;
@@ -346,8 +357,12 @@

     for (i = 0; i < n; i++) {

-        ngx_spawn_process(cycle, ngx_worker_process_cycle,
-                          (void *) (intptr_t) i, "worker process", type);
+        if (ngx_spawn_process(cycle, ngx_worker_process_cycle,
+                          (void *) (intptr_t) i, "worker process", type)
+            == NGX_INVALID_PID)
+        {
+            break;
+        }

         ch.pid = ngx_processes[ngx_process_slot].pid;
         ch.slot = ngx_process_slot;
@@ -355,6 +370,8 @@

         ngx_pass_open_channel(cycle, &ch);
     }
+
+    return i;
 }




More information about the nginx-devel mailing list