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