comparison src/core/nginx.c @ 219:f57597ec5249

nginx-0.0.1-2004-01-06-19:49:34 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 06 Jan 2004 16:49:34 +0000
parents 05592fd7a436
children 4f81b931e9ff
comparison
equal deleted inserted replaced
218:05592fd7a436 219:f57597ec5249
4 #include <ngx_event.h> 4 #include <ngx_event.h>
5 #include <nginx.h> 5 #include <nginx.h>
6 6
7 7
8 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data); 8 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data);
9 static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle, char **envp);
9 static void ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv); 10 static void ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv);
10 static ngx_int_t ngx_core_module_init(ngx_cycle_t *cycle); 11 static ngx_int_t ngx_core_module_init(ngx_cycle_t *cycle);
11 12
12 13
13 typedef struct { 14 typedef struct {
124 125
125 if (!(init_cycle.pool = ngx_create_pool(1024, log))) { 126 if (!(init_cycle.pool = ngx_create_pool(1024, log))) {
126 return 1; 127 return 1;
127 } 128 }
128 129
129 if (ngx_set_inherited_sockets(&init_cycle, envp) == NGX_ERROR) { 130 if (ngx_add_inherited_sockets(&init_cycle, envp) == NGX_ERROR) {
130 return 1; 131 return 1;
131 } 132 }
132 133
133 cycle = ngx_init_cycle(&init_cycle); 134 cycle = ngx_init_cycle(&init_cycle);
134 if (cycle == NULL) { 135 if (cycle == NULL) {
325 break; 326 break;
326 } 327 }
327 } 328 }
328 } 329 }
329 330
330 #if 0 331
331 332 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
332 static ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle)
333 { 333 {
334 ngx_int_t i, n, failed; 334 ngx_int_t i;
335 ngx_str_t conf_file; 335 ngx_listening_t *ls;
336 ngx_log_t *log; 336
337 ngx_conf_t conf; 337 if (user) {
338 ngx_pool_t *pool; 338 if (setuid(user) == -1) {
339 ngx_cycle_t *cycle, **old; 339 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
340 ngx_socket_t fd; 340 "setuid() failed");
341 ngx_core_conf_t *ccf; 341 /* fatal */
342 ngx_open_file_t *file; 342 exit(1);
343 ngx_listening_t *ls, *nls; 343 }
344 344 }
345 log = old_cycle->log; 345
346 346 ngx_init_temp_number();
347 if (!(pool = ngx_create_pool(16 * 1024, log))) { 347
348 return NULL; 348 /*
349 } 349 * disable deleting previous events for the listening sockets because
350 350 * in the worker processes there are no events at all at this point
351 if (!(cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t)))) { 351 */
352 ngx_destroy_pool(pool); 352 ls = cycle->listening.elts;
353 return NULL; 353 for (i = 0; i < cycle->listening.nelts; i++) {
354 } 354 ls[i].remain = 0;
355 cycle->pool = pool; 355 }
356
357 cycle->old_cycle = old_cycle;
358
359
360 n = old_cycle->pathes.nelts ? old_cycle->pathes.nelts : 10;
361 if (!(cycle->pathes.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *)))) {
362 ngx_destroy_pool(pool);
363 return NULL;
364 }
365 cycle->pathes.nelts = 0;
366 cycle->pathes.size = sizeof(ngx_path_t *);
367 cycle->pathes.nalloc = n;
368 cycle->pathes.pool = pool;
369
370
371 n = old_cycle->open_files.nelts ? old_cycle->open_files.nelts : 20;
372 cycle->open_files.elts = ngx_pcalloc(pool, n * sizeof(ngx_open_file_t));
373 if (cycle->open_files.elts == NULL) {
374 ngx_destroy_pool(pool);
375 return NULL;
376 }
377 cycle->open_files.nelts = 0;
378 cycle->open_files.size = sizeof(ngx_open_file_t);
379 cycle->open_files.nalloc = n;
380 cycle->open_files.pool = pool;
381
382
383 if (!(cycle->log = ngx_log_create_errlog(cycle, NULL))) {
384 ngx_destroy_pool(pool);
385 return NULL;
386 }
387
388
389 n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;
390 cycle->listening.elts = ngx_pcalloc(pool, n * sizeof(ngx_listening_t));
391 if (cycle->listening.elts == NULL) {
392 ngx_destroy_pool(pool);
393 return NULL;
394 }
395 cycle->listening.nelts = 0;
396 cycle->listening.size = sizeof(ngx_listening_t);
397 cycle->listening.nalloc = n;
398 cycle->listening.pool = pool;
399
400
401 cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
402 if (cycle->conf_ctx == NULL) {
403 ngx_destroy_pool(pool);
404 return NULL;
405 }
406
407
408 if (!(ccf = ngx_pcalloc(pool, sizeof(ngx_core_conf_t)))) {
409 ngx_destroy_pool(pool);
410 return NULL;
411 }
412 /* set by pcalloc()
413 *
414 * ccf->pid = NULL;
415 */
416 ccf->daemon = -1;
417 ccf->single = -1;
418 ((void **)(cycle->conf_ctx))[ngx_core_module.index] = ccf;
419
420
421 ngx_memzero(&conf, sizeof(ngx_conf_t));
422 /* STUB: init array ? */
423 conf.args = ngx_create_array(pool, 10, sizeof(ngx_str_t));
424 if (conf.args == NULL) {
425 ngx_destroy_pool(pool);
426 return NULL;
427 }
428
429 conf.ctx = cycle->conf_ctx;
430 conf.cycle = cycle;
431 /* STUB */ conf.pool = cycle->pool;
432 conf.log = log;
433 conf.module_type = NGX_CORE_MODULE;
434 conf.cmd_type = NGX_MAIN_CONF;
435
436 conf_file.len = sizeof(NGINX_CONF) - 1;
437 conf_file.data = NGINX_CONF;
438
439 if (ngx_conf_parse(&conf, &conf_file) != NGX_CONF_OK) {
440 ngx_destroy_pool(pool);
441 return NULL;
442 }
443
444
445 failed = 0;
446
447 file = cycle->open_files.elts;
448 for (i = 0; i < cycle->open_files.nelts; i++) {
449 if (file[i].name.data == NULL) {
450 continue;
451 }
452
453 file[i].fd = ngx_open_file(file[i].name.data,
454 NGX_FILE_RDWR,
455 NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND);
456
457 ngx_log_debug(log, "OPEN: %d:%s" _ file[i].fd _ file[i].name.data);
458
459 if (file[i].fd == NGX_INVALID_FILE) {
460 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
461 ngx_open_file_n " \"%s\" failed",
462 file[i].name.data);
463 failed = 1;
464 break;
465 }
466
467 #if (WIN32)
468 if (ngx_file_append_mode(file[i].fd) == NGX_ERROR) {
469 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
470 ngx_file_append_mode_n " \"%s\" failed",
471 file[i].name.data);
472 failed = 1;
473 break;
474 }
475 #endif
476 }
477
478 if (!failed) {
479 if (old_cycle->listening.nelts) {
480 ls = old_cycle->listening.elts;
481 for (i = 0; i < old_cycle->listening.nelts; i++) {
482 ls[i].remain = 0;
483 }
484
485 nls = cycle->listening.elts;
486 for (n = 0; n < cycle->listening.nelts; n++) {
487 for (i = 0; i < old_cycle->listening.nelts; i++) {
488 if (ls[i].ignore) {
489 continue;
490 }
491
492 ngx_log_error(NGX_LOG_INFO, log, 0,
493 "%X, %X",
494 *(int *) ls[i].sockaddr,
495 *(int *) nls[n].sockaddr);
496
497 if (ngx_memcmp(nls[n].sockaddr,
498 ls[i].sockaddr, ls[i].socklen) == 0)
499 {
500 fd = ls[i].fd;
501 #if (WIN32)
502 /*
503 * Winsock assignes a socket number divisible by 4 so
504 * to find a connection we divide a socket number by 4.
505 */
506
507 fd /= 4;
508 #endif
509 if (fd >= (ngx_socket_t) cycle->connection_n) {
510 ngx_log_error(NGX_LOG_EMERG, log, 0,
511 "%d connections is not enough to hold "
512 "an open listening socket on %s, "
513 "required at least %d connections",
514 cycle->connection_n,
515 ls[i].addr_text.data, fd);
516 failed = 1;
517 break;
518 }
519
520 nls[n].fd = ls[i].fd;
521 nls[i].remain = 1;
522 ls[i].remain = 1;
523 break;
524 }
525 }
526
527 if (nls[n].fd == -1) {
528 nls[n].new = 1;
529 }
530 }
531
532 } else {
533 ls = cycle->listening.elts;
534 for (i = 0; i < cycle->listening.nelts; i++) {
535 ls[i].new = 1;
536 }
537 }
538
539 if (!failed) {
540 if (ngx_open_listening_sockets(cycle) == NGX_ERROR) {
541 failed = 1;
542 }
543 }
544 }
545
546 if (failed) {
547
548 /* rollback the new cycle configuration */
549
550 file = cycle->open_files.elts;
551 for (i = 0; i < cycle->open_files.nelts; i++) {
552 if (file[i].fd == NGX_INVALID_FILE) {
553 continue;
554 }
555
556 if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
557 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
558 ngx_close_file_n " \"%s\" failed",
559 file[i].name.data);
560 }
561 }
562
563 ls = cycle->listening.elts;
564 for (i = 0; i < cycle->listening.nelts; i++) {
565 if (ls[i].new && ls[i].fd == -1) {
566 continue;
567 }
568
569 if (ngx_close_socket(ls[i].fd) == -1) {
570 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
571 ngx_close_socket_n " %s failed",
572 ls[i].addr_text.data);
573 }
574 }
575
576 ngx_destroy_pool(pool);
577 return NULL;
578 }
579
580 /* commit the new cycle configuration */
581
582 pool->log = cycle->log;
583
584 356
585 for (i = 0; ngx_modules[i]; i++) { 357 for (i = 0; ngx_modules[i]; i++) {
586 if (ngx_modules[i]->init_module) { 358 if (ngx_modules[i]->init_process) {
587 if (ngx_modules[i]->init_module(cycle) == NGX_ERROR) { 359 if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
588 /* fatal */ 360 /* fatal */
589 exit(1); 361 exit(1);
590 } 362 }
591 } 363 }
592 } 364 }
593 365
594 /* close and delete stuff that lefts from an old cycle */ 366 /* TODO: threads: start ngx_worker_thread_cycle() */
595 367
596 /* close the unneeded listening sockets */ 368 for ( ;; ) {
597 369 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
598 ls = old_cycle->listening.elts; 370
599 for (i = 0; i < old_cycle->listening.nelts; i++) { 371 ngx_process_events(cycle->log);
600 if (ls[i].remain) { 372
601 continue; 373 if (ngx_terminate) {
602 } 374 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting");
603 375 exit(0);
604 if (ngx_close_socket(ls[i].fd) == -1) { 376 }
605 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, 377
606 ngx_close_socket_n " %s failed", 378 if (ngx_quit) {
607 ls[i].addr_text.data); 379 ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
608 } 380 "gracefully shutdowning");
609 } 381 break;
610 382 }
611 383
612 /* close the unneeded open files */ 384 if (ngx_reopen) {
613 385 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopen logs");
614 file = old_cycle->open_files.elts; 386 ngx_reopen_files(cycle);
615 for (i = 0; i < old_cycle->open_files.nelts; i++) { 387 ngx_reopen = 0;
616 if (file[i].fd == NGX_INVALID_FILE) { 388 }
617 continue; 389 }
618 } 390
619 391 ngx_close_listening_sockets(cycle);
620 if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) { 392
621 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, 393 for ( ;; ) {
622 ngx_close_file_n " \"%s\" failed", 394 if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) {
623 file[i].name.data); 395 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting");
624 } 396 exit(0);
625 } 397 }
626 398
627 if (old_cycle->connections == NULL) { 399 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
628 /* an old cycle is an init cycle */ 400
629 ngx_destroy_pool(old_cycle->pool); 401 ngx_process_events(cycle->log);
630 return cycle; 402 }
631 }
632
633 if (master) {
634 ngx_destroy_pool(old_cycle->pool);
635 return cycle;
636 }
637
638 if (ngx_temp_pool == NULL) {
639 ngx_temp_pool = ngx_create_pool(128, cycle->log);
640 if (ngx_temp_pool == NULL) {
641 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
642 "can not create ngx_temp_pool");
643 exit(1);
644 }
645
646 n = 10;
647 ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool,
648 n * sizeof(ngx_cycle_t *));
649 if (ngx_old_cycles.elts == NULL) {
650 exit(1);
651 }
652 ngx_old_cycles.nelts = 0;
653 ngx_old_cycles.size = sizeof(ngx_cycle_t *);
654 ngx_old_cycles.nalloc = n;
655 ngx_old_cycles.pool = ngx_temp_pool;
656
657 ngx_cleaner_event.event_handler = ngx_clean_old_cycles;
658 ngx_cleaner_event.log = cycle->log;
659 ngx_cleaner_event.data = &dumb;
660 dumb.fd = (ngx_socket_t) -1;
661 }
662
663 ngx_temp_pool->log = cycle->log;
664
665 old = ngx_push_array(&ngx_old_cycles);
666 if (old == NULL) {
667 exit(1);
668 }
669 *old = old_cycle;
670
671 if (!ngx_cleaner_event.timer_set) {
672 ngx_add_timer(&ngx_cleaner_event, 30000);
673 ngx_cleaner_event.timer_set = 1;
674 }
675
676 return cycle;
677 } 403 }
678 404
679 #endif 405
680 406 static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle, char **envp)
681
682 #if 0
683
684 static ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle, char **envp)
685 { 407 {
686 char *p, *v; 408 char *p, *v;
687 ngx_socket_t s; 409 ngx_socket_t s;
688 ngx_listening_t *ls; 410 ngx_listening_t *ls;
689 struct sockaddr_in *addr_in;
690 411
691 for ( /* void */ ; *envp; envp++) { 412 for ( /* void */ ; *envp; envp++) {
692 if (ngx_strncmp(*envp, NGINX_VAR, NGINX_VAR_LEN) != 0) { 413 if (ngx_strncmp(*envp, NGINX_VAR, NGINX_VAR_LEN) != 0) {
693 continue; 414 continue;
694 } 415 }
714 if (!(ls = ngx_push_array(&cycle->listening))) { 435 if (!(ls = ngx_push_array(&cycle->listening))) {
715 return NGX_ERROR; 436 return NGX_ERROR;
716 } 437 }
717 438
718 ls->fd = s; 439 ls->fd = s;
719
720 /* AF_INET only */
721
722 ls->sockaddr = ngx_palloc(cycle->pool,
723 sizeof(struct sockaddr_in));
724 if (ls->sockaddr == NULL) {
725 return NGX_ERROR;
726 }
727
728 ls->socklen = sizeof(struct sockaddr_in);
729 if (getsockname(s, ls->sockaddr, &ls->socklen) == -1) {
730 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
731 "getsockname() of the inherited "
732 "socket #%d failed", s);
733 ls->ignore = 1;
734 continue;
735 }
736
737 addr_in = (struct sockaddr_in *) ls->sockaddr;
738
739 if (addr_in->sin_family != AF_INET) {
740 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
741 "the inherited socket #%d has "
742 "unsupported family", s);
743 ls->ignore = 1;
744 continue;
745 }
746 ls->addr_text_max_len = INET_ADDRSTRLEN;
747
748 ls->addr_text.data = ngx_palloc(cycle->pool,
749 ls->addr_text_max_len);
750 if (ls->addr_text.data == NULL) {
751 return NGX_ERROR;
752 }
753
754 addr_in->sin_len = 0;
755
756 ls->family = addr_in->sin_family;
757 ls->addr_text.len = ngx_sock_ntop(ls->family, ls->sockaddr,
758 ls->addr_text.data,
759 ls->addr_text_max_len);
760 if (ls->addr_text.len == 0) {
761 return NGX_ERROR;
762 }
763 } 440 }
764 } 441 }
765 442
766 break; 443 return ngx_set_inherited_sockets(cycle);
767 } 444 }
768 445
769 return NGX_OK; 446 return NGX_OK;
770 }
771
772 #endif
773
774
775 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
776 {
777 ngx_int_t i;
778 ngx_listening_t *ls;
779
780 if (user) {
781 if (setuid(user) == -1) {
782 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
783 "setuid() failed");
784 /* fatal */
785 exit(1);
786 }
787 }
788
789 ngx_init_temp_number();
790
791 /*
792 * disable deleting previous events for the listening sockets because
793 * in the worker processes there are no events at all at this point
794 */
795 ls = cycle->listening.elts;
796 for (i = 0; i < cycle->listening.nelts; i++) {
797 ls[i].remain = 0;
798 }
799
800 for (i = 0; ngx_modules[i]; i++) {
801 if (ngx_modules[i]->init_process) {
802 if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
803 /* fatal */
804 exit(1);
805 }
806 }
807 }
808
809 /* TODO: threads: start ngx_worker_thread_cycle() */
810
811 for ( ;; ) {
812 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
813
814 ngx_process_events(cycle->log);
815
816 if (ngx_terminate) {
817 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting");
818 exit(0);
819 }
820
821 if (ngx_quit) {
822 ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
823 "gracefully shutdowning");
824 break;
825 }
826
827 if (ngx_reopen) {
828 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopen logs");
829 ngx_reopen_files(cycle);
830 ngx_reopen = 0;
831 }
832 }
833
834 ngx_close_listening_sockets(cycle);
835
836 for ( ;; ) {
837 if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) {
838 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting");
839 exit(0);
840 }
841
842 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
843
844 ngx_process_events(cycle->log);
845 }
846 } 447 }
847 448
848 449
849 static void ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv) 450 static void ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
850 { 451 {