~ubuntu-branches/debian/squeeze/nginx/squeeze

« back to all changes in this revision

Viewing changes to .pc/fix_reloading_ipv6.diff/src/core/ngx_cycle.c

  • Committer: Bazaar Package Importer
  • Author(s): Kartik Mistry, Kartik Mistry
  • Date: 2010-04-14 11:36:48 UTC
  • Revision ID: james.westby@ubuntu.com-20100414113648-5lbclc1wb5obqlyf
Tags: 0.7.65-5
[Kartik Mistry]
* debian/patches/fix_reloading_ipv6.diff:
  + Added patch to fix reloading with IPv6 addresses, Thanks to
    Matthias-Christian Ott <ott@mirix.org> for patch (Closes: #577456)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * Copyright (C) Igor Sysoev
 
4
 */
 
5
 
 
6
 
 
7
#include <ngx_config.h>
 
8
#include <ngx_core.h>
 
9
#include <ngx_event.h>
 
10
 
 
11
 
 
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);
 
18
 
 
19
 
 
20
volatile ngx_cycle_t  *ngx_cycle;
 
21
ngx_array_t            ngx_old_cycles;
 
22
 
 
23
static ngx_pool_t     *ngx_temp_pool;
 
24
static ngx_event_t     ngx_cleaner_event;
 
25
 
 
26
ngx_uint_t             ngx_test_config;
 
27
 
 
28
#if (NGX_THREADS)
 
29
ngx_tls_key_t          ngx_core_tls_key;
 
30
#endif
 
31
 
 
32
 
 
33
/* STUB NAME */
 
34
static ngx_connection_t  dumb;
 
35
/* STUB */
 
36
 
 
37
static ngx_str_t  error_log = ngx_string(NGX_ERROR_LOG_PATH);
 
38
 
 
39
 
 
40
ngx_cycle_t *
 
41
ngx_init_cycle(ngx_cycle_t *old_cycle)
 
42
{
 
43
    void                *rv;
 
44
    char               **senv, **env;
 
45
    ngx_uint_t           i, n;
 
46
    ngx_log_t           *log;
 
47
    ngx_time_t          *tp;
 
48
    ngx_conf_t           conf;
 
49
    ngx_pool_t          *pool;
 
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];
 
58
 
 
59
    ngx_timezone_update();
 
60
 
 
61
    /* force localtime update with a new timezone */
 
62
 
 
63
    tp = ngx_timeofday();
 
64
    tp->sec = 0;
 
65
 
 
66
    ngx_time_update(0, 0);
 
67
 
 
68
 
 
69
    log = old_cycle->log;
 
70
 
 
71
    pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
 
72
    if (pool == NULL) {
 
73
        return NULL;
 
74
    }
 
75
    pool->log = log;
 
76
 
 
77
    cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));
 
78
    if (cycle == NULL) {
 
79
        ngx_destroy_pool(pool);
 
80
        return NULL;
 
81
    }
 
82
 
 
83
    cycle->pool = pool;
 
84
    cycle->log = log;
 
85
    cycle->new_log.log_level = NGX_LOG_ERR;
 
86
    cycle->old_cycle = old_cycle;
 
87
 
 
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);
 
92
        return NULL;
 
93
    }
 
94
 
 
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);
 
99
        return NULL;
 
100
    }
 
101
 
 
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);
 
106
        return NULL;
 
107
    }
 
108
    ngx_cpystrn(cycle->conf_file.data, old_cycle->conf_file.data,
 
109
                old_cycle->conf_file.len + 1);
 
110
 
 
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);
 
115
        return NULL;
 
116
    }
 
117
 
 
118
 
 
119
    n = old_cycle->pathes.nelts ? old_cycle->pathes.nelts : 10;
 
120
 
 
121
    cycle->pathes.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *));
 
122
    if (cycle->pathes.elts == NULL) {
 
123
        ngx_destroy_pool(pool);
 
124
        return NULL;
 
125
    }
 
126
 
 
127
    cycle->pathes.nelts = 0;
 
128
    cycle->pathes.size = sizeof(ngx_path_t *);
 
129
    cycle->pathes.nalloc = n;
 
130
    cycle->pathes.pool = pool;
 
131
 
 
132
 
 
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) {
 
136
            n += part->nelts;
 
137
        }
 
138
 
 
139
    } else {
 
140
        n = 20;
 
141
    }
 
142
 
 
143
    if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t))
 
144
        != NGX_OK)
 
145
    {
 
146
        ngx_destroy_pool(pool);
 
147
        return NULL;
 
148
    }
 
149
 
 
150
 
 
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)
 
154
        {
 
155
            n += part->nelts;
 
156
        }
 
157
 
 
158
    } else {
 
159
        n = 1;
 
160
    }
 
161
 
 
162
    if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t))
 
163
        != NGX_OK)
 
164
    {
 
165
        ngx_destroy_pool(pool);
 
166
        return NULL;
 
167
    }
 
168
 
 
169
    n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;
 
