3 * Copyright (C) Igor Sysoev
7 #include <ngx_config.h>
12 static void ngx_destroy_cycle_pools(ngx_conf_t
*conf
);
13 static ngx_int_t
ngx_cmp_sockaddr(struct sockaddr
*sa1
, struct sockaddr
*sa2
);
14 static ngx_int_t
ngx_init_zone_pool(ngx_cycle_t
*cycle
,
15 ngx_shm_zone_t
*shm_zone
);
16 static ngx_int_t
ngx_test_lockfile(u_char
*file
, ngx_log_t
*log
);
17 static void ngx_clean_old_cycles(ngx_event_t
*ev
);
20 volatile ngx_cycle_t
*ngx_cycle
;
21 ngx_array_t ngx_old_cycles
;
23 static ngx_pool_t
*ngx_temp_pool
;
24 static ngx_event_t ngx_cleaner_event
;
26 ngx_uint_t ngx_test_config
;
29 ngx_tls_key_t ngx_core_tls_key
;
34 static ngx_connection_t dumb
;
37 static ngx_str_t error_log
= ngx_string(NGX_ERROR_LOG_PATH
);
41 ngx_init_cycle(ngx_cycle_t
*old_cycle
)
50 ngx_cycle_t
*cycle
, **old
;
51 ngx_shm_zone_t
*shm_zone
, *oshm_zone
;
52 ngx_list_part_t
*part
, *opart
;
53 ngx_open_file_t
*file
;
54 ngx_listening_t
*ls
, *nls
;
55 ngx_core_conf_t
*ccf
, *old_ccf
;
56 ngx_core_module_t
*module
;
57 char hostname
[NGX_MAXHOSTNAMELEN
];
59 ngx_timezone_update();
61 /* force localtime update with a new timezone */
66 ngx_time_update(0, 0);
71 pool
= ngx_create_pool(NGX_CYCLE_POOL_SIZE
, log
);
77 cycle
= ngx_pcalloc(pool
, sizeof(ngx_cycle_t
));
79 ngx_destroy_pool(pool
);
85 cycle
->new_log
.log_level
= NGX_LOG_ERR
;
86 cycle
->old_cycle
= old_cycle
;
88 cycle
->conf_prefix
.len
= old_cycle
->conf_prefix
.len
;
89 cycle
->conf_prefix
.data
= ngx_pstrdup(pool
, &old_cycle
->conf_prefix
);
90 if (cycle
->conf_prefix
.data
== NULL
) {
91 ngx_destroy_pool(pool
);
95 cycle
->prefix
.len
= old_cycle
->prefix
.len
;
96 cycle
->prefix
.data
= ngx_pstrdup(pool
, &old_cycle
->prefix
);
97 if (cycle
->prefix
.data
== NULL
) {
98 ngx_destroy_pool(pool
);
102 cycle
->conf_file
.len
= old_cycle
->conf_file
.len
;
103 cycle
->conf_file
.data
= ngx_pnalloc(pool
, old_cycle
->conf_file
.len
+ 1);
104 if (cycle
->conf_file
.data
== NULL
) {
105 ngx_destroy_pool(pool
);
108 ngx_cpystrn(cycle
->conf_file
.data
, old_cycle
->conf_file
.data
,
109 old_cycle
->conf_file
.len
+ 1);
111 cycle
->conf_param
.len
= old_cycle
->conf_param
.len
;
112 cycle
->conf_param
.data
= ngx_pstrdup(pool
, &old_cycle
->conf_param
);
113 if (cycle
->conf_param
.data
== NULL
) {
114 ngx_destroy_pool(pool
);
119 n
= old_cycle
->pathes
.nelts
? old_cycle
->pathes
.nelts
: 10;
121 cycle
->pathes
.elts
= ngx_pcalloc(pool
, n
* sizeof(ngx_path_t
*));
122 if (cycle
->pathes
.elts
== NULL
) {
123 ngx_destroy_pool(pool
);
127 cycle
->pathes
.nelts
= 0;
128 cycle
->pathes
.size
= sizeof(ngx_path_t
*);
129 cycle
->pathes
.nalloc
= n
;
130 cycle
->pathes
.pool
= pool
;
133 if (old_cycle
->open_files
.part
.nelts
) {
134 n
= old_cycle
->open_files
.part
.nelts
;
135 for (part
= old_cycle
->open_files
.part
.next
; part
; part
= part
->next
) {
143 if (ngx_list_init(&cycle
->open_files
, pool
, n
, sizeof(ngx_open_file_t
))
146 ngx_destroy_pool(pool
);
151 if (old_cycle
->shared_memory
.part
.nelts
) {
152 n
= old_cycle
->shared_memory
.part
.nelts
;
153 for (part
= old_cycle
->shared_memory
.part
.next
; part
; part
= part
->next
)
162 if (ngx_list_init(&cycle
->shared_memory
, pool
, n
, sizeof(ngx_shm_zone_t
))
165 ngx_destroy_pool(pool
);
169 n
= old_cycle
->listening
.nelts
? old_cycle
->listening
.nelts
: 10;
171 cycle
->listening
.elts
= ngx_pcalloc(pool
, n
* sizeof(ngx_listening_t
));
172 if (cycle
->listening
.elts
== NULL
) {
173 ngx_destroy_pool(pool
);
177 cycle
->listening
.nelts
= 0;
178 cycle
->listening
.size
= sizeof(ngx_listening_t
);
179 cycle
->listening
.nalloc
= n
;
180 cycle
->listening
.pool
= pool
;
183 cycle
->conf_ctx
= ngx_pcalloc(pool
, ngx_max_module
* sizeof(void *));
184 if (cycle
->conf_ctx
== NULL
) {
185 ngx_destroy_pool(pool
);
190 if (gethostname(hostname
, NGX_MAXHOSTNAMELEN
) == -1) {
191 ngx_log_error(NGX_LOG_EMERG
, log
, ngx_errno
, "gethostname() failed");
192 ngx_destroy_pool(pool
);
196 /* on Linux gethostname() silently truncates name that does not fit */
198 hostname
[NGX_MAXHOSTNAMELEN
- 1] = '\0';
199 cycle
->hostname
.len
= ngx_strlen(hostname
);
201 cycle
->hostname
.data
= ngx_pnalloc(pool
, cycle
->hostname
.len
);
202 if (cycle
->hostname
.data
== NULL
) {
203 ngx_destroy_pool(pool
);
207 ngx_memcpy(cycle
->hostname
.data
, hostname
, cycle
->hostname
.len
);
210 for (i
= 0; ngx_modules
[i
]; i
++) {
211 if (ngx_modules
[i
]->type
!= NGX_CORE_MODULE
) {
215 module
= ngx_modules
[i
]->ctx
;
217 if (module
->create_conf
) {
218 rv
= module
->create_conf(cycle
);
220 ngx_destroy_pool(pool
);
223 cycle
->conf_ctx
[ngx_modules
[i
]->index
] = rv
;
231 ngx_memzero(&conf
, sizeof(ngx_conf_t
));
232 /* STUB: init array ? */
233 conf
.args
= ngx_array_create(pool
, 10, sizeof(ngx_str_t
));
234 if (conf
.args
== NULL
) {
235 ngx_destroy_pool(pool
);
239 conf
.temp_pool
= ngx_create_pool(NGX_CYCLE_POOL_SIZE
, log
);
240 if (conf
.temp_pool
== NULL
) {
241 ngx_destroy_pool(pool
);
246 conf
.ctx
= cycle
->conf_ctx
;
250 conf
.module_type
= NGX_CORE_MODULE
;
251 conf
.cmd_type
= NGX_MAIN_CONF
;
254 log
->log_level
= NGX_LOG_DEBUG_ALL
;
257 if (ngx_conf_param(&conf
) != NGX_CONF_OK
) {
259 ngx_destroy_cycle_pools(&conf
);
263 if (ngx_conf_parse(&conf
, &cycle
->conf_file
) != NGX_CONF_OK
) {
265 ngx_destroy_cycle_pools(&conf
);
269 if (ngx_test_config
) {
270 ngx_log_stderr(0, "the configuration file %s syntax is ok",
271 cycle
->conf_file
.data
);
274 for (i
= 0; ngx_modules
[i
]; i
++) {
275 if (ngx_modules
[i
]->type
!= NGX_CORE_MODULE
) {
279 module
= ngx_modules
[i
]->ctx
;
281 if (module
->init_conf
) {
282 if (module
->init_conf(cycle
, cycle
->conf_ctx
[ngx_modules
[i
]->index
])
286 ngx_destroy_cycle_pools(&conf
);
292 if (ngx_process
== NGX_PROCESS_SIGNALLER
) {
296 ccf
= (ngx_core_conf_t
*) ngx_get_conf(cycle
->conf_ctx
, ngx_core_module
);
298 if (ngx_test_config
) {
300 if (ngx_create_pidfile(&ccf
->pid
, log
) != NGX_OK
) {
304 } else if (!ngx_is_init_cycle(old_cycle
)) {
307 * we do not create the pid file in the first ngx_init_cycle() call
308 * because we need to write the demonized process pid
311 old_ccf
= (ngx_core_conf_t
*) ngx_get_conf(old_cycle
->conf_ctx
,
313 if (ccf
->pid
.len
!= old_ccf
->pid
.len
314 || ngx_strcmp(ccf
->pid
.data
, old_ccf
->pid
.data
) != 0)
316 /* new pid file name */
318 if (ngx_create_pidfile(&ccf
->pid
, log
) != NGX_OK
) {
322 ngx_delete_pidfile(old_cycle
);
327 if (ngx_test_lockfile(cycle
->lock_file
.data
, log
) != NGX_OK
) {
332 if (ngx_create_pathes(cycle
, ccf
->user
) != NGX_OK
) {
337 if (cycle
->new_log
.file
== NULL
) {
338 cycle
->new_log
.file
= ngx_conf_open_file(cycle
, &error_log
);
339 if (cycle
->new_log
.file
== NULL
) {
344 /* open the new files */
346 part
= &cycle
->open_files
.part
;
349 for (i
= 0; /* void */ ; i
++) {
351 if (i
>= part
->nelts
) {
352 if (part
->next
== NULL
) {
360 if (file
[i
].name
.len
== 0) {
364 file
[i
].fd
= ngx_open_file(file
[i
].name
.data
,
366 NGX_FILE_CREATE_OR_OPEN
,
367 NGX_FILE_DEFAULT_ACCESS
);
369 ngx_log_debug3(NGX_LOG_DEBUG_CORE
, log
, 0,
371 &file
[i
], file
[i
].fd
, file
[i
].name
.data
);
373 if (file
[i
].fd
== NGX_INVALID_FILE
) {
374 ngx_log_error(NGX_LOG_EMERG
, log
, ngx_errno
,
375 ngx_open_file_n
" \"%s\" failed",
381 if (fcntl(file
[i
].fd
, F_SETFD
, FD_CLOEXEC
) == -1) {
382 ngx_log_error(NGX_LOG_EMERG
, log
, ngx_errno
,
383 "fcntl(FD_CLOEXEC) \"%s\" failed",
390 cycle
->log
= &cycle
->new_log
;
391 pool
->log
= &cycle
->new_log
;
394 /* create shared memory */
396 part
= &cycle
->shared_memory
.part
;
397 shm_zone
= part
->elts
;
399 for (i
= 0; /* void */ ; i
++) {
401 if (i
>= part
->nelts
) {
402 if (part
->next
== NULL
) {
406 shm_zone
= part
->elts
;
410 if (shm_zone
[i
].shm
.size
== 0) {
411 ngx_log_error(NGX_LOG_EMERG
, log
, 0,
412 "zero size shared memory zone \"%V\"",
413 &shm_zone
[i
].shm
.name
);
417 if (shm_zone
[i
].init
== NULL
) {
418 /* unused shared zone */
422 shm_zone
[i
].shm
.log
= cycle
->log
;
424 opart
= &old_cycle
->shared_memory
.part
;
425 oshm_zone
= opart
->elts
;
427 for (n
= 0; /* void */ ; n
++) {
429 if (n
>= opart
->nelts
) {
430 if (opart
->next
== NULL
) {
434 oshm_zone
= opart
->elts
;
438 if (shm_zone
[i
].shm
.name
.len
!= oshm_zone
[n
].shm
.name
.len
) {
442 if (ngx_strncmp(shm_zone
[i
].shm
.name
.data
,
443 oshm_zone
[n
].shm
.name
.data
,
444 shm_zone
[i
].shm
.name
.len
)
450 if (shm_zone
[i
].shm
.size
== oshm_zone
[n
].shm
.size
) {
451 shm_zone
[i
].shm
.addr
= oshm_zone
[n
].shm
.addr
;
453 if (shm_zone
[i
].init(&shm_zone
[i
], oshm_zone
[n
].data
)
462 ngx_shm_free(&oshm_zone
[n
].shm
);
467 if (ngx_shm_alloc(&shm_zone
[i
].shm
) != NGX_OK
) {
471 if (ngx_init_zone_pool(cycle
, &shm_zone
[i
]) != NGX_OK
) {
475 if (shm_zone
[i
].init(&shm_zone
[i
], NULL
) != NGX_OK
) {
485 /* handle the listening sockets */
487 if (old_cycle
->listening
.nelts
) {
488 ls
= old_cycle
->listening
.elts
;
489 for (i
= 0; i
< old_cycle
->listening
.nelts
; i
++) {
493 nls
= cycle
->listening
.elts
;
494 for (n
= 0; n
< cycle
->listening
.nelts
; n
++) {
496 for (i
= 0; i
< old_cycle
->listening
.nelts
; i
++) {
501 if (ngx_cmp_sockaddr(nls
[n
].sockaddr
, ls
[i
].sockaddr
) == NGX_OK
)
503 nls
[n
].fd
= ls
[i
].fd
;
504 nls
[n
].previous
= &ls
[i
];
507 if (ls
[n
].backlog
!= nls
[i
].backlog
) {
511 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
514 * FreeBSD, except the most recent versions,
515 * could not remove accept filter
517 nls
[n
].deferred_accept
= ls
[i
].deferred_accept
;
519 if (ls
[i
].accept_filter
&& nls
[n
].accept_filter
) {
520 if (ngx_strcmp(ls
[i
].accept_filter
,
521 nls
[n
].accept_filter
)
524 nls
[n
].delete_deferred
= 1;
525 nls
[n
].add_deferred
= 1;
528 } else if (ls
[i
].accept_filter
) {
529 nls
[n
].delete_deferred
= 1;
531 } else if (nls
[n
].accept_filter
) {
532 nls
[n
].add_deferred
= 1;
536 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
538 if (ls
[n
].deferred_accept
&& !nls
[n
].deferred_accept
) {
539 nls
[n
].delete_deferred
= 1;
541 } else if (ls
[i
].deferred_accept
!= nls
[n
].deferred_accept
)
543 nls
[n
].add_deferred
= 1;
550 if (nls
[n
].fd
== -1) {
556 ls
= cycle
->listening
.elts
;
557 for (i
= 0; i
< cycle
->listening
.nelts
; i
++) {
559 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
560 if (ls
[i
].accept_filter
) {
561 ls
[i
].add_deferred
= 1;
564 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
565 if (ls
[i
].deferred_accept
) {
566 ls
[i
].add_deferred
= 1;
572 if (ngx_open_listening_sockets(cycle
) != NGX_OK
) {
576 if (!ngx_test_config
) {
577 ngx_configure_listening_sockets(cycle
);
581 /* commit the new cycle configuration */
583 if (!ngx_use_stderr
&& cycle
->log
->file
->fd
!= ngx_stderr
) {
585 if (ngx_set_stderr(cycle
->log
->file
->fd
) == NGX_FILE_ERROR
) {
586 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
587 ngx_set_stderr_n
" failed");
591 pool
->log
= cycle
->log
;
593 for (i
= 0; ngx_modules
[i
]; i
++) {
594 if (ngx_modules
[i
]->init_module
) {
595 if (ngx_modules
[i
]->init_module(cycle
) != NGX_OK
) {
603 /* close and delete stuff that lefts from an old cycle */
605 /* free the unnecessary shared memory */
607 opart
= &old_cycle
->shared_memory
.part
;
608 oshm_zone
= opart
->elts
;
610 for (i
= 0; /* void */ ; i
++) {
612 if (i
>= opart
->nelts
) {
613 if (opart
->next
== NULL
) {
614 goto old_shm_zone_done
;
617 oshm_zone
= opart
->elts
;
621 part
= &cycle
->shared_memory
.part
;
622 shm_zone
= part
->elts
;
624 for (n
= 0; /* void */ ; n
++) {
626 if (n
>= part
->nelts
) {
627 if (part
->next
== NULL
) {
631 shm_zone
= part
->elts
;
635 if (oshm_zone
[i
].shm
.name
.len
== shm_zone
[n
].shm
.name
.len
636 && ngx_strncmp(oshm_zone
[i
].shm
.name
.data
,
637 shm_zone
[n
].shm
.name
.data
,
638 oshm_zone
[i
].shm
.name
.len
)
645 ngx_shm_free(&oshm_zone
[i
].shm
);
655 /* close the unnecessary listening sockets */
657 ls
= old_cycle
->listening
.elts
;
658 for (i
= 0; i
< old_cycle
->listening
.nelts
; i
++) {
660 if (ls
[i
].remain
|| ls
[i
].fd
== -1) {
664 if (ngx_close_socket(ls
[i
].fd
) == -1) {
665 ngx_log_error(NGX_LOG_EMERG
, log
, ngx_socket_errno
,
666 ngx_close_socket_n
" listening socket on %V failed",
672 /* close the unnecessary open files */
674 part
= &old_cycle
->open_files
.part
;
677 for (i
= 0; /* void */ ; i
++) {
679 if (i
>= part
->nelts
) {
680 if (part
->next
== NULL
) {
688 if (file
[i
].fd
== NGX_INVALID_FILE
|| file
[i
].fd
== ngx_stderr
) {
692 if (ngx_close_file(file
[i
].fd
) == NGX_FILE_ERROR
) {
693 ngx_log_error(NGX_LOG_EMERG
, log
, ngx_errno
,
694 ngx_close_file_n
" \"%s\" failed",
699 ngx_destroy_pool(conf
.temp_pool
);
701 if (ngx_process
== NGX_PROCESS_MASTER
|| ngx_is_init_cycle(old_cycle
)) {
704 * perl_destruct() frees environ, if it is not the same as it was at
705 * perl_construct() time, therefore we save the previous cycle
706 * environment before ngx_conf_parse() where it will be changed.
712 ngx_destroy_pool(old_cycle
->pool
);
713 cycle
->old_cycle
= NULL
;
721 if (ngx_temp_pool
== NULL
) {
722 ngx_temp_pool
= ngx_create_pool(128, cycle
->log
);
723 if (ngx_temp_pool
== NULL
) {
724 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, 0,
725 "can not create ngx_temp_pool");
730 ngx_old_cycles
.elts
= ngx_pcalloc(ngx_temp_pool
,
731 n
* sizeof(ngx_cycle_t
*));
732 if (ngx_old_cycles
.elts
== NULL
) {
735 ngx_old_cycles
.nelts
= 0;
736 ngx_old_cycles
.size
= sizeof(ngx_cycle_t
*);
737 ngx_old_cycles
.nalloc
= n
;
738 ngx_old_cycles
.pool
= ngx_temp_pool
;
740 ngx_cleaner_event
.handler
= ngx_clean_old_cycles
;
741 ngx_cleaner_event
.log
= cycle
->log
;
742 ngx_cleaner_event
.data
= &dumb
;
743 dumb
.fd
= (ngx_socket_t
) -1;
746 ngx_temp_pool
->log
= cycle
->log
;
748 old
= ngx_array_push(&ngx_old_cycles
);
754 if (!ngx_cleaner_event
.timer_set
) {
755 ngx_add_timer(&ngx_cleaner_event
, 30000);
756 ngx_cleaner_event
.timer_set
= 1;
764 if (!ngx_is_init_cycle(old_cycle
)) {
765 old_ccf
= (ngx_core_conf_t
*) ngx_get_conf(old_cycle
->conf_ctx
,
767 if (old_ccf
->environment
) {
768 environ
= old_ccf
->environment
;
772 /* rollback the new cycle configuration */
774 part
= &cycle
->open_files
.part
;
777 for (i
= 0; /* void */ ; i
++) {
779 if (i
>= part
->nelts
) {
780 if (part
->next
== NULL
) {
788 if (file
[i
].fd
== NGX_INVALID_FILE
|| file
[i
].fd
== ngx_stderr
) {
792 if (ngx_close_file(file
[i
].fd
) == NGX_FILE_ERROR
) {
793 ngx_log_error(NGX_LOG_EMERG
, log
, ngx_errno
,
794 ngx_close_file_n
" \"%s\" failed",
799 if (ngx_test_config
) {
800 ngx_destroy_cycle_pools(&conf
);
804 ls
= cycle
->listening
.elts
;
805 for (i
= 0; i
< cycle
->listening
.nelts
; i
++) {
806 if (ls
[i
].fd
== -1 || !ls
[i
].open
) {
810 if (ngx_close_socket(ls
[i
].fd
) == -1) {
811 ngx_log_error(NGX_LOG_EMERG
, log
, ngx_socket_errno
,
812 ngx_close_socket_n
" %V failed",
817 ngx_destroy_cycle_pools(&conf
);
824 ngx_destroy_cycle_pools(ngx_conf_t
*conf
)
826 ngx_destroy_pool(conf
->temp_pool
);
827 ngx_destroy_pool(conf
->pool
);
832 ngx_cmp_sockaddr(struct sockaddr
*sa1
, struct sockaddr
*sa2
)
834 struct sockaddr_in
*sin1
, *sin2
;
836 struct sockaddr_in6
*sin61
, *sin62
;
839 if (sa1
->sa_family
!= sa2
->sa_family
) {
843 switch (sa1
->sa_family
) {
847 sin61
= (struct sockaddr_in6
*) sa1
;
848 sin62
= (struct sockaddr_in6
*) sa2
;
850 if (sin61
->sin6_port
!= sin61
->sin6_port
) {
854 if (ngx_memcmp(&sin61
->sin6_addr
, &sin62
->sin6_addr
, 16) != 0) {
861 default: /* AF_INET */
863 sin1
= (struct sockaddr_in
*) sa1
;
864 sin2
= (struct sockaddr_in
*) sa2
;
866 if (sin1
->sin_port
!= sin2
->sin_port
) {
870 if (sin1
->sin_addr
.s_addr
!= sin2
->sin_addr
.s_addr
) {
882 ngx_init_zone_pool(ngx_cycle_t
*cycle
, ngx_shm_zone_t
*zn
)
887 sp
= (ngx_slab_pool_t
*) zn
->shm
.addr
;
889 if (zn
->shm
.exists
) {
891 if (sp
== sp
->addr
) {
895 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, 0,
896 "shared zone \"%V\" has no equal addresses: %p vs %p",
897 &zn
->shm
.name
, sp
->addr
, sp
);
901 sp
->end
= zn
->shm
.addr
+ zn
->shm
.size
;
903 sp
->addr
= zn
->shm
.addr
;
905 #if (NGX_HAVE_ATOMIC_OPS)
911 file
= ngx_pnalloc(cycle
->pool
, cycle
->lock_file
.len
+ zn
->shm
.name
.len
);
916 (void) ngx_sprintf(file
, "%V%V%Z", &cycle
->lock_file
, &zn
->shm
.name
);
920 if (ngx_shmtx_create(&sp
->mutex
, (void *) &sp
->lock
, file
) != NGX_OK
) {
931 ngx_create_pidfile(ngx_str_t
*name
, ngx_log_t
*log
)
936 u_char pid
[NGX_INT64_LEN
+ 2];
938 if (ngx_process
> NGX_PROCESS_MASTER
) {
942 ngx_memzero(&file
, sizeof(ngx_file_t
));
947 create
= ngx_test_config
? NGX_FILE_CREATE_OR_OPEN
: NGX_FILE_TRUNCATE
;
949 file
.fd
= ngx_open_file(file
.name
.data
, NGX_FILE_RDWR
,
950 create
, NGX_FILE_DEFAULT_ACCESS
);
952 if (file
.fd
== NGX_INVALID_FILE
) {
953 ngx_log_error(NGX_LOG_EMERG
, log
, ngx_errno
,
954 ngx_open_file_n
" \"%s\" failed", file
.name
.data
);
958 if (!ngx_test_config
) {
959 len
= ngx_snprintf(pid
, NGX_INT64_LEN
+ 2, "%P%N", ngx_pid
) - pid
;
961 if (ngx_write_file(&file
, pid
, len
, 0) == NGX_ERROR
) {
966 if (ngx_close_file(file
.fd
) == NGX_FILE_ERROR
) {
967 ngx_log_error(NGX_LOG_ALERT
, log
, ngx_errno
,
968 ngx_close_file_n
" \"%s\" failed", file
.name
.data
);
976 ngx_delete_pidfile(ngx_cycle_t
*cycle
)
979 ngx_core_conf_t
*ccf
;
981 ccf
= (ngx_core_conf_t
*) ngx_get_conf(cycle
->conf_ctx
, ngx_core_module
);
983 name
= ngx_new_binary
? ccf
->oldpid
.data
: ccf
->pid
.data
;
985 if (ngx_delete_file(name
) == NGX_FILE_ERROR
) {
986 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
987 ngx_delete_file_n
" \"%s\" failed", name
);
993 ngx_signal_process(ngx_cycle_t
*cycle
, char *sig
)
998 ngx_core_conf_t
*ccf
;
999 u_char buf
[NGX_INT64_LEN
+ 2];
1001 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0, "signal process started");
1003 ccf
= (ngx_core_conf_t
*) ngx_get_conf(cycle
->conf_ctx
, ngx_core_module
);
1005 file
.name
= ccf
->pid
;
1006 file
.log
= cycle
->log
;
1008 file
.fd
= ngx_open_file(file
.name
.data
, NGX_FILE_RDONLY
,
1009 NGX_FILE_OPEN
, NGX_FILE_DEFAULT_ACCESS
);
1011 if (file
.fd
== NGX_INVALID_FILE
) {
1012 ngx_log_error(NGX_LOG_ERR
, cycle
->log
, ngx_errno
,
1013 ngx_open_file_n
" \"%s\" failed", file
.name
.data
);
1017 n
= ngx_read_file(&file
, buf
, NGX_INT64_LEN
+ 2, 0);
1019 if (ngx_close_file(file
.fd
) == NGX_FILE_ERROR
) {
1020 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
1021 ngx_close_file_n
" \"%s\" failed", file
.name
.data
);
1024 if (n
== NGX_ERROR
) {
1028 while (n
-- && (buf
[n
] == CR
|| buf
[n
] == LF
)) { /* void */ }
1030 pid
= ngx_atoi(buf
, ++n
);
1032 if (pid
== NGX_ERROR
) {
1033 ngx_log_error(NGX_LOG_ERR
, cycle
->log
, 0,
1034 "invalid PID number \"%*s\" in \"%s\"",
1035 n
, buf
, file
.name
.data
);
1039 return ngx_os_signal_process(cycle
, sig
, pid
);
1045 ngx_test_lockfile(u_char
*file
, ngx_log_t
*log
)
1047 #if !(NGX_HAVE_ATOMIC_OPS)
1050 fd
= ngx_open_file(file
, NGX_FILE_RDWR
, NGX_FILE_CREATE_OR_OPEN
,
1051 NGX_FILE_DEFAULT_ACCESS
);
1053 if (fd
== NGX_INVALID_FILE
) {
1054 ngx_log_error(NGX_LOG_EMERG
, log
, ngx_errno
,
1055 ngx_open_file_n
" \"%s\" failed", file
);
1059 if (ngx_close_file(fd
) == NGX_FILE_ERROR
) {
1060 ngx_log_error(NGX_LOG_ALERT
, log
, ngx_errno
,
1061 ngx_close_file_n
" \"%s\" failed", file
);
1064 if (ngx_delete_file(file
) == NGX_FILE_ERROR
) {
1065 ngx_log_error(NGX_LOG_ALERT
, log
, ngx_errno
,
1066 ngx_delete_file_n
" \"%s\" failed", file
);
1076 ngx_reopen_files(ngx_cycle_t
*cycle
, ngx_uid_t user
)
1081 ngx_list_part_t
*part
;
1082 ngx_open_file_t
*file
;
1084 part
= &cycle
->open_files
.part
;
1087 for (i
= 0; /* void */ ; i
++) {
1089 if (i
>= part
->nelts
) {
1090 if (part
->next
== NULL
) {
1098 if (file
[i
].name
.len
== 0) {
1102 len
= file
[i
].pos
- file
[i
].buffer
;
1104 if (file
[i
].buffer
&& len
!= 0) {
1106 n
= ngx_write_fd(file
[i
].fd
, file
[i
].buffer
, len
);
1108 if (n
== NGX_FILE_ERROR
) {
1109 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
1110 ngx_write_fd_n
" to \"%s\" failed",
1113 } else if (n
!= len
) {
1114 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, 0,
1115 ngx_write_fd_n
" to \"%s\" was incomplete: %z of %uz",
1116 file
[i
].name
.data
, n
, len
);
1119 file
[i
].pos
= file
[i
].buffer
;
1122 fd
= ngx_open_file(file
[i
].name
.data
, NGX_FILE_APPEND
,
1123 NGX_FILE_CREATE_OR_OPEN
, NGX_FILE_DEFAULT_ACCESS
);
1125 ngx_log_debug3(NGX_LOG_DEBUG_EVENT
, cycle
->log
, 0,
1126 "reopen file \"%s\", old:%d new:%d",
1127 file
[i
].name
.data
, file
[i
].fd
, fd
);
1129 if (fd
== NGX_INVALID_FILE
) {
1130 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, ngx_errno
,
1131 ngx_open_file_n
" \"%s\" failed", file
[i
].name
.data
);
1136 if (user
!= (ngx_uid_t
) NGX_CONF_UNSET_UINT
) {
1139 if (ngx_file_info((const char *) file
[i
].name
.data
, &fi
)
1142 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, ngx_errno
,
1143 ngx_file_info_n
" \"%s\" failed",
1146 if (ngx_close_file(fd
) == NGX_FILE_ERROR
) {
1147 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, ngx_errno
,
1148 ngx_close_file_n
" \"%s\" failed",
1153 if (fi
.st_uid
!= user
) {
1154 if (chown((const char *) file
[i
].name
.data
, user
, -1) == -1) {
1155 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, ngx_errno
,
1156 "chown(\"%s\", %d) failed",
1157 file
[i
].name
.data
, user
);
1159 if (ngx_close_file(fd
) == NGX_FILE_ERROR
) {
1160 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, ngx_errno
,
1161 ngx_close_file_n
" \"%s\" failed",
1167 if ((fi
.st_mode
& (S_IRUSR
|S_IWUSR
)) != (S_IRUSR
|S_IWUSR
)) {
1169 fi
.st_mode
|= (S_IRUSR
|S_IWUSR
);
1171 if (chmod((const char *) file
[i
].name
.data
, fi
.st_mode
) == -1) {
1172 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, ngx_errno
,
1173 "chmod() \"%s\" failed", file
[i
].name
.data
);
1175 if (ngx_close_file(fd
) == NGX_FILE_ERROR
) {
1176 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, ngx_errno
,
1177 ngx_close_file_n
" \"%s\" failed",
1184 if (fcntl(fd
, F_SETFD
, FD_CLOEXEC
) == -1) {
1185 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, ngx_errno
,
1186 "fcntl(FD_CLOEXEC) \"%s\" failed",
1189 if (ngx_close_file(fd
) == NGX_FILE_ERROR
) {
1190 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, ngx_errno
,
1191 ngx_close_file_n
" \"%s\" failed",
1199 if (ngx_close_file(file
[i
].fd
) == NGX_FILE_ERROR
) {
1200 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, ngx_errno
,
1201 ngx_close_file_n
" \"%s\" failed",
1210 if (cycle
->log
->file
->fd
!= STDERR_FILENO
) {
1211 if (dup2(cycle
->log
->file
->fd
, STDERR_FILENO
) == -1) {
1212 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, ngx_errno
,
1213 "dup2(STDERR) failed");
1222 ngx_shared_memory_add(ngx_conf_t
*cf
, ngx_str_t
*name
, size_t size
, void *tag
)
1225 ngx_shm_zone_t
*shm_zone
;
1226 ngx_list_part_t
*part
;
1228 part
= &cf
->cycle
->shared_memory
.part
;
1229 shm_zone
= part
->elts
;
1231 for (i
= 0; /* void */ ; i
++) {
1233 if (i
>= part
->nelts
) {
1234 if (part
->next
== NULL
) {
1238 shm_zone
= part
->elts
;
1242 if (name
->len
!= shm_zone
[i
].shm
.name
.len
) {
1246 if (ngx_strncmp(name
->data
, shm_zone
[i
].shm
.name
.data
, name
->len
)
1252 if (size
&& size
!= shm_zone
[i
].shm
.size
) {
1253 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1254 "the size %uz of shared memory zone \"%V\" "
1255 "conflicts with already declared size %uz",
1256 size
, &shm_zone
[i
].shm
.name
, shm_zone
[i
].shm
.size
);
1260 if (tag
!= shm_zone
[i
].tag
) {
1261 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1262 "the shared memory zone \"%V\" is "
1263 "already declared for a different use",
1264 &shm_zone
[i
].shm
.name
);
1268 return &shm_zone
[i
];
1271 shm_zone
= ngx_list_push(&cf
->cycle
->shared_memory
);
1273 if (shm_zone
== NULL
) {
1277 shm_zone
->data
= NULL
;
1278 shm_zone
->shm
.log
= cf
->cycle
->log
;
1279 shm_zone
->shm
.size
= size
;
1280 shm_zone
->shm
.name
= *name
;
1281 shm_zone
->shm
.exists
= 0;
1282 shm_zone
->init
= NULL
;
1283 shm_zone
->tag
= tag
;
1290 ngx_clean_old_cycles(ngx_event_t
*ev
)
1292 ngx_uint_t i
, n
, found
, live
;
1294 ngx_cycle_t
**cycle
;
1296 log
= ngx_cycle
->log
;
1297 ngx_temp_pool
->log
= log
;
1299 ngx_log_debug0(NGX_LOG_DEBUG_CORE
, log
, 0, "clean old cycles");
1303 cycle
= ngx_old_cycles
.elts
;
1304 for (i
= 0; i
< ngx_old_cycles
.nelts
; i
++) {
1306 if (cycle
[i
] == NULL
) {
1312 for (n
= 0; n
< cycle
[i
]->connection_n
; n
++) {
1313 if (cycle
[i
]->connections
[n
].fd
!= (ngx_socket_t
) -1) {
1316 ngx_log_debug1(NGX_LOG_DEBUG_CORE
, log
, 0, "live fd:%d", n
);
1327 ngx_log_debug1(NGX_LOG_DEBUG_CORE
, log
, 0, "clean old cycle: %d", i
);
1329 ngx_destroy_pool(cycle
[i
]->pool
);
1333 ngx_log_debug1(NGX_LOG_DEBUG_CORE
, log
, 0, "old cycles status: %d", live
);
1336 ngx_add_timer(ev
, 30000);
1339 ngx_destroy_pool(ngx_temp_pool
);
1340 ngx_temp_pool
= NULL
;
1341 ngx_old_cycles
.nelts
= 0;