# HG changeset patch # User Igor Sysoev # Date 1251057600 -14400 # Node ID 7efcdb93775276c87bcea0e51c889bd3e078430a # Parent 607556aed0a157b9d7fd34b36a561368e3448609 nginx 0.8.10 *) Bugfix: memory leaks if GeoIP City database was used. *) Bugfix: in copying temporary files to permanent storage area; the bug had appeared in 0.8.9. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,10 +1,18 @@ +Changes with nginx 0.8.10 24 Aug 2009 + + *) Bugfix: memory leaks if GeoIP City database was used. + + *) Bugfix: in copying temporary files to permanent storage area; the + bug had appeared in 0.8.9. + + Changes with nginx 0.8.9 17 Aug 2009 *) Feature: now the start cache loader runs in a separate process; this should improve large caches handling. - *) Feature: now temporarily files and permanent storage area may reside + *) Feature: now temporary files and permanent storage area may reside at different file systems. @@ -98,8 +106,7 @@ Changes with nginx 0.8.3 *) Feature: the $upstream_cache_status variable. - *) Bugfix: nginx could not be built on MacOSX 10.6. the bug had - appeared in 0.8.2. + *) Bugfix: nginx could not be built on MacOSX 10.6. *) Bugfix: nginx could not be built --without-http-cache; the bug had appeared in 0.8.2. @@ -1938,8 +1945,8 @@ Changes with nginx 0.5.12 amd64, sparc, and ppc; the bug had appeared in 0.5.8. *) Bugfix: a segmentation fault might occur in worker process if the - temporarily files were used while working with FastCGI server; the - bug had appeared in 0.5.8. + temporary files were used while working with FastCGI server; the bug + had appeared in 0.5.8. *) Bugfix: a segmentation fault might occur in worker process if the $fastcgi_script_name variable was logged. @@ -2842,8 +2849,8 @@ Changes with nginx 0.3.31 in 0.3.18. *) Bugfix: if the HTTPS protocol was used in the "proxy_pass" directive - and the request body was in temporarily file then the request was - not transferred. + and the request body was in temporary file then the request was not + transferred. *) Bugfix: perl 5.8.8 compatibility. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,12 @@ +Изменения в nginx 0.8.10 24.08.2009 + + *) Исправление: утечек памяти при использовании базы GeoIP City. + + *) Исправление: ошибки при копировании временных файлов в постоянное + место хранения; ошибка появилась в 0.8.9. + + Изменения в nginx 0.8.9 17.08.2009 *) Добавление: теперь стартовый загрузчик кэша работает в отдельном diff --git a/auto/os/linux b/auto/os/linux --- a/auto/os/linux +++ b/auto/os/linux @@ -18,7 +18,7 @@ CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURC # Linux kernel version version=$((`uname -r \ - | sed 's/^\([^.]*\)\.\([^.]*\)\.\([^.-]*\).*/\1*256*256+\2*256+\3/'`)) + | sed 's/^\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1*256*256+\2*256+\3/'`)) version=${version:-0} diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,8 +8,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 8009 -#define NGINX_VERSION "0.8.9" +#define nginx_version 8010 +#define NGINX_VERSION "0.8.10" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_buf.h b/src/core/ngx_buf.h --- a/src/core/ngx_buf.h +++ b/src/core/ngx_buf.h @@ -75,13 +75,13 @@ typedef struct { ngx_chain_t *free; ngx_chain_t *busy; - unsigned sendfile; - unsigned directio; + unsigned sendfile:1; + unsigned directio:1; #if (NGX_HAVE_ALIGNED_DIRECTIO) - unsigned unaligned; + unsigned unaligned:1; #endif - unsigned need_in_memory; - unsigned need_in_temp; + unsigned need_in_memory:1; + unsigned need_in_temp:1; ngx_pool_t *pool; ngx_int_t allocated; 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 @@ -8,8 +8,9 @@ #include -static ngx_atomic_uint_t ngx_temp_number; -static ngx_atomic_uint_t ngx_random_number; +static ngx_atomic_t temp_number = 0; +ngx_atomic_t *ngx_temp_number = &temp_number; +ngx_atomic_int_t ngx_random_number = 123456; ssize_t @@ -205,22 +206,16 @@ ngx_create_full_path(u_char *dir, ngx_ui } -void -ngx_init_temp_number(void) -{ - ngx_temp_number = 0; - ngx_random_number = 123456; -} - - ngx_atomic_uint_t ngx_next_temp_number(ngx_uint_t collision) { - if (collision) { - ngx_temp_number += ngx_random_number; - } + ngx_atomic_uint_t n, add; + + add = collision ? ngx_random_number : 1; - return ngx_temp_number++; + n = ngx_atomic_fetch_add(ngx_temp_number, add); + + return n + add; } @@ -576,7 +571,6 @@ ngx_ext_rename_file(ngx_str_t *src, ngx_ } err = ngx_errno; - goto failed; } #if (NGX_WIN32) @@ -605,34 +599,43 @@ ngx_ext_rename_file(ngx_str_t *src, ngx_ cf.time = ext->time; cf.log = ext->log; - name = ngx_alloc(to->len + 1 + 10, ext->log); + name = ngx_alloc(to->len + 1 + 10 + 1, ext->log); if (name == NULL) { return NGX_ERROR; } - (void) ngx_sprintf(name, "%*s.%010uD%Z", to->len - 1, to->data, + (void) ngx_sprintf(name, "%*s.%010uD%Z", to->len, to->data, (uint32_t) ngx_next_temp_number(0)); if (ngx_copy_file(src->data, name, &cf) == NGX_OK) { - if (ngx_rename_file(name, to->data) == NGX_FILE_ERROR) { + if (ngx_rename_file(name, to->data) != NGX_FILE_ERROR) { ngx_free(name); - goto failed; + + if (ngx_delete_file(src->data) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno, + ngx_delete_file_n " \"%s\" failed", + src->data); + return NGX_ERROR; + } + + return NGX_OK; } - ngx_free(name); + ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno, + ngx_rename_file_n " \"%s\" to \"%s\" failed", + name, to->data); - if (ngx_delete_file(src->data) == NGX_FILE_ERROR) { + if (ngx_delete_file(name) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno, - ngx_delete_file_n " \"%s\" failed", src->data); + ngx_delete_file_n " \"%s\" failed", name); - return NGX_ERROR; } - - return NGX_OK; } ngx_free(name); + + err = 0; } failed: diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h --- a/src/core/ngx_file.h +++ b/src/core/ngx_file.h @@ -129,7 +129,6 @@ ngx_int_t ngx_ext_rename_file(ngx_str_t ngx_int_t ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf); ngx_int_t ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_str_t *tree); -void ngx_init_temp_number(void); ngx_atomic_uint_t ngx_next_temp_number(ngx_uint_t collision); char *ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -138,4 +137,8 @@ char *ngx_conf_merge_path_value(ngx_conf char *ngx_conf_set_access_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +extern ngx_atomic_t *ngx_temp_number; +extern ngx_atomic_int_t ngx_random_number; + + #endif /* _NGX_FILE_H_INCLUDED_ */ diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -43,7 +43,7 @@ ngx_uint_t ngx_event_flags; ngx_event_actions_t ngx_event_actions; -ngx_atomic_t connection_counter = 1; +static ngx_atomic_t connection_counter = 1; ngx_atomic_t *ngx_connection_counter = &connection_counter; @@ -429,6 +429,7 @@ ngx_event_module_init(ngx_cycle_t *cycle u_char *shared; size_t size, cl; ngx_shm_t shm; + ngx_time_t *tp; ngx_core_conf_t *ccf; ngx_event_conf_t *ecf; @@ -492,7 +493,8 @@ ngx_event_module_init(ngx_cycle_t *cycle cl = 128; size = cl /* ngx_accept_mutex */ - + cl; /* ngx_connection_counter */ + + cl /* ngx_connection_counter */ + + cl; /* ngx_temp_number */ #if (NGX_STAT_STUB) @@ -526,23 +528,29 @@ ngx_event_module_init(ngx_cycle_t *cycle ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * cl); -#if (NGX_STAT_STUB) - - ngx_stat_accepted = (ngx_atomic_t *) (shared + 2 * cl); - ngx_stat_handled = (ngx_atomic_t *) (shared + 3 * cl); - ngx_stat_requests = (ngx_atomic_t *) (shared + 4 * cl); - ngx_stat_active = (ngx_atomic_t *) (shared + 5 * cl); - ngx_stat_reading = (ngx_atomic_t *) (shared + 6 * cl); - ngx_stat_writing = (ngx_atomic_t *) (shared + 7 * cl); - -#endif - (void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1); ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "counter: %p, %d", ngx_connection_counter, *ngx_connection_counter); + ngx_temp_number = (ngx_atomic_t *) (shared + 2 * cl); + + tp = ngx_timeofday(); + + ngx_random_number = (tp->msec << 16) + ngx_pid; + +#if (NGX_STAT_STUB) + + ngx_stat_accepted = (ngx_atomic_t *) (shared + 3 * cl); + ngx_stat_handled = (ngx_atomic_t *) (shared + 4 * cl); + ngx_stat_requests = (ngx_atomic_t *) (shared + 5 * cl); + ngx_stat_active = (ngx_atomic_t *) (shared + 6 * cl); + ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * cl); + ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * cl); + +#endif + return NGX_OK; } diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c --- a/src/http/modules/ngx_http_dav_module.c +++ b/src/http/modules/ngx_http_dav_module.c @@ -214,6 +214,8 @@ ngx_http_dav_put_handler(ngx_http_reques ngx_http_map_uri_to_path(r, &path, &root, 0); + path.len--; + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http put filename: \"%s\"", path.data); diff --git a/src/http/modules/ngx_http_geoip_module.c b/src/http/modules/ngx_http_geoip_module.c --- a/src/http/modules/ngx_http_geoip_module.c +++ b/src/http/modules/ngx_http_geoip_module.c @@ -181,6 +181,7 @@ ngx_http_geoip_city_variable(ngx_http_re { u_long addr; char *val; + size_t len; GeoIPRecord *gr; struct sockaddr_in *sin; ngx_http_geoip_conf_t *gcf; @@ -207,17 +208,32 @@ ngx_http_geoip_city_variable(ngx_http_re val = *(char **) ((char *) gr + data); if (val == NULL) { - goto not_found; + goto no_value; } - v->len = ngx_strlen(val); + len = ngx_strlen(val); + v->data = ngx_pnalloc(r->pool, len); + + if (v->data == NULL) { + GeoIPRecord_delete(gr); + return NGX_ERROR; + } + + ngx_memcpy(v->data, val, len); + + v->len = len; v->valid = 1; v->no_cacheable = 0; v->not_found = 0; - v->data = (u_char *) val; + + GeoIPRecord_delete(gr); return NGX_OK; +no_value: + + GeoIPRecord_delete(gr); + not_found: v->not_found = 1; diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c --- a/src/http/modules/ngx_http_log_module.c +++ b/src/http/modules/ngx_http_log_module.c @@ -837,7 +837,13 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx if (ngx_strcmp(value[1].data, "off") == 0) { llcf->off = 1; - return NGX_CONF_OK; + if (cf->args->nelts == 2) { + return NGX_CONF_OK; + } + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter \"%V\"", &value[2]); + return NGX_CONF_ERROR; } if (llcf->logs == NULL) { diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm --- a/src/http/modules/perl/nginx.pm +++ b/src/http/modules/perl/nginx.pm @@ -47,7 +47,7 @@ our @EXPORT = qw( HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '0.8.9'; +our $VERSION = '0.8.10'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -161,6 +161,12 @@ ngx_http_upstream_header_t ngx_http_ups offsetof(ngx_http_upstream_headers_in_t, last_modified), ngx_http_upstream_copy_last_modified, 0, 0 }, + { ngx_string("ETag"), + ngx_http_upstream_process_header_line, + offsetof(ngx_http_upstream_headers_in_t, etag), + ngx_http_upstream_copy_header_line, + offsetof(ngx_http_headers_out_t, etag), 0 }, + { ngx_string("Server"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, server), @@ -2661,6 +2667,8 @@ ngx_http_upstream_store(ngx_http_request } } + path.len--; + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "upstream stores \"%s\" to \"%s\"", tf->file.name.data, path.data); diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -277,8 +277,6 @@ ngx_single_process_cycle(ngx_cycle_t *cy { ngx_uint_t i; - ngx_init_temp_number(); - for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->init_process) { if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) { @@ -930,8 +928,6 @@ ngx_worker_process_init(ngx_cycle_t *cyc "sigprocmask() failed"); } - ngx_init_temp_number(); - /* * disable deleting previous events for the listening sockets because * in the worker processes there are no events at all at this point