3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
8 #include <ngx_config.h>
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
,
24 static char *ngx_set_worker_processes(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
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 }
35 static ngx_command_t ngx_core_commands
[] = {
37 { ngx_string("daemon"),
38 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_FLAG
,
39 ngx_conf_set_flag_slot
,
41 offsetof(ngx_core_conf_t
, daemon
),
44 { ngx_string("master_process"),
45 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_FLAG
,
46 ngx_conf_set_flag_slot
,
48 offsetof(ngx_core_conf_t
, master
),
51 { ngx_string("timer_resolution"),
52 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_TAKE1
,
53 ngx_conf_set_msec_slot
,
55 offsetof(ngx_core_conf_t
, timer_resolution
),
59 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_TAKE1
,
60 ngx_conf_set_str_slot
,
62 offsetof(ngx_core_conf_t
, pid
),
65 { ngx_string("lock_file"),
66 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_TAKE1
,
67 ngx_conf_set_str_slot
,
69 offsetof(ngx_core_conf_t
, lock_file
),
72 { ngx_string("worker_processes"),
73 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_TAKE1
,
74 ngx_set_worker_processes
,
79 { ngx_string("debug_points"),
80 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_TAKE1
,
81 ngx_conf_set_enum_slot
,
83 offsetof(ngx_core_conf_t
, debug_points
),
87 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_TAKE12
,
93 { ngx_string("worker_priority"),
94 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_TAKE1
,
100 { ngx_string("worker_cpu_affinity"),
101 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_1MORE
,
102 ngx_set_cpu_affinity
,
107 { ngx_string("worker_rlimit_nofile"),
108 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_TAKE1
,
109 ngx_conf_set_num_slot
,
111 offsetof(ngx_core_conf_t
, rlimit_nofile
),
114 { ngx_string("worker_rlimit_core"),
115 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_TAKE1
,
116 ngx_conf_set_off_slot
,
118 offsetof(ngx_core_conf_t
, rlimit_core
),
121 { ngx_string("worker_rlimit_sigpending"),
122 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_TAKE1
,
123 ngx_conf_set_num_slot
,
125 offsetof(ngx_core_conf_t
, rlimit_sigpending
),
128 { ngx_string("working_directory"),
129 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_TAKE1
,
130 ngx_conf_set_str_slot
,
132 offsetof(ngx_core_conf_t
, working_directory
),
136 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_TAKE1
,
144 { ngx_string("worker_threads"),
145 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_TAKE1
,
146 ngx_conf_set_num_slot
,
148 offsetof(ngx_core_conf_t
, worker_threads
),
151 { ngx_string("thread_stack_size"),
152 NGX_MAIN_CONF
|NGX_DIRECT_CONF
|NGX_CONF_TAKE1
,
153 ngx_conf_set_size_slot
,
155 offsetof(ngx_core_conf_t
, thread_stack_size
),
164 static ngx_core_module_t ngx_core_module_ctx
= {
166 ngx_core_module_create_conf
,
167 ngx_core_module_init_conf
171 ngx_module_t ngx_core_module
= {
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
187 ngx_uint_t ngx_max_module
;
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
;
198 static char **ngx_os_environ
;
202 main(int argc
, char *const *argv
)
206 ngx_cycle_t
*cycle
, init_cycle
;
207 ngx_core_conf_t
*ccf
;
211 if (ngx_strerror_init() != NGX_OK
) {
215 if (ngx_get_options(argc
, argv
) != NGX_OK
) {
219 if (ngx_show_version
) {
220 ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED
);
224 "Usage: nginx [-?hvVtq] [-s signal] [-c filename] "
225 "[-p prefix] [-g directives]" 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"
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
238 " -p prefix : set prefix path (default: "
239 NGX_PREFIX
")" NGX_LINEFEED
241 " -p prefix : set prefix path (default: NONE)" NGX_LINEFEED
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
250 if (ngx_show_configure
) {
253 "built by " NGX_COMPILER NGX_LINEFEED
256 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
257 "TLS SNI support enabled" NGX_LINEFEED
259 "TLS SNI support disabled" NGX_LINEFEED
262 "configure arguments:" NGX_CONFIGURE NGX_LINEFEED
);
265 if (!ngx_test_config
) {
270 /* TODO */ ngx_max_sockets
= -1;
278 ngx_pid
= ngx_getpid();
280 log
= ngx_log_init(ngx_prefix
);
291 * init_cycle->log is required for signal handlers and
292 * ngx_process_options()
295 ngx_memzero(&init_cycle
, sizeof(ngx_cycle_t
));
296 init_cycle
.log
= log
;
297 ngx_cycle
= &init_cycle
;
299 init_cycle
.pool
= ngx_create_pool(1024, log
);
300 if (init_cycle
.pool
== NULL
) {
304 if (ngx_save_argv(&init_cycle
, argc
, argv
) != NGX_OK
) {
308 if (ngx_process_options(&init_cycle
) != NGX_OK
) {
312 if (ngx_os_init(log
) != NGX_OK
) {
317 * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
320 if (ngx_crc32_table_init() != NGX_OK
) {
324 if (ngx_add_inherited_sockets(&init_cycle
) != NGX_OK
) {
329 for (i
= 0; ngx_modules
[i
]; i
++) {
330 ngx_modules
[i
]->index
= ngx_max_module
++;
333 cycle
= ngx_init_cycle(&init_cycle
);
335 if (ngx_test_config
) {
336 ngx_log_stderr(0, "configuration file %s test failed",
337 init_cycle
.conf_file
.data
);
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
);
353 return ngx_signal_process(cycle
, ngx_signal
);
356 ngx_os_status(cycle
->log
);
360 ccf
= (ngx_core_conf_t
*) ngx_get_conf(cycle
->conf_ctx
, ngx_core_module
);
362 if (ccf
->master
&& ngx_process
== NGX_PROCESS_SINGLE
) {
363 ngx_process
= NGX_PROCESS_MASTER
;
368 if (ngx_init_signals(cycle
->log
) != NGX_OK
) {
372 if (!ngx_inherited
&& ccf
->daemon
) {
373 if (ngx_daemon(cycle
->log
) != NGX_OK
) {
386 if (ngx_create_pidfile(&ccf
->pid
, cycle
->log
) != NGX_OK
) {
390 if (cycle
->log
->file
->fd
!= ngx_stderr
) {
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");
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");
408 if (ngx_process
== NGX_PROCESS_SINGLE
) {
409 ngx_single_process_cycle(cycle
);
412 ngx_master_process_cycle(cycle
);
420 ngx_add_inherited_sockets(ngx_cycle_t
*cycle
)
422 u_char
*p
, *v
, *inherited
;
426 inherited
= (u_char
*) getenv(NGINX_VAR
);
428 if (inherited
== NULL
) {
432 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0,
433 "using inherited sockets from \"%s\"", inherited
);
435 if (ngx_array_init(&cycle
->listening
, cycle
->pool
, 10,
436 sizeof(ngx_listening_t
))
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
);
455 ls
= ngx_array_push(&cycle
->listening
);
460 ngx_memzero(ls
, sizeof(ngx_listening_t
));
462 ls
->fd
= (ngx_socket_t
) s
;
468 return ngx_set_inherited_sockets(cycle
);
473 ngx_set_environment(ngx_cycle_t
*cycle
, ngx_uint_t
*last
)
478 ngx_core_conf_t
*ccf
;
480 ccf
= (ngx_core_conf_t
*) ngx_get_conf(cycle
->conf_ctx
, ngx_core_module
);
482 if (last
== NULL
&& ccf
->environment
) {
483 return ccf
->environment
;
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)
496 var
= ngx_array_push(&ccf
->env
);
502 var
->data
= (u_char
*) "TZ";
510 for (i
= 0; i
< ccf
->env
.nelts
; i
++) {
512 if (var
[i
].data
[var
[i
].len
] == '=') {
517 for (p
= ngx_os_environ
; *p
; p
++) {
519 if (ngx_strncmp(*p
, var
[i
].data
, var
[i
].len
) == 0
520 && (*p
)[var
[i
].len
] == '=')
529 env
= ngx_alloc((*last
+ n
+ 1) * sizeof(char *), cycle
->log
);
533 env
= ngx_palloc(cycle
->pool
, (n
+ 1) * sizeof(char *));
542 for (i
= 0; i
< ccf
->env
.nelts
; i
++) {
544 if (var
[i
].data
[var
[i
].len
] == '=') {
545 env
[n
++] = (char *) var
[i
].data
;
549 for (p
= ngx_os_environ
; *p
; p
++) {
551 if (ngx_strncmp(*p
, var
[i
].data
, var
[i
].len
) == 0
552 && (*p
)[var
[i
].len
] == '=')
563 ccf
->environment
= env
;
572 ngx_exec_new_binary(ngx_cycle_t
*cycle
, char *const *argv
)
579 ngx_core_conf_t
*ccf
;
582 ngx_memzero(&ctx
, sizeof(ngx_exec_ctx_t
));
585 ctx
.name
= "new binary process";
589 env
= ngx_set_environment(cycle
, &n
);
591 return NGX_INVALID_PID
;
594 var
= ngx_alloc(sizeof(NGINX_VAR
)
595 + cycle
->listening
.nelts
* (NGX_INT32_LEN
+ 1) + 2,
599 return NGX_INVALID_PID
;
602 p
= ngx_cpymem(var
, NGINX_VAR
"=", sizeof(NGINX_VAR
));
604 ls
= cycle
->listening
.elts
;
605 for (i
= 0; i
< cycle
->listening
.nelts
; i
++) {
606 p
= ngx_sprintf(p
, "%ud;", ls
[i
].fd
);
613 #if (NGX_SETPROCTITLE_USES_ENV)
615 /* allocate the spare 300 bytes for the new binary process title */
617 env
[n
++] = "SPARE=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
618 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
619 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
620 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
621 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
630 for (e
= env
; *e
; e
++) {
631 ngx_log_debug1(NGX_LOG_DEBUG_CORE
, cycle
->log
, 0, "env: %s", *e
);
636 ctx
.envp
= (char *const *) env
;
638 ccf
= (ngx_core_conf_t
*) ngx_get_conf(cycle
->conf_ctx
, ngx_core_module
);
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]);
649 return NGX_INVALID_PID
;
652 pid
= ngx_execute(cycle
, &ctx
);
654 if (pid
== NGX_INVALID_PID
) {
655 if (ngx_rename_file(ccf
->oldpid
.data
, ccf
->pid
.data
)
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]);
673 ngx_get_options(int argc
, char *const *argv
)
678 for (i
= 1; i
< argc
; i
++) {
680 p
= (u_char
*) argv
[i
];
683 ngx_log_stderr(0, "invalid option: \"%s\"", argv
[i
]);
693 ngx_show_version
= 1;
698 ngx_show_version
= 1;
702 ngx_show_version
= 1;
703 ngx_show_configure
= 1;
721 ngx_prefix
= (u_char
*) argv
[i
];
725 ngx_log_stderr(0, "option \"-p\" requires directory name");
735 ngx_conf_file
= (u_char
*) argv
[i
];
739 ngx_log_stderr(0, "option \"-c\" requires file name");
749 ngx_conf_params
= (u_char
*) argv
[i
];
753 ngx_log_stderr(0, "option \"-g\" requires parameter");
758 ngx_signal
= (char *) p
;
760 } else if (argv
[++i
]) {
761 ngx_signal
= argv
[i
];
764 ngx_log_stderr(0, "option \"-s\" requires parameter");
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)
773 ngx_process
= NGX_PROCESS_SIGNALLER
;
777 ngx_log_stderr(0, "invalid option: \"-s %s\"", ngx_signal
);
781 ngx_log_stderr(0, "invalid option: \"%c\"", *(p
- 1));
796 ngx_save_argv(ngx_cycle_t
*cycle
, int argc
, char *const *argv
)
800 ngx_os_argv
= (char **) argv
;
802 ngx_argv
= (char **) argv
;
808 ngx_os_argv
= (char **) argv
;
811 ngx_argv
= ngx_alloc((argc
+ 1) * sizeof(char *), cycle
->log
);
812 if (ngx_argv
== NULL
) {
816 for (i
= 0; i
< argc
; i
++) {
817 len
= ngx_strlen(argv
[i
]) + 1;
819 ngx_argv
[i
] = ngx_alloc(len
, cycle
->log
);
820 if (ngx_argv
[i
] == NULL
) {
824 (void) ngx_cpystrn((u_char
*) ngx_argv
[i
], (u_char
*) argv
[i
], len
);
831 ngx_os_environ
= environ
;
838 ngx_process_options(ngx_cycle_t
*cycle
)
844 len
= ngx_strlen(ngx_prefix
);
847 if (len
&& !ngx_path_separator(p
[len
- 1])) {
848 p
= ngx_pnalloc(cycle
->pool
, len
+ 1);
853 ngx_memcpy(p
, ngx_prefix
, len
);
857 cycle
->conf_prefix
.len
= len
;
858 cycle
->conf_prefix
.data
= p
;
859 cycle
->prefix
.len
= len
;
860 cycle
->prefix
.data
= p
;
866 p
= ngx_pnalloc(cycle
->pool
, NGX_MAX_PATH
);
871 if (ngx_getcwd(p
, NGX_MAX_PATH
) == 0) {
872 ngx_log_stderr(ngx_errno
, "[emerg]: " ngx_getcwd_n
" failed");
880 cycle
->conf_prefix
.len
= len
;
881 cycle
->conf_prefix
.data
= p
;
882 cycle
->prefix
.len
= len
;
883 cycle
->prefix
.data
= p
;
887 #ifdef NGX_CONF_PREFIX
888 ngx_str_set(&cycle
->conf_prefix
, NGX_CONF_PREFIX
);
890 ngx_str_set(&cycle
->conf_prefix
, NGX_PREFIX
);
892 ngx_str_set(&cycle
->prefix
, NGX_PREFIX
);
898 cycle
->conf_file
.len
= ngx_strlen(ngx_conf_file
);
899 cycle
->conf_file
.data
= ngx_conf_file
;
902 ngx_str_set(&cycle
->conf_file
, NGX_CONF_PATH
);
905 if (ngx_conf_full_name(cycle
, &cycle
->conf_file
, 0) != NGX_OK
) {
909 for (p
= cycle
->conf_file
.data
+ cycle
->conf_file
.len
- 1;
910 p
> cycle
->conf_file
.data
;
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
;
920 if (ngx_conf_params
) {
921 cycle
->conf_param
.len
= ngx_strlen(ngx_conf_params
);
922 cycle
->conf_param
.data
= ngx_conf_params
;
925 if (ngx_test_config
) {
926 cycle
->log
->log_level
= NGX_LOG_INFO
;
934 ngx_core_module_create_conf(ngx_cycle_t
*cycle
)
936 ngx_core_conf_t
*ccf
;
938 ccf
= ngx_pcalloc(cycle
->pool
, sizeof(ngx_core_conf_t
));
944 * set by ngx_pcalloc()
947 * ccf->oldpid = NULL;
949 * ccf->cpu_affinity_n = 0;
950 * ccf->cpu_affinity = NULL;
953 ccf
->daemon
= NGX_CONF_UNSET
;
954 ccf
->master
= NGX_CONF_UNSET
;
955 ccf
->timer_resolution
= NGX_CONF_UNSET_MSEC
;
957 ccf
->worker_processes
= NGX_CONF_UNSET
;
958 ccf
->debug_points
= NGX_CONF_UNSET
;
960 ccf
->rlimit_nofile
= NGX_CONF_UNSET
;
961 ccf
->rlimit_core
= NGX_CONF_UNSET
;
962 ccf
->rlimit_sigpending
= NGX_CONF_UNSET
;
964 ccf
->user
= (ngx_uid_t
) NGX_CONF_UNSET_UINT
;
965 ccf
->group
= (ngx_gid_t
) NGX_CONF_UNSET_UINT
;
968 ccf
->worker_threads
= NGX_CONF_UNSET
;
969 ccf
->thread_stack_size
= NGX_CONF_UNSET_SIZE
;
972 if (ngx_array_init(&ccf
->env
, cycle
->pool
, 1, sizeof(ngx_str_t
))
983 ngx_core_module_init_conf(ngx_cycle_t
*cycle
, void *conf
)
985 ngx_core_conf_t
*ccf
= conf
;
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);
991 ngx_conf_init_value(ccf
->worker_processes
, 1);
992 ngx_conf_init_value(ccf
->debug_points
, 0);
994 #if (NGX_HAVE_CPU_AFFINITY)
996 if (ccf
->cpu_affinity_n
997 && ccf
->cpu_affinity_n
!= 1
998 && ccf
->cpu_affinity_n
!= (ngx_uint_t
) ccf
->worker_processes
)
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");
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);
1017 if (ccf
->pid
.len
== 0) {
1018 ngx_str_set(&ccf
->pid
, NGX_PID_PATH
);
1021 if (ngx_conf_full_name(cycle
, &ccf
->pid
, 0) != NGX_OK
) {
1022 return NGX_CONF_ERROR
;
1025 ccf
->oldpid
.len
= ccf
->pid
.len
+ sizeof(NGX_OLDPID_EXT
);
1027 ccf
->oldpid
.data
= ngx_pnalloc(cycle
->pool
, ccf
->oldpid
.len
);
1028 if (ccf
->oldpid
.data
== NULL
) {
1029 return NGX_CONF_ERROR
;
1032 ngx_memcpy(ngx_cpymem(ccf
->oldpid
.data
, ccf
->pid
.data
, ccf
->pid
.len
),
1033 NGX_OLDPID_EXT
, sizeof(NGX_OLDPID_EXT
));
1038 if (ccf
->user
== (uid_t
) NGX_CONF_UNSET_UINT
&& geteuid() == 0) {
1043 pwd
= getpwnam(NGX_USER
);
1045 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, ngx_errno
,
1046 "getpwnam(\"" NGX_USER
"\") failed");
1047 return NGX_CONF_ERROR
;
1050 ccf
->username
= NGX_USER
;
1051 ccf
->user
= pwd
->pw_uid
;
1054 grp
= getgrnam(NGX_GROUP
);
1056 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, ngx_errno
,
1057 "getgrnam(\"" NGX_GROUP
"\") failed");
1058 return NGX_CONF_ERROR
;
1061 ccf
->group
= grp
->gr_gid
;
1065 if (ccf
->lock_file
.len
== 0) {
1066 ngx_str_set(&ccf
->lock_file
, NGX_LOCK_PATH
);
1069 if (ngx_conf_full_name(cycle
, &ccf
->lock_file
, 0) != NGX_OK
) {
1070 return NGX_CONF_ERROR
;
1074 ngx_str_t lock_file
;
1076 lock_file
= cycle
->old_cycle
->lock_file
;
1078 if (lock_file
.len
) {
1081 if (ccf
->lock_file
.len
!= lock_file
.len
1082 || ngx_strncmp(ccf
->lock_file
.data
, lock_file
.data
, lock_file
.len
)
1085 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, 0,
1086 "\"lock_file\" could not be changed, ignored");
1089 cycle
->lock_file
.len
= lock_file
.len
+ 1;
1090 lock_file
.len
+= sizeof(".accept");
1092 cycle
->lock_file
.data
= ngx_pstrdup(cycle
->pool
, &lock_file
);
1093 if (cycle
->lock_file
.data
== NULL
) {
1094 return NGX_CONF_ERROR
;
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
;
1105 ngx_memcpy(ngx_cpymem(cycle
->lock_file
.data
, ccf
->lock_file
.data
,
1106 ccf
->lock_file
.len
),
1107 ".accept", sizeof(".accept"));
1118 ngx_set_user(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
1122 ngx_conf_log_error(NGX_LOG_WARN
, cf
, 0,
1123 "\"user\" is not supported, ignored");
1129 ngx_core_conf_t
*ccf
= conf
;
1136 if (ccf
->user
!= (uid_t
) NGX_CONF_UNSET_UINT
) {
1137 return "is duplicate";
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");
1148 value
= (ngx_str_t
*) cf
->args
->elts
;
1150 ccf
->username
= (char *) value
[1].data
;
1153 pwd
= getpwnam((const char *) value
[1].data
);
1155 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, ngx_errno
,
1156 "getpwnam(\"%s\") failed", value
[1].data
);
1157 return NGX_CONF_ERROR
;
1160 ccf
->user
= pwd
->pw_uid
;
1162 group
= (char *) ((cf
->args
->nelts
== 2) ? value
[1].data
: value
[2].data
);
1165 grp
= getgrnam(group
);
1167 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, ngx_errno
,
1168 "getgrnam(\"%s\") failed", group
);
1169 return NGX_CONF_ERROR
;
1172 ccf
->group
= grp
->gr_gid
;
1181 ngx_set_env(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
1183 ngx_core_conf_t
*ccf
= conf
;
1185 ngx_str_t
*value
, *var
;
1188 var
= ngx_array_push(&ccf
->env
);
1190 return NGX_CONF_ERROR
;
1193 value
= cf
->args
->elts
;
1196 for (i
= 0; i
< value
[1].len
; i
++) {
1198 if (value
[1].data
[i
] == '=') {
1211 ngx_set_priority(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
1213 ngx_core_conf_t
*ccf
= conf
;
1216 ngx_uint_t n
, minus
;
1218 if (ccf
->priority
!= 0) {
1219 return "is duplicate";
1222 value
= cf
->args
->elts
;
1224 if (value
[1].data
[0] == '-') {
1228 } else if (value
[1].data
[0] == '+') {
1237 ccf
->priority
= ngx_atoi(&value
[1].data
[n
], value
[1].len
- n
);
1238 if (ccf
->priority
== NGX_ERROR
) {
1239 return "invalid number";
1243 ccf
->priority
= -ccf
->priority
;
1251 ngx_set_cpu_affinity(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
1253 #if (NGX_HAVE_CPU_AFFINITY)
1254 ngx_core_conf_t
*ccf
= conf
;
1261 if (ccf
->cpu_affinity
) {
1262 return "is duplicate";
1265 mask
= ngx_palloc(cf
->pool
, (cf
->args
->nelts
- 1) * sizeof(uint64_t));
1267 return NGX_CONF_ERROR
;
1270 ccf
->cpu_affinity_n
= cf
->args
->nelts
- 1;
1271 ccf
->cpu_affinity
= mask
;
1273 value
= cf
->args
->elts
;
1275 for (n
= 1; n
< cf
->args
->nelts
; n
++) {
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
;
1285 for (i
= 0; i
< value
[n
].len
; i
++) {
1287 ch
= value
[n
].data
[i
];
1304 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1305 "invalid character \"%c\" in \"worker_cpu_affinity\"",
1307 return NGX_CONF_ERROR
;
1313 ngx_conf_log_error(NGX_LOG_WARN
, cf
, 0,
1314 "\"worker_cpu_affinity\" is not supported "
1315 "on this platform, ignored");
1323 ngx_get_cpu_affinity(ngx_uint_t n
)
1325 ngx_core_conf_t
*ccf
;
1327 ccf
= (ngx_core_conf_t
*) ngx_get_conf(ngx_cycle
->conf_ctx
,
1330 if (ccf
->cpu_affinity
== NULL
) {
1334 if (ccf
->cpu_affinity_n
> n
) {
1335 return ccf
->cpu_affinity
[n
];
1338 return ccf
->cpu_affinity
[ccf
->cpu_affinity_n
- 1];
1343 ngx_set_worker_processes(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
1346 ngx_core_conf_t
*ccf
;
1348 ccf
= (ngx_core_conf_t
*) conf
;
1350 if (ccf
->worker_processes
!= NGX_CONF_UNSET
) {
1351 return "is duplicate";
1354 value
= (ngx_str_t
*) cf
->args
->elts
;
1356 if (ngx_strcmp(value
[1].data
, "auto") == 0) {
1357 ccf
->worker_processes
= ngx_ncpu
;
1361 ccf
->worker_processes
= ngx_atoi(value
[1].data
, value
[1].len
);
1363 if (ccf
->worker_processes
== NGX_ERROR
) {
1364 return "invalid value";