170
 
 
171
    cycle->listening.elts = ngx_pcalloc(pool, n * sizeof(ngx_listening_t));
 
172
    if (cycle->listening.elts == NULL) {
 
173
        ngx_destroy_pool(pool);
 
174
        return NULL;
 
175
    }
 
176
 
 
177
    cycle->listening.nelts = 0;
 
178
    cycle->listening.size = sizeof(ngx_listening_t);
 
179
    cycle->listening.nalloc = n;
 
180
    cycle->listening.pool = pool;
 
181
 
 
182
 
 
183
    cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
 
184
    if (cycle->conf_ctx == NULL) {
 
185
        ngx_destroy_pool(pool);
 
186
        return NULL;
 
187
    }
 
188
 
 
189
 
 
190
    if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) {
 
191
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "gethostname() failed");
 
192
        ngx_destroy_pool(pool);
 
193
        return NULL;
 
194
    }
 
195
 
 
196
    /* on Linux gethostname() silently truncates name that does not fit */
 
197
 
 
198
    hostname[NGX_MAXHOSTNAMELEN - 1] = '\0';
 
199
    cycle->hostname.len = ngx_strlen(hostname);
 
200
 
 
201
    cycle->hostname.data = ngx_pnalloc(pool, cycle->hostname.len);
 
202
    if (cycle->hostname.data == NULL) {
 
203
        ngx_destroy_pool(pool);
 
204
        return NULL;
 
205
    }
 
206
 
 
207
    ngx_memcpy(cycle->hostname.data, hostname, cycle->hostname.len);
 
208
 
 
209
 
 
210
    for (i = 0; ngx_modules[i]; i++) {
 
211
        if (ngx_modules[i]->type != NGX_CORE_MODULE) {
 
212
            continue;
 
213
        }
 
214
 
 
215
        module = ngx_modules[i]->ctx;
 
216
 
 
217
        if (module->create_conf) {
 
218
            rv = module->create_conf(cycle);
 
219
            if (rv == NULL) {
 
220
                ngx_destroy_pool(pool);
 
221
                return NULL;
 
222
            }
 
223
            cycle->conf_ctx[ngx_modules[i]->index] = rv;
 
224
        }
 
225
    }
 
226
 
 
227
 
 
228
    senv = environ;
 
229
 
 
230
 
 
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);
 
236
        return NULL;
 
237
    }
 
238
 
 
239
    conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
 
240
    if (conf.temp_pool == NULL) {
 
241
        ngx_destroy_pool(pool);
 
242
        return NULL;
 
243
    }
 
244
 
 
245
 
 
246
    conf.ctx = cycle->conf_ctx;
 
247
    conf.cycle = cycle;
 
248
    conf.pool = pool;
 
249
    conf.log = log;
 
250
    conf.module_type = NGX_CORE_MODULE;
 
251
    conf.cmd_type = NGX_MAIN_CONF;
 
252
 
 
253
#if 0
 
254
    log->log_level = NGX_LOG_DEBUG_ALL;
 
255
#endif
 
256
 
 
257
    if (ngx_conf_param(&conf) != NGX_CONF_OK) {
 
258
        environ = senv;
 
259
        ngx_destroy_cycle_pools(&conf);
 
260
        return NULL;
 
261
    }
 
262
 
 
263
    if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
 
264
        environ = senv;
 
265
        ngx_destroy_cycle_pools(&conf);
 
266
        return NULL;
 
267
    }
 
268
 
 
269
    if (ngx_test_config) {
 
270
        ngx_log_stderr(0, "the configuration file %s syntax is ok",
 
271
                       cycle->conf_file.data);
 
272
    }
 
273
 
 
274
    for (i = 0; ngx_modules[i]; i++) {
 
275
        if (ngx_modules[i]->type != NGX_CORE_MODULE) {
 
276
            continue;
 
277
        }
 
278
 
 
279
        module = ngx_modules[i]->ctx;
 
280
 
 
281
        if (module->init_conf) {
 
282
            if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index])
 
283
                == NGX_CONF_ERROR)
 
284
            {
 
285
                environ = senv;
 
286
                ngx_destroy_cycle_pools(&conf);
 
287
                return NULL;
 
288
            }
 
289
        }
 
290
    }
 
291
 
 
292
    if (ngx_process == NGX_PROCESS_SIGNALLER) {
 
293
        return cycle;
 
294
    }
 
295
 
 
296
    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
 
297
 
 
298
    if (ngx_test_config) {
 
299
 
 
300
        if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
 
301
            goto failed;
 
302
        }
 
303
 
 
304
    } else if (!ngx_is_init_cycle(old_cycle)) {
 
305
 
 
306
        /*
 
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
 
309
         */
 
310
 
 
311
        old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
 
312
                                                   ngx_core_module);
 
313
        if (ccf->pid.len != old_ccf->pid.len
 
314
            || ngx_strcmp(ccf->pid.data, old_ccf->pid.data) != 0)
 
