# HG changeset patch # User Igor Sysoev # Date 1245059295 0 # Node ID 87da6664fb49e91b0f3e39ceb6a986ddc282c9dd # Parent f892042956e34c1f552e12284255833ea94605ca merge r2897, r2898, r2899, r2901, r2902, r2904, r2905, r2906, r2907, r2909, r2910, r2922, r2923, r2924, r2925, r2929: various win32 fixes: *) use no-threads for Unix builds only *) Win32 returns ERROR_PATH_NOT_FOUND instead of ERROR_FILE_NOT_FOUND *) add trailing zero to a file name in ngx_win32_rename_file() *) fix logging in ngx_win32_rename_file() *) allow shared memory segments more than 4G *) fix memory leak in successful case *) log shared memory name in failure case *) test that zone has the same addresses in different processes *) add drive letter for Win32 root path *) log GetExitCodeProcess()'s errno *) test premature process termination *) fix debug logging *) exit if no workers could not be started *) do not quit old workers if no new workers could not be started *) a signaller process should stop configuration processing just after it is able to get pid file, this allows to not open log files, etc. *) win32 master process had aready closed listening sockets diff --git a/auto/cc/msvc b/auto/cc/msvc --- a/auto/cc/msvc +++ b/auto/cc/msvc @@ -125,7 +125,7 @@ ngx_objext="obj" ngx_binext=".exe" ngx_long_start='@<< - ' + ' ngx_long_end='<<' ngx_long_regex_cont=' \ ' diff --git a/auto/lib/openssl/make b/auto/lib/openssl/make --- a/auto/lib/openssl/make +++ b/auto/lib/openssl/make @@ -2,11 +2,6 @@ # Copyright (C) Igor Sysoev -case $USE_THREADS in - NO) OPENSSL_OPT="$OPENSSL_OPT no-threads" ;; - *) OPENSSL_OPT="$OPENSSL_OPT threads" ;; -esac - case "$CC" in cl) @@ -21,7 +16,7 @@ END ;; - cl | bcc32) + bcc32) ngx_opt=`echo "-DOPENSSL=\"$OPENSSL\" -DOPENSSL_OPT=\"$OPENSSL_OPT\"" \ | sed -e "s/\//$ngx_regex_dirsep/g"` @@ -45,16 +40,14 @@ END ;; *) - case $OPENSSL in + case $USE_THREADS in + NO) OPENSSL_OPT="$OPENSSL_OPT no-threads" ;; + *) OPENSSL_OPT="$OPENSSL_OPT threads" ;; + esac - /*) - ngx_prefix="$OPENSSL/openssl" - ;; - - *) - ngx_prefix="$PWD/$OPENSSL/openssl" - ;; - + case $OPENSSL in + /*) ngx_prefix="$OPENSSL/openssl" ;; + *) ngx_prefix="$PWD/$OPENSSL/openssl" ;; esac cat << END >> $NGX_MAKEFILE diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -330,6 +330,10 @@ main(int argc, char *const *argv) return 0; } + if (ngx_signal) { + return ngx_signal_process(cycle, ngx_signal); + } + ngx_os_status(cycle->log); ngx_cycle = cycle; @@ -340,10 +344,6 @@ main(int argc, char *const *argv) ngx_process = NGX_PROCESS_MASTER; } - if (ngx_signal) { - return ngx_signal_process(cycle, ngx_signal); - } - #if !(NGX_WIN32) if (ngx_init_signals(cycle->log) != NGX_OK) { diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -12,6 +12,7 @@ static ngx_int_t ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last); static ngx_int_t ngx_conf_read_token(ngx_conf_t *cf); static char *ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static ngx_int_t ngx_conf_test_full_name(ngx_str_t *name); static void ngx_conf_flush_files(ngx_cycle_t *cycle); @@ -802,29 +803,15 @@ ngx_int_t ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix) { size_t len; - u_char *p, *prefix; - ngx_str_t old; - -#if (NGX_WIN32) + u_char *p, *n, *prefix; + ngx_int_t rc; - if (name->len > 2 - && name->data[1] == ':' - && ((name->data[0] >= 'a' && name->data[0] <= 'z') - || (name->data[0] >= 'A' && name->data[0] <= 'Z'))) - { - return NGX_OK; - } + rc = ngx_conf_test_full_name(name); -#else - - if (name->data[0] == '/') { - return NGX_OK; + if (rc == NGX_OK) { + return rc; } -#endif - - old = *name; - if (conf_prefix) { len = cycle->conf_prefix.len; prefix = cycle->conf_prefix.data; @@ -834,19 +821,79 @@ ngx_conf_full_name(ngx_cycle_t *cycle, n prefix = cycle->prefix.data; } - name->len = len + old.len; - name->data = ngx_pnalloc(cycle->pool, name->len + 1); - if (name->data == NULL) { +#if (NGX_WIN32) + + if (rc == 2) { + len = rc; + } + +#endif + + n = ngx_pnalloc(cycle->pool, len + name->len + 1); + if (n == NULL) { return NGX_ERROR; } - p = ngx_cpymem(name->data, prefix, len); - ngx_cpystrn(p, old.data, old.len + 1); + p = ngx_cpymem(n, prefix, len); + ngx_cpystrn(p, name->data, name->len + 1); + + name->len += len; + name->data = n; return NGX_OK; } +static ngx_int_t +ngx_conf_test_full_name(ngx_str_t *name) +{ +#if (NGX_WIN32) + u_char c0, c1; + + c0 = name->data[0]; + + if (name->len < 2) { + if (c0 == '/') { + return 2; + } + + return NGX_DECLINED; + } + + c1 = name->data[1]; + + if (c1 == ':') { + c0 |= 0x20; + + if ((c0 >= 'a' && c0 <= 'z')) { + return NGX_OK; + } + + return NGX_DECLINED; + } + + if (c1 == '/') { + return NGX_OK; + } + + if (c0 == '/') { + return 2; + } + + return NGX_DECLINED; + +#else + + if (name->data[0] == '/') { + return NGX_OK; + } + + return NGX_DECLINED; + +#endif +} + + ngx_open_file_t * ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name) { diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -603,6 +603,8 @@ ngx_close_listening_sockets(ngx_cycle_t ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno, ngx_close_socket_n " %V failed", &ls[i].addr_text); } + + ls[i].fd = (ngx_socket_t) -1; } } 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 @@ -269,7 +269,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) cycle->conf_file.data); } - for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_CORE_MODULE) { continue; @@ -287,6 +286,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } } + if (ngx_process == NGX_PROCESS_SIGNALLER) { + return cycle; + } ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); @@ -463,11 +465,8 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) goto failed; } - if (!shm_zone[i].shm.exists) { - - if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) { - goto failed; - } + if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) { + goto failed; } if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) { @@ -567,14 +566,12 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } } - if (ngx_process != NGX_PROCESS_SIGNALLER) { - if (ngx_open_listening_sockets(cycle) != NGX_OK) { - goto failed; - } + if (ngx_open_listening_sockets(cycle) != NGX_OK) { + goto failed; + } - if (!ngx_test_config) { - ngx_configure_listening_sockets(cycle); - } + if (!ngx_test_config) { + ngx_configure_listening_sockets(cycle); } @@ -656,7 +653,8 @@ old_shm_zone_done: ls = old_cycle->listening.elts; for (i = 0; i < old_cycle->listening.nelts; i++) { - if (ls[i].remain) { + + if (ls[i].remain || ls[i].fd == -1) { continue; } @@ -885,8 +883,21 @@ ngx_init_zone_pool(ngx_cycle_t *cycle, n sp = (ngx_slab_pool_t *) zn->shm.addr; + if (zn->shm.exists) { + + if (sp == sp->addr) { + return NGX_OK; + } + + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, + "shared zone \"%V\" has no equal addresses: %p vs %p", + &zn->shm.name, sp->addr, sp); + return NGX_ERROR; + } + sp->end = zn->shm.addr + zn->shm.size; sp->min_shift = 3; + sp->addr = zn->shm.addr; #if (NGX_HAVE_ATOMIC_OPS) diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -558,8 +558,14 @@ ngx_ext_rename_file(ngx_str_t *src, ngx_ err = ngx_errno; - if (err == NGX_ENOENT) { - + if (err +#if (NGX_WIN32) + == ERROR_PATH_NOT_FOUND +#else + == NGX_ENOENT +#endif + ) + { if (!ext->create_path) { goto failed; } diff --git a/src/core/ngx_slab.h b/src/core/ngx_slab.h --- a/src/core/ngx_slab.h +++ b/src/core/ngx_slab.h @@ -39,6 +39,7 @@ typedef struct { u_char zero; void *data; + void *addr; } ngx_slab_pool_t; diff --git a/src/os/win32/ngx_files.c b/src/os/win32/ngx_files.c --- a/src/os/win32/ngx_files.c +++ b/src/os/win32/ngx_files.c @@ -269,7 +269,7 @@ ngx_win32_rename_file(ngx_str_t *from, n for ( ;; ) { num = ngx_next_temp_number(collision); - ngx_sprintf(name + to->len, ".%0muA.DELETE", num); + ngx_sprintf(name + to->len, ".%0muA.DELETE%Z", num); if (MoveFile((const char *) to->data, (const char *) name) != 0) { break; @@ -277,7 +277,8 @@ ngx_win32_rename_file(ngx_str_t *from, n collision = 1; - ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, "MoveFile() failed"); + ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, + "MoveFile() \"%s\" to \"%s\" failed", to->data, name); } if (MoveFile((const char *) from->data, (const char *) to->data) == 0) { @@ -288,11 +289,14 @@ ngx_win32_rename_file(ngx_str_t *from, n } if (DeleteFile((const char *) name) == 0) { - ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, "DeleteFile() failed"); + ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, + "DeleteFile() \"%s\" failed", name); } if (rc == NGX_ERROR) { - ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, "MoveFile() failed"); + ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, + "MoveFile() \"%s\" to \"%s\" failed", + from->data, to->data); } /* mutex_unlock() */ diff --git a/src/os/win32/ngx_process.c b/src/os/win32/ngx_process.c --- a/src/os/win32/ngx_process.c +++ b/src/os/win32/ngx_process.c @@ -19,10 +19,11 @@ ngx_process_t ngx_processes[NGX_MAX_P ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, char *name, ngx_int_t respawn) { - u_long rc, n; + u_long rc, n, code; ngx_int_t s; ngx_pid_t pid; ngx_exec_ctx_t ctx; + HANDLE events[2]; char file[MAX_PATH + 1]; if (respawn >= 0) { @@ -79,12 +80,15 @@ ngx_spawn_process(ngx_cycle_t *cycle, ch ngx_sprintf(ngx_processes[s].reopen_event, "ngx_%s_reopen_%ul%Z", name, pid); - rc = WaitForSingleObject(ngx_master_process_event, 5000); + events[0] = ngx_master_process_event; + events[1] = ctx.child; + + rc = WaitForMultipleObjects(2, events, 0, 5000); ngx_time_update(0, 0); ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, - "WaitForSingleObject: %ul", rc); + "WaitForMultipleObjects: %ul", rc); switch (rc) { @@ -126,6 +130,18 @@ ngx_spawn_process(ngx_cycle_t *cycle, ch break; + case WAIT_OBJECT_0 + 1: + if (GetExitCodeProcess(ctx.child, &code) == 0) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "GetExitCodeProcess(%P) failed", pid); + } + + ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, + "%s process %P exited with code %Xul", + name, pid, code); + + goto failed; + case WAIT_TIMEOUT: ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "the event \"%s\" was not signaled for 5s", diff --git a/src/os/win32/ngx_process_cycle.c b/src/os/win32/ngx_process_cycle.c --- a/src/os/win32/ngx_process_cycle.c +++ b/src/os/win32/ngx_process_cycle.c @@ -14,7 +14,7 @@ static void ngx_process_init(ngx_cycle_t static void ngx_console_init(ngx_cycle_t *cycle); static int __stdcall ngx_console_handler(u_long type); static ngx_int_t ngx_create_events(ngx_cycle_t *cycle); -static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t type); +static ngx_int_t ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t type); static void ngx_reopen_worker_processes(ngx_cycle_t *cycle); static void ngx_quit_worker_processes(ngx_cycle_t *cycle, ngx_uint_t old); static void ngx_terminate_worker_processes(ngx_cycle_t *cycle); @@ -116,7 +116,9 @@ ngx_master_process_cycle(ngx_cycle_t *cy ngx_close_listening_sockets(cycle); - ngx_start_worker_processes(cycle, NGX_PROCESS_RESPAWN); + if (ngx_start_worker_processes(cycle, NGX_PROCESS_RESPAWN) == 0) { + exit(2); + } timer = 0; timeout = INFINITE; @@ -206,8 +208,11 @@ ngx_master_process_cycle(ngx_cycle_t *cy ngx_cycle = cycle; - ngx_start_worker_processes(cycle, NGX_PROCESS_JUST_RESPAWN); - ngx_quit_worker_processes(cycle, 1); + ngx_close_listening_sockets(cycle); + + if (ngx_start_worker_processes(cycle, NGX_PROCESS_JUST_RESPAWN)) { + ngx_quit_worker_processes(cycle, 1); + } continue; } @@ -382,7 +387,7 @@ ngx_create_events(ngx_cycle_t *cycle) } -static void +static ngx_int_t ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t type) { ngx_int_t n; @@ -394,9 +399,11 @@ ngx_start_worker_processes(ngx_cycle_t * for (n = 0; n < ccf->worker_processes; n++) { if (ngx_spawn_process(cycle, "worker", type) == NGX_INVALID_PID) { - return; + break; } } + + return n; } @@ -428,7 +435,7 @@ ngx_quit_worker_processes(ngx_cycle_t *c for (n = 0; n < ngx_last_process; n++) { ngx_log_debug5(NGX_LOG_DEBUG_CORE, cycle->log, 0, - "process: %d %P %p e:%d t:%d r:%d j:%d", + "process: %d %P %p e:%d j:%d", n, ngx_processes[n].pid, ngx_processes[n].handle, @@ -495,7 +502,7 @@ ngx_reap_worker(ngx_cycle_t *cycle, HAND } if (GetExitCodeProcess(h, &code) == 0) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "GetExitCodeProcess(%P) failed", ngx_processes[n].pid); } @@ -538,7 +545,7 @@ found: for (n = 0; n < ngx_last_process; n++) { ngx_log_debug5(NGX_LOG_DEBUG_CORE, cycle->log, 0, - "process: %d %P %p e:%d t:%d r:%d j:%d", + "process: %d %P %p e:%d j:%d", n, ngx_processes[n].pid, ngx_processes[n].handle, diff --git a/src/os/win32/ngx_shmem.c b/src/os/win32/ngx_shmem.c --- a/src/os/win32/ngx_shmem.c +++ b/src/os/win32/ngx_shmem.c @@ -11,27 +11,36 @@ ngx_int_t ngx_shm_alloc(ngx_shm_t *shm) { - u_char *name; + u_char *name; + uint64_t size; name = ngx_alloc(shm->name.len + 2 + sizeof(NGX_INT32_LEN), shm->log); if (name == NULL) { return NGX_ERROR; } - ngx_sprintf(name, "%V_%s%Z", &shm->name, ngx_unique); + (void) ngx_sprintf(name, "%V_%s%Z", &shm->name, ngx_unique); ngx_set_errno(0); + size = shm->size; + shm->handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, - 0, shm->size, (char *) name); + (u_long) (size >> 32), + (u_long) (size & 0xffffffff), + (char *) name); if (shm->handle == NULL) { ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, "CreateFileMapping(%uz, %s) failed", - shm->size, shm->name.data); - goto failed; + shm->size, name); + ngx_free(name); + + return NGX_ERROR; } + ngx_free(name); + if (ngx_errno == ERROR_ALREADY_EXISTS) { shm->exists = 1; } @@ -43,17 +52,15 @@ ngx_shm_alloc(ngx_shm_t *shm) } ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, - "MapViewOfFile(%uz) failed", shm->size); + "MapViewOfFile(%uz) of file mapping \"%V\" failed", + shm->size, &shm->name); if (CloseHandle(shm->handle) == 0) { ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, - "CloseHandle() failed"); + "CloseHandle() of file mapping \"%V\" failed", + &shm->name); } -failed: - - ngx_free(name); - return NGX_ERROR; } @@ -63,11 +70,13 @@ ngx_shm_free(ngx_shm_t *shm) { if (UnmapViewOfFile(shm->addr) == 0) { ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, - "UnmapViewOfFile(%p) failed", shm->addr); + "UnmapViewOfFile(%p) of file mapping \"%V\" failed", + shm->addr, &shm->name); } if (CloseHandle(shm->handle) == 0) { ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, - "CloseHandle() failed"); + "CloseHandle() of file mapping \"%V\" failed", + &shm->name); } }