# HG changeset patch # User Maxim Dounin # Date 1715569992 -10800 # Node ID 4eb02e5ddb4823a928d78f3873a52ea8aafdb83e # Parent 6a3ee145d0b549a9b6f4e8a4abe81ef6f8c101df Core: added realpath() checking when testing PID files. This ensures that if the PID file path is changed, yet resolves to the same file via symbolic links, trying to recreate the PID file won't remove it. In particular, this resolves issues as observed on Linux systems with "/var/run/nginx.pid" changed to "/run/nginx.pid". diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -13,6 +13,8 @@ static void ngx_destroy_cycle_pools(ngx_conf_t *conf); static ngx_int_t ngx_init_zone_pool(ngx_cycle_t *cycle, ngx_shm_zone_t *shm_zone); +static ngx_int_t ngx_pidfile_changed(ngx_str_t *name1, ngx_str_t *name2, + ngx_log_t *log); static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log); static void ngx_clean_old_cycles(ngx_event_t *ev); static void ngx_shutdown_timer_handler(ngx_event_t *ev); @@ -332,9 +334,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx, ngx_core_module); - if (ccf->pid.len != old_ccf->pid.len - || ngx_strcmp(ccf->pid.data, old_ccf->pid.data) != 0) - { + + if (ngx_pidfile_changed(&ccf->pid, &old_ccf->pid, log)) { + /* new pid file name */ if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) { @@ -1087,6 +1089,54 @@ ngx_delete_pidfile(ngx_cycle_t *cycle) } +static ngx_int_t +ngx_pidfile_changed(ngx_str_t *name1, ngx_str_t *name2, ngx_log_t *log) +{ + u_char *real1, *real2; + ngx_int_t rc; + + if (name1->len == name2->len + && ngx_strcmp(name1->data, name2->data) == 0) + { + return 0; + } + + rc = 1; + real1 = NULL; + real2 = NULL; + + real1 = ngx_realpath(name1->data, NULL); + + if (real1 == NULL) { + ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, ngx_errno, + ngx_realpath_n " \"%s\" failed", name1->data); + goto done; + } + + real2 = ngx_realpath(name2->data, NULL); + + if (real2 == NULL) { + ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, ngx_errno, + ngx_realpath_n " \"%s\" failed", name2->data); + goto done; + } + + rc = ngx_strcmp(real1, real2); + +done: + + if (real1 && real1 != name1->data) { + ngx_free(real1); + } + + if (real2 && real2 != name2->data) { + ngx_free(real2); + } + + return rc; +} + + ngx_int_t ngx_signal_process(ngx_cycle_t *cycle, char *sig) {