315
        {
 
316
            /* new pid file name */
 
317
 
 
318
            if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
 
319
                goto failed;
 
320
            }
 
321
 
 
322
            ngx_delete_pidfile(old_cycle);
 
323
        }
 
324
    }
 
325
 
 
326
 
 
327
    if (ngx_test_lockfile(cycle->lock_file.data, log) != NGX_OK) {
 
328
        goto failed;
 
329
    }
 
330
 
 
331
 
 
332
    if (ngx_create_pathes(cycle, ccf->user) != NGX_OK) {
 
333
        goto failed;
 
334
    }
 
335
 
 
336
 
 
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) {
 
340
            goto failed;
 
341
        }
 
342
    }
 
343
 
 
344
    /* open the new files */
 
345
 
 
346
    part = &cycle->open_files.part;
 
347
    file = part->elts;
 
348
 
 
349
    for (i = 0; /* void */ ; i++) {
 
350
 
 
351
        if (i >= part->nelts) {
 
352
            if (part->next == NULL) {
 
353
                break;
 
354
            }
 
355
            part = part->next;
 
356
            file = part->elts;
 
357
            i = 0;
 
358
        }
 
359
 
 
360
        if (file[i].name.len == 0) {
 
361
            continue;
 
362
        }
 
363
 
 
364
        file[i].fd = ngx_open_file(file[i].name.data,
 
365
                                   NGX_FILE_APPEND,
 
366
                                   NGX_FILE_CREATE_OR_OPEN,
 
367
                                   NGX_FILE_DEFAULT_ACCESS);
 
368
 
 
369
        ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, 0,
 
370
                       "log: %p %d \"%s\"",
 
371
                       &file[i], file[i].fd, file[i].name.data);
 
372
 
 
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",
 
376
                          file[i].name.data);
 
377
            goto failed;
 
378
        }
 
379
 
 
380
#if !(NGX_WIN32)
 
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",
 
384
                          file[i].name.data);
 
385
            goto failed;
 
386
        }
 
387
#endif
 
388
    }
 
389
 
 
390
    cycle->log = &cycle->new_log;
 
391
    pool->log = &cycle->new_log;
 
392
 
 
393
 
 
394
    /* create shared memory */
 
395
 
 
396
    part = &cycle->shared_memory.part;
 
397
    shm_zone = part->elts;
 
398
 
 
399
    for (i = 0; /* void */ ; i++) {
 
400
 
 
401
        if (i >= part->nelts) {
 
402
            if (part->next == NULL) {
 
403
                break;
 
404
            }
 
405
            part = part->next;
 
406
            shm_zone = part->elts;
 
407
            i = 0;
 
408
        }
 
409
 
 
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);
 
414
            goto failed;
 
415
        }
 
416
 
 
417
        if (shm_zone[i].init == NULL) {
 
418
            /* unused shared zone */
 
419
            continue;
 
420
        }
 
421
 
 
422
        shm_zone[i].shm.log = cycle->log;
 
423
 
 
424
        opart = &old_cycle->shared_memory.part;
 
425
        oshm_zone = opart->elts;
 
426
 
 
427
        for (n = 0; /* void */ ; n++) {
 
428
 
 
429
            if (n >= opart->nelts) {
 
430
                if (opart->next == NULL) {
 
431
                    break;
 
432
                }
 
433
                opart = opart->next;
 
434
                oshm_zone = opart->elts;
 
435
                n = 0;
 
436
            }
 
437
 
 
438
            if (shm_zone[i].shm.name.len != oshm_zone[n].shm.name.len) {
 
439
                continue;
 
440
            }
 
441
 
 
442
            if (ngx_strncmp(shm_zone[i].shm.name.data,
 
443
                            oshm_zone[n].shm.name.data,
 
444
                            shm_zone[i].shm.name.len)
 
445
                != 0)
 
446
            {
 
447
                continue;
 
448
            }
 
449
 
 
450
            if (shm_zone[i].shm.size == oshm_zone[n].shm.size) {
 
451
                shm_zone[i].shm.addr = oshm_zone[n].shm.addr;
 
452
 
 
453
                if (shm_zone[i].init(&shm_zone[i], oshm_zone[n].data)
 
454
                    != NGX_OK)
 
455
                {
 
456
                    goto failed;
 
457
                }
 
458
 
 
459
                goto shm_zone_found;
 
460
            }
 
461
 
 
462
            ngx_shm_free(&oshm_zone[n].shm);
 
463
 
 
464
            break;
 
465
        }
 
466
 
 
467
        if (ngx_shm_alloc(&shm_zone[i].shm) != NGX_OK) {
 
468
            goto failed;
 
469
        }
 
470
 
 
471
        if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) {
 
472
            goto failed;
 
473
        }
 
474
 
 
475
        if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) {
 
476
            goto failed;
 
477
        }
 
478
 
 
479
    shm_zone_found:
 
480
 
 
481
        continue;
 
482
    }
 
483
 
 
484
 
 
485
    /* handle the listening sockets */
 
