zoukankan      html  css  js  c++  java
  • Nginx学习笔记(六) 源码分析&启动过程

    Nginx的启动过程

      主要介绍Nginx的启动过程,可以在/core/nginx.c中找到Nginx的主函数main(),那么就从这里开始分析Nginx的启动过程。

    涉及到的基本函数

    源码:

       1 /*
       2  * Copyright (C) Igor Sysoev
       3  * Copyright (C) Nginx, Inc.
       4  */
       5 
       6 
       7 #include <ngx_config.h>
       8 #include <ngx_core.h>
       9 #include <nginx.h>
      10 
      11 
      12 static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle);
      13 static ngx_int_t ngx_get_options(int argc, char *const *argv);
      14 static ngx_int_t ngx_process_options(ngx_cycle_t *cycle);
      15 static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv);
      16 static void *ngx_core_module_create_conf(ngx_cycle_t *cycle);
      17 static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf);
      18 static char *ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
      19 static char *ngx_set_env(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
      20 static char *ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
      21 static char *ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd,
      22     void *conf);
      23 static char *ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd,
      24     void *conf);
      25 
      26 
      27 static ngx_conf_enum_t  ngx_debug_points[] = {
      28     { ngx_string("stop"), NGX_DEBUG_POINTS_STOP },
      29     { ngx_string("abort"), NGX_DEBUG_POINTS_ABORT },
      30     { ngx_null_string, 0 }
      31 };
      32 
      33 
      34 static ngx_command_t  ngx_core_commands[] = {
      35 
      36     { ngx_string("daemon"),
      37       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
      38       ngx_conf_set_flag_slot,
      39       0,
      40       offsetof(ngx_core_conf_t, daemon),
      41       NULL },
      42 
      43     { ngx_string("master_process"),
      44       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
      45       ngx_conf_set_flag_slot,
      46       0,
      47       offsetof(ngx_core_conf_t, master),
      48       NULL },
      49 
      50     { ngx_string("timer_resolution"),
      51       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
      52       ngx_conf_set_msec_slot,
      53       0,
      54       offsetof(ngx_core_conf_t, timer_resolution),
      55       NULL },
      56 
      57     { ngx_string("pid"),
      58       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
      59       ngx_conf_set_str_slot,
      60       0,
      61       offsetof(ngx_core_conf_t, pid),
      62       NULL },
      63 
      64     { ngx_string("lock_file"),
      65       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
      66       ngx_conf_set_str_slot,
      67       0,
      68       offsetof(ngx_core_conf_t, lock_file),
      69       NULL },
      70 
      71     { ngx_string("worker_processes"),
      72       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
      73       ngx_set_worker_processes,
      74       0,
      75       0,
      76       NULL },
      77 
      78     { ngx_string("debug_points"),
      79       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
      80       ngx_conf_set_enum_slot,
      81       0,
      82       offsetof(ngx_core_conf_t, debug_points),
      83       &ngx_debug_points },
      84 
      85     { ngx_string("user"),
      86       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE12,
      87       ngx_set_user,
      88       0,
      89       0,
      90       NULL },
      91 
      92     { ngx_string("worker_priority"),
      93       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
      94       ngx_set_priority,
      95       0,
      96       0,
      97       NULL },
      98 
      99     { ngx_string("worker_cpu_affinity"),
     100       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_1MORE,
     101       ngx_set_cpu_affinity,
     102       0,
     103       0,
     104       NULL },
     105 
     106     { ngx_string("worker_rlimit_nofile"),
     107       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
     108       ngx_conf_set_num_slot,
     109       0,
     110       offsetof(ngx_core_conf_t, rlimit_nofile),
     111       NULL },
     112 
     113     { ngx_string("worker_rlimit_core"),
     114       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
     115       ngx_conf_set_off_slot,
     116       0,
     117       offsetof(ngx_core_conf_t, rlimit_core),
     118       NULL },
     119 
     120     { ngx_string("worker_rlimit_sigpending"),
     121       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
     122       ngx_conf_set_num_slot,
     123       0,
     124       offsetof(ngx_core_conf_t, rlimit_sigpending),
     125       NULL },
     126 
     127     { ngx_string("working_directory"),
     128       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
     129       ngx_conf_set_str_slot,
     130       0,
     131       offsetof(ngx_core_conf_t, working_directory),
     132       NULL },
     133 
     134     { ngx_string("env"),
     135       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
     136       ngx_set_env,
     137       0,
     138       0,
     139       NULL },
     140 
     141 #if (NGX_THREADS)
     142 
     143     { ngx_string("worker_threads"),
     144       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
     145       ngx_conf_set_num_slot,
     146       0,
     147       offsetof(ngx_core_conf_t, worker_threads),
     148       NULL },
     149 
     150     { ngx_string("thread_stack_size"),
     151       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
     152       ngx_conf_set_size_slot,
     153       0,
     154       offsetof(ngx_core_conf_t, thread_stack_size),
     155       NULL },
     156 
     157 #endif
     158 
     159       ngx_null_command
     160 };
     161 
     162 
     163 static ngx_core_module_t  ngx_core_module_ctx = {
     164     ngx_string("core"),
     165     ngx_core_module_create_conf,
     166     ngx_core_module_init_conf
     167 };
     168 
     169 
     170 ngx_module_t  ngx_core_module = {
     171     NGX_MODULE_V1,
     172     &ngx_core_module_ctx,                  /* module context */
     173     ngx_core_commands,                     /* module directives */
     174     NGX_CORE_MODULE,                       /* module type */
     175     NULL,                                  /* init master */
     176     NULL,                                  /* init module */
     177     NULL,                                  /* init process */
     178     NULL,                                  /* init thread */
     179     NULL,                                  /* exit thread */
     180     NULL,                                  /* exit process */
     181     NULL,                                  /* exit master */
     182     NGX_MODULE_V1_PADDING
     183 };
     184 
     185 
     186 ngx_uint_t          ngx_max_module;
     187 
     188 static ngx_uint_t   ngx_show_help;
     189 static ngx_uint_t   ngx_show_version;
     190 static ngx_uint_t   ngx_show_configure;
     191 static u_char      *ngx_prefix;
     192 static u_char      *ngx_conf_file;
     193 static u_char      *ngx_conf_params;
     194 static char        *ngx_signal;
     195 
     196 
     197 static char **ngx_os_environ;
     198 
     199 
     200 int ngx_cdecl
     201 main(int argc, char *const *argv)
     202 {
     203     ngx_int_t         i;
     204     ngx_log_t        *log;
     205     ngx_cycle_t      *cycle, init_cycle;
     206     ngx_core_conf_t  *ccf;
     207 
     208     ngx_debug_init();
     209 
     210     if (ngx_strerror_init() != NGX_OK) {
     211         return 1;
     212     }
     213 
     214     if (ngx_get_options(argc, argv) != NGX_OK) {
     215         return 1;
     216     }
     217 
     218     if (ngx_show_version) {
     219         ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED);
     220 
     221         if (ngx_show_help) {
     222             ngx_write_stderr(
     223                 "Usage: nginx [-?hvVtq] [-s signal] [-c filename] "
     224                              "[-p prefix] [-g directives]" NGX_LINEFEED
     225                              NGX_LINEFEED
     226                 "Options:" NGX_LINEFEED
     227                 "  -?,-h         : this help" NGX_LINEFEED
     228                 "  -v            : show version and exit" NGX_LINEFEED
     229                 "  -V            : show version and configure options then exit"
     230                                    NGX_LINEFEED
     231                 "  -t            : test configuration and exit" NGX_LINEFEED
     232                 "  -q            : suppress non-error messages "
     233                                    "during configuration testing" NGX_LINEFEED
     234                 "  -s signal     : send signal to a master process: "
     235                                    "stop, quit, reopen, reload" NGX_LINEFEED
     236 #ifdef NGX_PREFIX
     237                 "  -p prefix     : set prefix path (default: "
     238                                    NGX_PREFIX ")" NGX_LINEFEED
     239 #else
     240                 "  -p prefix     : set prefix path (default: NONE)" NGX_LINEFEED
     241 #endif
     242                 "  -c filename   : set configuration file (default: "
     243                                    NGX_CONF_PATH ")" NGX_LINEFEED
     244                 "  -g directives : set global directives out of configuration "
     245                                    "file" NGX_LINEFEED NGX_LINEFEED
     246                 );
     247         }
     248 
     249         if (ngx_show_configure) {
     250             ngx_write_stderr(
     251 #ifdef NGX_COMPILER
     252                 "built by " NGX_COMPILER NGX_LINEFEED
     253 #endif
     254 #if (NGX_SSL)
     255 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
     256                 "TLS SNI support enabled" NGX_LINEFEED
     257 #else
     258                 "TLS SNI support disabled" NGX_LINEFEED
     259 #endif
     260 #endif
     261                 "configure arguments:" NGX_CONFIGURE NGX_LINEFEED);
     262         }
     263 
     264         if (!ngx_test_config) {
     265             return 0;
     266         }
     267     }
     268 
     269     /* TODO */ ngx_max_sockets = -1;
     270 
     271     ngx_time_init();
     272 
     273 #if (NGX_PCRE)
     274     ngx_regex_init();
     275 #endif
     276 
     277     ngx_pid = ngx_getpid();
     278 
     279     log = ngx_log_init(ngx_prefix);
     280     if (log == NULL) {
     281         return 1;
     282     }
     283 
     284     /* STUB */
     285 #if (NGX_OPENSSL)
     286     ngx_ssl_init(log);
     287 #endif
     288 
     289     /*
     290      * init_cycle->log is required for signal handlers and
     291      * ngx_process_options()
     292      */
     293 
     294     ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
     295     init_cycle.log = log;
     296     ngx_cycle = &init_cycle;
     297 
     298     init_cycle.pool = ngx_create_pool(1024, log);
     299     if (init_cycle.pool == NULL) {
     300         return 1;
     301     }
     302 
     303     if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
     304         return 1;
     305     }
     306 
     307     if (ngx_process_options(&init_cycle) != NGX_OK) {
     308         return 1;
     309     }
     310 
     311     if (ngx_os_init(log) != NGX_OK) {
     312         return 1;
     313     }
     314 
     315     /*
     316      * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
     317      */
     318 
     319     if (ngx_crc32_table_init() != NGX_OK) {
     320         return 1;
     321     }
     322 
     323     if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
     324         return 1;
     325     }
     326 
     327     ngx_max_module = 0;
     328     for (i = 0; ngx_modules[i]; i++) {
     329         ngx_modules[i]->index = ngx_max_module++;
     330     }
     331 
     332     cycle = ngx_init_cycle(&init_cycle);
     333     if (cycle == NULL) {
     334         if (ngx_test_config) {
     335             ngx_log_stderr(0, "configuration file %s test failed",
     336                            init_cycle.conf_file.data);
     337         }
     338 
     339         return 1;
     340     }
     341 
     342     if (ngx_test_config) {
     343         if (!ngx_quiet_mode) {
     344             ngx_log_stderr(0, "configuration file %s test is successful",
     345                            cycle->conf_file.data);
     346         }
     347 
     348         return 0;
     349     }
     350 
     351     if (ngx_signal) {
     352         return ngx_signal_process(cycle, ngx_signal);
     353     }
     354 
     355     ngx_os_status(cycle->log);
     356 
     357     ngx_cycle = cycle;
     358 
     359     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
     360 
     361     if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
     362         ngx_process = NGX_PROCESS_MASTER;
     363     }
     364 
     365 #if !(NGX_WIN32)
     366 
     367     if (ngx_init_signals(cycle->log) != NGX_OK) {
     368         return 1;
     369     }
     370 
     371     if (!ngx_inherited && ccf->daemon) {
     372         if (ngx_daemon(cycle->log) != NGX_OK) {
     373             return 1;
     374         }
     375 
     376         ngx_daemonized = 1;
     377     }
     378 
     379     if (ngx_inherited) {
     380         ngx_daemonized = 1;
     381     }
     382 
     383 #endif
     384 
     385     if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
     386         return 1;
     387     }
     388 
     389     if (cycle->log->file->fd != ngx_stderr) {
     390 
     391         if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
     392             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
     393                           ngx_set_stderr_n " failed");
     394             return 1;
     395         }
     396     }
     397 
     398     if (log->file->fd != ngx_stderr) {
     399         if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
     400             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
     401                           ngx_close_file_n " built-in log failed");
     402         }
     403     }
     404 
     405     ngx_use_stderr = 0;
     406 
     407     if (ngx_process == NGX_PROCESS_SINGLE) {
     408         ngx_single_process_cycle(cycle);
     409 
     410     } else {
     411         ngx_master_process_cycle(cycle);
     412     }
     413 
     414     return 0;
     415 }
     416 
     417 
     418 static ngx_int_t
     419 ngx_add_inherited_sockets(ngx_cycle_t *cycle)
     420 {
     421     u_char           *p, *v, *inherited;
     422     ngx_int_t         s;
     423     ngx_listening_t  *ls;
     424 
     425     inherited = (u_char *) getenv(NGINX_VAR);
     426 
     427     if (inherited == NULL) {
     428         return NGX_OK;
     429     }
     430 
     431     ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
     432                   "using inherited sockets from "%s"", inherited);
     433 
     434     if (ngx_array_init(&cycle->listening, cycle->pool, 10,
     435                        sizeof(ngx_listening_t))
     436         != NGX_OK)
     437     {
     438         return NGX_ERROR;
     439     }
     440 
     441     for (p = inherited, v = p; *p; p++) {
     442         if (*p == ':' || *p == ';') {
     443             s = ngx_atoi(v, p - v);
     444             if (s == NGX_ERROR) {
     445                 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
     446                               "invalid socket number "%s" in " NGINX_VAR
     447                               " environment variable, ignoring the rest"
     448                               " of the variable", v);
     449                 break;
     450             }
     451 
     452             v = p + 1;
     453 
     454             ls = ngx_array_push(&cycle->listening);
     455             if (ls == NULL) {
     456                 return NGX_ERROR;
     457             }
     458 
     459             ngx_memzero(ls, sizeof(ngx_listening_t));
     460 
     461             ls->fd = (ngx_socket_t) s;
     462         }
     463     }
     464 
     465     ngx_inherited = 1;
     466 
     467     return ngx_set_inherited_sockets(cycle);
     468 }
     469 
     470 
     471 char **
     472 ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last)
     473 {
     474     char             **p, **env;
     475     ngx_str_t         *var;
     476     ngx_uint_t         i, n;
     477     ngx_core_conf_t   *ccf;
     478 
     479     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
     480 
     481     if (last == NULL && ccf->environment) {
     482         return ccf->environment;
     483     }
     484 
     485     var = ccf->env.elts;
     486 
     487     for (i = 0; i < ccf->env.nelts; i++) {
     488         if (ngx_strcmp(var[i].data, "TZ") == 0
     489             || ngx_strncmp(var[i].data, "TZ=", 3) == 0)
     490         {
     491             goto tz_found;
     492         }
     493     }
     494 
     495     var = ngx_array_push(&ccf->env);
     496     if (var == NULL) {
     497         return NULL;
     498     }
     499 
     500     var->len = 2;
     501     var->data = (u_char *) "TZ";
     502 
     503     var = ccf->env.elts;
     504 
     505 tz_found:
     506 
     507     n = 0;
     508 
     509     for (i = 0; i < ccf->env.nelts; i++) {
     510 
     511         if (var[i].data[var[i].len] == '=') {
     512             n++;
     513             continue;
     514         }
     515 
     516         for (p = ngx_os_environ; *p; p++) {
     517 
     518             if (ngx_strncmp(*p, var[i].data, var[i].len) == 0
     519                 && (*p)[var[i].len] == '=')
     520             {
     521                 n++;
     522                 break;
     523             }
     524         }
     525     }
     526 
     527     if (last) {
     528         env = ngx_alloc((*last + n + 1) * sizeof(char *), cycle->log);
     529         *last = n;
     530 
     531     } else {
     532         env = ngx_palloc(cycle->pool, (n + 1) * sizeof(char *));
     533     }
     534 
     535     if (env == NULL) {
     536         return NULL;
     537     }
     538 
     539     n = 0;
     540 
     541     for (i = 0; i < ccf->env.nelts; i++) {
     542 
     543         if (var[i].data[var[i].len] == '=') {
     544             env[n++] = (char *) var[i].data;
     545             continue;
     546         }
     547 
     548         for (p = ngx_os_environ; *p; p++) {
     549 
     550             if (ngx_strncmp(*p, var[i].data, var[i].len) == 0
     551                 && (*p)[var[i].len] == '=')
     552             {
     553                 env[n++] = *p;
     554                 break;
     555             }
     556         }
     557     }
     558 
     559     env[n] = NULL;
     560 
     561     if (last == NULL) {
     562         ccf->environment = env;
     563         environ = env;
     564     }
     565 
     566     return env;
     567 }
     568 
     569 
     570 ngx_pid_t
     571 ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
     572 {
     573     char             **env, *var;
     574     u_char            *p;
     575     ngx_uint_t         i, n;
     576     ngx_pid_t          pid;
     577     ngx_exec_ctx_t     ctx;
     578     ngx_core_conf_t   *ccf;
     579     ngx_listening_t   *ls;
     580 
     581     ngx_memzero(&ctx, sizeof(ngx_exec_ctx_t));
     582 
     583     ctx.path = argv[0];
     584     ctx.name = "new binary process";
     585     ctx.argv = argv;
     586 
     587     n = 2;
     588     env = ngx_set_environment(cycle, &n);
     589     if (env == NULL) {
     590         return NGX_INVALID_PID;
     591     }
     592 
     593     var = ngx_alloc(sizeof(NGINX_VAR)
     594                     + cycle->listening.nelts * (NGX_INT32_LEN + 1) + 2,
     595                     cycle->log);
     596     if (var == NULL) {
     597         ngx_free(env);
     598         return NGX_INVALID_PID;
     599     }
     600 
     601     p = ngx_cpymem(var, NGINX_VAR "=", sizeof(NGINX_VAR));
     602 
     603     ls = cycle->listening.elts;
     604     for (i = 0; i < cycle->listening.nelts; i++) {
     605         p = ngx_sprintf(p, "%ud;", ls[i].fd);
     606     }
     607 
     608     *p = '';
     609 
     610     env[n++] = var;
     611 
     612 #if (NGX_SETPROCTITLE_USES_ENV)
     613 
     614     /* allocate the spare 300 bytes for the new binary process title */
     615 
     616     env[n++] = "SPARE=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
     617                "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
     618                "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
     619                "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
     620                "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
     621 
     622 #endif
     623 
     624     env[n] = NULL;
     625 
     626 #if (NGX_DEBUG)
     627     {
     628     char  **e;
     629     for (e = env; *e; e++) {
     630         ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, "env: %s", *e);
     631     }
     632     }
     633 #endif
     634 
     635     ctx.envp = (char *const *) env;
     636 
     637     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
     638 
     639     if (ngx_rename_file(ccf->pid.data, ccf->oldpid.data) == NGX_FILE_ERROR) {
     640         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
     641                       ngx_rename_file_n " %s to %s failed "
     642                       "before executing new binary process "%s"",
     643                       ccf->pid.data, ccf->oldpid.data, argv[0]);
     644 
     645         ngx_free(env);
     646         ngx_free(var);
     647 
     648         return NGX_INVALID_PID;
     649     }
     650 
     651     pid = ngx_execute(cycle, &ctx);
     652 
     653     if (pid == NGX_INVALID_PID) {
     654         if (ngx_rename_file(ccf->oldpid.data, ccf->pid.data)
     655             == NGX_FILE_ERROR)
     656         {
     657             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
     658                           ngx_rename_file_n " %s back to %s failed after "
     659                           "an attempt to execute new binary process "%s"",
     660                           ccf->oldpid.data, ccf->pid.data, argv[0]);
     661         }
     662     }
     663 
     664     ngx_free(env);
     665     ngx_free(var);
     666 
     667     return pid;
     668 }
     669 
     670 
     671 static ngx_int_t
     672 ngx_get_options(int argc, char *const *argv)
     673 {
     674     u_char     *p;
     675     ngx_int_t   i;
     676 
     677     for (i = 1; i < argc; i++) {
     678 
     679         p = (u_char *) argv[i];
     680 
     681         if (*p++ != '-') {
     682             ngx_log_stderr(0, "invalid option: "%s"", argv[i]);
     683             return NGX_ERROR;
     684         }
     685 
     686         while (*p) {
     687 
     688             switch (*p++) {
     689 
     690             case '?':
     691             case 'h':
     692                 ngx_show_version = 1;
     693                 ngx_show_help = 1;
     694                 break;
     695 
     696             case 'v':
     697                 ngx_show_version = 1;
     698                 break;
     699 
     700             case 'V':
     701                 ngx_show_version = 1;
     702                 ngx_show_configure = 1;
     703                 break;
     704 
     705             case 't':
     706                 ngx_test_config = 1;
     707                 break;
     708 
     709             case 'q':
     710                 ngx_quiet_mode = 1;
     711                 break;
     712 
     713             case 'p':
     714                 if (*p) {
     715                     ngx_prefix = p;
     716                     goto next;
     717                 }
     718 
     719                 if (argv[++i]) {
     720                     ngx_prefix = (u_char *) argv[i];
     721                     goto next;
     722                 }
     723 
     724                 ngx_log_stderr(0, "option "-p" requires directory name");
     725                 return NGX_ERROR;
     726 
     727             case 'c':
     728                 if (*p) {
     729                     ngx_conf_file = p;
     730                     goto next;
     731                 }
     732 
     733                 if (argv[++i]) {
     734                     ngx_conf_file = (u_char *) argv[i];
     735                     goto next;
     736                 }
     737 
     738                 ngx_log_stderr(0, "option "-c" requires file name");
     739                 return NGX_ERROR;
     740 
     741             case 'g':
     742                 if (*p) {
     743                     ngx_conf_params = p;
     744                     goto next;
     745                 }
     746 
     747                 if (argv[++i]) {
     748                     ngx_conf_params = (u_char *) argv[i];
     749                     goto next;
     750                 }
     751 
     752                 ngx_log_stderr(0, "option "-g" requires parameter");
     753                 return NGX_ERROR;
     754 
     755             case 's':
     756                 if (*p) {
     757                     ngx_signal = (char *) p;
     758 
     759                 } else if (argv[++i]) {
     760                     ngx_signal = argv[i];
     761 
     762                 } else {
     763                     ngx_log_stderr(0, "option "-s" requires parameter");
     764                     return NGX_ERROR;
     765                 }
     766 
     767                 if (ngx_strcmp(ngx_signal, "stop") == 0
     768                     || ngx_strcmp(ngx_signal, "quit") == 0
     769                     || ngx_strcmp(ngx_signal, "reopen") == 0
     770                     || ngx_strcmp(ngx_signal, "reload") == 0)
     771                 {
     772                     ngx_process = NGX_PROCESS_SIGNALLER;
     773                     goto next;
     774                 }
     775 
     776                 ngx_log_stderr(0, "invalid option: "-s %s"", ngx_signal);
     777                 return NGX_ERROR;
     778 
     779             default:
     780                 ngx_log_stderr(0, "invalid option: "%c"", *(p - 1));
     781                 return NGX_ERROR;
     782             }
     783         }
     784 
     785     next:
     786 
     787         continue;
     788     }
     789 
     790     return NGX_OK;
     791 }
     792 
     793 
     794 static ngx_int_t
     795 ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv)
     796 {
     797 #if (NGX_FREEBSD)
     798 
     799     ngx_os_argv = (char **) argv;
     800     ngx_argc = argc;
     801     ngx_argv = (char **) argv;
     802 
     803 #else
     804     size_t     len;
     805     ngx_int_t  i;
     806 
     807     ngx_os_argv = (char **) argv;
     808     ngx_argc = argc;
     809 
     810     ngx_argv = ngx_alloc((argc + 1) * sizeof(char *), cycle->log);
     811     if (ngx_argv == NULL) {
     812         return NGX_ERROR;
     813     }
     814 
     815     for (i = 0; i < argc; i++) {
     816         len = ngx_strlen(argv[i]) + 1;
     817 
     818         ngx_argv[i] = ngx_alloc(len, cycle->log);
     819         if (ngx_argv[i] == NULL) {
     820             return NGX_ERROR;
     821         }
     822 
     823         (void) ngx_cpystrn((u_char *) ngx_argv[i], (u_char *) argv[i], len);
     824     }
     825 
     826     ngx_argv[i] = NULL;
     827 
     828 #endif
     829 
     830     ngx_os_environ = environ;
     831 
     832     return NGX_OK;
     833 }
     834 
     835 
     836 static ngx_int_t
     837 ngx_process_options(ngx_cycle_t *cycle)
     838 {
     839     u_char  *p;
     840     size_t   len;
     841 
     842     if (ngx_prefix) {
     843         len = ngx_strlen(ngx_prefix);
     844         p = ngx_prefix;
     845 
     846         if (len && !ngx_path_separator(p[len - 1])) {
     847             p = ngx_pnalloc(cycle->pool, len + 1);
     848             if (p == NULL) {
     849                 return NGX_ERROR;
     850             }
     851 
     852             ngx_memcpy(p, ngx_prefix, len);
     853             p[len++] = '/';
     854         }
     855 
     856         cycle->conf_prefix.len = len;
     857         cycle->conf_prefix.data = p;
     858         cycle->prefix.len = len;
     859         cycle->prefix.data = p;
     860 
     861     } else {
     862 
     863 #ifndef NGX_PREFIX
     864 
     865         p = ngx_pnalloc(cycle->pool, NGX_MAX_PATH);
     866         if (p == NULL) {
     867             return NGX_ERROR;
     868         }
     869 
     870         if (ngx_getcwd(p, NGX_MAX_PATH) == 0) {
     871             ngx_log_stderr(ngx_errno, "[emerg]: " ngx_getcwd_n " failed");
     872             return NGX_ERROR;
     873         }
     874 
     875         len = ngx_strlen(p);
     876 
     877         p[len++] = '/';
     878 
     879         cycle->conf_prefix.len = len;
     880         cycle->conf_prefix.data = p;
     881         cycle->prefix.len = len;
     882         cycle->prefix.data = p;
     883 
     884 #else
     885 
     886 #ifdef NGX_CONF_PREFIX
     887         ngx_str_set(&cycle->conf_prefix, NGX_CONF_PREFIX);
     888 #else
     889         ngx_str_set(&cycle->conf_prefix, NGX_PREFIX);
     890 #endif
     891         ngx_str_set(&cycle->prefix, NGX_PREFIX);
     892 
     893 #endif
     894     }
     895 
     896     if (ngx_conf_file) {
     897         cycle->conf_file.len = ngx_strlen(ngx_conf_file);
     898         cycle->conf_file.data = ngx_conf_file;
     899 
     900     } else {
     901         ngx_str_set(&cycle->conf_file, NGX_CONF_PATH);
     902     }
     903 
     904     if (ngx_conf_full_name(cycle, &cycle->conf_file, 0) != NGX_OK) {
     905         return NGX_ERROR;
     906     }
     907 
     908     for (p = cycle->conf_file.data + cycle->conf_file.len - 1;
     909          p > cycle->conf_file.data;
     910          p--)
     911     {
     912         if (ngx_path_separator(*p)) {
     913             cycle->conf_prefix.len = p - ngx_cycle->conf_file.data + 1;
     914             cycle->conf_prefix.data = ngx_cycle->conf_file.data;
     915             break;
     916         }
     917     }
     918 
     919     if (ngx_conf_params) {
     920         cycle->conf_param.len = ngx_strlen(ngx_conf_params);
     921         cycle->conf_param.data = ngx_conf_params;
     922     }
     923 
     924     if (ngx_test_config) {
     925         cycle->log->log_level = NGX_LOG_INFO;
     926     }
     927 
     928     return NGX_OK;
     929 }
     930 
     931 
     932 static void *
     933 ngx_core_module_create_conf(ngx_cycle_t *cycle)
     934 {
     935     ngx_core_conf_t  *ccf;
     936 
     937     ccf = ngx_pcalloc(cycle->pool, sizeof(ngx_core_conf_t));
     938     if (ccf == NULL) {
     939         return NULL;
     940     }
     941 
     942     /*
     943      * set by ngx_pcalloc()
     944      *
     945      *     ccf->pid = NULL;
     946      *     ccf->oldpid = NULL;
     947      *     ccf->priority = 0;
     948      *     ccf->cpu_affinity_n = 0;
     949      *     ccf->cpu_affinity = NULL;
     950      */
     951 
     952     ccf->daemon = NGX_CONF_UNSET;
     953     ccf->master = NGX_CONF_UNSET;
     954     ccf->timer_resolution = NGX_CONF_UNSET_MSEC;
     955 
     956     ccf->worker_processes = NGX_CONF_UNSET;
     957     ccf->debug_points = NGX_CONF_UNSET;
     958 
     959     ccf->rlimit_nofile = NGX_CONF_UNSET;
     960     ccf->rlimit_core = NGX_CONF_UNSET;
     961     ccf->rlimit_sigpending = NGX_CONF_UNSET;
     962 
     963     ccf->user = (ngx_uid_t) NGX_CONF_UNSET_UINT;
     964     ccf->group = (ngx_gid_t) NGX_CONF_UNSET_UINT;
     965 
     966 #if (NGX_THREADS)
     967     ccf->worker_threads = NGX_CONF_UNSET;
     968     ccf->thread_stack_size = NGX_CONF_UNSET_SIZE;
     969 #endif
     970 
     971     if (ngx_array_init(&ccf->env, cycle->pool, 1, sizeof(ngx_str_t))
     972         != NGX_OK)
     973     {
     974         return NULL;
     975     }
     976 
     977     return ccf;
     978 }
     979 
     980 
     981 static char *
     982 ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
     983 {
     984     ngx_core_conf_t  *ccf = conf;
     985 
     986     ngx_conf_init_value(ccf->daemon, 1);
     987     ngx_conf_init_value(ccf->master, 1);
     988     ngx_conf_init_msec_value(ccf->timer_resolution, 0);
     989 
     990     ngx_conf_init_value(ccf->worker_processes, 1);
     991     ngx_conf_init_value(ccf->debug_points, 0);
     992 
     993 #if (NGX_HAVE_CPU_AFFINITY)
     994 
     995     if (ccf->cpu_affinity_n
     996         && ccf->cpu_affinity_n != 1
     997         && ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes)
     998     {
     999         ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
    1000                       "the number of "worker_processes" is not equal to "
    1001                       "the number of "worker_cpu_affinity" masks, "
    1002                       "using last mask for remaining worker processes");
    1003     }
    1004 
    1005 #endif
    1006 
    1007 #if (NGX_THREADS)
    1008 
    1009     ngx_conf_init_value(ccf->worker_threads, 0);
    1010     ngx_threads_n = ccf->worker_threads;
    1011     ngx_conf_init_size_value(ccf->thread_stack_size, 2 * 1024 * 1024);
    1012 
    1013 #endif
    1014 
    1015 
    1016     if (ccf->pid.len == 0) {
    1017         ngx_str_set(&ccf->pid, NGX_PID_PATH);
    1018     }
    1019 
    1020     if (ngx_conf_full_name(cycle, &ccf->pid, 0) != NGX_OK) {
    1021         return NGX_CONF_ERROR;
    1022     }
    1023 
    1024     ccf->oldpid.len = ccf->pid.len + sizeof(NGX_OLDPID_EXT);
    1025 
    1026     ccf->oldpid.data = ngx_pnalloc(cycle->pool, ccf->oldpid.len);
    1027     if (ccf->oldpid.data == NULL) {
    1028         return NGX_CONF_ERROR;
    1029     }
    1030 
    1031     ngx_memcpy(ngx_cpymem(ccf->oldpid.data, ccf->pid.data, ccf->pid.len),
    1032                NGX_OLDPID_EXT, sizeof(NGX_OLDPID_EXT));
    1033 
    1034 
    1035 #if !(NGX_WIN32)
    1036 
    1037     if (ccf->user == (uid_t) NGX_CONF_UNSET_UINT && geteuid() == 0) {
    1038         struct group   *grp;
    1039         struct passwd  *pwd;
    1040 
    1041         ngx_set_errno(0);
    1042         pwd = getpwnam(NGX_USER);
    1043         if (pwd == NULL) {
    1044             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
    1045                           "getpwnam("" NGX_USER "") failed");
    1046             return NGX_CONF_ERROR;
    1047         }
    1048 
    1049         ccf->username = NGX_USER;
    1050         ccf->user = pwd->pw_uid;
    1051 
    1052         ngx_set_errno(0);
    1053         grp = getgrnam(NGX_GROUP);
    1054         if (grp == NULL) {
    1055             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
    1056                           "getgrnam("" NGX_GROUP "") failed");
    1057             return NGX_CONF_ERROR;
    1058         }
    1059 
    1060         ccf->group = grp->gr_gid;
    1061     }
    1062 
    1063 
    1064     if (ccf->lock_file.len == 0) {
    1065         ngx_str_set(&ccf->lock_file, NGX_LOCK_PATH);
    1066     }
    1067 
    1068     if (ngx_conf_full_name(cycle, &ccf->lock_file, 0) != NGX_OK) {
    1069         return NGX_CONF_ERROR;
    1070     }
    1071 
    1072     {
    1073     ngx_str_t  lock_file;
    1074 
    1075     lock_file = cycle->old_cycle->lock_file;
    1076 
    1077     if (lock_file.len) {
    1078         lock_file.len--;
    1079 
    1080         if (ccf->lock_file.len != lock_file.len
    1081             || ngx_strncmp(ccf->lock_file.data, lock_file.data, lock_file.len)
    1082                != 0)
    1083         {
    1084             ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
    1085                           ""lock_file" could not be changed, ignored");
    1086         }
    1087 
    1088         cycle->lock_file.len = lock_file.len + 1;
    1089         lock_file.len += sizeof(".accept");
    1090 
    1091         cycle->lock_file.data = ngx_pstrdup(cycle->pool, &lock_file);
    1092         if (cycle->lock_file.data == NULL) {
    1093             return NGX_CONF_ERROR;
    1094         }
    1095 
    1096     } else {
    1097         cycle->lock_file.len = ccf->lock_file.len + 1;
    1098         cycle->lock_file.data = ngx_pnalloc(cycle->pool,
    1099                                       ccf->lock_file.len + sizeof(".accept"));
    1100         if (cycle->lock_file.data == NULL) {
    1101             return NGX_CONF_ERROR;
    1102         }
    1103 
    1104         ngx_memcpy(ngx_cpymem(cycle->lock_file.data, ccf->lock_file.data,
    1105                               ccf->lock_file.len),
    1106                    ".accept", sizeof(".accept"));
    1107     }
    1108     }
    1109 
    1110 #endif
    1111 
    1112     return NGX_CONF_OK;
    1113 }
    1114 
    1115 
    1116 static char *
    1117 ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
    1118 {
    1119 #if (NGX_WIN32)
    1120 
    1121     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
    1122                        ""user" is not supported, ignored");
    1123 
    1124     return NGX_CONF_OK;
    1125 
    1126 #else
    1127 
    1128     ngx_core_conf_t  *ccf = conf;
    1129 
    1130     char             *group;
    1131     struct passwd    *pwd;
    1132     struct group     *grp;
    1133     ngx_str_t        *value;
    1134 
    1135     if (ccf->user != (uid_t) NGX_CONF_UNSET_UINT) {
    1136         return "is duplicate";
    1137     }
    1138 
    1139     if (geteuid() != 0) {
    1140         ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
    1141                            "the "user" directive makes sense only "
    1142                            "if the master process runs "
    1143                            "with super-user privileges, ignored");
    1144         return NGX_CONF_OK;
    1145     }
    1146 
    1147     value = (ngx_str_t *) cf->args->elts;
    1148 
    1149     ccf->username = (char *) value[1].data;
    1150 
    1151     ngx_set_errno(0);
    1152     pwd = getpwnam((const char *) value[1].data);
    1153     if (pwd == NULL) {
    1154         ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
    1155                            "getpwnam("%s") failed", value[1].data);
    1156         return NGX_CONF_ERROR;
    1157     }
    1158 
    1159     ccf->user = pwd->pw_uid;
    1160 
    1161     group = (char *) ((cf->args->nelts == 2) ? value[1].data : value[2].data);
    1162 
    1163     ngx_set_errno(0);
    1164     grp = getgrnam(group);
    1165     if (grp == NULL) {
    1166         ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
    1167                            "getgrnam("%s") failed", group);
    1168         return NGX_CONF_ERROR;
    1169     }
    1170 
    1171     ccf->group = grp->gr_gid;
    1172 
    1173     return NGX_CONF_OK;
    1174 
    1175 #endif
    1176 }
    1177 
    1178 
    1179 static char *
    1180 ngx_set_env(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
    1181 {
    1182     ngx_core_conf_t  *ccf = conf;
    1183 
    1184     ngx_str_t   *value, *var;
    1185     ngx_uint_t   i;
    1186 
    1187     var = ngx_array_push(&ccf->env);
    1188     if (var == NULL) {
    1189         return NGX_CONF_ERROR;
    1190     }
    1191 
    1192     value = cf->args->elts;
    1193     *var = value[1];
    1194 
    1195     for (i = 0; i < value[1].len; i++) {
    1196 
    1197         if (value[1].data[i] == '=') {
    1198 
    1199             var->len = i;
    1200 
    1201             return NGX_CONF_OK;
    1202         }
    1203     }
    1204 
    1205     return NGX_CONF_OK;
    1206 }
    1207 
    1208 
    1209 static char *
    1210 ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
    1211 {
    1212     ngx_core_conf_t  *ccf = conf;
    1213 
    1214     ngx_str_t        *value;
    1215     ngx_uint_t        n, minus;
    1216 
    1217     if (ccf->priority != 0) {
    1218         return "is duplicate";
    1219     }
    1220 
    1221     value = cf->args->elts;
    1222 
    1223     if (value[1].data[0] == '-') {
    1224         n = 1;
    1225         minus = 1;
    1226 
    1227     } else if (value[1].data[0] == '+') {
    1228         n = 1;
    1229         minus = 0;
    1230 
    1231     } else {
    1232         n = 0;
    1233         minus = 0;
    1234     }
    1235 
    1236     ccf->priority = ngx_atoi(&value[1].data[n], value[1].len - n);
    1237     if (ccf->priority == NGX_ERROR) {
    1238         return "invalid number";
    1239     }
    1240 
    1241     if (minus) {
    1242         ccf->priority = -ccf->priority;
    1243     }
    1244 
    1245     return NGX_CONF_OK;
    1246 }
    1247 
    1248 
    1249 static char *
    1250 ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
    1251 {
    1252 #if (NGX_HAVE_CPU_AFFINITY)
    1253     ngx_core_conf_t  *ccf = conf;
    1254 
    1255     u_char            ch;
    1256     uint64_t         *mask;
    1257     ngx_str_t        *value;
    1258     ngx_uint_t        i, n;
    1259 
    1260     if (ccf->cpu_affinity) {
    1261         return "is duplicate";
    1262     }
    1263 
    1264     mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(uint64_t));
    1265     if (mask == NULL) {
    1266         return NGX_CONF_ERROR;
    1267     }
    1268 
    1269     ccf->cpu_affinity_n = cf->args->nelts - 1;
    1270     ccf->cpu_affinity = mask;
    1271 
    1272     value = cf->args->elts;
    1273 
    1274     for (n = 1; n < cf->args->nelts; n++) {
    1275 
    1276         if (value[n].len > 64) {
    1277             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
    1278                          ""worker_cpu_affinity" supports up to 64 CPUs only");
    1279             return NGX_CONF_ERROR;
    1280         }
    1281 
    1282         mask[n - 1] = 0;
    1283 
    1284         for (i = 0; i < value[n].len; i++) {
    1285 
    1286             ch = value[n].data[i];
    1287 
    1288             if (ch == ' ') {
    1289                 continue;
    1290             }
    1291 
    1292             mask[n - 1] <<= 1;
    1293 
    1294             if (ch == '0') {
    1295                 continue;
    1296             }
    1297 
    1298             if (ch == '1') {
    1299                 mask[n - 1] |= 1;
    1300                 continue;
    1301             }
    1302 
    1303             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
    1304                           "invalid character "%c" in "worker_cpu_affinity"",
    1305                           ch);
    1306             return NGX_CONF_ERROR;
    1307         }
    1308     }
    1309 
    1310 #else
    1311 
    1312     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
    1313                        ""worker_cpu_affinity" is not supported "
    1314                        "on this platform, ignored");
    1315 #endif
    1316 
    1317     return NGX_CONF_OK;
    1318 }
    1319 
    1320 
    1321 uint64_t
    1322 ngx_get_cpu_affinity(ngx_uint_t n)
    1323 {
    1324     ngx_core_conf_t  *ccf;
    1325 
    1326     ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
    1327                                            ngx_core_module);
    1328 
    1329     if (ccf->cpu_affinity == NULL) {
    1330         return 0;
    1331     }
    1332 
    1333     if (ccf->cpu_affinity_n > n) {
    1334         return ccf->cpu_affinity[n];
    1335     }
    1336 
    1337     return ccf->cpu_affinity[ccf->cpu_affinity_n - 1];
    1338 }
    1339 
    1340 
    1341 static char *
    1342 ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
    1343 {
    1344     ngx_str_t        *value;
    1345     ngx_core_conf_t  *ccf;
    1346 
    1347     ccf = (ngx_core_conf_t *) conf;
    1348 
    1349     if (ccf->worker_processes != NGX_CONF_UNSET) {
    1350         return "is duplicate";
    1351     }
    1352 
    1353     value = (ngx_str_t *) cf->args->elts;
    1354 
    1355     if (ngx_strcmp(value[1].data, "auto") == 0) {
    1356         ccf->worker_processes = ngx_ncpu;
    1357         return NGX_CONF_OK;
    1358     }
    1359 
    1360     ccf->worker_processes = ngx_atoi(value[1].data, value[1].len);
    1361 
    1362     if (ccf->worker_processes == NGX_ERROR) {
    1363         return "invalid value";
    1364     }
    1365 
    1366     return NGX_CONF_OK;
    1367 }
    View Code

      Nginx的启动包括了很多的初始化和处理函数。这些函数相对来说,有一部分非常复杂,暂且从简单开始,从整体上对Ngixnd的启动有一个了解,方便日后的分析与学习。

      主要函数:

    //完成socket的继承
    static
    ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle);
    //对参数选项进行处理
    static ngx_int_t ngx_get_options(int argc, char *const *argv);
    //初始化ngx_cycle内的部分内容
    static ngx_int_t ngx_process_options(ngx_cycle_t *cycle);
    //命令行参数保存到ngx_os_argv、ngx_argc以及ngx_argv全局的变量中
    static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv);
    //创建模块的配置信息
    static void *ngx_core_module_create_conf(ngx_cycle_t *cycle);
    //初始化配置信息
    static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf); static char *ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_set_env(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    //设置优先级
    static char *ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    //设置CPU亲和性
    static char *ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    //设置worker进程
    static char *ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    Nginx启动的主要流程

       下图为Nginx的启动时函数的调用过程,其中大部分都是为了Nginx启动的初始化部分。从错误处理、参数设置、时间设置等方面进行初始化,并注册了我们需要的模块,最后根据信号选择单任务模式还是master-worker模式。

      流程图:

    初始化

      主函数在开始对系统错误、参数、时间、系统变量、日志等进行了初始化。

    //初始化系统中错误编号对应的含义
    ngx_strerror_init();
    //对参数选项进行处理
    ngx_get_options(argc, argv);
    //时间初始化
    ngx_time_init();
    //重置pcre内存管理的接口
    ngx_regex_init();
    //日志初始化
    ngx_log_init(ngx_prefix);
    //创建内存池
    ngx_create_pool(1024, log);
    //保存变量
    ngx_save_argv();
    //初始化ngx_cycle的prefix, conf_prefix, conf_file, conf_param
    ngx_process_options();
    //初始化系统相关变量,如内存页面大小ngx_pagesize,ngx_cacheline_size,最大连接数ngx_max_sockets等
    ngx_os_init();
    //初始化CRC表(后续的CRC校验通过查表进行,效率高)
    ngx_crc32_table_init();

    主要工作

      初始化完成后,需要先调用ngx_add_inherited_sockets函数继承socket,并储存在Listening数组中,在运行时候进行监听。之后就可以调用ngx_init_cycle来初始化ngx_cycle结构体,这个结构体用来存储所有的连接,具体如下:

    struct ngx_cycle_s {
        void                  ****conf_ctx;//配置上下文数组(含所有模块)
        ngx_pool_t               *pool;//内存池
    
        ngx_log_t                *log;//日志
        ngx_log_t                 new_log;
    
        ngx_connection_t        **files;//连接文件    
        ngx_connection_t         *free_connections;//空闲连接
        ngx_uint_t                free_connection_n;//空闲连接数
    
        ngx_queue_t               reusable_connections_queue;////再利用连接队列  
    
        ngx_array_t               listening;//监听数组
        ngx_array_t               paths;//路径数组
        ngx_list_t                open_files;//打开文件链表
        ngx_list_t                shared_memory;//共享内存链表
    
        ngx_uint_t                connection_n;//连接个数  
        ngx_uint_t                files_n;//打开文件个数 
    
        ngx_connection_t         *connections;
        ngx_event_t              *read_events;//读事件    
        ngx_event_t              *write_events;//写事件
    
        ngx_cycle_t              *old_cycle;
    
        ngx_str_t                 conf_file;//配置文件  
        ngx_str_t                 conf_param;//配置参数
        ngx_str_t                 conf_prefix;//配置前缀
        ngx_str_t                 prefix;//前缀
        ngx_str_t                 lock_file;//锁文件
        ngx_str_t                 hostname;

      调用ngx_init_signals来注册信号。

    //信号种类
    #define
    NGX_PROCESS_SINGLE 0 #define NGX_PROCESS_MASTER 1 #define NGX_PROCESS_SIGNALLER 2 #define NGX_PROCESS_WORKER 3 #define NGX_PROCESS_HELPER 4

      在进入处理之前,还要调用ngx_create_pidfile来记录进程id。最后,根据接收到的信号,来判断调用ngx_single_process_cycle还是ngx_master_process_cycle(master-worker模式

    if (ngx_process == NGX_PROCESS_SINGLE) {
            ngx_single_process_cycle(cycle);
    } else {
            ngx_master_process_cycle(cycle);
    }

      其中,守护进程函数为ngx_daemon,位于src/os/unix/Ngx_daemon.c

    //daemon
    ngx_int_t ngx_daemon(ngx_log_t
    *log) { int fd; switch (fork()) { case -1: ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed"); return NGX_ERROR; case 0: breakdefault: exit(0); } ngx_pid = ngx_getpid();//取得进程识别码 if (setsid() == -1) { //子进程将重新获得一个新的会话(session)id ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "setsid() failed"); return NGX_ERROR; } umask(0); fd = open("/dev/null", O_RDWR); if (fd == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "open("/dev/null") failed"); return NGX_ERROR; } if (dup2(fd, STDIN_FILENO) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDIN) failed"); return NGX_ERROR; } if (dup2(fd, STDOUT_FILENO) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDOUT) failed"); return NGX_ERROR; } #if 0 if (dup2(fd, STDERR_FILENO) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDERR) failed"); return NGX_ERROR; } #endif if (fd > STDERR_FILENO) { if (close(fd) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed"); return NGX_ERROR; } } return NGX_OK; }

     参考

    http://blog.xiuwz.com/2011/11/29/nginx-pcre-conflict/

    http://blog.csdn.net/liuhongxiangm/article/details/8107613

    http://www.4os.org/index.php/2010/11/25/nginx%E5%90%AF%E5%8A%A8%E5%88%9D%E5%A7%8B%E5%8C%96%E8%BF%87%E7%A8%8B%E8%BD%AC%E8%BD%BD/

    http://blog.csdn.net/livelylittlefish/article/details/7243718

  • 相关阅读:
    7 重排序与happens-before
    6 Java内存模型基础知识
    5 Java线程间的通信
    Java线程的状态及主要转化方法
    《The Boost C++ Libraries》 第一章 智能指针
    python通过swig调用静态库
    使用gdb调试
    Rsync服务部署使用
    UNP学习总结(二)
    read()函数的困惑
  • 原文地址:https://www.cnblogs.com/coder2012/p/3166658.html
Copyright © 2011-2022 走看看