~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/core/ngx_cycle.c

Version: ~ [ nginx-0.8.20 ] ~ [ nginx-0.7.62 ] ~ [ nginx-0.6.39 ] ~

  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 }
1344 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.