486
 
 
487
    if (old_cycle->listening.nelts) {
 
488
        ls = old_cycle->listening.elts;
 
489
        for (i = 0; i < old_cycle->listening.nelts; i++) {
 
490
            ls[i].remain = 0;
 
491
        }
 
492
 
 
493
        nls = cycle->listening.elts;
 
494
        for (n = 0; n < cycle->listening.nelts; n++) {
 
495
 
 
496
            for (i = 0; i < old_cycle->listening.nelts; i++) {
 
497
                if (ls[i].ignore) {
 
498
                    continue;
 
499
                }
 
500
 
 
501
                if (ngx_cmp_sockaddr(nls[n].sockaddr, ls[i].sockaddr) == NGX_OK)
 
502
                {
 
503
                    nls[n].fd = ls[i].fd;
 
504
                    nls[n].previous = &ls[i];
 
505
                    ls[i].remain = 1;
 
506
 
 
507
                    if (ls[n].backlog != nls[i].backlog) {
 
508
                        nls[n].listen = 1;
 
509
                    }
 
510
 
 
511
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
 
512
 
 
513
                    /*
 
514
                     * FreeBSD, except the most recent versions,
 
515
                     * could not remove accept filter
 
516
                     */
 
517
                    nls[n].deferred_accept = ls[i].deferred_accept;
 
518
 
 
519
                    if (ls[i].accept_filter && nls[n].accept_filter) {
 
520
                        if (ngx_strcmp(ls[i].accept_filter,
 
521
                                       nls[n].accept_filter)
 
522
                            != 0)
 
523
                        {
 
524
                            nls[n].delete_deferred = 1;
 
525
                            nls[n].add_deferred = 1;
 
526
                        }
 
527
 
 
528
                    } else if (ls[i].accept_filter) {
 
529
                        nls[n].delete_deferred = 1;
 
530
 
 
531
                    } else if (nls[n].accept_filter) {
 
532
                        nls[n].add_deferred = 1;
 
533
                    }
 
534
#endif
 
535
 
 
536
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
 
537
 
 
538
                    if (ls[n].deferred_accept && !nls[n].deferred_accept) {
 
539
                        nls[n].delete_deferred = 1;
 
540
 
 
541
                    } else if (ls[i].deferred_accept != nls[n].deferred_accept)
 
542
                    {
 
543
                        nls[n].add_deferred = 1;
 
544
                    }
 
545
#endif
 
546
                    break;
 
547
                }
 
548
            }
 
549
 
 
550
            if (nls[n].fd == -1) {
 
551
                nls[n].open = 1;
 
552
            }
 
553
        }
 
554
 
 
555
    } else {
 
556
        ls = cycle->listening.elts;
 
557
        for (i = 0; i < cycle->listening.nelts; i++) {
 
558
            ls[i].open = 1;
 
559
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
 
560
            if (ls[i].accept_filter) {
 
561
                ls[i].add_deferred = 1;
 
562
            }
 
563
#endif
 
564
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
 
565
            if (ls[i].deferred_accept) {
 
566
                ls[i].add_deferred = 1;
 
567
            }
 
568
#endif
 
569
        }
 
570
    }
 
571
 
 
572
    if (ngx_open_listening_sockets(cycle) != NGX_OK) {
 
573
        goto failed;
 
574
    }
 
575
 
 
576
    if (!ngx_test_config) {
 
577
        ngx_configure_listening_sockets(cycle);
 
578
    }
 
579
 
 
580
 
 
581
    /* commit the new cycle configuration */
 
582
 
 
583
    if (!ngx_use_stderr && cycle->log->file->fd != ngx_stderr) {
 
584
 
 
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");
 
588
        }
 
589
    }
 
590
 
 
591
    pool->log = cycle->log;
 
592
 
 
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) {
 
596
                /* fatal */
 
597
                exit(1);
 
598
            }
 
599
        }
 
600
    }
 
601
 
 
602
 
 
603
    /* close and delete stuff that lefts from an old cycle */
 
604
 
 
605
    /* free the unnecessary shared memory */
 
606
 
 
607
    opart = &old_cycle->shared_memory.part;
 
608
    oshm_zone = opart->elts;
 
609
 
 
610
    for (i = 0; /* void */ ; i++) {
 
611
 
 
612
        if (i >= opart->nelts) {
 
613
            if (opart->next == NULL) {
 
614
                goto old_shm_zone_done;
 
615
            }
 
616
            opart = opart->next;
 
617
            oshm_zone = opart->elts;
 
618
            i = 0;
 
619
        }
 
620
 
 
621
        part = &cycle->shared_memory.part;
 
622
        shm_zone = part->elts;
 
623
 
 
624
        for (n = 0; /* void */ ; n++) {
 
625
 
 
626
            if (n >= part->nelts) {
 
627
                if (part->next == NULL) {
 
628
                    break;
 
629
                }
 
630
                part = part->next;
 
631
                shm_zone = part->elts;
 
632
                n = 0;
 
633
            }
 
634
 
 
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)
 
639
                == 0)
 
