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 #include <ngx_channel.h>
0012 
0013 
0014 static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n,
0015     ngx_int_t type);
0016 static void ngx_start_cache_manager_processes(ngx_cycle_t *cycle,
0017     ngx_uint_t respawn);
0018 static void ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch);
0019 static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo);
0020 static ngx_uint_t ngx_reap_children(ngx_cycle_t *cycle);
0021 static void ngx_master_process_exit(ngx_cycle_t *cycle);
0022 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data);
0023 static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker);
0024 static void ngx_worker_process_exit(ngx_cycle_t *cycle);
0025 static void ngx_channel_handler(ngx_event_t *ev);
0026 static void ngx_cache_manager_process_cycle(ngx_cycle_t *cycle, void *data);
0027 static void ngx_cache_manager_process_handler(ngx_event_t *ev);
0028 static void ngx_cache_loader_process_handler(ngx_event_t *ev);
0029 
0030 
0031 ngx_uint_t    ngx_process;
0032 ngx_uint_t    ngx_worker;
0033 ngx_pid_t     ngx_pid;
0034 ngx_pid_t     ngx_parent;
0035 
0036 sig_atomic_t  ngx_reap;
0037 sig_atomic_t  ngx_sigio;
0038 sig_atomic_t  ngx_sigalrm;
0039 sig_atomic_t  ngx_terminate;
0040 sig_atomic_t  ngx_quit;
0041 sig_atomic_t  ngx_debug_quit;
0042 ngx_uint_t    ngx_exiting;
0043 sig_atomic_t  ngx_reconfigure;
0044 sig_atomic_t  ngx_reopen;
0045 
0046 sig_atomic_t  ngx_change_binary;
0047 ngx_pid_t     ngx_new_binary;
0048 ngx_uint_t    ngx_inherited;
0049 ngx_uint_t    ngx_daemonized;
0050 
0051 sig_atomic_t  ngx_noaccept;
0052 ngx_uint_t    ngx_noaccepting;
0053 ngx_uint_t    ngx_restart;
0054 
0055 
0056 static u_char  master_process[] = "master process";
0057 
0058 
0059 static ngx_cache_manager_ctx_t  ngx_cache_manager_ctx = {
0060     ngx_cache_manager_process_handler, "cache manager process", 0
0061 };
0062 
0063 static ngx_cache_manager_ctx_t  ngx_cache_loader_ctx = {
0064     ngx_cache_loader_process_handler, "cache loader process", 60000
0065 };
0066 
0067 
0068 static ngx_cycle_t      ngx_exit_cycle;
0069 static ngx_log_t        ngx_exit_log;
0070 static ngx_open_file_t  ngx_exit_log_file;
0071 
0072 
0073 void
0074 ngx_master_process_cycle(ngx_cycle_t *cycle)
0075 {
0076     char              *title;
0077     u_char            *p;
0078     size_t             size;
0079     ngx_int_t          i;
0080     ngx_uint_t         n, sigio;
0081     sigset_t           set;
0082     struct itimerval   itv;
0083     ngx_uint_t         live;
0084     ngx_msec_t         delay;
0085     ngx_listening_t   *ls;
0086     ngx_core_conf_t   *ccf;
0087 
0088     sigemptyset(&set);
0089     sigaddset(&set, SIGCHLD);
0090     sigaddset(&set, SIGALRM);
0091     sigaddset(&set, SIGIO);
0092     sigaddset(&set, SIGINT);
0093     sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
0094     sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
0095     sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
0096     sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
0097     sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
0098     sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));
0099 
0100     if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
0101         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
0102                       "sigprocmask() failed");
0103     }
0104 
0105     sigemptyset(&set);
0106 
0107 
0108     size = sizeof(master_process);
0109 
0110     for (i = 0; i < ngx_argc; i++) {
0111         size += ngx_strlen(ngx_argv[i]) + 1;
0112     }
0113 
0114     title = ngx_pnalloc(cycle->pool, size);
0115     if (title == NULL) {
0116         /* fatal */
0117         exit(2);
0118     }
0119 
0120     p = ngx_cpymem(title, master_process, sizeof(master_process) - 1);
0121     for (i = 0; i < ngx_argc; i++) {
0122         *p++ = ' ';
0123         p = ngx_cpystrn(p, (u_char *) ngx_argv[i], size);
0124     }
0125 
0126     ngx_setproctitle(title);
0127 
0128 
0129     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
0130 
0131     ngx_start_worker_processes(cycle, ccf->worker_processes,
0132                                NGX_PROCESS_RESPAWN);
0133     ngx_start_cache_manager_processes(cycle, 0);
0134 
0135     ngx_new_binary = 0;
0136     delay = 0;
0137     sigio = 0;
0138     live = 1;
0139 
0140     for ( ;; ) {
0141         if (delay) {
0142             if (ngx_sigalrm) {
0143                 sigio = 0;
0144                 delay *= 2;
0145                 ngx_sigalrm = 0;
0146             }
0147 
0148             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
0149                            "termination cycle: %M", delay);
0150 
0151             itv.it_interval.tv_sec = 0;
0152             itv.it_interval.tv_usec = 0;
0153             itv.it_value.tv_sec = delay / 1000;
0154             itv.it_value.tv_usec = (delay % 1000 ) * 1000;
0155 
0156             if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
0157                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
0158                               "setitimer() failed");
0159             }
0160         }
0161 
0162         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "sigsuspend");
0163 
0164         sigsuspend(&set);
0165 
0166         ngx_time_update();
0167 
0168         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
0169                        "wake up, sigio %i", sigio);
0170 
0171         if (ngx_reap) {
0172             ngx_reap = 0;
0173             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children");
0174 
0175             live = ngx_reap_children(cycle);
0176         }
0177 
0178         if (!live && (ngx_terminate || ngx_quit)) {
0179             ngx_master_process_exit(cycle);
0180         }
0181 
0182         if (ngx_terminate) {
0183             if (delay == 0) {
0184                 delay = 50;
0185             }
0186 
0187             if (sigio) {
0188                 sigio--;
0189                 continue;
0190             }
0191 
0192             sigio = ccf->worker_processes + 2 /* cache processes */;
0193 
0194             if (delay > 1000) {
0195                 ngx_signal_worker_processes(cycle, SIGKILL);
0196             } else {
0197                 ngx_signal_worker_processes(cycle,
0198                                        ngx_signal_value(NGX_TERMINATE_SIGNAL));
0199             }
0200 
0201             continue;
0202         }
0203 
0204         if (ngx_quit) {
0205             ngx_signal_worker_processes(cycle,
0206                                         ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
0207 
0208             ls = cycle->listening.elts;
0209             for (n = 0; n < cycle->listening.nelts; n++) {
0210                 if (ngx_close_socket(ls[n].fd) == -1) {
0211                     ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
0212                                   ngx_close_socket_n " %V failed",
0213                                   &ls[n].addr_text);
0214                 }
0215             }
0216             cycle->listening.nelts = 0;
0217 
0218             continue;
0219         }
0220 
0221         if (ngx_reconfigure) {
0222             ngx_reconfigure = 0;
0223 
0224             if (ngx_new_binary) {
0225                 ngx_start_worker_processes(cycle, ccf->worker_processes,
0226                                            NGX_PROCESS_RESPAWN);
0227                 ngx_start_cache_manager_processes(cycle, 0);
0228                 ngx_noaccepting = 0;
0229 
0230                 continue;
0231             }
0232 
0233             ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring");
0234 
0235             cycle = ngx_init_cycle(cycle);
0236             if (cycle == NULL) {
0237                 cycle = (ngx_cycle_t *) ngx_cycle;
0238                 continue;
0239             }
0240 
0241             ngx_cycle = cycle;
0242             ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
0243                                                    ngx_core_module);
0244             ngx_start_worker_processes(cycle, ccf->worker_processes,
0245                                        NGX_PROCESS_JUST_RESPAWN);
0246             ngx_start_cache_manager_processes(cycle, 1);
0247 
0248             /* allow new processes to start */
0249             ngx_msleep(100);
0250 
0251             live = 1;
0252             ngx_signal_worker_processes(cycle,
0253                                         ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
0254         }
0255 
0256         if (ngx_restart) {
0257             ngx_restart = 0;
0258             ngx_start_worker_processes(cycle, ccf->worker_processes,
0259                                        NGX_PROCESS_RESPAWN);
0260             ngx_start_cache_manager_processes(cycle, 0);
0261             live = 1;
0262         }
0263 
0264         if (ngx_reopen) {
0265             ngx_reopen = 0;
0266             ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
0267             ngx_reopen_files(cycle, ccf->user);
0268             ngx_signal_worker_processes(cycle,
0269                                         ngx_signal_value(NGX_REOPEN_SIGNAL));
0270         }
0271 
0272         if (ngx_change_binary) {
0273             ngx_change_binary = 0;
0274             ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "changing binary");
0275             ngx_new_binary = ngx_exec_new_binary(cycle, ngx_argv);
0276         }
0277 
0278         if (ngx_noaccept) {
0279             ngx_noaccept = 0;
0280             ngx_noaccepting = 1;
0281             ngx_signal_worker_processes(cycle,
0282                                         ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
0283         }
0284     }
0285 }
0286 
0287 
0288 void
0289 ngx_single_process_cycle(ngx_cycle_t *cycle)
0290 {
0291     ngx_uint_t  i;
0292 
0293     if (ngx_set_environment(cycle, NULL) == NULL) {
0294         /* fatal */
0295         exit(2);
0296     }
0297 
0298     for (i = 0; cycle->modules[i]; i++) {
0299         if (cycle->modules[i]->init_process) {
0300             if (cycle->modules[i]->init_process(cycle) == NGX_ERROR) {
0301                 /* fatal */
0302                 exit(2);
0303             }
0304         }
0305     }
0306 
0307     for ( ;; ) {
0308         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
0309 
0310         ngx_process_events_and_timers(cycle);
0311 
0312         if (ngx_terminate || ngx_quit) {
0313 
0314             for (i = 0; cycle->modules[i]; i++) {
0315                 if (cycle->modules[i]->exit_process) {
0316                     cycle->modules[i]->exit_process(cycle);
0317                 }
0318             }
0319 
0320             ngx_master_process_exit(cycle);
0321         }
0322 
0323         if (ngx_reconfigure) {
0324             ngx_reconfigure = 0;
0325             ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring");
0326 
0327             cycle = ngx_init_cycle(cycle);
0328             if (cycle == NULL) {
0329                 cycle = (ngx_cycle_t *) ngx_cycle;
0330                 continue;
0331             }
0332 
0333             ngx_cycle = cycle;
0334         }
0335 
0336         if (ngx_reopen) {
0337             ngx_reopen = 0;
0338             ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
0339             ngx_reopen_files(cycle, (ngx_uid_t) -1);
0340         }
0341     }
0342 }
0343 
0344 
0345 static void
0346 ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
0347 {
0348     ngx_int_t      i;
0349     ngx_channel_t  ch;
0350 
0351     ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
0352 
0353     ngx_memzero(&ch, sizeof(ngx_channel_t));
0354 
0355     ch.command = NGX_CMD_OPEN_CHANNEL;
0356 
0357     for (i = 0; i < n; i++) {
0358 
0359         ngx_spawn_process(cycle, ngx_worker_process_cycle,
0360                           (void *) (intptr_t) i, "worker process", type);
0361 
0362         ch.pid = ngx_processes[ngx_process_slot].pid;
0363         ch.slot = ngx_process_slot;
0364         ch.fd = ngx_processes[ngx_process_slot].channel[0];
0365 
0366         ngx_pass_open_channel(cycle, &ch);
0367     }
0368 }
0369 
0370 
0371 static void
0372 ngx_start_cache_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn)
0373 {
0374     ngx_uint_t       i, manager, loader;
0375     ngx_path_t     **path;
0376     ngx_channel_t    ch;
0377 
0378     manager = 0;
0379     loader = 0;
0380 
0381     path = ngx_cycle->paths.elts;
0382     for (i = 0; i < ngx_cycle->paths.nelts; i++) {
0383 
0384         if (path[i]->manager) {
0385             manager = 1;
0386         }
0387 
0388         if (path[i]->loader) {
0389             loader = 1;
0390         }
0391     }
0392 
0393     if (manager == 0) {
0394         return;
0395     }
0396 
0397     ngx_spawn_process(cycle, ngx_cache_manager_process_cycle,
0398                       &ngx_cache_manager_ctx, "cache manager process",
0399                       respawn ? NGX_PROCESS_JUST_RESPAWN : NGX_PROCESS_RESPAWN);
0400 
0401     ngx_memzero(&ch, sizeof(ngx_channel_t));
0402 
0403     ch.command = NGX_CMD_OPEN_CHANNEL;
0404     ch.pid = ngx_processes[ngx_process_slot].pid;
0405     ch.slot = ngx_process_slot;
0406     ch.fd = ngx_processes[ngx_process_slot].channel[0];
0407 
0408     ngx_pass_open_channel(cycle, &ch);
0409 
0410     if (loader == 0) {
0411         return;
0412     }
0413 
0414     ngx_spawn_process(cycle, ngx_cache_manager_process_cycle,
0415                       &ngx_cache_loader_ctx, "cache loader process",
0416                       respawn ? NGX_PROCESS_JUST_SPAWN : NGX_PROCESS_NORESPAWN);
0417 
0418     ch.command = NGX_CMD_OPEN_CHANNEL;
0419     ch.pid = ngx_processes[ngx_process_slot].pid;
0420     ch.slot = ngx_process_slot;
0421     ch.fd = ngx_processes[ngx_process_slot].channel[0];
0422 
0423     ngx_pass_open_channel(cycle, &ch);
0424 }
0425 
0426 
0427 static void
0428 ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch)
0429 {
0430     ngx_int_t  i;
0431 
0432     for (i = 0; i < ngx_last_process; i++) {
0433 
0434         if (i == ngx_process_slot
0435             || ngx_processes[i].pid == -1
0436             || ngx_processes[i].channel[0] == -1)
0437         {
0438             continue;
0439         }
0440 
0441         ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0,
0442                       "pass channel s:%i pid:%P fd:%d to s:%i pid:%P fd:%d",
0443                       ch->slot, ch->pid, ch->fd,
0444                       i, ngx_processes[i].pid,
0445                       ngx_processes[i].channel[0]);
0446 
0447         /* TODO: NGX_AGAIN */
0448 
0449         ngx_write_channel(ngx_processes[i].channel[0],
0450                           ch, sizeof(ngx_channel_t), cycle->log);
0451     }
0452 }
0453 
0454 
0455 static void
0456 ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo)
0457 {
0458     ngx_int_t      i;
0459     ngx_err_t      err;
0460     ngx_channel_t  ch;
0461 
0462     ngx_memzero(&ch, sizeof(ngx_channel_t));
0463 
0464 #if (NGX_BROKEN_SCM_RIGHTS)
0465 
0466     ch.command = 0;
0467 
0468 #else
0469 
0470     switch (signo) {
0471 
0472     case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
0473         ch.command = NGX_CMD_QUIT;
0474         break;
0475 
0476     case ngx_signal_value(NGX_TERMINATE_SIGNAL):
0477         ch.command = NGX_CMD_TERMINATE;
0478         break;
0479 
0480     case ngx_signal_value(NGX_REOPEN_SIGNAL):
0481         ch.command = NGX_CMD_REOPEN;
0482         break;
0483 
0484     default:
0485         ch.command = 0;
0486     }
0487 
0488 #endif
0489 
0490     ch.fd = -1;
0491 
0492 
0493     for (i = 0; i < ngx_last_process; i++) {
0494 
0495         ngx_log_debug7(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
0496                        "child: %i %P e:%d t:%d d:%d r:%d j:%d",
0497                        i,
0498                        ngx_processes[i].pid,
0499                        ngx_processes[i].exiting,
0500                        ngx_processes[i].exited,
0501                        ngx_processes[i].detached,
0502                        ngx_processes[i].respawn,
0503                        ngx_processes[i].just_spawn);
0504 
0505         if (ngx_processes[i].detached || ngx_processes[i].pid == -1) {
0506             continue;
0507         }
0508 
0509         if (ngx_processes[i].just_spawn) {
0510             ngx_processes[i].just_spawn = 0;
0511             continue;
0512         }
0513 
0514         if (ngx_processes[i].exiting
0515             && signo == ngx_signal_value(NGX_SHUTDOWN_SIGNAL))
0516         {
0517             continue;
0518         }
0519 
0520         if (ch.command) {
0521             if (ngx_write_channel(ngx_processes[i].channel[0],
0522                                   &ch, sizeof(ngx_channel_t), cycle->log)
0523                 == NGX_OK)
0524             {
0525                 if (signo != ngx_signal_value(NGX_REOPEN_SIGNAL)) {
0526                     ngx_processes[i].exiting = 1;
0527                 }
0528 
0529                 continue;
0530             }
0531         }
0532 
0533         ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
0534                        "kill (%P, %d)", ngx_processes[i].pid, signo);
0535 
0536         if (kill(ngx_processes[i].pid, signo) == -1) {
0537             err = ngx_errno;
0538             ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
0539                           "kill(%P, %d) failed", ngx_processes[i].pid, signo);
0540 
0541             if (err == NGX_ESRCH) {
0542                 ngx_processes[i].exited = 1;
0543                 ngx_processes[i].exiting = 0;
0544                 ngx_reap = 1;
0545             }
0546 
0547             continue;
0548         }
0549 
0550         if (signo != ngx_signal_value(NGX_REOPEN_SIGNAL)) {
0551             ngx_processes[i].exiting = 1;
0552         }
0553     }
0554 }
0555 
0556 
0557 static ngx_uint_t
0558 ngx_reap_children(ngx_cycle_t *cycle)
0559 {
0560     ngx_int_t         i, n;
0561     ngx_uint_t        live;
0562     ngx_channel_t     ch;
0563     ngx_core_conf_t  *ccf;
0564 
0565     ngx_memzero(&ch, sizeof(ngx_channel_t));
0566 
0567     ch.command = NGX_CMD_CLOSE_CHANNEL;
0568     ch.fd = -1;
0569 
0570     live = 0;
0571     for (i = 0; i < ngx_last_process; i++) {
0572 
0573         ngx_log_debug7(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
0574                        "child: %i %P e:%d t:%d d:%d r:%d j:%d",
0575                        i,
0576                        ngx_processes[i].pid,
0577                        ngx_processes[i].exiting,
0578                        ngx_processes[i].exited,
0579                        ngx_processes[i].detached,
0580                        ngx_processes[i].respawn,
0581                        ngx_processes[i].just_spawn);
0582 
0583         if (ngx_processes[i].pid == -1) {
0584             continue;
0585         }
0586 
0587         if (ngx_processes[i].exited) {
0588 
0589             if (!ngx_processes[i].detached) {
0590                 ngx_close_channel(ngx_processes[i].channel, cycle->log);
0591 
0592                 ngx_processes[i].channel[0] = -1;
0593                 ngx_processes[i].channel[1] = -1;
0594 
0595                 ch.pid = ngx_processes[i].pid;
0596                 ch.slot = i;
0597 
0598                 for (n = 0; n < ngx_last_process; n++) {
0599                     if (ngx_processes[n].exited
0600                         || ngx_processes[n].pid == -1
0601                         || ngx_processes[n].channel[0] == -1)
0602                     {
0603                         continue;
0604                     }
0605 
0606                     ngx_log_debug3(NGX_LOG_DEBUG_CORE, cycle->log, 0,
0607                                    "pass close channel s:%i pid:%P to:%P",
0608                                    ch.slot, ch.pid, ngx_processes[n].pid);
0609 
0610                     /* TODO: NGX_AGAIN */
0611 
0612                     ngx_write_channel(ngx_processes[n].channel[0],
0613                                       &ch, sizeof(ngx_channel_t), cycle->log);
0614                 }
0615             }
0616 
0617             if (ngx_processes[i].respawn
0618                 && !ngx_processes[i].exiting
0619                 && !ngx_terminate
0620                 && !ngx_quit)
0621             {
0622                 if (ngx_spawn_process(cycle, ngx_processes[i].proc,
0623                                       ngx_processes[i].data,
0624                                       ngx_processes[i].name, i)
0625                     == NGX_INVALID_PID)
0626                 {
0627                     ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
0628                                   "could not respawn %s",
0629                                   ngx_processes[i].name);
0630                     continue;
0631                 }
0632 
0633 
0634                 ch.command = NGX_CMD_OPEN_CHANNEL;
0635                 ch.pid = ngx_processes[ngx_process_slot].pid;
0636                 ch.slot = ngx_process_slot;
0637                 ch.fd = ngx_processes[ngx_process_slot].channel[0];
0638 
0639                 ngx_pass_open_channel(cycle, &ch);
0640 
0641                 live = 1;
0642 
0643                 continue;
0644             }
0645 
0646             if (ngx_processes[i].pid == ngx_new_binary) {
0647 
0648                 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
0649                                                        ngx_core_module);
0650 
0651                 if (ngx_rename_file((char *) ccf->oldpid.data,
0652                                     (char *) ccf->pid.data)
0653                     == NGX_FILE_ERROR)
0654                 {
0655                     ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
0656                                   ngx_rename_file_n " %s back to %s failed "
0657                                   "after the new binary process \"%s\" exited",
0658                                   ccf->oldpid.data, ccf->pid.data, ngx_argv[0]);
0659                 }
0660 
0661                 ngx_new_binary = 0;
0662                 if (ngx_noaccepting) {
0663                     ngx_restart = 1;
0664                     ngx_noaccepting = 0;
0665                 }
0666             }
0667 
0668             if (i == ngx_last_process - 1) {
0669                 ngx_last_process--;
0670 
0671             } else {
0672                 ngx_processes[i].pid = -1;
0673             }
0674 
0675         } else if (ngx_processes[i].exiting || !ngx_processes[i].detached) {
0676             live = 1;
0677         }
0678     }
0679 
0680     return live;
0681 }
0682 
0683 
0684 static void
0685 ngx_master_process_exit(ngx_cycle_t *cycle)
0686 {
0687     ngx_uint_t  i;
0688 
0689     ngx_delete_pidfile(cycle);
0690 
0691     ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exit");
0692 
0693     for (i = 0; cycle->modules[i]; i++) {
0694         if (cycle->modules[i]->exit_master) {
0695             cycle->modules[i]->exit_master(cycle);
0696         }
0697     }
0698 
0699     ngx_close_listening_sockets(cycle);
0700 
0701     /*
0702      * Copy ngx_cycle->log related data to the special static exit cycle,
0703      * log, and log file structures enough to allow a signal handler to log.
0704      * The handler may be called when standard ngx_cycle->log allocated from
0705      * ngx_cycle->pool is already destroyed.
0706      */
0707 
0708 
0709     ngx_exit_log = *ngx_log_get_file_log(ngx_cycle->log);
0710 
0711     ngx_exit_log_file.fd = ngx_exit_log.file->fd;
0712     ngx_exit_log.file = &ngx_exit_log_file;
0713     ngx_exit_log.next = NULL;
0714     ngx_exit_log.writer = NULL;
0715 
0716     ngx_exit_cycle.log = &ngx_exit_log;
0717     ngx_exit_cycle.files = ngx_cycle->files;
0718     ngx_exit_cycle.files_n = ngx_cycle->files_n;
0719     ngx_cycle = &ngx_exit_cycle;
0720 
0721     ngx_destroy_pool(cycle->pool);
0722 
0723     exit(0);
0724 }
0725 
0726 
0727 static void
0728 ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
0729 {
0730     ngx_int_t worker = (intptr_t) data;
0731 
0732     ngx_process = NGX_PROCESS_WORKER;
0733     ngx_worker = worker;
0734 
0735     ngx_worker_process_init(cycle, worker);
0736 
0737     ngx_setproctitle("worker process");
0738 
0739     for ( ;; ) {
0740 
0741         if (ngx_exiting) {
0742             if (ngx_event_no_timers_left() == NGX_OK) {
0743                 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
0744                 ngx_worker_process_exit(cycle);
0745             }
0746         }
0747 
0748         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
0749 
0750         ngx_process_events_and_timers(cycle);
0751 
0752         if (ngx_terminate) {
0753             ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
0754             ngx_worker_process_exit(cycle);
0755         }
0756 
0757         if (ngx_quit) {
0758             ngx_quit = 0;
0759             ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
0760                           "gracefully shutting down");
0761             ngx_setproctitle("worker process is shutting down");
0762 
0763             if (!ngx_exiting) {
0764                 ngx_exiting = 1;
0765                 ngx_set_shutdown_timer(cycle);
0766                 ngx_close_listening_sockets(cycle);
0767                 ngx_close_idle_connections(cycle);
0768             }
0769         }
0770 
0771         if (ngx_reopen) {
0772             ngx_reopen = 0;
0773             ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
0774             ngx_reopen_files(cycle, -1);
0775         }
0776     }
0777 }
0778 
0779 
0780 static void
0781 ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
0782 {
0783     sigset_t          set;
0784     ngx_int_t         n;
0785     ngx_time_t       *tp;
0786     ngx_uint_t        i;
0787     ngx_cpuset_t     *cpu_affinity;
0788     struct rlimit     rlmt;
0789     ngx_core_conf_t  *ccf;
0790     ngx_listening_t  *ls;
0791 
0792     if (ngx_set_environment(cycle, NULL) == NULL) {
0793         /* fatal */
0794         exit(2);
0795     }
0796 
0797     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
0798 
0799     if (worker >= 0 && ccf->priority != 0) {
0800         if (setpriority(PRIO_PROCESS, 0, ccf->priority) == -1) {
0801             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
0802                           "setpriority(%d) failed", ccf->priority);
0803         }
0804     }
0805 
0806     if (ccf->rlimit_nofile != NGX_CONF_UNSET) {
0807         rlmt.rlim_cur = (rlim_t) ccf->rlimit_nofile;
0808         rlmt.rlim_max = (rlim_t) ccf->rlimit_nofile;
0809 
0810         if (setrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
0811             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
0812                           "setrlimit(RLIMIT_NOFILE, %i) failed",
0813                           ccf->rlimit_nofile);
0814         }
0815     }
0816 
0817     if (ccf->rlimit_core != NGX_CONF_UNSET) {
0818         rlmt.rlim_cur = (rlim_t) ccf->rlimit_core;
0819         rlmt.rlim_max = (rlim_t) ccf->rlimit_core;
0820 
0821         if (setrlimit(RLIMIT_CORE, &rlmt) == -1) {
0822             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
0823                           "setrlimit(RLIMIT_CORE, %O) failed",
0824                           ccf->rlimit_core);
0825         }
0826     }
0827 
0828     if (geteuid() == 0) {
0829         if (setgid(ccf->group) == -1) {
0830             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
0831                           "setgid(%d) failed", ccf->group);
0832             /* fatal */
0833             exit(2);
0834         }
0835 
0836         if (initgroups(ccf->username, ccf->group) == -1) {
0837             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
0838                           "initgroups(%s, %d) failed",
0839                           ccf->username, ccf->group);
0840         }
0841 
0842 #if (NGX_HAVE_PR_SET_KEEPCAPS && NGX_HAVE_CAPABILITIES)
0843         if (ccf->transparent && ccf->user) {
0844             if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) {
0845                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
0846                               "prctl(PR_SET_KEEPCAPS, 1) failed");
0847                 /* fatal */
0848                 exit(2);
0849             }
0850         }
0851 #endif
0852 
0853         if (setuid(ccf->user) == -1) {
0854             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
0855                           "setuid(%d) failed", ccf->user);
0856             /* fatal */
0857             exit(2);
0858         }
0859 
0860 #if (NGX_HAVE_CAPABILITIES)
0861         if (ccf->transparent && ccf->user) {
0862             struct __user_cap_data_struct    data;
0863             struct __user_cap_header_struct  header;
0864 
0865             ngx_memzero(&header, sizeof(struct __user_cap_header_struct));
0866             ngx_memzero(&data, sizeof(struct __user_cap_data_struct));
0867 
0868             header.version = _LINUX_CAPABILITY_VERSION_1;
0869             data.effective = CAP_TO_MASK(CAP_NET_RAW);
0870             data.permitted = data.effective;
0871 
0872             if (syscall(SYS_capset, &header, &data) == -1) {
0873                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
0874                               "capset() failed");
0875                 /* fatal */
0876                 exit(2);
0877             }
0878         }
0879 #endif
0880     }
0881 
0882     if (worker >= 0) {
0883         cpu_affinity = ngx_get_cpu_affinity(worker);
0884 
0885         if (cpu_affinity) {
0886             ngx_setaffinity(cpu_affinity, cycle->log);
0887         }
0888     }
0889 
0890 #if (NGX_HAVE_PR_SET_DUMPABLE)
0891 
0892     /* allow coredump after setuid() in Linux 2.4.x */
0893 
0894     if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
0895         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
0896                       "prctl(PR_SET_DUMPABLE) failed");
0897     }
0898 
0899 #endif
0900 
0901     if (ccf->working_directory.len) {
0902         if (chdir((char *) ccf->working_directory.data) == -1) {
0903             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
0904                           "chdir(\"%s\") failed", ccf->working_directory.data);
0905             /* fatal */
0906             exit(2);
0907         }
0908     }
0909 
0910     sigemptyset(&set);
0911 
0912     if (sigprocmask(SIG_SETMASK, &set, NULL) == -1) {
0913         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
0914                       "sigprocmask() failed");
0915     }
0916 
0917     tp = ngx_timeofday();
0918     srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec);
0919 
0920     /*
0921      * disable deleting previous events for the listening sockets because
0922      * in the worker processes there are no events at all at this point
0923      */
0924     ls = cycle->listening.elts;
0925     for (i = 0; i < cycle->listening.nelts; i++) {
0926         ls[i].previous = NULL;
0927     }
0928 
0929     for (i = 0; cycle->modules[i]; i++) {
0930         if (cycle->modules[i]->init_process) {
0931             if (cycle->modules[i]->init_process(cycle) == NGX_ERROR) {
0932                 /* fatal */
0933                 exit(2);
0934             }
0935         }
0936     }
0937 
0938     for (n = 0; n < ngx_last_process; n++) {
0939 
0940         if (ngx_processes[n].pid == -1) {
0941             continue;
0942         }
0943 
0944         if (n == ngx_process_slot) {
0945             continue;
0946         }
0947 
0948         if (ngx_processes[n].channel[1] == -1) {
0949             continue;
0950         }
0951 
0952         if (close(ngx_processes[n].channel[1]) == -1) {
0953             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
0954                           "close() channel failed");
0955         }
0956     }
0957 
0958     if (close(ngx_processes[ngx_process_slot].channel[0]) == -1) {
0959         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
0960                       "close() channel failed");
0961     }
0962 
0963 #if 0
0964     ngx_last_process = 0;
0965 #endif
0966 
0967     if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT,
0968                               ngx_channel_handler)
0969         == NGX_ERROR)
0970     {
0971         /* fatal */
0972         exit(2);
0973     }
0974 }
0975 
0976 
0977 static void
0978 ngx_worker_process_exit(ngx_cycle_t *cycle)
0979 {
0980     ngx_uint_t         i;
0981     ngx_connection_t  *c;
0982 
0983     for (i = 0; cycle->modules[i]; i++) {
0984         if (cycle->modules[i]->exit_process) {
0985             cycle->modules[i]->exit_process(cycle);
0986         }
0987     }
0988 
0989     if (ngx_exiting) {
0990         c = cycle->connections;
0991         for (i = 0; i < cycle->connection_n; i++) {
0992             if (c[i].fd != -1
0993                 && c[i].read
0994                 && !c[i].read->accept
0995                 && !c[i].read->channel
0996                 && !c[i].read->resolver)
0997             {
0998                 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
0999                               "*%uA open socket #%d left in connection %ui",
1000                               c[i].number, c[i].fd, i);
1001                 ngx_debug_quit = 1;
1002             }
1003         }
1004 
1005         if (ngx_debug_quit) {
1006             ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "aborting");
1007             ngx_debug_point();
1008         }
1009     }
1010 
1011     /*
1012      * Copy ngx_cycle->log related data to the special static exit cycle,
1013      * log, and log file structures enough to allow a signal handler to log.
1014      * The handler may be called when standard ngx_cycle->log allocated from
1015      * ngx_cycle->pool is already destroyed.
1016      */
1017 
1018     ngx_exit_log = *ngx_log_get_file_log(ngx_cycle->log);
1019 
1020     ngx_exit_log_file.fd = ngx_exit_log.file->fd;
1021     ngx_exit_log.file = &ngx_exit_log_file;
1022     ngx_exit_log.next = NULL;
1023     ngx_exit_log.writer = NULL;
1024 
1025     ngx_exit_cycle.log = &ngx_exit_log;
1026     ngx_exit_cycle.files = ngx_cycle->files;
1027     ngx_exit_cycle.files_n = ngx_cycle->files_n;
1028     ngx_cycle = &ngx_exit_cycle;
1029 
1030     ngx_destroy_pool(cycle->pool);
1031 
1032     ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, "exit");
1033 
1034     exit(0);
1035 }
1036 
1037 
1038 static void
1039 ngx_channel_handler(ngx_event_t *ev)
1040 {
1041     ngx_int_t          n;
1042     ngx_channel_t      ch;
1043     ngx_connection_t  *c;
1044 
1045     if (ev->timedout) {
1046         ev->timedout = 0;
1047         return;
1048     }
1049 
1050     c = ev->data;
1051 
1052     ngx_log_debug0(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel handler");
1053 
1054     for ( ;; ) {
1055 
1056         n = ngx_read_channel(c->fd, &ch, sizeof(ngx_channel_t), ev->log);
1057 
1058         ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel: %i", n);
1059 
1060         if (n == NGX_ERROR) {
1061 
1062             if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
1063                 ngx_del_conn(c, 0);
1064             }
1065 
1066             ngx_close_connection(c);
1067             return;
1068         }
1069 
1070         if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
1071             if (ngx_add_event(ev, NGX_READ_EVENT, 0) == NGX_ERROR) {
1072                 return;
1073             }
1074         }
1075 
1076         if (n == NGX_AGAIN) {
1077             return;
1078         }
1079 
1080         ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0,
1081                        "channel command: %ui", ch.command);
1082 
1083         switch (ch.command) {
1084 
1085         case NGX_CMD_QUIT:
1086             ngx_quit = 1;
1087             break;
1088 
1089         case NGX_CMD_TERMINATE:
1090             ngx_terminate = 1;
1091             break;
1092 
1093         case NGX_CMD_REOPEN:
1094             ngx_reopen = 1;
1095             break;
1096 
1097         case NGX_CMD_OPEN_CHANNEL:
1098 
1099             ngx_log_debug3(NGX_LOG_DEBUG_CORE, ev->log, 0,
1100                            "get channel s:%i pid:%P fd:%d",
1101                            ch.slot, ch.pid, ch.fd);
1102 
1103             ngx_processes[ch.slot].pid = ch.pid;
1104             ngx_processes[ch.slot].channel[0] = ch.fd;
1105             break;
1106 
1107         case NGX_CMD_CLOSE_CHANNEL:
1108 
1109             ngx_log_debug4(NGX_LOG_DEBUG_CORE, ev->log, 0,
1110                            "close channel s:%i pid:%P our:%P fd:%d",
1111                            ch.slot, ch.pid, ngx_processes[ch.slot].pid,
1112                            ngx_processes[ch.slot].channel[0]);
1113 
1114             if (close(ngx_processes[ch.slot].channel[0]) == -1) {
1115                 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
1116                               "close() channel failed");
1117             }
1118 
1119             ngx_processes[ch.slot].channel[0] = -1;
1120             break;
1121         }
1122     }
1123 }
1124 
1125 
1126 static void
1127 ngx_cache_manager_process_cycle(ngx_cycle_t *cycle, void *data)
1128 {
1129     ngx_cache_manager_ctx_t *ctx = data;
1130 
1131     void         *ident[4];
1132     ngx_event_t   ev;
1133 
1134     /*
1135      * Set correct process type since closing listening Unix domain socket
1136      * in a master process also removes the Unix domain socket file.
1137      */
1138     ngx_process = NGX_PROCESS_HELPER;
1139 
1140     ngx_close_listening_sockets(cycle);
1141 
1142     /* Set a moderate number of connections for a helper process. */
1143     cycle->connection_n = 512;
1144 
1145     ngx_worker_process_init(cycle, -1);
1146 
1147     ngx_memzero(&ev, sizeof(ngx_event_t));
1148     ev.handler = ctx->handler;
1149     ev.data = ident;
1150     ev.log = cycle->log;
1151     ident[3] = (void *) -1;
1152 
1153     ngx_use_accept_mutex = 0;
1154 
1155     ngx_setproctitle(ctx->name);
1156 
1157     ngx_add_timer(&ev, ctx->delay);
1158 
1159     for ( ;; ) {
1160 
1161         if (ngx_terminate || ngx_quit) {
1162             ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
1163             exit(0);
1164         }
1165 
1166         if (ngx_reopen) {
1167             ngx_reopen = 0;
1168             ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
1169             ngx_reopen_files(cycle, -1);
1170         }
1171 
1172         ngx_process_events_and_timers(cycle);
1173     }
1174 }
1175 
1176 
1177 static void
1178 ngx_cache_manager_process_handler(ngx_event_t *ev)
1179 {
1180     ngx_uint_t    i;
1181     ngx_msec_t    next, n;
1182     ngx_path_t  **path;
1183 
1184     next = 60 * 60 * 1000;
1185 
1186     path = ngx_cycle->paths.elts;
1187     for (i = 0; i < ngx_cycle->paths.nelts; i++) {
1188 
1189         if (path[i]->manager) {
1190             n = path[i]->manager(path[i]->data);
1191 
1192             next = (n <= next) ? n : next;
1193 
1194             ngx_time_update();
1195         }
1196     }
1197 
1198     if (next == 0) {
1199         next = 1;
1200     }
1201 
1202     ngx_add_timer(ev, next);
1203 }
1204 
1205 
1206 static void
1207 ngx_cache_loader_process_handler(ngx_event_t *ev)
1208 {
1209     ngx_uint_t     i;
1210     ngx_path_t   **path;
1211     ngx_cycle_t   *cycle;
1212 
1213     cycle = (ngx_cycle_t *) ngx_cycle;
1214 
1215     path = cycle->paths.elts;
1216     for (i = 0; i < cycle->paths.nelts; i++) {
1217 
1218         if (ngx_terminate || ngx_quit) {
1219             break;
1220         }
1221 
1222         if (path[i]->loader) {
1223             path[i]->loader(path[i]->data);
1224             ngx_time_update();
1225         }
1226     }
1227 
1228     exit(0);
1229 }