blob: 11e413f4ea1cc1fbc4b51c756e02bc0c3cd4e2f7 [file] [log] [blame]
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001
Igor Sysoevd90282d2004-09-28 08:34:51 +00002/*
Igor Sysoevff8da912004-09-29 16:00:49 +00003 * Copyright (C) Igor Sysoev
Maxim Konovalovf8d59e32012-01-18 15:07:43 +00004 * Copyright (C) Nginx, Inc.
Igor Sysoevd90282d2004-09-28 08:34:51 +00005 */
6
7
Igor Sysoev3c3ca172004-01-05 20:55:48 +00008#include <ngx_config.h>
9#include <ngx_core.h>
10#include <ngx_event.h>
Igor Sysoev3c3ca172004-01-05 20:55:48 +000011
12
Igor Sysoev9e580192006-02-01 18:22:15 +000013static void ngx_destroy_cycle_pools(ngx_conf_t *conf);
Igor Sysoevf7a08d52009-04-18 19:27:28 +000014static ngx_int_t ngx_init_zone_pool(ngx_cycle_t *cycle,
15 ngx_shm_zone_t *shm_zone);
16static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log);
Igor Sysoev3c3ca172004-01-05 20:55:48 +000017static void ngx_clean_old_cycles(ngx_event_t *ev);
18
19
20volatile ngx_cycle_t *ngx_cycle;
21ngx_array_t ngx_old_cycles;
22
23static ngx_pool_t *ngx_temp_pool;
24static ngx_event_t ngx_cleaner_event;
25
Igor Sysoev630ad0c2004-04-16 05:14:16 +000026ngx_uint_t ngx_test_config;
Igor Sysoev2cb30f12010-09-02 13:43:02 +000027ngx_uint_t ngx_quiet_mode;
Igor Sysoev630ad0c2004-04-16 05:14:16 +000028
Ruslan Ermilovba1e8662015-03-04 18:26:25 +030029#if (NGX_OLD_THREADS)
Igor Sysoev2b979932004-07-07 15:01:00 +000030ngx_tls_key_t ngx_core_tls_key;
31#endif
32
Igor Sysoev3c3ca172004-01-05 20:55:48 +000033
34/* STUB NAME */
35static ngx_connection_t dumb;
36/* STUB */
37
38
Igor Sysoevc2068d02005-10-19 12:33:58 +000039ngx_cycle_t *
40ngx_init_cycle(ngx_cycle_t *old_cycle)
Igor Sysoev3c3ca172004-01-05 20:55:48 +000041{
Igor Sysoev7f35ae62007-12-16 11:58:16 +000042 void *rv;
43 char **senv, **env;
Igor Sysoev7f35ae62007-12-16 11:58:16 +000044 ngx_uint_t i, n;
45 ngx_log_t *log;
Igor Sysoevfcb5a702008-08-30 19:52:07 +000046 ngx_time_t *tp;
Igor Sysoev7f35ae62007-12-16 11:58:16 +000047 ngx_conf_t conf;
48 ngx_pool_t *pool;
49 ngx_cycle_t *cycle, **old;
50 ngx_shm_zone_t *shm_zone, *oshm_zone;
Igor Sysoev7f35ae62007-12-16 11:58:16 +000051 ngx_list_part_t *part, *opart;
52 ngx_open_file_t *file;
53 ngx_listening_t *ls, *nls;
54 ngx_core_conf_t *ccf, *old_ccf;
55 ngx_core_module_t *module;
Igor Sysoev3be52572008-05-16 14:39:06 +000056 char hostname[NGX_MAXHOSTNAMELEN];
Igor Sysoev3c3ca172004-01-05 20:55:48 +000057
Igor Sysoevfcb5a702008-08-30 19:52:07 +000058 ngx_timezone_update();
59
60 /* force localtime update with a new timezone */
61
62 tp = ngx_timeofday();
63 tp->sec = 0;
64
Igor Sysoev6d45d8a2010-03-25 09:10:10 +000065 ngx_time_update();
Igor Sysoevfcb5a702008-08-30 19:52:07 +000066
67
Igor Sysoev3c3ca172004-01-05 20:55:48 +000068 log = old_cycle->log;
69
Igor Sysoev02f742b2005-04-08 15:18:55 +000070 pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
Igor Sysoevc1571722005-03-19 12:38:37 +000071 if (pool == NULL) {
Igor Sysoev3c3ca172004-01-05 20:55:48 +000072 return NULL;
73 }
Igor Sysoev68df19d2004-04-15 15:34:36 +000074 pool->log = log;
Igor Sysoev3c3ca172004-01-05 20:55:48 +000075
Igor Sysoevc1571722005-03-19 12:38:37 +000076 cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));
77 if (cycle == NULL) {
Igor Sysoev3c3ca172004-01-05 20:55:48 +000078 ngx_destroy_pool(pool);
79 return NULL;
80 }
Igor Sysoevc1571722005-03-19 12:38:37 +000081
Igor Sysoev3c3ca172004-01-05 20:55:48 +000082 cycle->pool = pool;
Igor Sysoevcccc5522004-04-14 20:34:05 +000083 cycle->log = log;
Igor Sysoev3c3ca172004-01-05 20:55:48 +000084 cycle->old_cycle = old_cycle;
Igor Sysoevab517d52004-05-18 15:29:08 +000085
Igor Sysoev5ef370d2009-04-27 11:32:33 +000086 cycle->conf_prefix.len = old_cycle->conf_prefix.len;
87 cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix);
88 if (cycle->conf_prefix.data == NULL) {
89 ngx_destroy_pool(pool);
90 return NULL;
91 }
92
93 cycle->prefix.len = old_cycle->prefix.len;
94 cycle->prefix.data = ngx_pstrdup(pool, &old_cycle->prefix);
95 if (cycle->prefix.data == NULL) {
96 ngx_destroy_pool(pool);
97 return NULL;
98 }
Igor Sysoevab517d52004-05-18 15:29:08 +000099
Igor Sysoev9e580192006-02-01 18:22:15 +0000100 cycle->conf_file.len = old_cycle->conf_file.len;
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000101 cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + 1);
Igor Sysoev9e580192006-02-01 18:22:15 +0000102 if (cycle->conf_file.data == NULL) {
103 ngx_destroy_pool(pool);
104 return NULL;
105 }
106 ngx_cpystrn(cycle->conf_file.data, old_cycle->conf_file.data,
107 old_cycle->conf_file.len + 1);
108
Igor Sysoevb4fbdcf2008-06-30 12:35:16 +0000109 cycle->conf_param.len = old_cycle->conf_param.len;
Igor Sysoev5ef370d2009-04-27 11:32:33 +0000110 cycle->conf_param.data = ngx_pstrdup(pool, &old_cycle->conf_param);
Igor Sysoevb4fbdcf2008-06-30 12:35:16 +0000111 if (cycle->conf_param.data == NULL) {
112 ngx_destroy_pool(pool);
113 return NULL;
114 }
Igor Sysoevb4fbdcf2008-06-30 12:35:16 +0000115
116
Andrey Belov8be233c2012-09-28 13:49:26 +0000117 n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10;
Igor Sysoevc1571722005-03-19 12:38:37 +0000118
Andrey Belov8be233c2012-09-28 13:49:26 +0000119 cycle->paths.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *));
120 if (cycle->paths.elts == NULL) {
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000121 ngx_destroy_pool(pool);
122 return NULL;
123 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000124
Andrey Belov8be233c2012-09-28 13:49:26 +0000125 cycle->paths.nelts = 0;
126 cycle->paths.size = sizeof(ngx_path_t *);
127 cycle->paths.nalloc = n;
128 cycle->paths.pool = pool;
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000129
130
Igor Sysoevb9e34412004-09-03 15:50:30 +0000131 if (old_cycle->open_files.part.nelts) {
132 n = old_cycle->open_files.part.nelts;
133 for (part = old_cycle->open_files.part.next; part; part = part->next) {
134 n += part->nelts;
135 }
136
137 } else {
138 n = 20;
139 }
140
Igor Sysoevaab4d8c2004-09-06 18:45:00 +0000141 if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t))
Igor Sysoev1f4220e2009-02-24 10:42:23 +0000142 != NGX_OK)
Igor Sysoev980a9242004-09-05 19:54:02 +0000143 {
Igor Sysoevb9e34412004-09-03 15:50:30 +0000144 ngx_destroy_pool(pool);
145 return NULL;
146 }
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000147
148
Igor Sysoev67cd3362006-11-20 08:51:45 +0000149 if (old_cycle->shared_memory.part.nelts) {
150 n = old_cycle->shared_memory.part.nelts;
151 for (part = old_cycle->shared_memory.part.next; part; part = part->next)
152 {
153 n += part->nelts;
154 }
155
156 } else {
157 n = 1;
158 }
159
160 if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t))
Igor Sysoev1f4220e2009-02-24 10:42:23 +0000161 != NGX_OK)
Igor Sysoev67cd3362006-11-20 08:51:45 +0000162 {
163 ngx_destroy_pool(pool);
164 return NULL;
165 }
166
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000167 n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;
Igor Sysoevc1571722005-03-19 12:38:37 +0000168
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000169 cycle->listening.elts = ngx_pcalloc(pool, n * sizeof(ngx_listening_t));
170 if (cycle->listening.elts == NULL) {
171 ngx_destroy_pool(pool);
172 return NULL;
173 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000174
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000175 cycle->listening.nelts = 0;
176 cycle->listening.size = sizeof(ngx_listening_t);
177 cycle->listening.nalloc = n;
178 cycle->listening.pool = pool;
179
180
Igor Sysoev4956ac52011-04-04 12:26:53 +0000181 ngx_queue_init(&cycle->reusable_connections_queue);
182
183
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000184 cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
185 if (cycle->conf_ctx == NULL) {
186 ngx_destroy_pool(pool);
187 return NULL;
188 }
189
190
Igor Sysoev3be52572008-05-16 14:39:06 +0000191 if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) {
192 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "gethostname() failed");
193 ngx_destroy_pool(pool);
194 return NULL;
195 }
196
197 /* on Linux gethostname() silently truncates name that does not fit */
198
199 hostname[NGX_MAXHOSTNAMELEN - 1] = '\0';
200 cycle->hostname.len = ngx_strlen(hostname);
201
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000202 cycle->hostname.data = ngx_pnalloc(pool, cycle->hostname.len);
Igor Sysoev3be52572008-05-16 14:39:06 +0000203 if (cycle->hostname.data == NULL) {
204 ngx_destroy_pool(pool);
205 return NULL;
206 }
207
Igor Sysoev42b72992009-10-21 17:04:13 +0000208 ngx_strlow(cycle->hostname.data, (u_char *) hostname, cycle->hostname.len);
Igor Sysoev3be52572008-05-16 14:39:06 +0000209
210
Igor Sysoev43f13192004-04-12 16:38:09 +0000211 for (i = 0; ngx_modules[i]; i++) {
212 if (ngx_modules[i]->type != NGX_CORE_MODULE) {
213 continue;
214 }
215
216 module = ngx_modules[i]->ctx;
217
218 if (module->create_conf) {
219 rv = module->create_conf(cycle);
Igor Sysoev260c4322009-06-02 16:09:44 +0000220 if (rv == NULL) {
Igor Sysoev43f13192004-04-12 16:38:09 +0000221 ngx_destroy_pool(pool);
222 return NULL;
223 }
224 cycle->conf_ctx[ngx_modules[i]->index] = rv;
225 }
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000226 }
227
228
Igor Sysoev7f35ae62007-12-16 11:58:16 +0000229 senv = environ;
230
231
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000232 ngx_memzero(&conf, sizeof(ngx_conf_t));
233 /* STUB: init array ? */
Igor Sysoevc1571722005-03-19 12:38:37 +0000234 conf.args = ngx_array_create(pool, 10, sizeof(ngx_str_t));
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000235 if (conf.args == NULL) {
236 ngx_destroy_pool(pool);
237 return NULL;
238 }
239
Igor Sysoev305a9d82005-12-26 17:07:48 +0000240 conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
241 if (conf.temp_pool == NULL) {
242 ngx_destroy_pool(pool);
243 return NULL;
244 }
245
Igor Sysoev9e580192006-02-01 18:22:15 +0000246
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000247 conf.ctx = cycle->conf_ctx;
248 conf.cycle = cycle;
Igor Sysoev68df19d2004-04-15 15:34:36 +0000249 conf.pool = pool;
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000250 conf.log = log;
251 conf.module_type = NGX_CORE_MODULE;
252 conf.cmd_type = NGX_MAIN_CONF;
253
Igor Sysoev50cc0c92006-10-02 08:50:03 +0000254#if 0
Igor Sysoevc0edbcc2004-10-21 15:34:38 +0000255 log->log_level = NGX_LOG_DEBUG_ALL;
256#endif
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000257
Igor Sysoevb4fbdcf2008-06-30 12:35:16 +0000258 if (ngx_conf_param(&conf) != NGX_CONF_OK) {
Igor Sysoev15c149e2009-09-18 09:21:14 +0000259 environ = senv;
Igor Sysoevb4fbdcf2008-06-30 12:35:16 +0000260 ngx_destroy_cycle_pools(&conf);
261 return NULL;
262 }
263
Igor Sysoeve9b2cb12004-02-09 20:47:18 +0000264 if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
Igor Sysoev15c149e2009-09-18 09:21:14 +0000265 environ = senv;
Igor Sysoev9e580192006-02-01 18:22:15 +0000266 ngx_destroy_cycle_pools(&conf);
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000267 return NULL;
268 }
269
Igor Sysoev2cb30f12010-09-02 13:43:02 +0000270 if (ngx_test_config && !ngx_quiet_mode) {
Igor Sysoevc28ff712009-04-23 11:13:12 +0000271 ngx_log_stderr(0, "the configuration file %s syntax is ok",
Igor Sysoev1153aa62009-04-19 16:06:09 +0000272 cycle->conf_file.data);
Igor Sysoev9bfb4342004-04-18 19:06:02 +0000273 }
274
Igor Sysoev43f13192004-04-12 16:38:09 +0000275 for (i = 0; ngx_modules[i]; i++) {
276 if (ngx_modules[i]->type != NGX_CORE_MODULE) {
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000277 continue;
278 }
279
Igor Sysoev43f13192004-04-12 16:38:09 +0000280 module = ngx_modules[i]->ctx;
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000281
Igor Sysoev43f13192004-04-12 16:38:09 +0000282 if (module->init_conf) {
283 if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index])
Igor Sysoev305a9d82005-12-26 17:07:48 +0000284 == NGX_CONF_ERROR)
Igor Sysoev43f13192004-04-12 16:38:09 +0000285 {
Igor Sysoev15c149e2009-09-18 09:21:14 +0000286 environ = senv;
Igor Sysoev9e580192006-02-01 18:22:15 +0000287 ngx_destroy_cycle_pools(&conf);
Igor Sysoev43f13192004-04-12 16:38:09 +0000288 return NULL;
289 }
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000290 }
Igor Sysoev43f13192004-04-12 16:38:09 +0000291 }
292
Igor Sysoev165aa392009-06-06 12:41:31 +0000293 if (ngx_process == NGX_PROCESS_SIGNALLER) {
294 return cycle;
295 }
Igor Sysoev43f13192004-04-12 16:38:09 +0000296
Igor Sysoevffe71442006-02-08 15:33:12 +0000297 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
Igor Sysoev43f13192004-04-12 16:38:09 +0000298
Igor Sysoevffe71442006-02-08 15:33:12 +0000299 if (ngx_test_config) {
Igor Sysoev43f13192004-04-12 16:38:09 +0000300
Igor Sysoevffe71442006-02-08 15:33:12 +0000301 if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
302 goto failed;
303 }
Igor Sysoevd43bee82004-11-20 19:52:20 +0000304
Igor Sysoevffe71442006-02-08 15:33:12 +0000305 } else if (!ngx_is_init_cycle(old_cycle)) {
306
307 /*
308 * we do not create the pid file in the first ngx_init_cycle() call
309 * because we need to write the demonized process pid
310 */
311
312 old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
313 ngx_core_module);
314 if (ccf->pid.len != old_ccf->pid.len
315 || ngx_strcmp(ccf->pid.data, old_ccf->pid.data) != 0)
316 {
317 /* new pid file name */
318
319 if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
320 goto failed;
321 }
322
323 ngx_delete_pidfile(old_cycle);
Igor Sysoevd43bee82004-11-20 19:52:20 +0000324 }
325 }
326
Igor Sysoevb9e34412004-09-03 15:50:30 +0000327
Igor Sysoev67cd3362006-11-20 08:51:45 +0000328 if (ngx_test_lockfile(cycle->lock_file.data, log) != NGX_OK) {
Igor Sysoevffe71442006-02-08 15:33:12 +0000329 goto failed;
330 }
Igor Sysoev1b735832004-11-11 14:07:14 +0000331
Igor Sysoevb9e34412004-09-03 15:50:30 +0000332
Andrey Belov8be233c2012-09-28 13:49:26 +0000333 if (ngx_create_paths(cycle, ccf->user) != NGX_OK) {
Igor Sysoevffe71442006-02-08 15:33:12 +0000334 goto failed;
335 }
Igor Sysoevb9e34412004-09-03 15:50:30 +0000336
Igor Sysoevb9e34412004-09-03 15:50:30 +0000337
Vladimir Homutovdd3e13e2013-06-28 17:24:54 +0400338 if (ngx_log_open_default(cycle) != NGX_OK) {
339 goto failed;
Igor Sysoev0cd76ea2009-04-30 13:53:42 +0000340 }
341
Igor Sysoevffe71442006-02-08 15:33:12 +0000342 /* open the new files */
Igor Sysoev43f13192004-04-12 16:38:09 +0000343
Igor Sysoevffe71442006-02-08 15:33:12 +0000344 part = &cycle->open_files.part;
345 file = part->elts;
Igor Sysoev43f13192004-04-12 16:38:09 +0000346
Igor Sysoevffe71442006-02-08 15:33:12 +0000347 for (i = 0; /* void */ ; i++) {
Igor Sysoevb9e34412004-09-03 15:50:30 +0000348
Igor Sysoevffe71442006-02-08 15:33:12 +0000349 if (i >= part->nelts) {
350 if (part->next == NULL) {
Igor Sysoev43f13192004-04-12 16:38:09 +0000351 break;
352 }
Igor Sysoevffe71442006-02-08 15:33:12 +0000353 part = part->next;
354 file = part->elts;
355 i = 0;
356 }
357
Igor Sysoev5ef370d2009-04-27 11:32:33 +0000358 if (file[i].name.len == 0) {
Igor Sysoevffe71442006-02-08 15:33:12 +0000359 continue;
360 }
361
Igor Sysoevfadc7a72009-03-30 14:51:51 +0000362 file[i].fd = ngx_open_file(file[i].name.data,
Igor Sysoev24c27872009-03-31 13:52:01 +0000363 NGX_FILE_APPEND,
Igor Sysoevfadc7a72009-03-30 14:51:51 +0000364 NGX_FILE_CREATE_OR_OPEN,
Igor Sysoev50034b82007-01-18 20:15:09 +0000365 NGX_FILE_DEFAULT_ACCESS);
Igor Sysoevffe71442006-02-08 15:33:12 +0000366
367 ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, 0,
368 "log: %p %d \"%s\"",
369 &file[i], file[i].fd, file[i].name.data);
370
371 if (file[i].fd == NGX_INVALID_FILE) {
372 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
373 ngx_open_file_n " \"%s\" failed",
374 file[i].name.data);
375 goto failed;
376 }
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000377
Igor Sysoeva2de7b92009-04-08 19:13:28 +0000378#if !(NGX_WIN32)
Igor Sysoevffe71442006-02-08 15:33:12 +0000379 if (fcntl(file[i].fd, F_SETFD, FD_CLOEXEC) == -1) {
380 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
381 "fcntl(FD_CLOEXEC) \"%s\" failed",
382 file[i].name.data);
383 goto failed;
384 }
385#endif
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000386 }
387
Igor Sysoev0cd76ea2009-04-30 13:53:42 +0000388 cycle->log = &cycle->new_log;
389 pool->log = &cycle->new_log;
Igor Sysoev9aa30bc2009-01-26 14:31:49 +0000390
Igor Sysoev1b735832004-11-11 14:07:14 +0000391
Igor Sysoev67cd3362006-11-20 08:51:45 +0000392 /* create shared memory */
393
394 part = &cycle->shared_memory.part;
Igor Sysoev28c7f762007-01-02 23:54:14 +0000395 shm_zone = part->elts;
Igor Sysoev67cd3362006-11-20 08:51:45 +0000396
397 for (i = 0; /* void */ ; i++) {
398
399 if (i >= part->nelts) {
400 if (part->next == NULL) {
401 break;
402 }
403 part = part->next;
Igor Sysoev28c7f762007-01-02 23:54:14 +0000404 shm_zone = part->elts;
Igor Sysoev67cd3362006-11-20 08:51:45 +0000405 i = 0;
406 }
407
Igor Sysoev14110b32007-01-06 18:52:06 +0000408 if (shm_zone[i].shm.size == 0) {
409 ngx_log_error(NGX_LOG_EMERG, log, 0,
410 "zero size shared memory zone \"%V\"",
Igor Sysoevc7f876b2009-04-16 19:25:09 +0000411 &shm_zone[i].shm.name);
Igor Sysoev14110b32007-01-06 18:52:06 +0000412 goto failed;
413 }
414
Igor Sysoev28c7f762007-01-02 23:54:14 +0000415 shm_zone[i].shm.log = cycle->log;
Igor Sysoev67cd3362006-11-20 08:51:45 +0000416
417 opart = &old_cycle->shared_memory.part;
Igor Sysoev28c7f762007-01-02 23:54:14 +0000418 oshm_zone = opart->elts;
Igor Sysoev67cd3362006-11-20 08:51:45 +0000419
420 for (n = 0; /* void */ ; n++) {
421
422 if (n >= opart->nelts) {
423 if (opart->next == NULL) {
424 break;
425 }
426 opart = opart->next;
Igor Sysoev28c7f762007-01-02 23:54:14 +0000427 oshm_zone = opart->elts;
Igor Sysoev67cd3362006-11-20 08:51:45 +0000428 n = 0;
429 }
430
Igor Sysoevc7f876b2009-04-16 19:25:09 +0000431 if (shm_zone[i].shm.name.len != oshm_zone[n].shm.name.len) {
Igor Sysoev67cd3362006-11-20 08:51:45 +0000432 continue;
433 }
434
Igor Sysoevc7f876b2009-04-16 19:25:09 +0000435 if (ngx_strncmp(shm_zone[i].shm.name.data,
436 oshm_zone[n].shm.name.data,
437 shm_zone[i].shm.name.len)
Igor Sysoev28c7f762007-01-02 23:54:14 +0000438 != 0)
439 {
440 continue;
441 }
442
Ruslan Ermilova94a1012012-11-23 12:43:58 +0000443 if (shm_zone[i].tag == oshm_zone[n].tag
444 && shm_zone[i].shm.size == oshm_zone[n].shm.size)
445 {
Igor Sysoev28c7f762007-01-02 23:54:14 +0000446 shm_zone[i].shm.addr = oshm_zone[n].shm.addr;
Igor Sysoev4e77a2b2007-01-09 15:59:20 +0000447
448 if (shm_zone[i].init(&shm_zone[i], oshm_zone[n].data)
449 != NGX_OK)
450 {
451 goto failed;
452 }
453
Igor Sysoev667a79b2007-01-09 16:02:29 +0000454 goto shm_zone_found;
Igor Sysoev67cd3362006-11-20 08:51:45 +0000455 }
456
Igor Sysoev28c7f762007-01-02 23:54:14 +0000457 ngx_shm_free(&oshm_zone[n].shm);
Igor Sysoev67cd3362006-11-20 08:51:45 +0000458
459 break;
460 }
461
Igor Sysoev28c7f762007-01-02 23:54:14 +0000462 if (ngx_shm_alloc(&shm_zone[i].shm) != NGX_OK) {
Igor Sysoev67cd3362006-11-20 08:51:45 +0000463 goto failed;
464 }
465
Igor Sysoeva1195842009-06-02 13:57:59 +0000466 if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) {
467 goto failed;
Igor Sysoev67cd3362006-11-20 08:51:45 +0000468 }
469
Igor Sysoev4e77a2b2007-01-09 15:59:20 +0000470 if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) {
Igor Sysoev28c7f762007-01-02 23:54:14 +0000471 goto failed;
472 }
473
Igor Sysoev667a79b2007-01-09 16:02:29 +0000474 shm_zone_found:
Igor Sysoev67cd3362006-11-20 08:51:45 +0000475
476 continue;
477 }
478
479
Igor Sysoevffe71442006-02-08 15:33:12 +0000480 /* handle the listening sockets */
Igor Sysoev1b735832004-11-11 14:07:14 +0000481
Igor Sysoevffe71442006-02-08 15:33:12 +0000482 if (old_cycle->listening.nelts) {
483 ls = old_cycle->listening.elts;
484 for (i = 0; i < old_cycle->listening.nelts; i++) {
485 ls[i].remain = 0;
486 }
487
488 nls = cycle->listening.elts;
489 for (n = 0; n < cycle->listening.nelts; n++) {
490
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000491 for (i = 0; i < old_cycle->listening.nelts; i++) {
Igor Sysoevffe71442006-02-08 15:33:12 +0000492 if (ls[i].ignore) {
493 continue;
494 }
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000495
Ruslan Ermilovefd0e0e2013-12-06 14:30:27 +0400496 if (ngx_cmp_sockaddr(nls[n].sockaddr, nls[n].socklen,
Maxim Dounin8800f0c2014-03-07 15:17:38 +0400497 ls[i].sockaddr, ls[i].socklen, 1)
Ruslan Ermilovefd0e0e2013-12-06 14:30:27 +0400498 == NGX_OK)
Igor Sysoevffe71442006-02-08 15:33:12 +0000499 {
500 nls[n].fd = ls[i].fd;
501 nls[n].previous = &ls[i];
502 ls[i].remain = 1;
Igor Sysoev1b735832004-11-11 14:07:14 +0000503
Maxim Dounin8800f0c2014-03-07 15:17:38 +0400504 if (ls[i].backlog != nls[n].backlog) {
Igor Sysoevffe71442006-02-08 15:33:12 +0000505 nls[n].listen = 1;
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000506 }
507
Igor Sysoevb145b062005-06-15 18:33:41 +0000508#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
509
Igor Sysoevffe71442006-02-08 15:33:12 +0000510 /*
511 * FreeBSD, except the most recent versions,
512 * could not remove accept filter
513 */
514 nls[n].deferred_accept = ls[i].deferred_accept;
Igor Sysoevb145b062005-06-15 18:33:41 +0000515
Igor Sysoevffe71442006-02-08 15:33:12 +0000516 if (ls[i].accept_filter && nls[n].accept_filter) {
517 if (ngx_strcmp(ls[i].accept_filter,
518 nls[n].accept_filter)
519 != 0)
Igor Sysoevb145b062005-06-15 18:33:41 +0000520 {
Igor Sysoevffe71442006-02-08 15:33:12 +0000521 nls[n].delete_deferred = 1;
Igor Sysoevb145b062005-06-15 18:33:41 +0000522 nls[n].add_deferred = 1;
523 }
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000524
Igor Sysoevffe71442006-02-08 15:33:12 +0000525 } else if (ls[i].accept_filter) {
526 nls[n].delete_deferred = 1;
527
528 } else if (nls[n].accept_filter) {
529 nls[n].add_deferred = 1;
530 }
531#endif
532
533#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
534
Maxim Dounin8800f0c2014-03-07 15:17:38 +0400535 if (ls[i].deferred_accept && !nls[n].deferred_accept) {
Igor Sysoevffe71442006-02-08 15:33:12 +0000536 nls[n].delete_deferred = 1;
537
538 } else if (ls[i].deferred_accept != nls[n].deferred_accept)
539 {
540 nls[n].add_deferred = 1;
541 }
542#endif
543 break;
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000544 }
545 }
546
Maxim Dounin48d96ce2013-09-04 20:48:28 +0400547 if (nls[n].fd == (ngx_socket_t) -1) {
Igor Sysoevffe71442006-02-08 15:33:12 +0000548 nls[n].open = 1;
Piotr Sikora47583282013-10-24 14:18:37 -0700549#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
550 if (nls[n].accept_filter) {
551 nls[n].add_deferred = 1;
552 }
553#endif
554#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
555 if (nls[n].deferred_accept) {
556 nls[n].add_deferred = 1;
557 }
558#endif
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000559 }
560 }
561
Igor Sysoevffe71442006-02-08 15:33:12 +0000562 } else {
563 ls = cycle->listening.elts;
564 for (i = 0; i < cycle->listening.nelts; i++) {
565 ls[i].open = 1;
566#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
567 if (ls[i].accept_filter) {
568 ls[i].add_deferred = 1;
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000569 }
Igor Sysoevffe71442006-02-08 15:33:12 +0000570#endif
571#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
572 if (ls[i].deferred_accept) {
573 ls[i].add_deferred = 1;
Igor Sysoevb145b062005-06-15 18:33:41 +0000574 }
Igor Sysoevffe71442006-02-08 15:33:12 +0000575#endif
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000576 }
577 }
578
Igor Sysoev165aa392009-06-06 12:41:31 +0000579 if (ngx_open_listening_sockets(cycle) != NGX_OK) {
580 goto failed;
581 }
Igor Sysoev9e580192006-02-01 18:22:15 +0000582
Igor Sysoev165aa392009-06-06 12:41:31 +0000583 if (!ngx_test_config) {
584 ngx_configure_listening_sockets(cycle);
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000585 }
586
Igor Sysoev25b36fe2004-02-03 16:43:54 +0000587
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000588 /* commit the new cycle configuration */
589
Vladimir Homutovdd3e13e2013-06-28 17:24:54 +0400590 if (!ngx_use_stderr) {
591 (void) ngx_log_redirect_stderr(cycle);
Igor Sysoevaad1b892004-10-03 20:02:06 +0000592 }
593
Igor Sysoevaad1b892004-10-03 20:02:06 +0000594 pool->log = cycle->log;
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000595
596 for (i = 0; ngx_modules[i]; i++) {
597 if (ngx_modules[i]->init_module) {
Igor Sysoevffe71442006-02-08 15:33:12 +0000598 if (ngx_modules[i]->init_module(cycle) != NGX_OK) {
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000599 /* fatal */
600 exit(1);
601 }
602 }
603 }
604
Igor Sysoevd43bee82004-11-20 19:52:20 +0000605
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000606 /* close and delete stuff that lefts from an old cycle */
607
Igor Sysoev3a257b32007-01-09 16:00:57 +0000608 /* free the unnecessary shared memory */
609
610 opart = &old_cycle->shared_memory.part;
611 oshm_zone = opart->elts;
612
613 for (i = 0; /* void */ ; i++) {
614
615 if (i >= opart->nelts) {
616 if (opart->next == NULL) {
617 goto old_shm_zone_done;
618 }
619 opart = opart->next;
620 oshm_zone = opart->elts;
621 i = 0;
622 }
623
624 part = &cycle->shared_memory.part;
625 shm_zone = part->elts;
626
627 for (n = 0; /* void */ ; n++) {
628
629 if (n >= part->nelts) {
630 if (part->next == NULL) {
631 break;
632 }
633 part = part->next;
634 shm_zone = part->elts;
635 n = 0;
636 }
637
Igor Sysoevc7f876b2009-04-16 19:25:09 +0000638 if (oshm_zone[i].shm.name.len == shm_zone[n].shm.name.len
639 && ngx_strncmp(oshm_zone[i].shm.name.data,
640 shm_zone[n].shm.name.data,
641 oshm_zone[i].shm.name.len)
Igor Sysoev3a257b32007-01-09 16:00:57 +0000642 == 0)
643 {
644 goto live_shm_zone;
645 }
646 }
647
648 ngx_shm_free(&oshm_zone[i].shm);
649
650 live_shm_zone:
651
652 continue;
653 }
654
655old_shm_zone_done:
656
657
Igor Sysoeva269c822007-01-09 16:00:07 +0000658 /* close the unnecessary listening sockets */
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000659
660 ls = old_cycle->listening.elts;
661 for (i = 0; i < old_cycle->listening.nelts; i++) {
Igor Sysoev366bf712009-06-06 12:53:55 +0000662
Maxim Dounin48d96ce2013-09-04 20:48:28 +0400663 if (ls[i].remain || ls[i].fd == (ngx_socket_t) -1) {
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000664 continue;
665 }
666
667 if (ngx_close_socket(ls[i].fd) == -1) {
668 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000669 ngx_close_socket_n " listening socket on %V failed",
Igor Sysoev1b735832004-11-11 14:07:14 +0000670 &ls[i].addr_text);
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000671 }
Igor Sysoev1f073922010-06-04 13:34:23 +0000672
673#if (NGX_HAVE_UNIX_DOMAIN)
674
675 if (ls[i].sockaddr->sa_family == AF_UNIX) {
676 u_char *name;
677
678 name = ls[i].addr_text.data + sizeof("unix:") - 1;
679
680 ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
681 "deleting socket %s", name);
682
Valentin Bartenev604e18f2013-03-25 15:49:11 +0000683 if (ngx_delete_file(name) == NGX_FILE_ERROR) {
Igor Sysoev1f073922010-06-04 13:34:23 +0000684 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
685 ngx_delete_file_n " %s failed", name);
686 }
687 }
688
689#endif
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000690 }
691
692
Igor Sysoeva269c822007-01-09 16:00:07 +0000693 /* close the unnecessary open files */
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000694
Igor Sysoevb9e34412004-09-03 15:50:30 +0000695 part = &old_cycle->open_files.part;
696 file = part->elts;
697
698 for (i = 0; /* void */ ; i++) {
699
700 if (i >= part->nelts) {
701 if (part->next == NULL) {
702 break;
703 }
704 part = part->next;
705 file = part->elts;
706 i = 0;
707 }
708
Igor Sysoevc28ff712009-04-23 11:13:12 +0000709 if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000710 continue;
711 }
712
713 if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
714 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
715 ngx_close_file_n " \"%s\" failed",
716 file[i].name.data);
717 }
718 }
719
Igor Sysoev305a9d82005-12-26 17:07:48 +0000720 ngx_destroy_pool(conf.temp_pool);
721
Igor Sysoev9e580192006-02-01 18:22:15 +0000722 if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) {
723
Igor Sysoev7f35ae62007-12-16 11:58:16 +0000724 /*
Igor Sysoev2d95c3f2009-09-18 09:12:40 +0000725 * perl_destruct() frees environ, if it is not the same as it was at
726 * perl_construct() time, therefore we save the previous cycle
Igor Sysoev7f35ae62007-12-16 11:58:16 +0000727 * environment before ngx_conf_parse() where it will be changed.
728 */
729
730 env = environ;
731 environ = senv;
732
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000733 ngx_destroy_pool(old_cycle->pool);
Igor Sysoevffe71442006-02-08 15:33:12 +0000734 cycle->old_cycle = NULL;
735
Igor Sysoev7f35ae62007-12-16 11:58:16 +0000736 environ = env;
737
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000738 return cycle;
739 }
740
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000741
742 if (ngx_temp_pool == NULL) {
743 ngx_temp_pool = ngx_create_pool(128, cycle->log);
744 if (ngx_temp_pool == NULL) {
745 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
Ruslan Ermilova823c552011-09-19 14:48:29 +0000746 "could not create ngx_temp_pool");
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000747 exit(1);
748 }
749
750 n = 10;
751 ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool,
752 n * sizeof(ngx_cycle_t *));
753 if (ngx_old_cycles.elts == NULL) {
754 exit(1);
755 }
756 ngx_old_cycles.nelts = 0;
757 ngx_old_cycles.size = sizeof(ngx_cycle_t *);
758 ngx_old_cycles.nalloc = n;
759 ngx_old_cycles.pool = ngx_temp_pool;
760
Igor Sysoev899b44e2005-05-12 14:58:06 +0000761 ngx_cleaner_event.handler = ngx_clean_old_cycles;
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000762 ngx_cleaner_event.log = cycle->log;
763 ngx_cleaner_event.data = &dumb;
764 dumb.fd = (ngx_socket_t) -1;
765 }
766
767 ngx_temp_pool->log = cycle->log;
768
Igor Sysoevc1571722005-03-19 12:38:37 +0000769 old = ngx_array_push(&ngx_old_cycles);
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000770 if (old == NULL) {
771 exit(1);
772 }
773 *old = old_cycle;
774
775 if (!ngx_cleaner_event.timer_set) {
776 ngx_add_timer(&ngx_cleaner_event, 30000);
777 ngx_cleaner_event.timer_set = 1;
778 }
779
780 return cycle;
Igor Sysoevffe71442006-02-08 15:33:12 +0000781
782
783failed:
784
Igor Sysoeve5e4c002007-04-18 11:28:11 +0000785 if (!ngx_is_init_cycle(old_cycle)) {
786 old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
787 ngx_core_module);
788 if (old_ccf->environment) {
789 environ = old_ccf->environment;
790 }
791 }
792
Igor Sysoevffe71442006-02-08 15:33:12 +0000793 /* rollback the new cycle configuration */
794
795 part = &cycle->open_files.part;
796 file = part->elts;
797
798 for (i = 0; /* void */ ; i++) {
799
800 if (i >= part->nelts) {
801 if (part->next == NULL) {
802 break;
803 }
804 part = part->next;
805 file = part->elts;
806 i = 0;
807 }
808
Igor Sysoevc28ff712009-04-23 11:13:12 +0000809 if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
Igor Sysoevffe71442006-02-08 15:33:12 +0000810 continue;
811 }
812
813 if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
814 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
815 ngx_close_file_n " \"%s\" failed",
816 file[i].name.data);
817 }
818 }
819
820 if (ngx_test_config) {
821 ngx_destroy_cycle_pools(&conf);
822 return NULL;
823 }
824
825 ls = cycle->listening.elts;
826 for (i = 0; i < cycle->listening.nelts; i++) {
Maxim Dounin48d96ce2013-09-04 20:48:28 +0400827 if (ls[i].fd == (ngx_socket_t) -1 || !ls[i].open) {
Igor Sysoevffe71442006-02-08 15:33:12 +0000828 continue;
829 }
830
831 if (ngx_close_socket(ls[i].fd) == -1) {
832 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
833 ngx_close_socket_n " %V failed",
834 &ls[i].addr_text);
835 }
836 }
837
838 ngx_destroy_cycle_pools(&conf);
839
840 return NULL;
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000841}
842
843
Igor Sysoev9e580192006-02-01 18:22:15 +0000844static void
845ngx_destroy_cycle_pools(ngx_conf_t *conf)
846{
Igor Sysoev9e580192006-02-01 18:22:15 +0000847 ngx_destroy_pool(conf->temp_pool);
848 ngx_destroy_pool(conf->pool);
849}
850
851
Igor Sysoevc2068d02005-10-19 12:33:58 +0000852static ngx_int_t
Igor Sysoevf7a08d52009-04-18 19:27:28 +0000853ngx_init_zone_pool(ngx_cycle_t *cycle, ngx_shm_zone_t *zn)
854{
855 u_char *file;
856 ngx_slab_pool_t *sp;
857
858 sp = (ngx_slab_pool_t *) zn->shm.addr;
859
Igor Sysoeva1195842009-06-02 13:57:59 +0000860 if (zn->shm.exists) {
861
862 if (sp == sp->addr) {
863 return NGX_OK;
864 }
865
866 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
867 "shared zone \"%V\" has no equal addresses: %p vs %p",
868 &zn->shm.name, sp->addr, sp);
869 return NGX_ERROR;
870 }
871
Igor Sysoevf7a08d52009-04-18 19:27:28 +0000872 sp->end = zn->shm.addr + zn->shm.size;
873 sp->min_shift = 3;
Igor Sysoeva1195842009-06-02 13:57:59 +0000874 sp->addr = zn->shm.addr;
Igor Sysoevf7a08d52009-04-18 19:27:28 +0000875
876#if (NGX_HAVE_ATOMIC_OPS)
877
878 file = NULL;
879
880#else
881
882 file = ngx_pnalloc(cycle->pool, cycle->lock_file.len + zn->shm.name.len);
883 if (file == NULL) {
Igor Sysoevdc5ad522009-04-21 19:38:02 +0000884 return NGX_ERROR;
Igor Sysoevf7a08d52009-04-18 19:27:28 +0000885 }
886
887 (void) ngx_sprintf(file, "%V%V%Z", &cycle->lock_file, &zn->shm.name);
888
889#endif
890
Maxim Dounin91ecc8f2011-11-23 13:55:38 +0000891 if (ngx_shmtx_create(&sp->mutex, &sp->lock, file) != NGX_OK) {
Igor Sysoevdc5ad522009-04-21 19:38:02 +0000892 return NGX_ERROR;
Igor Sysoevf7a08d52009-04-18 19:27:28 +0000893 }
894
895 ngx_slab_init(sp);
896
897 return NGX_OK;
898}
899
900
Igor Sysoevc2068d02005-10-19 12:33:58 +0000901ngx_int_t
Igor Sysoevffe71442006-02-08 15:33:12 +0000902ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
Igor Sysoev076498e2004-04-12 06:10:53 +0000903{
Igor Sysoevb37316d2009-04-08 19:51:30 +0000904 size_t len;
905 ngx_uint_t create;
906 ngx_file_t file;
907 u_char pid[NGX_INT64_LEN + 2];
Igor Sysoev076498e2004-04-12 06:10:53 +0000908
Igor Sysoevbd919992009-04-20 06:08:47 +0000909 if (ngx_process > NGX_PROCESS_MASTER) {
910 return NGX_OK;
911 }
912
Igor Sysoev43f13192004-04-12 16:38:09 +0000913 ngx_memzero(&file, sizeof(ngx_file_t));
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000914
Igor Sysoevffe71442006-02-08 15:33:12 +0000915 file.name = *name;
916 file.log = log;
Igor Sysoev076498e2004-04-12 06:10:53 +0000917
Igor Sysoev2ec2e352009-04-08 19:03:41 +0000918 create = ngx_test_config ? NGX_FILE_CREATE_OR_OPEN : NGX_FILE_TRUNCATE;
Igor Sysoev090849d2004-05-18 20:28:54 +0000919
Igor Sysoev43f13192004-04-12 16:38:09 +0000920 file.fd = ngx_open_file(file.name.data, NGX_FILE_RDWR,
Igor Sysoev2ec2e352009-04-08 19:03:41 +0000921 create, NGX_FILE_DEFAULT_ACCESS);
Igor Sysoev43f13192004-04-12 16:38:09 +0000922
923 if (file.fd == NGX_INVALID_FILE) {
Igor Sysoevffe71442006-02-08 15:33:12 +0000924 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
Igor Sysoev43f13192004-04-12 16:38:09 +0000925 ngx_open_file_n " \"%s\" failed", file.name.data);
Igor Sysoev076498e2004-04-12 06:10:53 +0000926 return NGX_ERROR;
927 }
928
Igor Sysoev090849d2004-05-18 20:28:54 +0000929 if (!ngx_test_config) {
Igor Sysoev9ba14ac2006-12-22 20:30:26 +0000930 len = ngx_snprintf(pid, NGX_INT64_LEN + 2, "%P%N", ngx_pid) - pid;
Igor Sysoev1b735832004-11-11 14:07:14 +0000931
Igor Sysoev090849d2004-05-18 20:28:54 +0000932 if (ngx_write_file(&file, pid, len, 0) == NGX_ERROR) {
933 return NGX_ERROR;
934 }
Igor Sysoev076498e2004-04-12 06:10:53 +0000935 }
936
Igor Sysoev43f13192004-04-12 16:38:09 +0000937 if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
Igor Sysoevffe71442006-02-08 15:33:12 +0000938 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
Igor Sysoev43f13192004-04-12 16:38:09 +0000939 ngx_close_file_n " \"%s\" failed", file.name.data);
Igor Sysoev076498e2004-04-12 06:10:53 +0000940 }
941
942 return NGX_OK;
943}
944
945
Igor Sysoevc2068d02005-10-19 12:33:58 +0000946void
947ngx_delete_pidfile(ngx_cycle_t *cycle)
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +0000948{
Igor Sysoev076498e2004-04-12 06:10:53 +0000949 u_char *name;
950 ngx_core_conf_t *ccf;
951
952 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
953
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000954 name = ngx_new_binary ? ccf->oldpid.data : ccf->pid.data;
Igor Sysoev076498e2004-04-12 06:10:53 +0000955
956 if (ngx_delete_file(name) == NGX_FILE_ERROR) {
957 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
958 ngx_delete_file_n " \"%s\" failed", name);
959 }
960}
961
962
Igor Sysoevc8e9f262009-04-21 20:25:49 +0000963ngx_int_t
964ngx_signal_process(ngx_cycle_t *cycle, char *sig)
965{
966 ssize_t n;
967 ngx_int_t pid;
968 ngx_file_t file;
969 ngx_core_conf_t *ccf;
970 u_char buf[NGX_INT64_LEN + 2];
971
972 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "signal process started");
973
974 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
975
Andrey Belovb33a3162012-09-28 13:15:11 +0000976 ngx_memzero(&file, sizeof(ngx_file_t));
977
Igor Sysoevc8e9f262009-04-21 20:25:49 +0000978 file.name = ccf->pid;
979 file.log = cycle->log;
980
981 file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
982 NGX_FILE_OPEN, NGX_FILE_DEFAULT_ACCESS);
983
984 if (file.fd == NGX_INVALID_FILE) {
985 ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
986 ngx_open_file_n " \"%s\" failed", file.name.data);
987 return 1;
988 }
989
990 n = ngx_read_file(&file, buf, NGX_INT64_LEN + 2, 0);
991
992 if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
993 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
994 ngx_close_file_n " \"%s\" failed", file.name.data);
995 }
996
997 if (n == NGX_ERROR) {
998 return 1;
999 }
1000
1001 while (n-- && (buf[n] == CR || buf[n] == LF)) { /* void */ }
1002
1003 pid = ngx_atoi(buf, ++n);
1004
1005 if (pid == NGX_ERROR) {
1006 ngx_log_error(NGX_LOG_ERR, cycle->log, 0,
1007 "invalid PID number \"%*s\" in \"%s\"",
1008 n, buf, file.name.data);
1009 return 1;
1010 }
1011
1012 return ngx_os_signal_process(cycle, sig, pid);
1013
1014}
1015
1016
Igor Sysoevffe71442006-02-08 15:33:12 +00001017static ngx_int_t
1018ngx_test_lockfile(u_char *file, ngx_log_t *log)
1019{
1020#if !(NGX_HAVE_ATOMIC_OPS)
1021 ngx_fd_t fd;
1022
Igor Sysoev8e750112007-02-11 07:49:12 +00001023 fd = ngx_open_file(file, NGX_FILE_RDWR, NGX_FILE_CREATE_OR_OPEN,
1024 NGX_FILE_DEFAULT_ACCESS);
Igor Sysoevffe71442006-02-08 15:33:12 +00001025
1026 if (fd == NGX_INVALID_FILE) {
1027 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
1028 ngx_open_file_n " \"%s\" failed", file);
1029 return NGX_ERROR;
1030 }
1031
1032 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
1033 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
1034 ngx_close_file_n " \"%s\" failed", file);
1035 }
1036
1037 if (ngx_delete_file(file) == NGX_FILE_ERROR) {
1038 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
1039 ngx_delete_file_n " \"%s\" failed", file);
1040 }
1041
1042#endif
1043
1044 return NGX_OK;
1045}
1046
1047
Igor Sysoevc2068d02005-10-19 12:33:58 +00001048void
1049ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001050{
1051 ngx_fd_t fd;
Igor Sysoev10a543a2004-03-16 07:10:12 +00001052 ngx_uint_t i;
Igor Sysoevb9e34412004-09-03 15:50:30 +00001053 ngx_list_part_t *part;
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001054 ngx_open_file_t *file;
1055
Igor Sysoevb9e34412004-09-03 15:50:30 +00001056 part = &cycle->open_files.part;
1057 file = part->elts;
1058
1059 for (i = 0; /* void */ ; i++) {
1060
1061 if (i >= part->nelts) {
1062 if (part->next == NULL) {
1063 break;
1064 }
1065 part = part->next;
Igor Sysoevb145b062005-06-15 18:33:41 +00001066 file = part->elts;
Igor Sysoevb9e34412004-09-03 15:50:30 +00001067 i = 0;
1068 }
1069
Igor Sysoev5ef370d2009-04-27 11:32:33 +00001070 if (file[i].name.len == 0) {
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001071 continue;
1072 }
1073
Valentin Barteneva8ffed52012-12-23 15:36:52 +00001074 if (file[i].flush) {
1075 file[i].flush(&file[i], cycle->log);
Igor Sysoev697d1ae2005-10-27 15:46:13 +00001076 }
1077
Igor Sysoev24c27872009-03-31 13:52:01 +00001078 fd = ngx_open_file(file[i].name.data, NGX_FILE_APPEND,
Igor Sysoevfadc7a72009-03-30 14:51:51 +00001079 NGX_FILE_CREATE_OR_OPEN, NGX_FILE_DEFAULT_ACCESS);
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001080
1081 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
1082 "reopen file \"%s\", old:%d new:%d",
1083 file[i].name.data, file[i].fd, fd);
1084
1085 if (fd == NGX_INVALID_FILE) {
1086 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1087 ngx_open_file_n " \"%s\" failed", file[i].name.data);
1088 continue;
1089 }
1090
Igor Sysoeva2de7b92009-04-08 19:13:28 +00001091#if !(NGX_WIN32)
Igor Sysoev4959ec42005-05-23 12:07:45 +00001092 if (user != (ngx_uid_t) NGX_CONF_UNSET_UINT) {
Igor Sysoev86ef6aa2007-12-10 12:09:51 +00001093 ngx_file_info_t fi;
Igor Sysoev924bd792004-10-11 15:07:03 +00001094
Igor Sysoevef919752009-04-29 19:28:52 +00001095 if (ngx_file_info((const char *) file[i].name.data, &fi)
1096 == NGX_FILE_ERROR)
1097 {
Igor Sysoev924bd792004-10-11 15:07:03 +00001098 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1099 ngx_file_info_n " \"%s\" failed",
1100 file[i].name.data);
1101
1102 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
1103 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1104 ngx_close_file_n " \"%s\" failed",
1105 file[i].name.data);
1106 }
Maxim Dounin60169aa2014-04-30 19:16:40 +04001107
1108 continue;
Igor Sysoev924bd792004-10-11 15:07:03 +00001109 }
1110
Igor Sysoevd43bee82004-11-20 19:52:20 +00001111 if (fi.st_uid != user) {
1112 if (chown((const char *) file[i].name.data, user, -1) == -1) {
1113 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1114 "chown(\"%s\", %d) failed",
1115 file[i].name.data, user);
1116
1117 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
1118 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1119 ngx_close_file_n " \"%s\" failed",
1120 file[i].name.data);
1121 }
Maxim Dounin60169aa2014-04-30 19:16:40 +04001122
1123 continue;
Igor Sysoevd43bee82004-11-20 19:52:20 +00001124 }
1125 }
1126
Igor Sysoev924bd792004-10-11 15:07:03 +00001127 if ((fi.st_mode & (S_IRUSR|S_IWUSR)) != (S_IRUSR|S_IWUSR)) {
1128
1129 fi.st_mode |= (S_IRUSR|S_IWUSR);
1130
1131 if (chmod((const char *) file[i].name.data, fi.st_mode) == -1) {
1132 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
Igor Sysoevd43bee82004-11-20 19:52:20 +00001133 "chmod() \"%s\" failed", file[i].name.data);
Igor Sysoev924bd792004-10-11 15:07:03 +00001134
1135 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
1136 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1137 ngx_close_file_n " \"%s\" failed",
1138 file[i].name.data);
1139 }
Maxim Dounin60169aa2014-04-30 19:16:40 +04001140
1141 continue;
Igor Sysoev924bd792004-10-11 15:07:03 +00001142 }
1143 }
Igor Sysoeva5362982004-03-04 07:04:55 +00001144 }
1145
Igor Sysoev0911f772004-01-14 18:19:42 +00001146 if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
1147 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1148 "fcntl(FD_CLOEXEC) \"%s\" failed",
1149 file[i].name.data);
1150
1151 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
1152 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1153 ngx_close_file_n " \"%s\" failed",
1154 file[i].name.data);
1155 }
1156
1157 continue;
1158 }
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001159#endif
1160
1161 if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
1162 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1163 ngx_close_file_n " \"%s\" failed",
1164 file[i].name.data);
1165 }
1166
1167 file[i].fd = fd;
1168 }
Igor Sysoev25b36fe2004-02-03 16:43:54 +00001169
Vladimir Homutovdd3e13e2013-06-28 17:24:54 +04001170 (void) ngx_log_redirect_stderr(cycle);
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001171}
1172
1173
Igor Sysoev28c7f762007-01-02 23:54:14 +00001174ngx_shm_zone_t *
1175ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, size_t size, void *tag)
1176{
1177 ngx_uint_t i;
1178 ngx_shm_zone_t *shm_zone;
1179 ngx_list_part_t *part;
1180
1181 part = &cf->cycle->shared_memory.part;
1182 shm_zone = part->elts;
1183
1184 for (i = 0; /* void */ ; i++) {
1185
1186 if (i >= part->nelts) {
1187 if (part->next == NULL) {
1188 break;
1189 }
1190 part = part->next;
1191 shm_zone = part->elts;
1192 i = 0;
1193 }
1194
Igor Sysoevc7f876b2009-04-16 19:25:09 +00001195 if (name->len != shm_zone[i].shm.name.len) {
Igor Sysoev28c7f762007-01-02 23:54:14 +00001196 continue;
1197 }
1198
Igor Sysoevc7f876b2009-04-16 19:25:09 +00001199 if (ngx_strncmp(name->data, shm_zone[i].shm.name.data, name->len)
1200 != 0)
1201 {
Igor Sysoev28c7f762007-01-02 23:54:14 +00001202 continue;
1203 }
1204
Igor Sysoev28c7f762007-01-02 23:54:14 +00001205 if (tag != shm_zone[i].tag) {
1206 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoevc7f876b2009-04-16 19:25:09 +00001207 "the shared memory zone \"%V\" is "
1208 "already declared for a different use",
1209 &shm_zone[i].shm.name);
Igor Sysoev28c7f762007-01-02 23:54:14 +00001210 return NULL;
1211 }
1212
Andrey Belov1c421282012-08-01 14:37:08 +00001213 if (size && size != shm_zone[i].shm.size) {
1214 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1215 "the size %uz of shared memory zone \"%V\" "
1216 "conflicts with already declared size %uz",
1217 size, &shm_zone[i].shm.name, shm_zone[i].shm.size);
1218 return NULL;
1219 }
1220
Igor Sysoev28c7f762007-01-02 23:54:14 +00001221 return &shm_zone[i];
1222 }
1223
1224 shm_zone = ngx_list_push(&cf->cycle->shared_memory);
1225
1226 if (shm_zone == NULL) {
1227 return NULL;
1228 }
1229
1230 shm_zone->data = NULL;
1231 shm_zone->shm.log = cf->cycle->log;
1232 shm_zone->shm.size = size;
Igor Sysoevc7f876b2009-04-16 19:25:09 +00001233 shm_zone->shm.name = *name;
Igor Sysoevf7a08d52009-04-18 19:27:28 +00001234 shm_zone->shm.exists = 0;
Igor Sysoev28c7f762007-01-02 23:54:14 +00001235 shm_zone->init = NULL;
Igor Sysoev28c7f762007-01-02 23:54:14 +00001236 shm_zone->tag = tag;
1237
1238 return shm_zone;
1239}
1240
1241
Igor Sysoevc2068d02005-10-19 12:33:58 +00001242static void
1243ngx_clean_old_cycles(ngx_event_t *ev)
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001244{
Igor Sysoev10a543a2004-03-16 07:10:12 +00001245 ngx_uint_t i, n, found, live;
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001246 ngx_log_t *log;
1247 ngx_cycle_t **cycle;
1248
1249 log = ngx_cycle->log;
1250 ngx_temp_pool->log = log;
1251
Igor Sysoev54498db2004-02-11 17:08:49 +00001252 ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "clean old cycles");
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001253
1254 live = 0;
1255
1256 cycle = ngx_old_cycles.elts;
1257 for (i = 0; i < ngx_old_cycles.nelts; i++) {
1258
1259 if (cycle[i] == NULL) {
1260 continue;
1261 }
1262
1263 found = 0;
1264
1265 for (n = 0; n < cycle[i]->connection_n; n++) {
Igor Sysoev78452232005-10-12 13:50:36 +00001266 if (cycle[i]->connections[n].fd != (ngx_socket_t) -1) {
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001267 found = 1;
Igor Sysoev54498db2004-02-11 17:08:49 +00001268
1269 ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "live fd:%d", n);
1270
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001271 break;
1272 }
1273 }
1274
1275 if (found) {
1276 live = 1;
1277 continue;
1278 }
1279
Igor Sysoev54498db2004-02-11 17:08:49 +00001280 ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "clean old cycle: %d", i);
1281
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001282 ngx_destroy_pool(cycle[i]->pool);
1283 cycle[i] = NULL;
1284 }
1285
Igor Sysoev54498db2004-02-11 17:08:49 +00001286 ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "old cycles status: %d", live);
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001287
1288 if (live) {
Igor Sysoev3c3ca172004-01-05 20:55:48 +00001289 ngx_add_timer(ev, 30000);
1290
1291 } else {
1292 ngx_destroy_pool(ngx_temp_pool);
1293 ngx_temp_pool = NULL;
1294 ngx_old_cycles.nelts = 0;
1295 }
1296}