640
            {
 
641
                goto live_shm_zone;
 
642
            }
 
643
        }
 
644
 
 
645
        ngx_shm_free(&oshm_zone[i].shm);
 
646
 
 
647
    live_shm_zone:
 
648
 
 
649
        continue;
 
650
    }
 
651
 
 
652
old_shm_zone_done:
 
653
 
 
654
 
 
655
    /* close the unnecessary listening sockets */
 
656
 
 
657
    ls = old_cycle->listening.elts;
 
658
    for (i = 0; i < old_cycle->listening.nelts; i++) {
 
659
 
 
660
        if (ls[i].remain || ls[i].fd == -1) {
 
661
            continue;
 
662
        }
 
663
 
 
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",
 
667
                          &ls[i].addr_text);
 
668
        }
 
669
    }
 
670
 
 
671
 
 
672
    /* close the unnecessary open files */
 
673
 
 
674
    part = &old_cycle->open_files.part;
 
675
    file = part->elts;
 
676
 
 
677
    for (i = 0; /* void */ ; i++) {
 
678
 
 
679
        if (i >= part->nelts) {
 
680
            if (part->next == NULL) {
 
681
                break;
 
682
            }
 
683
            part = part->next;
 
684
            file = part->elts;
 
685
            i = 0;
 
686
        }
 
687
 
 
688
        if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
 
689
            continue;
 
690
        }
 
691
 
 
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",
 
695
                          file[i].name.data);
 
696
        }
 
697
    }
 
698
 
 
699
    ngx_destroy_pool(conf.temp_pool);
 
700
 
 
701
    if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) {
 
702
 
 
703
        /*
 
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.
 
707
         */
 
708
 
 
709
        env = environ;
 
710
        environ = senv;
 
711
 
 
712
        ngx_destroy_pool(old_cycle->pool);
 
713
        cycle->old_cycle = NULL;
 
714
 
 
715
        environ = env;
 
716
 
 
717
        return cycle;
 
718
    }
 
719
 
 
720
 
 
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");
 
726
            exit(1);
 
727
        }
 
728
 
 
729
        n = 10;
 
730
        ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool,
 
731
                                          n * sizeof(ngx_cycle_t *));
 
732
        if (ngx_old_cycles.elts == NULL) {
 
733
            exit(1);
 
734
        }
 
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;
 
739
 
 
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;
 
744
    }
 
745
 
 
746
    ngx_temp_pool->log = cycle->log;
 
747
 
 
748
    old = ngx_array_push(&ngx_old_cycles);
 
749
    if (old == NULL) {
 
750
        exit(1);
 
751
    }
 
752
    *old = old_cycle;
 
753
 
 
754
    if (!ngx_cleaner_event.timer_set) {
 
755
        ngx_add_timer(&ngx_cleaner_event, 30000);
 
756
        ngx_cleaner_event.timer_set = 1;
 
757
    }
 
758
 
 
759
    return cycle;
 
760
 
 
761
 
 
762
failed:
 
763
 
 
764
    if (!ngx_is_init_cycle(old_cycle)) {
 
765
        old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
 
766
                                                   ngx_core_module);
 
767
        if (old_ccf->environment) {
 
768
            environ = old_ccf->environment;
 
769
        }
 
770
    }
 
771
 
 
772
    /* rollback the new cycle configuration */
 
773
 
 
774
    part = &cycle->open_files.part;
 
775
    file = part->elts;
 
776
 
 
777
    for (i = 0; /* void */ ; i++) {
 
778
 
 
779
        if (i >= part->nelts) {
 
780
            if (part->next == NULL) {
 
781
                break;
 
782
            }
 
783
            part = part->next;
 
784
            file = part->elts;
 
785
            i = 0;
 
786
        }
 
787
 
 
788
        if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
 
789
            continue;
 
790
        }
 
791
 
 
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",
 
795
                          file[i].name.data);
 
796
        }
 
797
    }
 
798
 
 
799
    if (ngx_test_config) {
 
800
        ngx_destroy_cycle_pools(&conf);
 
801
        return NULL;
 
802
    }
 
803
 
 
804
    ls = cycle->listening.elts;
 
805
    for (i = 0; i < cycle->listening.nelts; i++) {
 
806
        if (ls[i].fd == -1 || !ls[i].open) {
 
807
            continue;
 
808
        }
 
809
 
 
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",
 
813
                          &ls[i].addr_text);
 
814
        }
 
815
    }
 
816
 
 
817
    ngx_destroy_cycle_pools(&conf);
 
818
 
 
819
    return NULL;
 
820
}
 
821
 
 
822
 
 
823
static void
 
824
ngx_destroy_cycle_pools(ngx_conf_t *conf)
 
825
{
 
826
    ngx_destroy_pool(conf->temp_pool);
 
827
    ngx_destroy_pool(conf->pool);
 
828
}
 
829
 
 
830
 
 
831
static ngx_int_t
 
832
ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2)
 
