Return to nginx.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / nginx / src / core |
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: }