Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.2 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 #include <ngx_event.h>
0011 
0012 
0013 static void ngx_destroy_cycle_pools(ngx_conf_t *conf);
0014 static ngx_int_t ngx_init_zone_pool(ngx_cycle_t *cycle,
0015     ngx_shm_zone_t *shm_zone);
0016 static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log);
0017 static void ngx_clean_old_cycles(ngx_event_t *ev);
0018 static void ngx_shutdown_timer_handler(ngx_event_t *ev);
0019 
0020 
0021 volatile ngx_cycle_t  *ngx_cycle;
0022 ngx_array_t            ngx_old_cycles;
0023 
0024 static ngx_pool_t     *ngx_temp_pool;
0025 static ngx_event_t     ngx_cleaner_event;
0026 static ngx_event_t     ngx_shutdown_event;
0027 
0028 ngx_uint_t             ngx_test_config;
0029 ngx_uint_t             ngx_dump_config;
0030 ngx_uint_t             ngx_quiet_mode;
0031 
0032 
0033 /* STUB NAME */
0034 static ngx_connection_t  dumb;
0035 /* STUB */
0036 
0037 
0038 ngx_cycle_t *
0039 ngx_init_cycle(ngx_cycle_t *old_cycle)
0040 {
0041     void                *rv;
0042     char               **senv;
0043     ngx_uint_t           i, n;
0044     ngx_log_t           *log;
0045     ngx_time_t          *tp;
0046     ngx_conf_t           conf;
0047     ngx_pool_t          *pool;
0048     ngx_cycle_t         *cycle, **old;
0049     ngx_shm_zone_t      *shm_zone, *oshm_zone;
0050     ngx_list_part_t     *part, *opart;
0051     ngx_open_file_t     *file;
0052     ngx_listening_t     *ls, *nls;
0053     ngx_core_conf_t     *ccf, *old_ccf;
0054     ngx_core_module_t   *module;
0055     char                 hostname[NGX_MAXHOSTNAMELEN];
0056 
0057     ngx_timezone_update();
0058 
0059     /* force localtime update with a new timezone */
0060 
0061     tp = ngx_timeofday();
0062     tp->sec = 0;
0063 
0064     ngx_time_update();
0065 
0066 
0067     log = old_cycle->log;
0068 
0069     pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
0070     if (pool == NULL) {
0071         return NULL;
0072     }
0073     pool->log = log;
0074 
0075     cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));
0076     if (cycle == NULL) {
0077         ngx_destroy_pool(pool);
0078         return NULL;
0079     }
0080 
0081     cycle->pool = pool;
0082     cycle->log = log;
0083     cycle->old_cycle = old_cycle;
0084 
0085     cycle->conf_prefix.len = old_cycle->conf_prefix.len;
0086     cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix);
0087     if (cycle->conf_prefix.data == NULL) {
0088         ngx_destroy_pool(pool);
0089         return NULL;
0090     }
0091 
0092     cycle->prefix.len = old_cycle->prefix.len;
0093     cycle->prefix.data = ngx_pstrdup(pool, &old_cycle->prefix);
0094     if (cycle->prefix.data == NULL) {
0095         ngx_destroy_pool(pool);
0096         return NULL;
0097     }
0098 
0099     cycle->conf_file.len = old_cycle->conf_file.len;
0100     cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + 1);
0101     if (cycle->conf_file.data == NULL) {
0102         ngx_destroy_pool(pool);
0103         return NULL;
0104     }
0105     ngx_cpystrn(cycle->conf_file.data, old_cycle->conf_file.data,
0106                 old_cycle->conf_file.len + 1);
0107 
0108     cycle->conf_param.len = old_cycle->conf_param.len;
0109     cycle->conf_param.data = ngx_pstrdup(pool, &old_cycle->conf_param);
0110     if (cycle->conf_param.data == NULL) {
0111         ngx_destroy_pool(pool);
0112         return NULL;
0113     }
0114 
0115 
0116     n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10;
0117 
0118     if (ngx_array_init(&cycle->paths, pool, n, sizeof(ngx_path_t *))
0119         != NGX_OK)
0120     {
0121         ngx_destroy_pool(pool);
0122         return NULL;
0123     }
0124 
0125     ngx_memzero(cycle->paths.elts, n * sizeof(ngx_path_t *));
0126 
0127 
0128     if (ngx_array_init(&cycle->config_dump, pool, 1, sizeof(ngx_conf_dump_t))
0129         != NGX_OK)
0130     {
0131         ngx_destroy_pool(pool);
0132         return NULL;
0133     }
0134 
0135     ngx_rbtree_init(&cycle->config_dump_rbtree, &cycle->config_dump_sentinel,
0136                     ngx_str_rbtree_insert_value);
0137 
0138     if (old_cycle->open_files.part.nelts) {
0139         n = old_cycle->open_files.part.nelts;
0140         for (part = old_cycle->open_files.part.next; part; part = part->next) {
0141             n += part->nelts;
0142         }
0143 
0144     } else {
0145         n = 20;
0146     }
0147 
0148     if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t))
0149         != NGX_OK)
0150     {
0151         ngx_destroy_pool(pool);
0152         return NULL;
0153     }
0154 
0155 
0156     if (old_cycle->shared_memory.part.nelts) {
0157         n = old_cycle->shared_memory.part.nelts;
0158         for (part = old_cycle->shared_memory.part.next; part; part = part->next)
0159         {
0160             n += part->nelts;
0161         }
0162 
0163     } else {
0164         n = 1;
0165     }
0166 
0167     if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t))
0168         != NGX_OK)
0169     {
0170         ngx_destroy_pool(pool);
0171         return NULL;
0172     }
0173 
0174     n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;
0175 
0176     if (ngx_array_init(&cycle->listening, pool, n, sizeof(ngx_listening_t))
0177         != NGX_OK)
0178     {
0179         ngx_destroy_pool(pool);
0180         return NULL;
0181     }
0182 
0183     ngx_memzero(cycle->listening.elts, n * sizeof(ngx_listening_t));
0184 
0185 
0186     ngx_queue_init(&cycle->reusable_connections_queue);
0187 
0188 
0189     cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
0190     if (cycle->conf_ctx == NULL) {
0191         ngx_destroy_pool(pool);
0192         return NULL;
0193     }
0194 
0195 
0196     if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) {
0197         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "gethostname() failed");
0198         ngx_destroy_pool(pool);
0199         return NULL;
0200     }
0201 
0202     /* on Linux gethostname() silently truncates name that does not fit */
0203 
0204     hostname[NGX_MAXHOSTNAMELEN - 1] = '\0';
0205     cycle->hostname.len = ngx_strlen(hostname);
0206 
0207     cycle->hostname.data = ngx_pnalloc(pool, cycle->hostname.len);
0208     if (cycle->hostname.data == NULL) {
0209         ngx_destroy_pool(pool);
0210         return NULL;
0211     }
0212 
0213     ngx_strlow(cycle->hostname.data, (u_char *) hostname, cycle->hostname.len);
0214 
0215 
0216     if (ngx_cycle_modules(cycle) != NGX_OK) {
0217         ngx_destroy_pool(pool);
0218         return NULL;
0219     }
0220 
0221 
0222     for (i = 0; cycle->modules[i]; i++) {
0223         if (cycle->modules[i]->type != NGX_CORE_MODULE) {
0224             continue;
0225         }
0226 
0227         module = cycle->modules[i]->ctx;
0228 
0229         if (module->create_conf) {
0230             rv = module->create_conf(cycle);
0231             if (rv == NULL) {
0232                 ngx_destroy_pool(pool);
0233                 return NULL;
0234             }
0235             cycle->conf_ctx[cycle->modules[i]->index] = rv;
0236         }
0237     }
0238 
0239 
0240     senv = environ;
0241 
0242 
0243     ngx_memzero(&conf, sizeof(ngx_conf_t));
0244     /* STUB: init array ? */
0245     conf.args = ngx_array_create(pool, 10, sizeof(ngx_str_t));
0246     if (conf.args == NULL) {
0247         ngx_destroy_pool(pool);
0248         return NULL;
0249     }
0250 
0251     conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
0252     if (conf.temp_pool == NULL) {
0253         ngx_destroy_pool(pool);
0254         return NULL;
0255     }
0256 
0257 
0258     conf.ctx = cycle->conf_ctx;
0259     conf.cycle = cycle;
0260     conf.pool = pool;
0261     conf.log = log;
0262     conf.module_type = NGX_CORE_MODULE;
0263     conf.cmd_type = NGX_MAIN_CONF;
0264 
0265 #if 0
0266     log->log_level = NGX_LOG_DEBUG_ALL;
0267 #endif
0268 
0269     if (ngx_conf_param(&conf) != NGX_CONF_OK) {
0270         environ = senv;
0271         ngx_destroy_cycle_pools(&conf);
0272         return NULL;
0273     }
0274 
0275     if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
0276         environ = senv;
0277         ngx_destroy_cycle_pools(&conf);
0278         return NULL;
0279     }
0280 
0281     if (ngx_test_config && !ngx_quiet_mode) {
0282         ngx_log_stderr(0, "the configuration file %s syntax is ok",
0283                        cycle->conf_file.data);
0284     }
0285 
0286     for (i = 0; cycle->modules[i]; i++) {
0287         if (cycle->modules[i]->type != NGX_CORE_MODULE) {
0288             continue;
0289         }
0290 
0291         module = cycle->modules[i]->ctx;
0292 
0293         if (module->init_conf) {
0294             if (module->init_conf(cycle,
0295                                   cycle->conf_ctx[cycle->modules[i]->index])
0296                 == NGX_CONF_ERROR)
0297             {
0298                 environ = senv;
0299                 ngx_destroy_cycle_pools(&conf);
0300                 return NULL;
0301             }
0302         }
0303     }
0304 
0305     if (ngx_process == NGX_PROCESS_SIGNALLER) {
0306         return cycle;
0307     }
0308 
0309     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
0310 
0311     if (ngx_test_config) {
0312 
0313         if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
0314             goto failed;
0315         }
0316 
0317     } else if (!ngx_is_init_cycle(old_cycle)) {
0318 
0319         /*
0320          * we do not create the pid file in the first ngx_init_cycle() call
0321          * because we need to write the demonized process pid
0322          */
0323 
0324         old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
0325                                                    ngx_core_module);
0326         if (ccf->pid.len != old_ccf->pid.len
0327             || ngx_strcmp(ccf->pid.data, old_ccf->pid.data) != 0)
0328         {
0329             /* new pid file name */
0330 
0331             if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
0332                 goto failed;
0333             }
0334 
0335             ngx_delete_pidfile(old_cycle);
0336         }
0337     }
0338 
0339 
0340     if (ngx_test_lockfile(cycle->lock_file.data, log) != NGX_OK) {
0341         goto failed;
0342     }
0343 
0344 
0345     if (ngx_create_paths(cycle, ccf->user) != NGX_OK) {
0346         goto failed;
0347     }
0348 
0349 
0350     if (ngx_log_open_default(cycle) != NGX_OK) {
0351         goto failed;
0352     }
0353 
0354     /* open the new files */
0355 
0356     part = &cycle->open_files.part;
0357     file = part->elts;
0358 
0359     for (i = 0; /* void */ ; i++) {
0360 
0361         if (i >= part->nelts) {
0362             if (part->next == NULL) {
0363                 break;
0364             }
0365             part = part->next;
0366             file = part->elts;
0367             i = 0;
0368         }
0369 
0370         if (file[i].name.len == 0) {
0371             continue;
0372         }
0373 
0374         file[i].fd = ngx_open_file(file[i].name.data,
0375                                    NGX_FILE_APPEND,
0376                                    NGX_FILE_CREATE_OR_OPEN,
0377                                    NGX_FILE_DEFAULT_ACCESS);
0378 
0379         ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, 0,
0380                        "log: %p %d \"%s\"",
0381                        &file[i], file[i].fd, file[i].name.data);
0382 
0383         if (file[i].fd == NGX_INVALID_FILE) {
0384             ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
0385                           ngx_open_file_n " \"%s\" failed",
0386                           file[i].name.data);
0387             goto failed;
0388         }
0389 
0390 #if !(NGX_WIN32)
0391         if (fcntl(file[i].fd, F_SETFD, FD_CLOEXEC) == -1) {
0392             ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
0393                           "fcntl(FD_CLOEXEC) \"%s\" failed",
0394                           file[i].name.data);
0395             goto failed;
0396         }
0397 #endif
0398     }
0399 
0400     cycle->log = &cycle->new_log;
0401     pool->log = &cycle->new_log;
0402 
0403 
0404     /* create shared memory */
0405 
0406     part = &cycle->shared_memory.part;
0407     shm_zone = part->elts;
0408 
0409     for (i = 0; /* void */ ; i++) {
0410 
0411         if (i >= part->nelts) {
0412             if (part->next == NULL) {
0413                 break;
0414             }
0415             part = part->next;
0416             shm_zone = part->elts;
0417             i = 0;
0418         }
0419 
0420         if (shm_zone[i].shm.size == 0) {
0421             ngx_log_error(NGX_LOG_EMERG, log, 0,
0422                           "zero size shared memory zone \"%V\"",
0423                           &shm_zone[i].shm.name);
0424             goto failed;
0425         }
0426 
0427         shm_zone[i].shm.log = cycle->log;
0428 
0429         opart = &old_cycle->shared_memory.part;
0430         oshm_zone = opart->elts;
0431 
0432         for (n = 0; /* void */ ; n++) {
0433 
0434             if (n >= opart->nelts) {
0435                 if (opart->next == NULL) {
0436                     break;
0437                 }
0438                 opart = opart->next;
0439                 oshm_zone = opart->elts;
0440                 n = 0;
0441             }
0442 
0443             if (shm_zone[i].shm.name.len != oshm_zone[n].shm.name.len) {
0444                 continue;
0445             }
0446 
0447             if (ngx_strncmp(shm_zone[i].shm.name.data,
0448                             oshm_zone[n].shm.name.data,
0449                             shm_zone[i].shm.name.len)
0450                 != 0)
0451             {
0452                 continue;
0453             }
0454 
0455             if (shm_zone[i].tag == oshm_zone[n].tag
0456                 && shm_zone[i].shm.size == oshm_zone[n].shm.size
0457                 && !shm_zone[i].noreuse)
0458             {
0459                 shm_zone[i].shm.addr = oshm_zone[n].shm.addr;
0460 #if (NGX_WIN32)
0461                 shm_zone[i].shm.handle = oshm_zone[n].shm.handle;
0462 #endif
0463 
0464                 if (shm_zone[i].init(&shm_zone[i], oshm_zone[n].data)
0465                     != NGX_OK)
0466                 {
0467                     goto failed;
0468                 }
0469 
0470                 goto shm_zone_found;
0471             }
0472 
0473             ngx_shm_free(&oshm_zone[n].shm);
0474 
0475             break;
0476         }
0477 
0478         if (ngx_shm_alloc(&shm_zone[i].shm) != NGX_OK) {
0479             goto failed;
0480         }
0481 
0482         if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) {
0483             goto failed;
0484         }
0485 
0486         if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) {
0487             goto failed;
0488         }
0489 
0490     shm_zone_found:
0491 
0492         continue;
0493     }
0494 
0495 
0496     /* handle the listening sockets */
0497 
0498     if (old_cycle->listening.nelts) {
0499         ls = old_cycle->listening.elts;
0500         for (i = 0; i < old_cycle->listening.nelts; i++) {
0501             ls[i].remain = 0;
0502         }
0503 
0504         nls = cycle->listening.elts;
0505         for (n = 0; n < cycle->listening.nelts; n++) {
0506 
0507             for (i = 0; i < old_cycle->listening.nelts; i++) {
0508                 if (ls[i].ignore) {
0509                     continue;
0510                 }
0511 
0512                 if (ls[i].remain) {
0513                     continue;
0514                 }
0515 
0516                 if (ls[i].type != nls[n].type) {
0517                     continue;
0518                 }
0519 
0520                 if (ngx_cmp_sockaddr(nls[n].sockaddr, nls[n].socklen,
0521                                      ls[i].sockaddr, ls[i].socklen, 1)
0522                     == NGX_OK)
0523                 {
0524                     nls[n].fd = ls[i].fd;
0525                     nls[n].previous = &ls[i];
0526                     ls[i].remain = 1;
0527 
0528                     if (ls[i].backlog != nls[n].backlog) {
0529                         nls[n].listen = 1;
0530                     }
0531 
0532 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
0533 
0534                     /*
0535                      * FreeBSD, except the most recent versions,
0536                      * could not remove accept filter
0537                      */
0538                     nls[n].deferred_accept = ls[i].deferred_accept;
0539 
0540                     if (ls[i].accept_filter && nls[n].accept_filter) {
0541                         if (ngx_strcmp(ls[i].accept_filter,
0542                                        nls[n].accept_filter)
0543                             != 0)
0544                         {
0545                             nls[n].delete_deferred = 1;
0546                             nls[n].add_deferred = 1;
0547                         }
0548 
0549                     } else if (ls[i].accept_filter) {
0550                         nls[n].delete_deferred = 1;
0551 
0552                     } else if (nls[n].accept_filter) {
0553                         nls[n].add_deferred = 1;
0554                     }
0555 #endif
0556 
0557 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
0558 
0559                     if (ls[i].deferred_accept && !nls[n].deferred_accept) {
0560                         nls[n].delete_deferred = 1;
0561 
0562                     } else if (ls[i].deferred_accept != nls[n].deferred_accept)
0563                     {
0564                         nls[n].add_deferred = 1;
0565                     }
0566 #endif
0567 
0568 #if (NGX_HAVE_REUSEPORT)
0569                     if (nls[n].reuseport && !ls[i].reuseport) {
0570                         nls[n].add_reuseport = 1;
0571                     }
0572 #endif
0573 
0574                     break;
0575                 }
0576             }
0577 
0578             if (nls[n].fd == (ngx_socket_t) -1) {
0579                 nls[n].open = 1;
0580 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
0581                 if (nls[n].accept_filter) {
0582                     nls[n].add_deferred = 1;
0583                 }
0584 #endif
0585 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
0586                 if (nls[n].deferred_accept) {
0587                     nls[n].add_deferred = 1;
0588                 }
0589 #endif
0590             }
0591         }
0592 
0593     } else {
0594         ls = cycle->listening.elts;
0595         for (i = 0; i < cycle->listening.nelts; i++) {
0596             ls[i].open = 1;
0597 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
0598             if (ls[i].accept_filter) {
0599                 ls[i].add_deferred = 1;
0600             }
0601 #endif
0602 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
0603             if (ls[i].deferred_accept) {
0604                 ls[i].add_deferred = 1;
0605             }
0606 #endif
0607         }
0608     }
0609 
0610     if (ngx_open_listening_sockets(cycle) != NGX_OK) {
0611         goto failed;
0612     }
0613 
0614     if (!ngx_test_config) {
0615         ngx_configure_listening_sockets(cycle);
0616     }
0617 
0618 
0619     /* commit the new cycle configuration */
0620 
0621     if (!ngx_use_stderr) {
0622         (void) ngx_log_redirect_stderr(cycle);
0623     }
0624 
0625     pool->log = cycle->log;
0626 
0627     if (ngx_init_modules(cycle) != NGX_OK) {
0628         /* fatal */
0629         exit(1);
0630     }
0631 
0632 
0633     /* close and delete stuff that lefts from an old cycle */
0634 
0635     /* free the unnecessary shared memory */
0636 
0637     opart = &old_cycle->shared_memory.part;
0638     oshm_zone = opart->elts;
0639 
0640     for (i = 0; /* void */ ; i++) {
0641 
0642         if (i >= opart->nelts) {
0643             if (opart->next == NULL) {
0644                 goto old_shm_zone_done;
0645             }
0646             opart = opart->next;
0647             oshm_zone = opart->elts;
0648             i = 0;
0649         }
0650 
0651         part = &cycle->shared_memory.part;
0652         shm_zone = part->elts;
0653 
0654         for (n = 0; /* void */ ; n++) {
0655 
0656             if (n >= part->nelts) {
0657                 if (part->next == NULL) {
0658                     break;
0659                 }
0660                 part = part->next;
0661                 shm_zone = part->elts;
0662                 n = 0;
0663             }
0664 
0665             if (oshm_zone[i].shm.name.len == shm_zone[n].shm.name.len
0666                 && ngx_strncmp(oshm_zone[i].shm.name.data,
0667                                shm_zone[n].shm.name.data,
0668                                oshm_zone[i].shm.name.len)
0669                 == 0)
0670             {
0671                 goto live_shm_zone;
0672             }
0673         }
0674 
0675         ngx_shm_free(&oshm_zone[i].shm);
0676 
0677     live_shm_zone:
0678 
0679         continue;
0680     }
0681 
0682 old_shm_zone_done:
0683 
0684 
0685     /* close the unnecessary listening sockets */
0686 
0687     ls = old_cycle->listening.elts;
0688     for (i = 0; i < old_cycle->listening.nelts; i++) {
0689 
0690         if (ls[i].remain || ls[i].fd == (ngx_socket_t) -1) {
0691             continue;
0692         }
0693 
0694         if (ngx_close_socket(ls[i].fd) == -1) {
0695             ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
0696                           ngx_close_socket_n " listening socket on %V failed",
0697                           &ls[i].addr_text);
0698         }
0699 
0700 #if (NGX_HAVE_UNIX_DOMAIN)
0701 
0702         if (ls[i].sockaddr->sa_family == AF_UNIX) {
0703             u_char  *name;
0704 
0705             name = ls[i].addr_text.data + sizeof("unix:") - 1;
0706 
0707             ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
0708                           "deleting socket %s", name);
0709 
0710             if (ngx_delete_file(name) == NGX_FILE_ERROR) {
0711                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
0712                               ngx_delete_file_n " %s failed", name);
0713             }
0714         }
0715 
0716 #endif
0717     }
0718 
0719 
0720     /* close the unnecessary open files */
0721 
0722     part = &old_cycle->open_files.part;
0723     file = part->elts;
0724 
0725     for (i = 0; /* void */ ; i++) {
0726 
0727         if (i >= part->nelts) {
0728             if (part->next == NULL) {
0729                 break;
0730             }
0731             part = part->next;
0732             file = part->elts;
0733             i = 0;
0734         }
0735 
0736         if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
0737             continue;
0738         }
0739 
0740         if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
0741             ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
0742                           ngx_close_file_n " \"%s\" failed",
0743                           file[i].name.data);
0744         }
0745     }
0746 
0747     ngx_destroy_pool(conf.temp_pool);
0748 
0749     if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) {
0750 
0751         ngx_destroy_pool(old_cycle->pool);
0752         cycle->old_cycle = NULL;
0753 
0754         return cycle;
0755     }
0756 
0757 
0758     if (ngx_temp_pool == NULL) {
0759         ngx_temp_pool = ngx_create_pool(128, cycle->log);
0760         if (ngx_temp_pool == NULL) {
0761             ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
0762                           "could not create ngx_temp_pool");
0763             exit(1);
0764         }
0765 
0766         n = 10;
0767 
0768         if (ngx_array_init(&ngx_old_cycles, ngx_temp_pool, n,
0769                            sizeof(ngx_cycle_t *))
0770             != NGX_OK)
0771         {
0772             exit(1);
0773         }
0774 
0775         ngx_memzero(ngx_old_cycles.elts, n * sizeof(ngx_cycle_t *));
0776 
0777         ngx_cleaner_event.handler = ngx_clean_old_cycles;
0778         ngx_cleaner_event.log = cycle->log;
0779         ngx_cleaner_event.data = &dumb;
0780         dumb.fd = (ngx_socket_t) -1;
0781     }
0782 
0783     ngx_temp_pool->log = cycle->log;
0784 
0785     old = ngx_array_push(&ngx_old_cycles);
0786     if (old == NULL) {
0787         exit(1);
0788     }
0789     *old = old_cycle;
0790 
0791     if (!ngx_cleaner_event.timer_set) {
0792         ngx_add_timer(&ngx_cleaner_event, 30000);
0793         ngx_cleaner_event.timer_set = 1;
0794     }
0795 
0796     return cycle;
0797 
0798 
0799 failed:
0800 
0801     if (!ngx_is_init_cycle(old_cycle)) {
0802         old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
0803                                                    ngx_core_module);
0804         if (old_ccf->environment) {
0805             environ = old_ccf->environment;
0806         }
0807     }
0808 
0809     /* rollback the new cycle configuration */
0810 
0811     part = &cycle->open_files.part;
0812     file = part->elts;
0813 
0814     for (i = 0; /* void */ ; i++) {
0815 
0816         if (i >= part->nelts) {
0817             if (part->next == NULL) {
0818                 break;
0819             }
0820             part = part->next;
0821             file = part->elts;
0822             i = 0;
0823         }
0824 
0825         if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
0826             continue;
0827         }
0828 
0829         if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
0830             ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
0831                           ngx_close_file_n " \"%s\" failed",
0832                           file[i].name.data);
0833         }
0834     }
0835 
0836     if (ngx_test_config) {
0837         ngx_destroy_cycle_pools(&conf);
0838         return NULL;
0839     }
0840 
0841     ls = cycle->listening.elts;
0842     for (i = 0; i < cycle->listening.nelts; i++) {
0843         if (ls[i].fd == (ngx_socket_t) -1 || !ls[i].open) {
0844             continue;
0845         }
0846 
0847         if (ngx_close_socket(ls[i].fd) == -1) {
0848             ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
0849                           ngx_close_socket_n " %V failed",
0850                           &ls[i].addr_text);
0851         }
0852     }
0853 
0854     ngx_destroy_cycle_pools(&conf);
0855 
0856     return NULL;
0857 }
0858 
0859 
0860 static void
0861 ngx_destroy_cycle_pools(ngx_conf_t *conf)
0862 {
0863     ngx_destroy_pool(conf->temp_pool);
0864     ngx_destroy_pool(conf->pool);
0865 }
0866 
0867 
0868 static ngx_int_t
0869 ngx_init_zone_pool(ngx_cycle_t *cycle, ngx_shm_zone_t *zn)
0870 {
0871     u_char           *file;
0872     ngx_slab_pool_t  *sp;
0873 
0874     sp = (ngx_slab_pool_t *) zn->shm.addr;
0875 
0876     if (zn->shm.exists) {
0877 
0878         if (sp == sp->addr) {
0879             return NGX_OK;
0880         }
0881 
0882 #if (NGX_WIN32)
0883 
0884         /* remap at the required address */
0885 
0886         if (ngx_shm_remap(&zn->shm, sp->addr) != NGX_OK) {
0887             return NGX_ERROR;
0888         }
0889 
0890         sp = (ngx_slab_pool_t *) zn->shm.addr;
0891 
0892         if (sp == sp->addr) {
0893             return NGX_OK;
0894         }
0895 
0896 #endif
0897 
0898         ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
0899                       "shared zone \"%V\" has no equal addresses: %p vs %p",
0900                       &zn->shm.name, sp->addr, sp);
0901         return NGX_ERROR;
0902     }
0903 
0904     sp->end = zn->shm.addr + zn->shm.size;
0905     sp->min_shift = 3;
0906     sp->addr = zn->shm.addr;
0907 
0908 #if (NGX_HAVE_ATOMIC_OPS)
0909 
0910     file = NULL;
0911 
0912 #else
0913 
0914     file = ngx_pnalloc(cycle->pool, cycle->lock_file.len + zn->shm.name.len);
0915     if (file == NULL) {
0916         return NGX_ERROR;
0917     }
0918 
0919     (void) ngx_sprintf(file, "%V%V%Z", &cycle->lock_file, &zn->shm.name);
0920 
0921 #endif
0922 
0923     if (ngx_shmtx_create(&sp->mutex, &sp->lock, file) != NGX_OK) {
0924         return NGX_ERROR;
0925     }
0926 
0927     ngx_slab_init(sp);
0928 
0929     return NGX_OK;
0930 }
0931 
0932 
0933 ngx_int_t
0934 ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
0935 {
0936     size_t      len;
0937     ngx_uint_t  create;
0938     ngx_file_t  file;
0939     u_char      pid[NGX_INT64_LEN + 2];
0940 
0941     if (ngx_process > NGX_PROCESS_MASTER) {
0942         return NGX_OK;
0943     }
0944 
0945     ngx_memzero(&file, sizeof(ngx_file_t));
0946 
0947     file.name = *name;
0948     file.log = log;
0949 
0950     create = ngx_test_config ? NGX_FILE_CREATE_OR_OPEN : NGX_FILE_TRUNCATE;
0951 
0952     file.fd = ngx_open_file(file.name.data, NGX_FILE_RDWR,
0953                             create, NGX_FILE_DEFAULT_ACCESS);
0954 
0955     if (file.fd == NGX_INVALID_FILE) {
0956         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
0957                       ngx_open_file_n " \"%s\" failed", file.name.data);
0958         return NGX_ERROR;
0959     }
0960 
0961     if (!ngx_test_config) {
0962         len = ngx_snprintf(pid, NGX_INT64_LEN + 2, "%P%N", ngx_pid) - pid;
0963 
0964         if (ngx_write_file(&file, pid, len, 0) == NGX_ERROR) {
0965             return NGX_ERROR;
0966         }
0967     }
0968 
0969     if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
0970         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
0971                       ngx_close_file_n " \"%s\" failed", file.name.data);
0972     }
0973 
0974     return NGX_OK;
0975 }
0976 
0977 
0978 void
0979 ngx_delete_pidfile(ngx_cycle_t *cycle)
0980 {
0981     u_char           *name;
0982     ngx_core_conf_t  *ccf;
0983 
0984     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
0985 
0986     name = ngx_new_binary ? ccf->oldpid.data : ccf->pid.data;
0987 
0988     if (ngx_delete_file(name) == NGX_FILE_ERROR) {
0989         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
0990                       ngx_delete_file_n " \"%s\" failed", name);
0991     }
0992 }
0993 
0994 
0995 ngx_int_t
0996 ngx_signal_process(ngx_cycle_t *cycle, char *sig)
0997 {
0998     ssize_t           n;
0999     ngx_pid_t         pid;
1000     ngx_file_t        file;
1001     ngx_core_conf_t  *ccf;
1002     u_char            buf[NGX_INT64_LEN + 2];
1003 
1004     ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "signal process started");
1005 
1006     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
1007 
1008     ngx_memzero(&file, sizeof(ngx_file_t));
1009 
1010     file.name = ccf->pid;
1011     file.log = cycle->log;
1012 
1013     file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
1014                             NGX_FILE_OPEN, NGX_FILE_DEFAULT_ACCESS);
1015 
1016     if (file.fd == NGX_INVALID_FILE) {
1017         ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
1018                       ngx_open_file_n " \"%s\" failed", file.name.data);
1019         return 1;
1020     }
1021 
1022     n = ngx_read_file(&file, buf, NGX_INT64_LEN + 2, 0);
1023 
1024     if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
1025         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
1026                       ngx_close_file_n " \"%s\" failed", file.name.data);
1027     }
1028 
1029     if (n == NGX_ERROR) {
1030         return 1;
1031     }
1032 
1033     while (n-- && (buf[n] == CR || buf[n] == LF)) { /* void */ }
1034 
1035     pid = ngx_atoi(buf, ++n);
1036 
1037     if (pid == (ngx_pid_t) NGX_ERROR) {
1038         ngx_log_error(NGX_LOG_ERR, cycle->log, 0,
1039                       "invalid PID number \"%*s\" in \"%s\"",
1040                       n, buf, file.name.data);
1041         return 1;
1042     }
1043 
1044     return ngx_os_signal_process(cycle, sig, pid);
1045 
1046 }
1047 
1048 
1049 static ngx_int_t
1050 ngx_test_lockfile(u_char *file, ngx_log_t *log)
1051 {
1052 #if !(NGX_HAVE_ATOMIC_OPS)
1053     ngx_fd_t  fd;
1054 
1055     fd = ngx_open_file(file, NGX_FILE_RDWR, NGX_FILE_CREATE_OR_OPEN,
1056                        NGX_FILE_DEFAULT_ACCESS);
1057 
1058     if (fd == NGX_INVALID_FILE) {
1059         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
1060                       ngx_open_file_n " \"%s\" failed", file);
1061         return NGX_ERROR;
1062     }
1063 
1064     if (ngx_close_file(fd) == NGX_FILE_ERROR) {
1065         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
1066                       ngx_close_file_n " \"%s\" failed", file);
1067     }
1068 
1069     if (ngx_delete_file(file) == NGX_FILE_ERROR) {
1070         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
1071                       ngx_delete_file_n " \"%s\" failed", file);
1072     }
1073 
1074 #endif
1075 
1076     return NGX_OK;
1077 }
1078 
1079 
1080 void
1081 ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
1082 {
1083     ngx_fd_t          fd;
1084     ngx_uint_t        i;
1085     ngx_list_part_t  *part;
1086     ngx_open_file_t  *file;
1087 
1088     part = &cycle->open_files.part;
1089     file = part->elts;
1090 
1091     for (i = 0; /* void */ ; i++) {
1092 
1093         if (i >= part->nelts) {
1094             if (part->next == NULL) {
1095                 break;
1096             }
1097             part = part->next;
1098             file = part->elts;
1099             i = 0;
1100         }
1101 
1102         if (file[i].name.len == 0) {
1103             continue;
1104         }
1105 
1106         if (file[i].flush) {
1107             file[i].flush(&file[i], cycle->log);
1108         }
1109 
1110         fd = ngx_open_file(file[i].name.data, NGX_FILE_APPEND,
1111                            NGX_FILE_CREATE_OR_OPEN, NGX_FILE_DEFAULT_ACCESS);
1112 
1113         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
1114                        "reopen file \"%s\", old:%d new:%d",
1115                        file[i].name.data, file[i].fd, fd);
1116 
1117         if (fd == NGX_INVALID_FILE) {
1118             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1119                           ngx_open_file_n " \"%s\" failed", file[i].name.data);
1120             continue;
1121         }
1122 
1123 #if !(NGX_WIN32)
1124         if (user != (ngx_uid_t) NGX_CONF_UNSET_UINT) {
1125             ngx_file_info_t  fi;
1126 
1127             if (ngx_file_info((const char *) file[i].name.data, &fi)
1128                 == NGX_FILE_ERROR)
1129             {
1130                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1131                               ngx_file_info_n " \"%s\" failed",
1132                               file[i].name.data);
1133 
1134                 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
1135                     ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1136                                   ngx_close_file_n " \"%s\" failed",
1137                                   file[i].name.data);
1138                 }
1139 
1140                 continue;
1141             }
1142 
1143             if (fi.st_uid != user) {
1144                 if (chown((const char *) file[i].name.data, user, -1) == -1) {
1145                     ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1146                                   "chown(\"%s\", %d) failed",
1147                                   file[i].name.data, user);
1148 
1149                     if (ngx_close_file(fd) == NGX_FILE_ERROR) {
1150                         ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1151                                       ngx_close_file_n " \"%s\" failed",
1152                                       file[i].name.data);
1153                     }
1154 
1155                     continue;
1156                 }
1157             }
1158 
1159             if ((fi.st_mode & (S_IRUSR|S_IWUSR)) != (S_IRUSR|S_IWUSR)) {
1160 
1161                 fi.st_mode |= (S_IRUSR|S_IWUSR);
1162 
1163                 if (chmod((const char *) file[i].name.data, fi.st_mode) == -1) {
1164                     ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1165                                   "chmod() \"%s\" failed", file[i].name.data);
1166 
1167                     if (ngx_close_file(fd) == NGX_FILE_ERROR) {
1168                         ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1169                                       ngx_close_file_n " \"%s\" failed",
1170                                       file[i].name.data);
1171                     }
1172 
1173                     continue;
1174                 }
1175             }
1176         }
1177 
1178         if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
1179             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1180                           "fcntl(FD_CLOEXEC) \"%s\" failed",
1181                           file[i].name.data);
1182 
1183             if (ngx_close_file(fd) == NGX_FILE_ERROR) {
1184                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1185                               ngx_close_file_n " \"%s\" failed",
1186                               file[i].name.data);
1187             }
1188 
1189             continue;
1190         }
1191 #endif
1192 
1193         if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
1194             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
1195                           ngx_close_file_n " \"%s\" failed",
1196                           file[i].name.data);
1197         }
1198 
1199         file[i].fd = fd;
1200     }
1201 
1202     (void) ngx_log_redirect_stderr(cycle);
1203 }
1204 
1205 
1206 ngx_shm_zone_t *
1207 ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, size_t size, void *tag)
1208 {
1209     ngx_uint_t        i;
1210     ngx_shm_zone_t   *shm_zone;
1211     ngx_list_part_t  *part;
1212 
1213     part = &cf->cycle->shared_memory.part;
1214     shm_zone = part->elts;
1215 
1216     for (i = 0; /* void */ ; i++) {
1217 
1218         if (i >= part->nelts) {
1219             if (part->next == NULL) {
1220                 break;
1221             }
1222             part = part->next;
1223             shm_zone = part->elts;
1224             i = 0;
1225         }
1226 
1227         if (name->len != shm_zone[i].shm.name.len) {
1228             continue;
1229         }
1230 
1231         if (ngx_strncmp(name->data, shm_zone[i].shm.name.data, name->len)
1232             != 0)
1233         {
1234             continue;
1235         }
1236 
1237         if (tag != shm_zone[i].tag) {
1238             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1239                             "the shared memory zone \"%V\" is "
1240                             "already declared for a different use",
1241                             &shm_zone[i].shm.name);
1242             return NULL;
1243         }
1244 
1245         if (shm_zone[i].shm.size == 0) {
1246             shm_zone[i].shm.size = size;
1247         }
1248 
1249         if (size && size != shm_zone[i].shm.size) {
1250             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1251                             "the size %uz of shared memory zone \"%V\" "
1252                             "conflicts with already declared size %uz",
1253                             size, &shm_zone[i].shm.name, shm_zone[i].shm.size);
1254             return NULL;
1255         }
1256 
1257         return &shm_zone[i];
1258     }
1259 
1260     shm_zone = ngx_list_push(&cf->cycle->shared_memory);
1261 
1262     if (shm_zone == NULL) {
1263         return NULL;
1264     }
1265 
1266     shm_zone->data = NULL;
1267     shm_zone->shm.log = cf->cycle->log;
1268     shm_zone->shm.size = size;
1269     shm_zone->shm.name = *name;
1270     shm_zone->shm.exists = 0;
1271     shm_zone->init = NULL;
1272     shm_zone->tag = tag;
1273     shm_zone->noreuse = 0;
1274 
1275     return shm_zone;
1276 }
1277 
1278 
1279 static void
1280 ngx_clean_old_cycles(ngx_event_t *ev)
1281 {
1282     ngx_uint_t     i, n, found, live;
1283     ngx_log_t     *log;
1284     ngx_cycle_t  **cycle;
1285 
1286     log = ngx_cycle->log;
1287     ngx_temp_pool->log = log;
1288 
1289     ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "clean old cycles");
1290 
1291     live = 0;
1292 
1293     cycle = ngx_old_cycles.elts;
1294     for (i = 0; i < ngx_old_cycles.nelts; i++) {
1295 
1296         if (cycle[i] == NULL) {
1297             continue;
1298         }
1299 
1300         found = 0;
1301 
1302         for (n = 0; n < cycle[i]->connection_n; n++) {
1303             if (cycle[i]->connections[n].fd != (ngx_socket_t) -1) {
1304                 found = 1;
1305 
1306                 ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "live fd:%ui", n);
1307 
1308                 break;
1309             }
1310         }
1311 
1312         if (found) {
1313             live = 1;
1314             continue;
1315         }
1316 
1317         ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "clean old cycle: %ui", i);
1318 
1319         ngx_destroy_pool(cycle[i]->pool);
1320         cycle[i] = NULL;
1321     }
1322 
1323     ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "old cycles status: %ui", live);
1324 
1325     if (live) {
1326         ngx_add_timer(ev, 30000);
1327 
1328     } else {
1329         ngx_destroy_pool(ngx_temp_pool);
1330         ngx_temp_pool = NULL;
1331         ngx_old_cycles.nelts = 0;
1332     }
1333 }
1334 
1335 
1336 void
1337 ngx_set_shutdown_timer(ngx_cycle_t *cycle)
1338 {
1339     ngx_core_conf_t  *ccf;
1340 
1341     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
1342 
1343     if (ccf->shutdown_timeout) {
1344         ngx_shutdown_event.handler = ngx_shutdown_timer_handler;
1345         ngx_shutdown_event.data = cycle;
1346         ngx_shutdown_event.log = cycle->log;
1347         ngx_shutdown_event.cancelable = 1;
1348 
1349         ngx_add_timer(&ngx_shutdown_event, ccf->shutdown_timeout);
1350     }
1351 }
1352 
1353 
1354 static void
1355 ngx_shutdown_timer_handler(ngx_event_t *ev)
1356 {
1357     ngx_uint_t         i;
1358     ngx_cycle_t       *cycle;
1359     ngx_connection_t  *c;
1360 
1361     cycle = ev->data;
1362 
1363     c = cycle->connections;
1364 
1365     for (i = 0; i < cycle->connection_n; i++) {
1366 
1367         if (c[i].fd == (ngx_socket_t) -1
1368             || c[i].read == NULL
1369             || c[i].read->accept
1370             || c[i].read->channel
1371             || c[i].read->resolver)
1372         {
1373             continue;
1374         }
1375 
1376         ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0,
1377                        "*%uA shutdown timeout", c[i].number);
1378 
1379         c[i].close = 1;
1380         c[i].error = 1;
1381 
1382         c[i].read->handler(c[i].read);
1383     }
1384 }