Core: master_process_auto_reload directive.

When a child process exits on an abnormal signal, such as SIGKILL
or SIGSEGV, master process will perform reconfiguration.
This commit is contained in:
jo-carter 2025-04-30 14:09:43 +01:00
parent 020b1db7eb
commit 2dca48711a
4 changed files with 45 additions and 10 deletions

View File

@ -55,6 +55,13 @@ static ngx_command_t ngx_core_commands[] = {
offsetof(ngx_core_conf_t, master),
NULL },
{ ngx_string("master_process_auto_reload"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
0,
offsetof(ngx_core_conf_t, auto_reload),
NULL },
{ ngx_string("timer_resolution"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
@ -1113,6 +1120,7 @@ ngx_core_module_create_conf(ngx_cycle_t *cycle)
ccf->daemon = NGX_CONF_UNSET;
ccf->master = NGX_CONF_UNSET;
ccf->auto_reload = NGX_CONF_UNSET;
ccf->timer_resolution = NGX_CONF_UNSET_MSEC;
ccf->shutdown_timeout = NGX_CONF_UNSET_MSEC;
@ -1142,6 +1150,7 @@ ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
ngx_conf_init_value(ccf->daemon, 1);
ngx_conf_init_value(ccf->master, 1);
ngx_conf_init_value(ccf->auto_reload, 0);
ngx_conf_init_msec_value(ccf->timer_resolution, 0);
ngx_conf_init_msec_value(ccf->shutdown_timeout, 0);

View File

@ -434,6 +434,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
}
shm_zone[i].shm.log = cycle->log;
shm_zone[i].skip_inherit = 0;
opart = &old_cycle->shared_memory.part;
oshm_zone = opart->elts;
@ -463,6 +464,10 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
continue;
}
if (shm_zone[i].tag == oshm_zone[n].tag && oshm_zone[i].skip_inherit) {
break;
}
if (shm_zone[i].tag == oshm_zone[n].tag && shm_zone[i].noreuse) {
data = oshm_zone[n].data;
break;
@ -1363,6 +1368,7 @@ ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, size_t size, void *tag)
shm_zone->init = NULL;
shm_zone->tag = tag;
shm_zone->noreuse = 0;
shm_zone->skip_inherit = 0;
return shm_zone;
}

View File

@ -32,7 +32,8 @@ struct ngx_shm_zone_s {
ngx_shm_zone_init_pt init;
void *tag;
void *sync;
ngx_uint_t noreuse; /* unsigned noreuse:1; */
ngx_uint_t noreuse:1;
ngx_uint_t skip_inherit:1;
};
@ -89,6 +90,7 @@ struct ngx_cycle_s {
typedef struct {
ngx_flag_t daemon;
ngx_flag_t master;
ngx_flag_t auto_reload;
ngx_msec_t timer_resolution;
ngx_msec_t shutdown_timeout;

View File

@ -23,7 +23,7 @@ typedef struct {
static void ngx_execute_proc(ngx_cycle_t *cycle, void *data);
static void ngx_signal_handler(int signo, siginfo_t *siginfo, void *ucontext);
static void ngx_process_get_status(void);
static void ngx_unlock_mutexes(ngx_pid_t pid);
static void ngx_unlock_mutexes(ngx_pid_t pid, ngx_int_t skip_inherit);
int ngx_argc;
@ -470,15 +470,20 @@ ngx_signal_handler(int signo, siginfo_t *siginfo, void *ucontext)
static void
ngx_process_get_status(void)
{
int status;
char *process;
ngx_pid_t pid;
ngx_err_t err;
ngx_int_t i;
ngx_uint_t one;
int status;
char *process;
ngx_pid_t pid;
ngx_err_t err;
ngx_int_t i, skip_inherit;
ngx_uint_t one;
ngx_core_conf_t *ccf;
skip_inherit = 0;
one = 0;
ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
ngx_core_module);
for ( ;; ) {
pid = waitpid(-1, &status, WNOHANG);
@ -541,6 +546,15 @@ ngx_process_get_status(void)
"%s %P exited on signal %d",
process, pid, WTERMSIG(status));
#endif
if (ccf->auto_reload) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
"reconfiguring due to child exiting from "
"abnormal signal %d", WTERMSIG(status));
ngx_processes[i].respawn = 0;
ngx_reconfigure = 1;
skip_inherit = 1;
}
} else {
ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
@ -556,13 +570,13 @@ ngx_process_get_status(void)
ngx_processes[i].respawn = 0;
}
ngx_unlock_mutexes(pid);
ngx_unlock_mutexes(pid, skip_inherit);
}
}
static void
ngx_unlock_mutexes(ngx_pid_t pid)
ngx_unlock_mutexes(ngx_pid_t pid, ngx_int_t skip_inherit)
{
ngx_uint_t i;
ngx_shm_zone_t *shm_zone;
@ -604,6 +618,10 @@ ngx_unlock_mutexes(ngx_pid_t pid)
"shared memory zone \"%V\" was locked by %P",
&shm_zone[i].shm.name, pid);
}
if (skip_inherit) {
shm_zone[i].skip_inherit = 1;
}
}
}