1
2 /*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_event.h>
10 #include <nginx.h>
11
12
13 static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle);
14 static ngx_int_t ngx_getopt(ngx_cycle_t *cycle, int argc, char *const *argv);
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_version;
187 static ngx_uint_t ngx_show_configure;
188
189 static char **ngx_os_environ;
190
191
192 int ngx_cdecl
193 main(int argc, char *const *argv)
194 {
195 ngx_int_t i;
196 ngx_log_t *log;
197 ngx_cycle_t *cycle, init_cycle;
198 ngx_core_conf_t *ccf;
199
200 #if (NGX_FREEBSD)
201 ngx_debug_init();
202 #endif
203
204 /* TODO */ ngx_max_sockets = -1;
205
206 ngx_time_init();
207
208 #if (NGX_PCRE)
209 ngx_regex_init();
210 #endif
211
212 ngx_pid = ngx_getpid();
213
214 log = ngx_log_init();
215 if (log == NULL) {
216 return 1;
217 }
218
219 /* STUB */
220 #if (NGX_OPENSSL)
221 ngx_ssl_init(log);
222 #endif
223
224 /* init_cycle->log is required for signal handlers and ngx_getopt() */
225
226 ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
227 init_cycle.log = log;
228 ngx_cycle = &init_cycle;
229
230 init_cycle.pool = ngx_create_pool(1024, log);
231 if (init_cycle.pool == NULL) {
232 return 1;
233 }
234
235 if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
236 return 1;
237 }
238
239 if (ngx_getopt(&init_cycle, argc, ngx_argv) != NGX_OK) {
240 return 1;
241 }
242
243 if (ngx_show_version) {
244 ngx_write_fd(ngx_stderr_fileno, "nginx version: " NGINX_VER CRLF,
245 sizeof("nginx version: " NGINX_VER CRLF) - 1);
246
247 if (ngx_show_configure) {
248 #ifdef NGX_COMPILER
249 ngx_write_fd(ngx_stderr_fileno, "built by " NGX_COMPILER CRLF,
250 sizeof("built by " NGX_COMPILER CRLF) - 1);
251 #endif
252
253 #ifndef __WATCOMC__
254
255 /* OpenWatcomC could not build the long NGX_CONFIGURE string */
256
257 ngx_write_fd(ngx_stderr_fileno,
258 "configure arguments: " NGX_CONFIGURE CRLF,
259 sizeof("configure arguments :" NGX_CONFIGURE CRLF) - 1);
260 #endif
261 }
262
263 if (!ngx_test_config) {
264 return 0;
265 }
266 }
267
268 if (ngx_test_config) {
269 log->log_level = NGX_LOG_INFO;
270 }
271
272 if (ngx_os_init(log) != NGX_OK) {
273 return 1;
274 }
275
276 /*
277 * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
278 */
279
280 if (ngx_crc32_table_init() != NGX_OK) {
281 return 1;
282 }
283
284 if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
285 return 1;
286 }
287
288 ngx_max_module = 0;
289 for (i = 0; ngx_modules[i]; i++) {
290 ngx_modules[i]->index = ngx_max_module++;
291 }
292
293 cycle = ngx_init_cycle(&init_cycle);
294 if (cycle == NULL) {
295 if (ngx_test_config) {
296 ngx_log_error(NGX_LOG_EMERG, log, 0,
297 "the configuration file %s test failed",
298 init_cycle.conf_file.data);
299 }
300
301 return 1;
302 }
303
304 if (ngx_test_config) {
305 ngx_log_error(NGX_LOG_INFO, log, 0,
306 "the configuration file %s was tested successfully",
307 cycle->conf_file.data);
308 return 0;
309 }
310
311 ngx_os_status(cycle->log);
312
313 ngx_cycle = cycle;
314
315 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
316
317 ngx_process = ccf->master ? NGX_PROCESS_MASTER : NGX_PROCESS_SINGLE;
318
319 #if (NGX_WIN32)
320
321 #if 0
322
323 TODO:
324
325 if (ccf->run_as_service) {
326 if (ngx_service(cycle->log) != NGX_OK) {
327 return 1;
328 }
329
330 return 0;
331 }
332 #endif
333
334 #else
335
336 if (ngx_init_signals(cycle->log) != NGX_OK) {
337 return 1;
338 }
339
340 if (!ngx_inherited && ccf->daemon) {
341 if (ngx_daemon(cycle->log) != NGX_OK) {
342 return 1;
343 }
344
345 ngx_daemonized = 1;
346 }
347
348 if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
349 return 1;
350 }
351
352 #endif
353
354 if (ngx_process == NGX_PROCESS_MASTER) {
355 ngx_master_process_cycle(cycle);
356
357 } else {
358 ngx_single_process_cycle(cycle);
359 }
360
361 return 0;
362 }
363
364
365 static ngx_int_t
366 ngx_add_inherited_sockets(ngx_cycle_t *cycle)
367 {
368 u_char *p, *v, *inherited;
369 ngx_int_t s;
370 ngx_listening_t *ls;
371
372 inherited = (u_char *) getenv(NGINX_VAR);
373
374 if (inherited == NULL) {
375 return NGX_OK;
376 }
377
378 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
379 "using inherited sockets from \"%s\"", inherited);
380
381 if (ngx_array_init(&cycle->listening, cycle->pool, 10,
382 sizeof(ngx_listening_t))
383 == NGX_ERROR)
384 {
385 return NGX_ERROR;
386 }
387
388 for (p = inherited, v = p; *p; p++) {
389 if (*p == ':' || *p == ';') {
390 s = ngx_atoi(v, p - v);
391 if (s == NGX_ERROR) {
392 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
393 "invalid socket number \"%s\" in " NGINX_VAR
394 " environment variable, ignoring the rest"
395 " of the variable", v);
396 break;
397 }
398
399 v = p + 1;
400
401 ls = ngx_array_push(&cycle->listening);
402 if (ls == NULL) {
403 return NGX_ERROR;
404 }
405
406 ngx_memzero(ls, sizeof(ngx_listening_t));
407
408 ls->fd = (ngx_socket_t) s;
409 }
410 }
411
412 ngx_inherited = 1;
413
414 return ngx_set_inherited_sockets(cycle);
415 }
416
417
418 char **
419 ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last)
420 {
421 char **p, **env;
422 ngx_str_t *var;
423 ngx_uint_t i, n;
424 ngx_core_conf_t *ccf;
425
426 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
427
428 if (last == NULL && ccf->environment) {
429 return ccf->environment;
430 }
431
432 var = ccf->env.elts;
433
434 for (i = 0; i < ccf->env.nelts; i++) {
435 if (ngx_strcmp(var[i].data, "TZ") == 0
436 || ngx_strncmp(var[i].data, "TZ=", 3) == 0)
437 {
438 goto tz_found;
439 }
440 }
441
442 var = ngx_array_push(&ccf->env);
443 if (var == NULL) {
444 return NULL;
445 }
446
447 var->len = 2;
448 var->data = (u_char *) "TZ";
449
450 var = ccf->env.elts;
451
452 tz_found:
453
454 n = 0;
455
456 for (i = 0; i < ccf->env.nelts; i++) {
457
458 if (var[i].data[var[i].len] == '=') {
459 n++;
460 continue;
461 }
462
463 for (p = ngx_os_environ; *p; p++) {
464
465 if (ngx_strncmp(*p, var[i].data, var[i].len) == 0
466 && (*p)[var[i].len] == '=')
467 {
468 n++;
469 break;
470 }
471 }
472 }
473
474 if (last) {
475 env = ngx_alloc((*last + n + 1) * sizeof(char *), cycle->log);
476 *last = n;
477
478 } else {
479 env = ngx_palloc(cycle->pool, (n + 1) * sizeof(char *));
480 }
481
482 if (env == NULL) {
483 return NULL;
484 }
485
486 n = 0;
487
488 for (i = 0; i < ccf->env.nelts; i++) {
489
490 if (var[i].data[var[i].len] == '=') {
491 env[n++] = (char *) var[i].data;
492 continue;
493 }
494
495 for (p = ngx_os_environ; *p; p++) {
496
497 if (ngx_strncmp(*p, var[i].data, var[i].len) == 0
498 && (*p)[var[i].len] == '=')
499 {
500 env[n++] = *p;
501 break;
502 }
503 }
504 }
505
506 env[n] = NULL;
507
508 if (last == NULL) {
509 ccf->environment = env;
510 environ = env;
511 }
512
513 return env;
514 }
515
516
517 ngx_pid_t
518 ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
519 {
520 char **env, *var;
521 u_char *p;
522 ngx_uint_t i, n;
523 ngx_pid_t pid;
524 ngx_exec_ctx_t ctx;
525 ngx_core_conf_t *ccf;
526 ngx_listening_t *ls;
527
528 ctx.path = argv[0];
529 ctx.name = "new binary process";
530 ctx.argv = argv;
531
532 n = 2;
533 env = ngx_set_environment(cycle, &n);
534 if (env == NULL) {
535 return NGX_INVALID_PID;
536 }
537
538 var = ngx_alloc(sizeof(NGINX_VAR)
539 + cycle->listening.nelts * (NGX_INT32_LEN + 1) + 2,
540 cycle->log);
541
542 p = ngx_cpymem(var, NGINX_VAR "=", sizeof(NGINX_VAR));
543
544 ls = cycle->listening.elts;
545 for (i = 0; i < cycle->listening.nelts; i++) {
546 p = ngx_sprintf(p, "%ud;", ls[i].fd);
547 }
548
549 *p = '\0';
550
551 env[n++] = var;
552
553 #if (NGX_SETPROCTITLE_USES_ENV)
554
555 /* allocate the spare 300 bytes for the new binary process title */
556
557 env[n++] = "SPARE=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
558 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
559 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
560 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
561 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
562
563 #endif
564
565 env[n] = NULL;
566
567 #if (NGX_DEBUG)
568 {
569 char **e;
570 for (e = env; *e; e++) {
571 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, "env: %s", *e);
572 }
573 }
574 #endif
575
576 ctx.envp = (char *const *) env;
577
578 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
579
580 if (ngx_rename_file(ccf->pid.data, ccf->oldpid.data) != NGX_OK) {
581 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
582 ngx_rename_file_n " %s to %s failed "
583 "before executing new binary process \"%s\"",
584 ccf->pid.data, ccf->oldpid.data, argv[0]);
585
586 ngx_free(env);
587 ngx_free(var);
588
589 return NGX_INVALID_PID;
590 }
591
592 pid = ngx_execute(cycle, &ctx);
593
594 if (pid == NGX_INVALID_PID) {
595 if (ngx_rename_file(ccf->oldpid.data, ccf->pid.data) != NGX_OK) {
596 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
597 ngx_rename_file_n " %s back to %s failed after "
598 "the try to execute the new binary process \"%s\"",
599 ccf->oldpid.data, ccf->pid.data, argv[0]);
600 }
601 }
602
603 ngx_free(env);
604 ngx_free(var);
605
606 return pid;
607 }
608
609
610 static ngx_int_t
611 ngx_getopt(ngx_cycle_t *cycle, int argc, char *const *argv)
612 {
613 ngx_int_t i;
614
615 for (i = 1; i < argc; i++) {
616 if (argv[i][0] != '-') {
617 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
618 "invalid option: \"%s\"", argv[i]);
619 return NGX_ERROR;
620 }
621
622 switch (argv[i][1]) {
623
624 case 'v':
625 ngx_show_version = 1;
626 break;
627
628 case 'V':
629 ngx_show_version = 1;
630 ngx_show_configure = 1;
631 break;
632
633 case 't':
634 ngx_test_config = 1;
635 break;
636
637 case 'c':
638 if (argv[i + 1] == NULL) {
639 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
640 "the option: \"%s\" requires file name",
641 argv[i]);
642 return NGX_ERROR;
643 }
644
645 cycle->conf_file.data = (u_char *) argv[++i];
646 cycle->conf_file.len = ngx_strlen(cycle->conf_file.data);
647 break;
648
649 default:
650 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
651 "invalid option: \"%s\"", argv[i]);
652 return NGX_ERROR;
653 }
654 }
655
656 if (cycle->conf_file.data == NULL) {
657 cycle->conf_file.len = sizeof(NGX_CONF_PATH) - 1;
658 cycle->conf_file.data = (u_char *) NGX_CONF_PATH;
659 }
660
661 return NGX_OK;
662 }
663
664
665 static ngx_int_t
666 ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv)
667 {
668 #if (NGX_FREEBSD)
669
670 ngx_os_argv = (char **) argv;
671 ngx_argc = argc;
672 ngx_argv = (char **) argv;
673
674 #else
675 size_t len;
676 ngx_int_t i;
677
678 ngx_os_argv = (char **) argv;
679 ngx_argc = argc;
680
681 ngx_argv = ngx_alloc((argc + 1) * sizeof(char *), cycle->log);
682 if (ngx_argv == NULL) {
683 return NGX_ERROR;
684 }
685
686 for (i = 0; i < argc; i++) {
687 len = ngx_strlen(argv[i]) + 1;
688
689 ngx_argv[i] = ngx_alloc(len, cycle->log);
690 if (ngx_argv[i] == NULL) {
691 return NGX_ERROR;
692 }
693
694 (void) ngx_cpystrn((u_char *) ngx_argv[i], (u_char *) argv[i], len);
695 }
696
697 ngx_argv[i] = NULL;
698
699 #endif
700
701 ngx_os_environ = environ;
702
703 return NGX_OK;
704 }
705
706
707 static void *
708 ngx_core_module_create_conf(ngx_cycle_t *cycle)
709 {
710 ngx_core_conf_t *ccf;
711
712 ccf = ngx_pcalloc(cycle->pool, sizeof(ngx_core_conf_t));
713 if (ccf == NULL) {
714 return NULL;
715 }
716
717 /*
718 * set by pcalloc()
719 *
720 * ccf->pid = NULL;
721 * ccf->oldpid = NULL;
722 * ccf->priority = 0;
723 * ccf->cpu_affinity_n = 0;
724 * ccf->cpu_affinity = NULL;
725 */
726
727 ccf->daemon = NGX_CONF_UNSET;
728 ccf->master = NGX_CONF_UNSET;
729 ccf->timer_resolution = NGX_CONF_UNSET_MSEC;
730
731 ccf->worker_processes = NGX_CONF_UNSET;
732 ccf->debug_points = NGX_CONF_UNSET;
733
734 ccf->rlimit_nofile = NGX_CONF_UNSET;
735 ccf->rlimit_core = NGX_CONF_UNSET_SIZE;
736 ccf->rlimit_sigpending = NGX_CONF_UNSET;
737
738 ccf->user = (ngx_uid_t) NGX_CONF_UNSET_UINT;
739 ccf->group = (ngx_gid_t) NGX_CONF_UNSET_UINT;
740
741 #if (NGX_THREADS)
742 ccf->worker_threads = NGX_CONF_UNSET;
743 ccf->thread_stack_size = NGX_CONF_UNSET_SIZE;
744 #endif
745
746 if (ngx_array_init(&ccf->env, cycle->pool, 1, sizeof(ngx_str_t))
747 != NGX_OK)
748 {
749 return NULL;
750 }
751
752 return ccf;
753 }
754
755
756 static char *
757 ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
758 {
759 ngx_core_conf_t *ccf = conf;
760
761 ngx_conf_init_value(ccf->daemon, 1);
762 ngx_conf_init_value(ccf->master, 1);
763 ngx_conf_init_msec_value(ccf->timer_resolution, 0);
764
765 ngx_conf_init_value(ccf->worker_processes, 1);
766 ngx_conf_init_value(ccf->debug_points, 0);
767
768 #if (NGX_HAVE_SCHED_SETAFFINITY)
769
770 if (ccf->cpu_affinity_n
771 && ccf->cpu_affinity_n != 1
772 && ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes)
773 {
774 ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
775 "number of the \"worker_processes\" is not equal to "
776 "the number of the \"worker_cpu_affinity\" mask, "
777 "using last mask for remaining worker processes");
778 }
779
780 #endif
781
782 #if (NGX_THREADS)
783
784 ngx_conf_init_value(ccf->worker_threads, 0);
785 ngx_threads_n = ccf->worker_threads;
786 ngx_conf_init_size_value(ccf->thread_stack_size, 2 * 1024 * 1024);
787
788 #endif
789
790 #if !(NGX_WIN32)
791
792 if (ccf->user == (uid_t) NGX_CONF_UNSET_UINT && geteuid() == 0) {
793 struct group *grp;
794 struct passwd *pwd;
795
796 ngx_set_errno(0);
797 pwd = getpwnam(NGX_USER);
798 if (pwd == NULL) {
799 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
800 "getpwnam(\"" NGX_USER "\") failed");
801 return NGX_CONF_ERROR;
802 }
803
804 ccf->username = NGX_USER;
805 ccf->user = pwd->pw_uid;
806
807 ngx_set_errno(0);
808 grp = getgrnam(NGX_GROUP);
809 if (grp == NULL) {
810 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
811 "getgrnam(\"" NGX_GROUP "\") failed");
812 return NGX_CONF_ERROR;
813 }
814
815 ccf->group = grp->gr_gid;
816 }
817
818 if (ccf->pid.len == 0) {
819 ccf->pid.len = sizeof(NGX_PID_PATH) - 1;
820 ccf->pid.data = (u_char *) NGX_PID_PATH;
821 }
822
823 if (ngx_conf_full_name(cycle, &ccf->pid, 0) == NGX_ERROR) {
824 return NGX_CONF_ERROR;
825 }
826
827 ccf->oldpid.len = ccf->pid.len + sizeof(NGX_OLDPID_EXT);
828
829 ccf->oldpid.data = ngx_palloc(cycle->pool, ccf->oldpid.len);
830 if (ccf->oldpid.data == NULL) {
831 return NGX_CONF_ERROR;
832 }
833
834 ngx_memcpy(ngx_cpymem(ccf->oldpid.data, ccf->pid.data, ccf->pid.len),
835 NGX_OLDPID_EXT, sizeof(NGX_OLDPID_EXT));
836
837
838 if (ccf->lock_file.len == 0) {
839 ccf->lock_file.len = sizeof(NGX_LOCK_PATH) - 1;
840 ccf->lock_file.data = (u_char *) NGX_LOCK_PATH;
841 }
842
843 if (ngx_conf_full_name(cycle, &ccf->lock_file, 0) == NGX_ERROR) {
844 return NGX_CONF_ERROR;
845 }
846
847 {
848 ngx_str_t lock_file;
849
850 lock_file = cycle->old_cycle->lock_file;
851
852 if (lock_file.len) {
853 lock_file.len--;
854
855 if (ccf->lock_file.len != lock_file.len
856 || ngx_strncmp(ccf->lock_file.data, lock_file.data, lock_file.len)
857 != 0)
858 {
859 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
860 "\"lock_file\" could not be changed, ignored");
861 }
862
863 cycle->lock_file.len = lock_file.len + 1;
864 lock_file.len += sizeof(".accept");
865
866 cycle->lock_file.data = ngx_pstrdup(cycle->pool, &lock_file);
867 if (cycle->lock_file.data == NULL) {
868 return NGX_CONF_ERROR;
869 }
870
871 } else {
872 cycle->lock_file.len = ccf->lock_file.len + 1;
873 cycle->lock_file.data = ngx_palloc(cycle->pool,
874 ccf->lock_file.len + sizeof(".accept"));
875 if (cycle->lock_file.data == NULL) {
876 return NGX_CONF_ERROR;
877 }
878
879 ngx_memcpy(ngx_cpymem(cycle->lock_file.data, ccf->lock_file.data,
880 ccf->lock_file.len),
881 ".accept", sizeof(".accept"));
882 }
883 }
884
885 #endif
886
887 return NGX_CONF_OK;
888 }
889
890
891 static char *
892 ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
893 {
894 #if (NGX_WIN32)
895
896 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
897 "\"user\" is not supported, ignored");
898
899 return NGX_CONF_OK;
900
901 #else
902
903 ngx_core_conf_t *ccf = conf;
904
905 char *group;
906 struct passwd *pwd;
907 struct group *grp;
908 ngx_str_t *value;
909
910 if (ccf->user != (uid_t) NGX_CONF_UNSET_UINT) {
911 return "is duplicate";
912 }
913
914 if (geteuid() != 0) {
915 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
916 "the \"user\" directive makes sense only "
917 "if the master process runs "
918 "with super-user privileges, ignored");
919 return NGX_CONF_OK;
920 }
921
922 value = (ngx_str_t *) cf->args->elts;
923
924 ccf->username = (char *) value[1].data;
925
926 ngx_set_errno(0);
927 pwd = getpwnam((const char *) value[1].data);
928 if (pwd == NULL) {
929 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
930 "getpwnam(\"%s\") failed", value[1].data);
931 return NGX_CONF_ERROR;
932 }
933
934 ccf->user = pwd->pw_uid;
935
936 group = (char *) ((cf->args->nelts == 2) ? value[1].data : value[2].data);
937
938 ngx_set_errno(0);
939 grp = getgrnam(group);
940 if (grp == NULL) {
941 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
942 "getgrnam(\"%s\") failed", group);
943 return NGX_CONF_ERROR;
944 }
945
946 ccf->group = grp->gr_gid;
947
948 return NGX_CONF_OK;
949
950 #endif
951 }
952
953
954 static char *
955 ngx_set_env(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
956 {
957 ngx_core_conf_t *ccf = conf;
958
959 ngx_str_t *value, *var;
960 ngx_uint_t i;
961
962 var = ngx_array_push(&ccf->env);
963 if (var == NULL) {
964 return NGX_CONF_ERROR;
965 }
966
967 value = cf->args->elts;
968 *var = value[1];
969
970 for (i = 0; i < value[1].len; i++) {
971
972 if (value[1].data[i] == '=') {
973
974 var->len = i;
975
976 return NGX_CONF_OK;
977 }
978 }
979
980 return NGX_CONF_OK;
981 }
982
983
984 static char *
985 ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
986 {
987 ngx_core_conf_t *ccf = conf;
988
989 ngx_str_t *value;
990 ngx_uint_t n, minus;
991
992 if (ccf->priority != 0) {
993 return "is duplicate";
994 }
995
996 value = cf->args->elts;
997
998 if (value[1].data[0] == '-') {
999 n = 1;
1000 minus = 1;
1001
1002 } else if (value[1].data[0] == '+') {
1003 n = 1;
1004 minus = 0;
1005
1006 } else {
1007 n = 0;
1008 minus = 0;
1009 }
1010
1011 ccf->priority = ngx_atoi(&value[1].data[n], value[1].len - n);
1012 if (ccf->priority == NGX_ERROR) {
1013 return "invalid number";
1014 }
1015
1016 if (minus) {
1017 ccf->priority = -ccf->priority;
1018 }
1019
1020 return NGX_CONF_OK;
1021 }
1022
1023
1024 static char *
1025 ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1026 {
1027 #if (NGX_HAVE_SCHED_SETAFFINITY)
1028 ngx_core_conf_t *ccf = conf;
1029
1030 u_char ch;
1031 u_long *mask;
1032 ngx_str_t *value;
1033 ngx_uint_t i, n;
1034
1035 if (ccf->cpu_affinity) {
1036 return "is duplicate";
1037 }
1038
1039 mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(long));
1040 if (mask == NULL) {
1041 return NGX_CONF_ERROR;
1042 }
1043
1044 ccf->cpu_affinity_n = cf->args->nelts - 1;
1045 ccf->cpu_affinity = mask;
1046
1047 value = cf->args->elts;
1048
1049 for (n = 1; n < cf->args->nelts; n++) {
1050
1051 if (value[n].len > 32) {
1052 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1053 "\"worker_cpu_affinity\" supports up to 32 CPU only");
1054 return NGX_CONF_ERROR;
1055 }
1056
1057 mask[n - 1] = 0;
1058
1059 for (i = 0; i < value[n].len; i++) {
1060
1061 ch = value[n].data[i];
1062
1063 if (ch == ' ') {
1064 continue;
1065 }
1066
1067 mask[n - 1] <<= 1;
1068
1069 if (ch == '') {
1070 continue;
1071 }
1072
1073 if (ch == '1') {
1074 mask[n - 1] |= 1;
1075 continue;
1076 }
1077
1078 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1079 "invalid character \"%c\" in \"worker_cpu_affinity\"",
1080 ch);
1081 return NGX_CONF_ERROR ;
1082 }
1083 }
1084
1085 #else
1086
1087 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1088 "\"worker_cpu_affinity\" is not supported "
1089 "on this platform, ignored");
1090 #endif
1091
1092 return NGX_CONF_OK;
1093 }
1094
1095
1096 u_long
1097 ngx_get_cpu_affinity(ngx_uint_t n)
1098 {
1099 ngx_core_conf_t *ccf;
1100
1101 ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
1102 ngx_core_module);
1103
1104 if (ccf->cpu_affinity == NULL) {
1105 return 0;
1106 }
1107
1108 if (ccf->cpu_affinity_n > n) {
1109 return ccf->cpu_affinity[n];
1110 }
1111
1112 return ccf->cpu_affinity[ccf->cpu_affinity_n - 1];
1113 }
1114
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.