833
{
 
834
    struct sockaddr_in   *sin1, *sin2;
 
835
#if (NGX_HAVE_INET6)
 
836
    struct sockaddr_in6  *sin61, *sin62;
 
837
#endif
 
838
 
 
839
    if (sa1->sa_family != sa2->sa_family) {
 
840
        return NGX_DECLINED;
 
841
    }
 
842
 
 
843
    switch (sa1->sa_family) {
 
844
 
 
845
#if (NGX_HAVE_INET6)
 
846
    case AF_INET6:
 
847
        sin61 = (struct sockaddr_in6 *) sa1;
 
848
        sin62 = (struct sockaddr_in6 *) sa2;
 
849
 
 
850
        if (sin61->sin6_port != sin61->sin6_port) {
 
851
            return NGX_DECLINED;
 
852
        }
 
853
 
 
854
        if (ngx_memcmp(&sin61->sin6_addr, &sin62->sin6_addr, 16) != 0) {
 
855
            return NGX_DECLINED;
 
856
        }
 
857
 
 
858
        break;
 
859
#endif
 
860
 
 
861
    default: /* AF_INET */
 
862
 
 
863
        sin1 = (struct sockaddr_in *) sa1;
 
864
        sin2 = (struct sockaddr_in *) sa2;
 
865
 
 
866
        if (sin1->sin_port != sin2->sin_port) {
 
867
            return NGX_DECLINED;
 
868
        }
 
869
 
 
870
        if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
 
871
            return NGX_DECLINED;
 
872
        }
 
873
 
 
874
        break;
 
875
    }
 
876
 
 
877
    return NGX_OK;
 
878
}
 
879
 
 
880
 
 
881
static ngx_int_t
 
882
ngx_init_zone_pool(ngx_cycle_t *cycle, ngx_shm_zone_t *zn)
 
883
{
 
884
    u_char           *file;
 
885
    ngx_slab_pool_t  *sp;
 
886
 
 
887
    sp = (ngx_slab_pool_t *) zn->shm.addr;
 
888
 
 
889
    if (zn->shm.exists) {
 
890
 
 
891
        if (sp == sp->addr) {
 
892
            return NGX_OK;
 
893
        }
 
894
 
 
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);
 
898
        return NGX_ERROR;
 
899
    }
 
900
 
 
901
    sp->end = zn->shm.addr + zn->shm.size;
 
902
    sp->min_shift = 3;
 
903
    sp->addr = zn->shm.addr;
 
904
 
 
905
#if (NGX_HAVE_ATOMIC_OPS)
 
906
 
 
907
    file = NULL;
 
908
 
 
909
#else
 
910
 
 
911
    file = ngx_pnalloc(cycle->pool, cycle->lock_file.len + zn->shm.name.len);
 
912
    if (file == NULL) {
 
913
        return NGX_ERROR;
 
914
    }
 
915
 
 
916
    (void) ngx_sprintf(file, "%V%V%Z", &cycle->lock_file, &zn->shm.name);
 
917
 
 
918
#endif
 
919
 
 
920
    if (ngx_shmtx_create(&sp->mutex, (void *) &sp->lock, file) != NGX_OK) {
 
921
        return NGX_ERROR;
 
922
    }
 
923
 
 
924
    ngx_slab_init(sp);
 
925
 
 
926
    return NGX_OK;
 
927
}
 
928
 
 
929
 
 
930
ngx_int_t
 
931
ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
 
932
{
 
933
    size_t      len;
 
934
    ngx_uint_t  create;
 
935
    ngx_file_t  file;
 
936
    u_char      pid[NGX_INT64_LEN + 2];
 
937
 
 
938
    if (ngx_process > NGX_PROCESS_MASTER) {
 
939
        return NGX_OK;
 
940
    }
 
941
 
 
942
    ngx_memzero(&file, sizeof(ngx_file_t));
 
943
 
 
944
    file.name = *name;
 
945
    file.log = log;
 
946
 
 
947
    create = ngx_test_config ? NGX_FILE_CREATE_OR_OPEN : NGX_FILE_TRUNCATE;
 
948
 
 
949
    file.fd = ngx_open_file(file.name.data, NGX_FILE_RDWR,
 
950
                            create, NGX_FILE_DEFAULT_ACCESS);
 
951
 
 
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);
 
955
        return NGX_ERROR;
 
956
    }
 
957
 
 
958
    if (!ngx_test_config) {
 
959
        len = ngx_snprintf(pid, NGX_INT64_LEN + 2, "%P%N", ngx_pid) - pid;
 
960
 
 
961
        if (ngx_write_file(&file, pid, len, 0) == NGX_ERROR) {
 
962
            return NGX_ERROR;
 
963
        }
 
964
    }
 
965
 
 
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);
 
969
    }
 
970
 
 
971
    return NGX_OK;
 
972
}
 
973
 
 
974
 
 
975
void
 
976
ngx_delete_pidfile(ngx_cycle_t *cycle)
 
