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

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

~ [ 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.