3
3
* Copyright (C) Igor Sysoev
4
* Copyright (C) Nginx, Inc.
7
8
#include <ngx_config.h>
8
9
#include <ngx_core.h>
13
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);
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);
15
16
static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv);
16
17
static void *ngx_core_module_create_conf(ngx_cycle_t *cycle);
17
18
static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf);
20
21
static char *ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
21
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,
25
28
static ngx_conf_enum_t ngx_debug_points[] = {
69
72
{ ngx_string("worker_processes"),
70
73
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
71
ngx_conf_set_num_slot,
73
offsetof(ngx_core_conf_t, worker_processes),
74
ngx_set_worker_processes,
76
79
{ ngx_string("debug_points"),
184
ngx_uint_t ngx_max_module;
186
static ngx_uint_t ngx_show_version;
187
static ngx_uint_t ngx_show_configure;
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;
189
198
static char **ngx_os_environ;
193
202
main(int argc, char *const *argv)
199
206
ngx_cycle_t *cycle, init_cycle;
200
207
ngx_core_conf_t *ccf;
203
209
ngx_debug_init();
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) {
206
270
/* TODO */ ngx_max_sockets = -1;
241
if (ngx_getopt(&init_cycle, argc, ngx_argv) != NGX_OK) {
308
if (ngx_process_options(&init_cycle) != NGX_OK) {
245
if (ngx_show_version) {
247
p = "nginx version: " NGINX_VER CRLF;
248
n = sizeof("nginx version: " NGINX_VER CRLF) - 1;
250
if (ngx_write_fd(ngx_stderr_fileno, p, n) != n) {
254
if (ngx_show_configure) {
256
p = "built by " NGX_COMPILER CRLF;
257
n = sizeof("built by " NGX_COMPILER CRLF) - 1;
259
if (ngx_write_fd(ngx_stderr_fileno, p, n) != n) {
264
p = "configure arguments: " NGX_CONFIGURE CRLF;
265
n = sizeof("configure arguments :" NGX_CONFIGURE CRLF) - 1;
267
if (ngx_write_fd(ngx_stderr_fileno, p, n) != n) {
272
if (!ngx_test_config) {
277
if (ngx_test_config) {
278
log->log_level = NGX_LOG_INFO;
281
312
if (ngx_os_init(log) != NGX_OK) {
302
333
cycle = ngx_init_cycle(&init_cycle);
303
334
if (cycle == NULL) {
304
335
if (ngx_test_config) {
305
ngx_log_error(NGX_LOG_EMERG, log, 0,
306
"the configuration file %s test failed",
307
init_cycle.conf_file.data);
336
ngx_log_stderr(0, "configuration file %s test failed",
337
init_cycle.conf_file.data);
313
343
if (ngx_test_config) {
314
ngx_log_error(NGX_LOG_INFO, log, 0,
315
"the configuration file %s was tested successfully",
316
cycle->conf_file.data);
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);
320
356
ngx_os_status(cycle->log);
322
358
ngx_cycle = cycle;
324
360
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
326
ngx_process = ccf->master ? NGX_PROCESS_MASTER : NGX_PROCESS_SINGLE;
334
if (ccf->run_as_service) {
335
if (ngx_service(cycle->log) != NGX_OK) {
362
if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
363
ngx_process = NGX_PROCESS_MASTER;
345
368
if (ngx_init_signals(cycle->log) != NGX_OK) {
354
377
ngx_daemonized = 1;
357
386
if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
363
if (ngx_process == NGX_PROCESS_MASTER) {
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);
364
412
ngx_master_process_cycle(cycle);
367
ngx_single_process_cycle(cycle);
587
638
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
589
if (ngx_rename_file(ccf->pid.data, ccf->oldpid.data) != NGX_OK) {
640
if (ngx_rename_file(ccf->pid.data, ccf->oldpid.data) == NGX_FILE_ERROR) {
590
641
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
591
642
ngx_rename_file_n " %s to %s failed "
592
643
"before executing new binary process \"%s\"",
601
652
pid = ngx_execute(cycle, &ctx);
603
654
if (pid == NGX_INVALID_PID) {
604
if (ngx_rename_file(ccf->oldpid.data, ccf->pid.data) != NGX_OK) {
655
if (ngx_rename_file(ccf->oldpid.data, ccf->pid.data)
605
658
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
606
659
ngx_rename_file_n " %s back to %s failed after "
607
"the try to execute the new binary process \"%s\"",
660
"an attempt to execute new binary process \"%s\"",
608
661
ccf->oldpid.data, ccf->pid.data, argv[0]);
620
ngx_getopt(ngx_cycle_t *cycle, int argc, char *const *argv)
673
ngx_get_options(int argc, char *const *argv)
624
678
for (i = 1; i < argc; i++) {
625
if (argv[i][0] != '-') {
626
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
627
"invalid option: \"%s\"", argv[i]);
680
p = (u_char *) argv[i];
683
ngx_log_stderr(0, "invalid option: \"%s\"", argv[i]);
628
684
return NGX_ERROR;
631
switch (argv[i][1]) {
634
ngx_show_version = 1;
638
ngx_show_version = 1;
639
ngx_show_configure = 1;
647
if (argv[i + 1] == NULL) {
648
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
649
"the option: \"%s\" requires file name",
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));
651
782
return NGX_ERROR;
654
cycle->conf_file.data = (u_char *) argv[++i];
655
cycle->conf_file.len = ngx_strlen(cycle->conf_file.data);
659
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
660
"invalid option: \"%s\"", argv[i]);
665
if (cycle->conf_file.data == NULL) {
666
cycle->conf_file.len = sizeof(NGX_CONF_PATH) - 1;
667
cycle->conf_file.data = (u_char *) NGX_CONF_PATH;
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;
717
934
ngx_core_module_create_conf(ngx_cycle_t *cycle)
741
958
ccf->debug_points = NGX_CONF_UNSET;
743
960
ccf->rlimit_nofile = NGX_CONF_UNSET;
744
ccf->rlimit_core = NGX_CONF_UNSET_SIZE;
961
ccf->rlimit_core = NGX_CONF_UNSET;
745
962
ccf->rlimit_sigpending = NGX_CONF_UNSET;
747
964
ccf->user = (ngx_uid_t) NGX_CONF_UNSET_UINT;
774
991
ngx_conf_init_value(ccf->worker_processes, 1);
775
992
ngx_conf_init_value(ccf->debug_points, 0);
777
#if (NGX_HAVE_SCHED_SETAFFINITY)
994
#if (NGX_HAVE_CPU_AFFINITY)
779
996
if (ccf->cpu_affinity_n
780
997
&& ccf->cpu_affinity_n != 1
781
998
&& ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes)
783
1000
ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
784
"number of the \"worker_processes\" is not equal to "
785
"the number of the \"worker_cpu_affinity\" mask, "
1001
"the number of \"worker_processes\" is not equal to "
1002
"the number of \"worker_cpu_affinity\" masks, "
786
1003
"using last mask for remaining worker processes");
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));
799
1036
#if !(NGX_WIN32)
801
1038
if (ccf->user == (uid_t) NGX_CONF_UNSET_UINT && geteuid() == 0) {
824
1061
ccf->group = grp->gr_gid;
827
if (ccf->pid.len == 0) {
828
ccf->pid.len = sizeof(NGX_PID_PATH) - 1;
829
ccf->pid.data = (u_char *) NGX_PID_PATH;
832
if (ngx_conf_full_name(cycle, &ccf->pid, 0) == NGX_ERROR) {
833
return NGX_CONF_ERROR;
836
ccf->oldpid.len = ccf->pid.len + sizeof(NGX_OLDPID_EXT);
838
ccf->oldpid.data = ngx_palloc(cycle->pool, ccf->oldpid.len);
839
if (ccf->oldpid.data == NULL) {
840
return NGX_CONF_ERROR;
843
ngx_memcpy(ngx_cpymem(ccf->oldpid.data, ccf->pid.data, ccf->pid.len),
844
NGX_OLDPID_EXT, sizeof(NGX_OLDPID_EXT));
847
1065
if (ccf->lock_file.len == 0) {
848
ccf->lock_file.len = sizeof(NGX_LOCK_PATH) - 1;
849
ccf->lock_file.data = (u_char *) NGX_LOCK_PATH;
1066
ngx_str_set(&ccf->lock_file, NGX_LOCK_PATH);
852
if (ngx_conf_full_name(cycle, &ccf->lock_file, 0) == NGX_ERROR) {
1069
if (ngx_conf_full_name(cycle, &ccf->lock_file, 0) != NGX_OK) {
853
1070
return NGX_CONF_ERROR;
881
1098
cycle->lock_file.len = ccf->lock_file.len + 1;
882
cycle->lock_file.data = ngx_palloc(cycle->pool,
1099
cycle->lock_file.data = ngx_pnalloc(cycle->pool,
883
1100
ccf->lock_file.len + sizeof(".accept"));
884
1101
if (cycle->lock_file.data == NULL) {
885
1102
return NGX_CONF_ERROR;
1058
1275
for (n = 1; n < cf->args->nelts; n++) {
1060
if (value[n].len > 32) {
1277
if (value[n].len > 64) {
1061
1278
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1062
"\"worker_cpu_affinity\" supports up to 32 CPU only");
1279
"\"worker_cpu_affinity\" supports up to 64 CPUs only");
1063
1280
return NGX_CONF_ERROR;
1121
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";