977
{
 
978
    u_char           *name;
 
979
    ngx_core_conf_t  *ccf;
 
980
 
 
981
    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
 
982
 
 
983
    name = ngx_new_binary ? ccf->oldpid.data : ccf->pid.data;
 
984
 
 
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);
 
988
    }
 
989
}
 
990
 
 
991
 
 
992
ngx_int_t
 
993
ngx_signal_process(ngx_cycle_t *cycle, char *sig)
 
994
{
 
995
    ssize_t           n;
 
996
    ngx_int_t         pid;
 
997
    ngx_file_t        file;
 
998
    ngx_core_conf_t  *ccf;
 
999
    u_char            buf[NGX_INT64_LEN + 2];
 
1000
 
 
1001
    ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "signal process started");
 
1002
 
 
1003
    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
 
1004
 
 
1005
    file.name = ccf->pid;
 
1006
    file.log = cycle->log;
 
1007
 
 
1008
    file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
 
1009
                            NGX_FILE_OPEN, NGX_FILE_DEFAULT_ACCESS);
 
1010
 
 
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);
 
1014
        return 1;
 
1015
    }
 
1016
 
 
1017
    n = ngx_read_file(&file, buf, NGX_INT64_LEN + 2, 0);
 
1018
 
 
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);
 
1022
    }
 
1023
 
 
1024
    if (n == NGX_ERROR) {
 
1025
        return 1;
 
1026
    }
 
1027
 
 
1028
    while (n-- && (buf[n] == CR || buf[n] == LF)) { /* void */ }
 
1029
 
 
1030
    pid = ngx_atoi(buf, ++n);
 
1031
 
 
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);
 
1036
        return 1;
 
1037
    }
 
1038
 
 
1039
    return ngx_os_signal_process(cycle, sig, pid);
 
1040
 
 
1041
}
 
1042
 
 
1043
 
 
1044
static ngx_int_t
 
1045
ngx_test_lockfile(u_char *file, ngx_log_t *log)
 
1046
{
 
1047
#if !(NGX_HAVE_ATOMIC_OPS)
 
1048
    ngx_fd_t  fd;
 
1049
 
 
1050
    fd = ngx_open_file(file, NGX_FILE_RDWR, NGX_FILE_CREATE_OR_OPEN,
 
1051
                       NGX_FILE_DEFAULT_ACCESS);
 
1052
 
 
1053
    if (fd == NGX_INVALID_FILE) {
 
1054
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
 
1055
                      ngx_open_file_n " \"%s\" failed", file);
 
1056
        return NGX_ERROR;
 
1057
    }
 
1058
 
 
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);
 
1062
    }
 
1063
 
 
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);
 
1067
    }
 
1068
 
 
1069
#endif
 
1070
 
 
1071
    return NGX_OK;
 
1072
}
 
1073
 
 
1074
 
 
1075
void
 
1076
ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
 
1077
{
 
1078
    ssize_t           n, len;
 
1079
    ngx_fd_t          fd;
 
1080
    ngx_uint_t        i;
 
1081
    ngx_list_part_t  *part;
 
1082
    ngx_open_file_t  *file;
 
1083
 
 
1084
    part = &cycle->open_files.part;
 
1085
    file = part->elts;
 
1086
 
 
1087
    for (i = 0; /* void */ ; i++) {
 
1088
 
 
1089
        if (i >= part->nelts) {
 
1090
            if (part->next == NULL) {
 
1091
                break;
 
1092
            }
 
1093
            part = part->next;
 
1094
            file = part->elts;
 
1095
            i = 0;
 
1096
        }
 
1097
 
 
1098
        if (file[i].name.len == 0) {
 
1099
            continue;
 
1100
        }
 
1101
 
 
1102
        len = file[i].pos - file[i].buffer;
 
1103
 
 
1104
        if (file[i].buffer && len != 0) {
 
1105
 
 
1106
            n = ngx_write_fd(file[i].fd, file[i].buffer, len);
 
1107
 
 
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",
 
1111
                              file[i].name.data);
 
1112
 
 
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);
 
1117
            }
 
1118
 
 
1119
            file[i].pos = file[i].buffer;
 
1120
        }
 
1121
 
 
1122
        fd = ngx_open_file(file[i].name.data, NGX_FILE_APPEND,
 
1123
                           NGX_FILE_CREATE_OR_OPEN, NGX_FILE_DEFAULT_ACCESS);
 
1124
 
 
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);
 
1128
 
 
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);
 
1132
            continue;
 
1133
        }
 
1134
 
 
1135
#if !(NGX_WIN32)
 
1136
        if (user != (ngx_uid_t) NGX_CONF_UNSET_UINT) {
 
1137
            ngx_file_info_t  fi;
 
1138
 
 
1139
            if (ngx_file_info((const char *) file[i].name.data, &fi)
 
1140
                == NGX_FILE_ERROR)
 
1141
            {
 
1142
                ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
 
1143
                              ngx_file_info_n " \"%s\" failed",
 
1144
                              file[i].name.data);
 
1145
 
 
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",
 
1149
                                  file[i].name.data);
 
1150
                }
 
1151
            }
 
1152
 
 
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);
 
1158
 
 
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",
 
1162
                                      file[i].name.data);
 
1163
                    }
 
1164
                }
 
1165
            }
 
1166
 
 
1167
            if ((fi.st_mode & (S_IRUSR|S_IWUSR)) != (S_IRUSR|S_IWUSR)) {
 
1168
 
 
1169
                fi.st_mode |= (S_IRUSR|S_IWUSR);
 
1170
 
 
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);
 
1174
 
 
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",
 
1178
                                      file[i].name.data);
 
1179
                    }
 
1180
                }
 
1181
            }
 
1182
        }
 
1183
 
 
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",
 
1187
                          file[i].name.data);
 
1188
 
 
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",
 
1192
                              file[i].name.data);
 
1193
            }
 
1194
 
 
1195
            continue;
 
1196
        }
 
1197
#endif
 
1198
 
 
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",
 
1202
                          file[i].name.data);
 
1203
        }
 
1204
 
 
1205
        file[i].fd = fd;
 
1206
    }
 
1207
 
 
1208
#if !(NGX_WIN32)
 
1209
 
 
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");
 
1214
        }
 
1215
    }
 
1216
 
 
1217
#endif
 
1218
}
 
1219
 
 
1220
 
 
1221
ngx_shm_zone_t *
 
1222
ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, size_t size, void *tag)
 
1223
{
 
1224
    ngx_uint_t        i;
 
1225
    ngx_shm_zone_t   *shm_zone;
 
1226
    ngx_list_part_t  *part;
 
1227
 
 
1228
    part = &cf->cycle->shared_memory.part;
 
1229
    shm_zone = part->elts;
 
1230
 
 
1231
    for (i = 0; /* void */ ; i++) {
 
1232
 
 
1233
        if (i >= part->nelts) {
 
1234
            if (part->next == NULL) {
 
1235
                break;
 
1236
            }
 
1237
            part = part->next;
 
1238
            shm_zone = part->elts;
 
1239
            i = 0;
 
1240
        }
 
1241
 
 
1242
        if (name->len != shm_zone[i].shm.name.len) {
 
1243
            continue;
 
1244
        }
 
1245
 
 
1246
        if (ngx_strncmp(name->data, shm_zone[i].shm.name.data, name->len)
 
1247
            != 0)
 
1248
        {
 
1249
            continue;
 
1250
        }
 
1251
 
 
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);
 
1257
            return NULL;
 
1258
        }
 
1259
 
 
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);
 
1265
            return NULL;
 
1266
        }
 
1267
 
 
1268
        return &shm_zone[i];
 
1269
    }
 
1270
 
 
1271
    shm_zone = ngx_list_push(&cf->cycle->shared_memory);
 
1272
 
 
1273
    if (shm_zone == NULL) {
 
1274
        return NULL;
 
1275
    }
 
1276
 
 
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;
 
1284
 
 
1285
    return shm_zone;
 
1286
}
 
1287
 
 
1288
 
 
1289
static void
 
1290
ngx_clean_old_cycles(ngx_event_t *ev)
 
1291
{
 
1292
    ngx_uint_t     i, n, found, live;
 
1293
    ngx_log_t     *log;
 
1294
    ngx_cycle_t  **cycle;
 
1295
 
 
1296
    log = ngx_cycle->log;
 
1297
    ngx_temp_pool->log = log;
 
1298
 
 
1299
    ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "clean old cycles");
 
1300
 
 
1301
    live = 0;
 
1302
 
 
1303
    cycle = ngx_old_cycles.elts;
 
1304
    for (i = 0; i < ngx_old_cycles.nelts; i++) {
 
1305
 
 
1306
        if (cycle[i] == NULL) {
 
1307
            continue;
 
1308
        }
 
1309
 
 
1310
        found = 0;
 
1311
 
 
1312
        for (n = 0; n < cycle[i]->connection_n; n++) {
 
1313
            if (cycle[i]->connections[n].fd != (ngx_socket_t) -1) {
 
1314
                found = 1;
 
1315
 
 
1316
                ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "live fd:%d", n);
 
1317
 
 
1318
                break;
 
1319
            }
 
1320
        }
 
1321
 
 
1322
        if (found) {
 
1323
            live = 1;
 
1324
            continue;
 
1325
        }
 
1326
 
 
1327
        ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "clean old cycle: %d", i);
 
1328
 
 
1329
        ngx_destroy_pool(cycle[i]->pool);
 
1330
        cycle[i] = NULL;
 
1331
    }
 
1332
 
 
1333
    ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "old cycles status: %d", live);
 
1334
 
 
1335
    if (live) {
 
1336
        ngx_add_timer(ev, 30000);
 
1337
 
 
1338
    } else {
 
1339
        ngx_destroy_pool(ngx_temp_pool);
 
1340
        ngx_temp_pool = NULL;
 
1341
        ngx_old_cycles.nelts = 0;
 
1342
    }
 
1343
}