void ngx_debug_point(void) { ngx_core_conf_t *ccf; ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, ngx_core_module); switch (ccf->debug_points) { case NGX_DEBUG_POINTS_STOP: raise(SIGSTOP); break; case NGX_DEBUG_POINTS_ABORT: ngx_abort(); } }
static ngx_int_t ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t type) { ngx_int_t n; ngx_core_conf_t *ccf; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes"); ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); for (n = 0; n < ccf->worker_processes; n++) { if (ngx_spawn_process(cycle, "worker", type) == NGX_INVALID_PID) { break; } } return n; }
u_long ngx_get_cpu_affinity(ngx_uint_t n) { ngx_core_conf_t *ccf; ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, ngx_core_module); if (ccf->cpu_affinity == NULL) { return 0; } if (ccf->cpu_affinity_n > n) { return ccf->cpu_affinity[n]; } return ccf->cpu_affinity[ccf->cpu_affinity_n - 1]; }
static void ngx_http_groonga_exit_process(ngx_cycle_t *cycle) { ngx_http_conf_ctx_t *http_conf; ngx_http_groonga_database_callback_data_t data; http_conf = (ngx_http_conf_ctx_t *)ngx_get_conf(cycle->conf_ctx, ngx_http_module); data.log = cycle->log; data.pool = cycle->pool; ngx_http_groonga_each_loc_conf(http_conf, ngx_http_groonga_close_database_callback, &data); grn_fin(); return; }
static ngx_int_t ngx_squ_file_module_init(ngx_cycle_t *cycle) { int n; ngx_squ_conf_t *scf; ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "squ file module init"); scf = (ngx_squ_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_squ_module); squ_getglobal(scf->l, NGX_SQU_TABLE); squL_newmetatable(scf->l, NGX_SQU_FILE); squ_pushvalue(scf->l, -1); squ_setfield(scf->l, -2, "__index"); for (n = 0; ngx_squ_file_methods[n].name != NULL; n++) { squ_pushcfunction(scf->l, ngx_squ_file_methods[n].func); squ_setfield(scf->l, -2, ngx_squ_file_methods[n].name); } squ_pop(scf->l, 1); n = sizeof(ngx_squ_file_consts) / sizeof(ngx_squ_const_t) - 1; n += 2; squ_createtable(scf->l, 0, n); for (n = 0; ngx_squ_file_consts[n].name != NULL; n++) { squ_pushinteger(scf->l, ngx_squ_file_consts[n].value); squ_setfield(scf->l, -2, ngx_squ_file_consts[n].name); } squ_pushcfunction(scf->l, ngx_squ_file_open); squ_setfield(scf->l, -2, "open"); squ_pushcfunction(scf->l, ngx_squ_file_info); squ_setfield(scf->l, -2, "attributes"); squ_setfield(scf->l, -2, "file"); squ_pop(scf->l, 1); return NGX_OK; }
static ngx_int_t ngx_zeromq_process_init(ngx_cycle_t *cycle) { ngx_zeromq_conf_t *zcf; zcf = (ngx_zeromq_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_zeromq_module); if (zmq_used) { zmq_context = zmq_init(zcf->threads); if (zmq_context == NULL) { ngx_zeromq_log_error(cycle->log, "zmq_init()"); return NGX_ERROR; } } return NGX_OK; }
ngx_thread_pool_t * ngx_thread_pool_get(ngx_cycle_t *cycle, ngx_str_t *name) { ngx_uint_t i; ngx_thread_pool_t **tpp; ngx_thread_pool_conf_t *tcf; tcf = (ngx_thread_pool_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_thread_pool_module); tpp = tcf->pools.elts; for (i = 0; i < tcf->pools.nelts; i++) { if (tpp[i]->name.len == name->len && ngx_strncmp(tpp[i]->name.data, name->data, name->len) == 0) { return tpp[i]; } } return NULL; }
ngx_int_t ngx_signal_process(ngx_cycle_t *cycle, char *sig) { ssize_t n; ngx_int_t pid; ngx_file_t file; ngx_core_conf_t *ccf; u_char buf[NGX_INT64_LEN + 2]; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "signal process started"); ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); file.name = ccf->pid; file.log = cycle->log; //打开pid文件,过滤掉里面的空格,找出pid进程id file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,NGX_FILE_OPEN, NGX_FILE_DEFAULT_ACCESS); if (file.fd == NGX_INVALID_FILE) { ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, ngx_open_file_n " \"%s\" failed", file.name.data); return 1; } n = ngx_read_file(&file, buf, NGX_INT64_LEN + 2, 0); if (ngx_close_file(file.fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_close_file_n " \"%s\" failed", file.name.data); } if (n == NGX_ERROR) { return 1; } while (n-- && (buf[n] == CR || buf[n] == LF)) { /* void */ } pid = ngx_atoi(buf, ++n); if (pid == NGX_ERROR) { ngx_log_error(NGX_LOG_ERR, cycle->log, 0, "invalid PID number \"%*s\" in \"%s\"", n, buf, file.name.data); return 1; } return ngx_os_signal_process(cycle, sig, pid); }
ngx_int_t ngx_http_shmtest_init_process(ngx_cycle_t *cycle) { shmtest_main_conf_t* conf = (shmtest_main_conf_t*)ngx_get_conf(cycle->conf_ctx, ngx_http_shmtest_module); if(conf == NULL){ NLOG_INFO("conf is null!"); return 0; } printf("process [%d] inited!\n", ngx_getpid()); //多进程并发测试 int i; int64_t ret=0; for(i=0;i<10000;i++){ ngx_str_t key = ngx_string("test"); ngx_shmap_inc_int(conf->shmap, &key, 1, 0, &ret); } printf("process [%d] init ok! ret=%lld\n", ngx_getpid(), (long long)ret); return 0; }
static void ngx_rtmp_auto_push_exit_process(ngx_cycle_t *cycle) { #if (NGX_HAVE_UNIX_DOMAIN) ngx_rtmp_auto_push_conf_t *apcf; u_char path[NGX_MAX_PATH]; apcf = (ngx_rtmp_auto_push_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_rtmp_auto_push_module); if (apcf->auto_push == 0) { return; } *ngx_snprintf(path, sizeof(path), "%V/" NGX_RTMP_AUTO_PUSH_SOCKNAME ".%i", &apcf->socket_dir, ngx_process_slot) = 0; ngx_delete_file(path); #endif }
static void ngx_console_init(ngx_cycle_t *cycle) { ngx_core_conf_t *ccf; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ccf->daemon) { if (FreeConsole() == 0) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "FreeConsole() failed"); } return; } if (SetConsoleCtrlHandler(ngx_console_handler, 1) == 0) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "SetConsoleCtrlHandler() failed"); } }
//检查是否已经有该name的ngx_thread_pool_t,有则直接返回,没有则创建并添加到ngx_thread_pool_conf_t中 ngx_thread_pool_t * ngx_thread_pool_add(ngx_conf_t *cf, ngx_str_t *name) { ngx_thread_pool_t *tp, **tpp; ngx_thread_pool_conf_t *tcf; if (name == NULL) { name = &ngx_thread_pool_default; } //检查该名字的线程池是否已经存在,存在则直接返回以前的线程池ngx_thread_pool_t,没有返回NULL tp = ngx_thread_pool_get(cf->cycle, name); if (tp) { return tp; } //创建新的ngx_thread_pool_t tp = ngx_pcalloc(cf->pool, sizeof(ngx_thread_pool_t)); if (tp == NULL) { return NULL; } tp->name = *name; tp->file = cf->conf_file->file.name.data; tp->line = cf->conf_file->line; tcf = (ngx_thread_pool_conf_t *) ngx_get_conf(cf->cycle->conf_ctx, ngx_thread_pool_module); tpp = ngx_array_push(&tcf->pools); if (tpp == NULL) { return NULL; } *tpp = tp; return tp; }
void ngx_show_dso_directives(ngx_conf_t *cf) { ngx_str_t name; ngx_uint_t i; ngx_module_t *module; ngx_command_t *cmd; ngx_dso_module_t *dm; ngx_dso_conf_ctx_t *ctx; ctx = (ngx_dso_conf_ctx_t *) ngx_get_conf(cf->cycle->conf_ctx, ngx_dso_module); if (ctx == NULL || ctx->modules == NULL) { return; } dm = ctx->modules->elts; for (i = 0; i < ctx->modules->nelts; i++) { if (dm[i].name.len == 0) { continue; } name = dm[i].name; module = dm[i].module; ngx_log_stderr(0, "%V (shared):", &name); cmd = module->commands; if(cmd == NULL) { continue; } for ( /* void */ ; cmd->name.len; cmd++) { ngx_log_stderr(0, " %V", &cmd->name); } } }
static ngx_int_t ngx_lua_http_btt_module_init(ngx_cycle_t *cycle) { ngx_lua_conf_t *lcf; ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "lua http btt module init"); lcf = (ngx_lua_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_lua_module); lua_getglobal(lcf->l, NGX_LUA_TABLE); lua_getfield(lcf->l, -1, NGX_LUA_HTTP_TABLE); lua_createtable(lcf->l, 0, 1); lua_pushcfunction(lcf->l, ngx_lua_http_btt_announce); lua_setfield(lcf->l, -2, "announce"); lua_setfield(lcf->l, -2, "btt"); lua_pop(lcf->l, 2); return NGX_OK; }
static ngx_int_t ngx_http_groonga_init_process(ngx_cycle_t *cycle) { grn_rc rc; ngx_http_conf_ctx_t *http_conf; ngx_http_groonga_database_callback_data_t data; rc = grn_init(); if (rc != GRN_SUCCESS) { return NGX_ERROR; } http_conf = (ngx_http_conf_ctx_t *)ngx_get_conf(cycle->conf_ctx, ngx_http_module); data.log = cycle->log; data.pool = cycle->pool; data.rc = NGX_OK; ngx_http_groonga_each_loc_conf(http_conf, ngx_http_groonga_open_database_callback, &data); return data.rc; }
static ngx_int_t ngx_zeromq_process_init(ngx_cycle_t *cycle) { ngx_zeromq_conf_t *zcf; zcf = (ngx_zeromq_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_zeromq_module); if (ngx_zeromq_used) { ngx_zeromq_ctx = zmq_ctx_new(); if (ngx_zeromq_ctx == NULL) { ngx_zeromq_log_error(cycle->log, "zmq_ctx_new()"); return NGX_ERROR; } if (zmq_ctx_set(ngx_zeromq_ctx, ZMQ_IO_THREADS, zcf->threads) == -1) { ngx_zeromq_log_error(cycle->log, "zmq_ctx_set(ZMQ_IO_THREADS)"); } } return NGX_OK; }
static void ngx_process_init(ngx_cycle_t *cycle) { ngx_err_t err; ngx_core_conf_t *ccf; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ngx_init_threads(ngx_threads_n, ccf->thread_stack_size, cycle) != NGX_OK) { /* fatal */ exit(2); } err = ngx_thread_key_create(&ngx_core_tls_key); if (err != 0) { ngx_log_error(NGX_LOG_ALERT, cycle->log, err, ngx_thread_key_create_n " failed"); /* fatal */ exit(2); } }
static void ngx_thread_pool_exit_worker(ngx_cycle_t *cycle) { ngx_uint_t i; ngx_thread_pool_t **tpp; ngx_thread_pool_conf_t *tcf; if (ngx_process != NGX_PROCESS_WORKER && ngx_process != NGX_PROCESS_SINGLE) { return; } tcf = (ngx_thread_pool_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_thread_pool_module); if (tcf == NULL) { return; } tpp = tcf->pools.elts; for (i = 0; i < tcf->pools.nelts; i++) { ngx_thread_pool_destroy(tpp[i]); } }
static ngx_int_t ngx_http_groonga_init_process(ngx_cycle_t *cycle) { grn_rc rc; ngx_http_conf_ctx_t *http_conf; ngx_http_groonga_database_callback_data_t data; grn_thread_set_get_limit_func(ngx_http_groonga_get_thread_limit, NULL); #ifdef NGX_HTTP_GROONGA_LOG_PATH grn_default_logger_set_path(NGX_HTTP_GROONGA_LOG_PATH); #endif rc = grn_init(); if (rc != GRN_SUCCESS) { return NGX_ERROR; } grn_set_segv_handler(); rc = grn_ctx_init(context, GRN_NO_FLAGS); if (rc != GRN_SUCCESS) { return NGX_ERROR; } http_conf = (ngx_http_conf_ctx_t *)ngx_get_conf(cycle->conf_ctx, ngx_http_module); data.log = cycle->log; data.pool = cycle->pool; data.rc = NGX_OK; ngx_http_groonga_each_loc_conf(http_conf, ngx_http_groonga_open_database_callback, &data); return data.rc; }
static ngx_int_t ngx_squ_tcp_request_module_init(ngx_cycle_t *cycle) { int n; SQRESULT rc; ngx_squ_conf_t *scf; ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "squ tcp request module init"); scf = (ngx_squ_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_squ_module); sq_pushroottable(scf->v); sq_pushstring(scf->v, NGX_SQU_TABLE, sizeof(NGX_SQU_TABLE) - 1); rc = sq_get(scf->v, -2); sq_pushstring(scf->v, NGX_SQU_TCP_TABLE, sizeof(NGX_SQU_TCP_TABLE) - 1); rc = sq_get(scf->v, -2); n = sizeof(ngx_squ_tcp_request_methods) / sizeof(SQRegFunction) - 1; sq_pushstring(scf->v, "request", sizeof("request") - 1); sq_newtableex(scf->v, n); for (n = 0; ngx_squ_tcp_request_methods[n].name != NULL; n++) { sq_pushstring(scf->v, ngx_squ_tcp_request_methods[n].name, -1); sq_newclosure(scf->v, ngx_squ_tcp_request_methods[n].f, 0); rc = sq_newslot(scf->v, -3, SQFalse); } rc = sq_newslot(scf->v, -3, SQFalse); sq_pop(scf->v, 3); return NGX_OK; }
ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv) { char **env, *var; u_char *p; ngx_uint_t i, n; ngx_pid_t pid; ngx_exec_ctx_t ctx; ngx_core_conf_t *ccf; ngx_listening_t *ls; ngx_memzero(&ctx, sizeof(ngx_exec_ctx_t)); ctx.path = argv[0]; ctx.name = "new binary process"; ctx.argv = argv; n = 2; env = ngx_set_environment(cycle, &n); if (env == NULL) { return NGX_INVALID_PID; } var = ngx_alloc(sizeof(NGINX_VAR) + cycle->listening.nelts * (NGX_INT32_LEN + 1) + 2, cycle->log); p = ngx_cpymem(var, NGINX_VAR "=", sizeof(NGINX_VAR)); ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { p = ngx_sprintf(p, "%ud;", ls[i].fd); } *p = '\0'; env[n++] = var; #if (NGX_SETPROCTITLE_USES_ENV) /* allocate the spare 300 bytes for the new binary process title */ env[n++] = "SPARE=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; #endif env[n] = NULL; #if (NGX_DEBUG) { char **e; for (e = env; *e; e++) { ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, "env: %s", *e); } } #endif ctx.envp = (char *const *) env; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ngx_rename_file(ccf->pid.data, ccf->oldpid.data) != NGX_OK) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_rename_file_n " %s to %s failed " "before executing new binary process \"%s\"", ccf->pid.data, ccf->oldpid.data, argv[0]); ngx_free(env); ngx_free(var); return NGX_INVALID_PID; } pid = ngx_execute(cycle, &ctx); if (pid == NGX_INVALID_PID) { if (ngx_rename_file(ccf->oldpid.data, ccf->pid.data) != NGX_OK) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_rename_file_n " %s back to %s failed after " "the try to execute the new binary process \"%s\"", ccf->oldpid.data, ccf->pid.data, argv[0]); } } ngx_free(env); ngx_free(var); return pid; }
//1.时间、正则、错误日志、ssl等初始化 //2.读入命令行参数 //3.OS相关初始化 //4.读入并解析配置 //5.核心模块初始化 //6.创建各种临时文件和目录 //7.创建共享内存 //8.打开listen的端口 //9.所有模块初始化 //10.启动worker进程 int ngx_cdecl main(int argc, char *const *argv) { ngx_int_t i; ngx_log_t *log; ngx_cycle_t *cycle, init_cycle; ngx_core_conf_t *ccf; #if (NGX_FREEBSD) ngx_debug_init(); #endif if (ngx_strerror_init() != NGX_OK) { return 1; } //获取参数和配置参数,比如命令是nginx -v 那么ngx_show_version就设置为1 if (ngx_get_options(argc, argv) != NGX_OK) { return 1; } if (ngx_show_version) { ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED); if (ngx_show_help) { ngx_write_stderr( "Usage: nginx [-?hvVtq] [-s signal] [-c filename] " "[-p prefix] [-g directives]" NGX_LINEFEED NGX_LINEFEED "Options:" NGX_LINEFEED " -?,-h : this help" NGX_LINEFEED " -v : show version and exit" NGX_LINEFEED " -V : show version and configure options then exit" NGX_LINEFEED " -t : test configuration and exit" NGX_LINEFEED " -q : suppress non-error messages " "during configuration testing" NGX_LINEFEED " -s signal : send signal to a master process: " "stop, quit, reopen, reload" NGX_LINEFEED #ifdef NGX_PREFIX " -p prefix : set prefix path (default: " NGX_PREFIX ")" NGX_LINEFEED #else " -p prefix : set prefix path (default: NONE)" NGX_LINEFEED #endif " -c filename : set configuration file (default: " NGX_CONF_PATH ")" NGX_LINEFEED " -g directives : set global directives out of configuration " "file" NGX_LINEFEED NGX_LINEFEED ); } if (ngx_show_configure) { ngx_write_stderr( #ifdef NGX_COMPILER "built by " NGX_COMPILER NGX_LINEFEED #endif #if (NGX_SSL) #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME "TLS SNI support enabled" NGX_LINEFEED #else "TLS SNI support disabled" NGX_LINEFEED #endif #endif "configure arguments:" NGX_CONFIGURE NGX_LINEFEED); } if (!ngx_test_config) { return 0; } } /* TODO */ ngx_max_sockets = -1; //初始化nginx环境的当前时间 ngx_time_init(); #if (NGX_PCRE) ngx_regex_init(); #endif //master pid, 获取当前进程ID ngx_pid = ngx_getpid(); // 初始化日志,如打开日志文件 log = ngx_log_init(ngx_prefix); if (log == NULL) { return 1; } /* STUB */ #if (NGX_OPENSSL) ngx_ssl_init(log); //是否开启了ssl,如果开启在这里进行初始化 #endif /* * init_cycle->log is required for signal handlers and * ngx_process_options() */ ngx_memzero(&init_cycle, sizeof(ngx_cycle_t)); init_cycle.log = log; ngx_cycle = &init_cycle; // 为cycle创建一个1024B的内存池 init_cycle.pool = ngx_create_pool(1024, log); if (init_cycle.pool == NULL) { return 1; } // 保存参数到全局变量中 if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) { return 1; } // 初始化init_cycle中的一些如: conf_file,prefix,conf_prefix等字段 if (ngx_process_options(&init_cycle) != NGX_OK) { return 1; } // 初始化系统相关变量,如内存页面大小ngx_pagesize,ngx_cacheline_size,最大连接数ngx_max_sockets等 if (ngx_os_init(log) != NGX_OK) { // 这个ngx_os_init在不同操作系统调用不同的函数 return 1; } /* * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init() */ // 初始化CRC表,提高效率,以后就不用计算了,直接用 if (ngx_crc32_table_init() != NGX_OK) { return 1; } // 继承sockets,继承来的socket将会放到init_cycle的listening数组 if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) { return 1; } // 计算模块个数,并且设置各个模块顺序(索引) ngx_max_module = 0; for (i = 0; ngx_modules[i]; i++) { // 这里面的ngx_modules会有非常多的模块,[ngx_core_module,ngx_errlog_module,ngx_conf_moduel] ngx_modules[i]->index = ngx_max_module++; } // 对ngx_cycle结构进行初始化,这里是nginx启动核心之处! cycle = ngx_init_cycle(&init_cycle); if (cycle == NULL) { if (ngx_test_config) { ngx_log_stderr(0, "configuration file %s test failed", init_cycle.conf_file.data); } return 1; } if (ngx_test_config) { if (!ngx_quiet_mode) { ngx_log_stderr(0, "configuration file %s test is successful", cycle->conf_file.data); } return 0; } // 检查是否有设置信号处理,如有,进入ngx_signal_process处理 if (ngx_signal) { return ngx_signal_process(cycle, ngx_signal); } ngx_os_status(cycle->log); ngx_cycle = cycle; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) { ngx_process = NGX_PROCESS_MASTER; } #if !(NGX_WIN32) if (ngx_init_signals(cycle->log) != NGX_OK) { return 1; } if (!ngx_inherited && ccf->daemon) { if (ngx_daemon(cycle->log) != NGX_OK) { //如果是daemon模式,本进程变为守护进程 return 1; } ngx_daemonized = 1; } if (ngx_inherited) { ngx_daemonized = 1; } #endif // 创建进程记录文件 if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) { return 1; } if (cycle->log->file->fd != ngx_stderr) { if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, ngx_set_stderr_n " failed"); return 1; } } if (log->file->fd != ngx_stderr) { if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_close_file_n " built-in log failed"); } } ngx_use_stderr = 0; if (ngx_process == NGX_PROCESS_SINGLE) { ngx_single_process_cycle(cycle); //单进程 } else { ngx_master_process_cycle(cycle); //多进程,master进程进入这个,这个函数在不同操作系统有不同实现。 } return 0; }
ngx_cycle_t * ngx_init_cycle(ngx_cycle_t *old_cycle) { void *rv; char **senv, **env; ngx_uint_t i, n; ngx_log_t *log; ngx_time_t *tp; ngx_conf_t conf; ngx_pool_t *pool; ngx_cycle_t *cycle, **old; ngx_shm_zone_t *shm_zone, *oshm_zone; ngx_list_part_t *part, *opart; ngx_open_file_t *file; ngx_listening_t *ls, *nls; ngx_core_conf_t *ccf, *old_ccf; ngx_core_module_t *module; char hostname[NGX_MAXHOSTNAMELEN]; ngx_timezone_update(); /* force localtime update with a new timezone */ tp = ngx_timeofday(); tp->sec = 0; ngx_time_update(); log = old_cycle->log; pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log); if (pool == NULL) { return NULL; } pool->log = log; cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t)); if (cycle == NULL) { ngx_destroy_pool(pool); return NULL; } cycle->pool = pool; cycle->log = log; cycle->old_cycle = old_cycle; cycle->conf_prefix.len = old_cycle->conf_prefix.len; cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix); if (cycle->conf_prefix.data == NULL) { ngx_destroy_pool(pool); return NULL; } cycle->prefix.len = old_cycle->prefix.len; cycle->prefix.data = ngx_pstrdup(pool, &old_cycle->prefix); if (cycle->prefix.data == NULL) { ngx_destroy_pool(pool); return NULL; } cycle->conf_file.len = old_cycle->conf_file.len; cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + 1); if (cycle->conf_file.data == NULL) { ngx_destroy_pool(pool); return NULL; } ngx_cpystrn(cycle->conf_file.data, old_cycle->conf_file.data, old_cycle->conf_file.len + 1); cycle->conf_param.len = old_cycle->conf_param.len; cycle->conf_param.data = ngx_pstrdup(pool, &old_cycle->conf_param); if (cycle->conf_param.data == NULL) { ngx_destroy_pool(pool); return NULL; } n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10; cycle->paths.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *)); if (cycle->paths.elts == NULL) { ngx_destroy_pool(pool); return NULL; } cycle->paths.nelts = 0; cycle->paths.size = sizeof(ngx_path_t *); cycle->paths.nalloc = n; cycle->paths.pool = pool; if (old_cycle->open_files.part.nelts) { n = old_cycle->open_files.part.nelts; for (part = old_cycle->open_files.part.next; part; part = part->next) { n += part->nelts; } } else { n = 20; } if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t)) != NGX_OK) { ngx_destroy_pool(pool); return NULL; } if (old_cycle->shared_memory.part.nelts) { n = old_cycle->shared_memory.part.nelts; for (part = old_cycle->shared_memory.part.next; part; part = part->next) { n += part->nelts; } } else { n = 1; } if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t)) != NGX_OK) { ngx_destroy_pool(pool); return NULL; } n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10; cycle->listening.elts = ngx_pcalloc(pool, n * sizeof(ngx_listening_t)); if (cycle->listening.elts == NULL) { ngx_destroy_pool(pool); return NULL; } cycle->listening.nelts = 0; cycle->listening.size = sizeof(ngx_listening_t); cycle->listening.nalloc = n; cycle->listening.pool = pool; ngx_queue_init(&cycle->reusable_connections_queue); cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *)); if (cycle->conf_ctx == NULL) { ngx_destroy_pool(pool); return NULL; } if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "gethostname() failed"); ngx_destroy_pool(pool); return NULL; } /* on Linux gethostname() silently truncates name that does not fit */ hostname[NGX_MAXHOSTNAMELEN - 1] = '\0'; cycle->hostname.len = ngx_strlen(hostname); cycle->hostname.data = ngx_pnalloc(pool, cycle->hostname.len); if (cycle->hostname.data == NULL) { ngx_destroy_pool(pool); return NULL; } ngx_strlow(cycle->hostname.data, (u_char *) hostname, cycle->hostname.len); for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_CORE_MODULE) { continue; } module = ngx_modules[i]->ctx; if (module->create_conf) { rv = module->create_conf(cycle); if (rv == NULL) { ngx_destroy_pool(pool); return NULL; } cycle->conf_ctx[ngx_modules[i]->index] = rv; } } senv = environ; ngx_memzero(&conf, sizeof(ngx_conf_t)); /* STUB: init array ? */ conf.args = ngx_array_create(pool, 10, sizeof(ngx_str_t)); if (conf.args == NULL) { ngx_destroy_pool(pool); return NULL; } conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log); if (conf.temp_pool == NULL) { ngx_destroy_pool(pool); return NULL; } conf.ctx = cycle->conf_ctx; conf.cycle = cycle; conf.pool = pool; conf.log = log; conf.module_type = NGX_CORE_MODULE; conf.cmd_type = NGX_MAIN_CONF; #if 0 log->log_level = NGX_LOG_DEBUG_ALL; #endif if (ngx_conf_param(&conf) != NGX_CONF_OK) { environ = senv; ngx_destroy_cycle_pools(&conf); return NULL; } if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) { environ = senv; ngx_destroy_cycle_pools(&conf); return NULL; } if (ngx_test_config && !ngx_quiet_mode) { ngx_log_stderr(0, "the configuration file %s syntax is ok", cycle->conf_file.data); } for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_CORE_MODULE) { continue; } module = ngx_modules[i]->ctx; if (module->init_conf) { if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index]) == NGX_CONF_ERROR) { environ = senv; ngx_destroy_cycle_pools(&conf); return NULL; } } } if (ngx_process == NGX_PROCESS_SIGNALLER) { return cycle; } ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ngx_test_config) { if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) { goto failed; } } else if (!ngx_is_init_cycle(old_cycle)) { /* * we do not create the pid file in the first ngx_init_cycle() call * because we need to write the demonized process pid */ old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx, ngx_core_module); if (ccf->pid.len != old_ccf->pid.len || ngx_strcmp(ccf->pid.data, old_ccf->pid.data) != 0) { /* new pid file name */ if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) { goto failed; } ngx_delete_pidfile(old_cycle); } } if (ngx_test_lockfile(cycle->lock_file.data, log) != NGX_OK) { goto failed; } if (ngx_create_paths(cycle, ccf->user) != NGX_OK) { goto failed; } if (ngx_log_open_default(cycle) != NGX_OK) { goto failed; } /* open the new files */ part = &cycle->open_files.part; file = part->elts; for (i = 0; /* void */ ; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; file = part->elts; i = 0; } if (file[i].name.len == 0) { continue; } file[i].fd = ngx_open_file(file[i].name.data, NGX_FILE_APPEND, NGX_FILE_CREATE_OR_OPEN, NGX_FILE_DEFAULT_ACCESS); ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, 0, "log: %p %d \"%s\"", &file[i], file[i].fd, file[i].name.data); if (file[i].fd == NGX_INVALID_FILE) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, ngx_open_file_n " \"%s\" failed", file[i].name.data); goto failed; } #if !(NGX_WIN32) if (fcntl(file[i].fd, F_SETFD, FD_CLOEXEC) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fcntl(FD_CLOEXEC) \"%s\" failed", file[i].name.data); goto failed; } #endif } cycle->log = &cycle->new_log; pool->log = &cycle->new_log; /* create shared memory */ part = &cycle->shared_memory.part; shm_zone = part->elts; for (i = 0; /* void */ ; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; shm_zone = part->elts; i = 0; } if (shm_zone[i].shm.size == 0) { ngx_log_error(NGX_LOG_EMERG, log, 0, "zero size shared memory zone \"%V\"", &shm_zone[i].shm.name); goto failed; } shm_zone[i].shm.log = cycle->log; opart = &old_cycle->shared_memory.part; oshm_zone = opart->elts; for (n = 0; /* void */ ; n++) { if (n >= opart->nelts) { if (opart->next == NULL) { break; } opart = opart->next; oshm_zone = opart->elts; n = 0; } if (shm_zone[i].shm.name.len != oshm_zone[n].shm.name.len) { continue; } if (ngx_strncmp(shm_zone[i].shm.name.data, oshm_zone[n].shm.name.data, shm_zone[i].shm.name.len) != 0) { continue; } if (shm_zone[i].tag == oshm_zone[n].tag && shm_zone[i].shm.size == oshm_zone[n].shm.size) { shm_zone[i].shm.addr = oshm_zone[n].shm.addr; if (shm_zone[i].init(&shm_zone[i], oshm_zone[n].data) != NGX_OK) { goto failed; } goto shm_zone_found; } ngx_shm_free(&oshm_zone[n].shm); break; } if (ngx_shm_alloc(&shm_zone[i].shm) != NGX_OK) { goto failed; } if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) { goto failed; } if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) { goto failed; } shm_zone_found: continue; } /* handle the listening sockets */ if (old_cycle->listening.nelts) { ls = old_cycle->listening.elts; for (i = 0; i < old_cycle->listening.nelts; i++) { ls[i].remain = 0; } nls = cycle->listening.elts; for (n = 0; n < cycle->listening.nelts; n++) { for (i = 0; i < old_cycle->listening.nelts; i++) { if (ls[i].ignore) { continue; } if (ngx_cmp_sockaddr(nls[n].sockaddr, ls[i].sockaddr) == NGX_OK) { nls[n].fd = ls[i].fd; nls[n].previous = &ls[i]; ls[i].remain = 1; if (ls[n].backlog != nls[i].backlog) { nls[n].listen = 1; } #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) /* * FreeBSD, except the most recent versions, * could not remove accept filter */ nls[n].deferred_accept = ls[i].deferred_accept; if (ls[i].accept_filter && nls[n].accept_filter) { if (ngx_strcmp(ls[i].accept_filter, nls[n].accept_filter) != 0) { nls[n].delete_deferred = 1; nls[n].add_deferred = 1; } } else if (ls[i].accept_filter) { nls[n].delete_deferred = 1; } else if (nls[n].accept_filter) { nls[n].add_deferred = 1; } #endif #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) if (ls[n].deferred_accept && !nls[n].deferred_accept) { nls[n].delete_deferred = 1; } else if (ls[i].deferred_accept != nls[n].deferred_accept) { nls[n].add_deferred = 1; } #endif break; } } if (nls[n].fd == (ngx_socket_t) -1) { nls[n].open = 1; #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) if (nls[n].accept_filter) { nls[n].add_deferred = 1; } #endif #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) if (nls[n].deferred_accept) { nls[n].add_deferred = 1; } #endif } } } else { ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { ls[i].open = 1; #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) if (ls[i].accept_filter) { ls[i].add_deferred = 1; } #endif #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) if (ls[i].deferred_accept) { ls[i].add_deferred = 1; } #endif } } if (ngx_open_listening_sockets(cycle) != NGX_OK) { goto failed; } if (!ngx_test_config) { ngx_configure_listening_sockets(cycle); } /* commit the new cycle configuration */ if (!ngx_use_stderr) { (void) ngx_log_redirect_stderr(cycle); } pool->log = cycle->log; for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->init_module) { if (ngx_modules[i]->init_module(cycle) != NGX_OK) { /* fatal */ exit(1); } } } /* close and delete stuff that lefts from an old cycle */ /* free the unnecessary shared memory */ opart = &old_cycle->shared_memory.part; oshm_zone = opart->elts; for (i = 0; /* void */ ; i++) { if (i >= opart->nelts) { if (opart->next == NULL) { goto old_shm_zone_done; } opart = opart->next; oshm_zone = opart->elts; i = 0; } part = &cycle->shared_memory.part; shm_zone = part->elts; for (n = 0; /* void */ ; n++) { if (n >= part->nelts) { if (part->next == NULL) { break; } part = part->next; shm_zone = part->elts; n = 0; } if (oshm_zone[i].shm.name.len == shm_zone[n].shm.name.len && ngx_strncmp(oshm_zone[i].shm.name.data, shm_zone[n].shm.name.data, oshm_zone[i].shm.name.len) == 0) { goto live_shm_zone; } } ngx_shm_free(&oshm_zone[i].shm); live_shm_zone: continue; } old_shm_zone_done: /* close the unnecessary listening sockets */ ls = old_cycle->listening.elts; for (i = 0; i < old_cycle->listening.nelts; i++) { if (ls[i].remain || ls[i].fd == (ngx_socket_t) -1) { continue; } if (ngx_close_socket(ls[i].fd) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, ngx_close_socket_n " listening socket on %V failed", &ls[i].addr_text); } #if (NGX_HAVE_UNIX_DOMAIN) if (ls[i].sockaddr->sa_family == AF_UNIX) { u_char *name; name = ls[i].addr_text.data + sizeof("unix:") - 1; ngx_log_error(NGX_LOG_WARN, cycle->log, 0, "deleting socket %s", name); if (ngx_delete_file(name) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno, ngx_delete_file_n " %s failed", name); } } #endif } /* close the unnecessary open files */ part = &old_cycle->open_files.part; file = part->elts; for (i = 0; /* void */ ; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; file = part->elts; i = 0; } if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) { continue; } if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, ngx_close_file_n " \"%s\" failed", file[i].name.data); } } ngx_destroy_pool(conf.temp_pool); if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) { /* * perl_destruct() frees environ, if it is not the same as it was at * perl_construct() time, therefore we save the previous cycle * environment before ngx_conf_parse() where it will be changed. */ env = environ; environ = senv; ngx_destroy_pool(old_cycle->pool); cycle->old_cycle = NULL; environ = env; return cycle; } if (ngx_temp_pool == NULL) { ngx_temp_pool = ngx_create_pool(128, cycle->log); if (ngx_temp_pool == NULL) { ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "could not create ngx_temp_pool"); exit(1); } n = 10; ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool, n * sizeof(ngx_cycle_t *)); if (ngx_old_cycles.elts == NULL) { exit(1); } ngx_old_cycles.nelts = 0; ngx_old_cycles.size = sizeof(ngx_cycle_t *); ngx_old_cycles.nalloc = n; ngx_old_cycles.pool = ngx_temp_pool; ngx_cleaner_event.handler = ngx_clean_old_cycles; ngx_cleaner_event.log = cycle->log; ngx_cleaner_event.data = &dumb; dumb.fd = (ngx_socket_t) -1; } ngx_temp_pool->log = cycle->log; old = ngx_array_push(&ngx_old_cycles); if (old == NULL) { exit(1); } *old = old_cycle; if (!ngx_cleaner_event.timer_set) { ngx_add_timer(&ngx_cleaner_event, 30000); ngx_cleaner_event.timer_set = 1; } return cycle; failed: if (!ngx_is_init_cycle(old_cycle)) { old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx, ngx_core_module); if (old_ccf->environment) { environ = old_ccf->environment; } } /* rollback the new cycle configuration */ part = &cycle->open_files.part; file = part->elts; for (i = 0; /* void */ ; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; file = part->elts; i = 0; } if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) { continue; } if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, ngx_close_file_n " \"%s\" failed", file[i].name.data); } } if (ngx_test_config) { ngx_destroy_cycle_pools(&conf); return NULL; } ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { if (ls[i].fd == (ngx_socket_t) -1 || !ls[i].open) { continue; } if (ngx_close_socket(ls[i].fd) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, ngx_close_socket_n " %V failed", &ls[i].addr_text); } } ngx_destroy_cycle_pools(&conf); return NULL; }
int ngx_cdecl main(int argc, char *const *argv) { ngx_int_t i; ngx_log_t *log; ngx_cycle_t *cycle, init_cycle; ngx_core_conf_t *ccf; #if !(NGX_WIN32) struct rlimit rlmt; #endif if (ngx_get_options(argc, argv) != NGX_OK) { return 1; } if (ngx_show_version) { ngx_log_stderr(0, "nginx version: " NGINX_VER); if (ngx_show_help) { ngx_log_stderr(0, "Usage: nginx [-?hvVt] [-s signal] [-c filename] " "[-p prefix] [-g directives]" CRLF CRLF "Options:" CRLF " -?,-h : this help" CRLF " -v : show version and exit" CRLF " -V : show version and configure options then exit" CRLF " -t : test configuration and exit" CRLF " -s signal : send signal to a master process: " "stop, quit, reopen, reload" CRLF #ifdef NGX_PREFIX " -p prefix : set prefix path (default: " NGX_PREFIX ")" CRLF #else " -p prefix : set prefix path (default: NONE)" CRLF #endif " -c filename : set configuration file (default: " NGX_CONF_PATH ")" CRLF " -g directives : set global directives out of configuration " "file" CRLF ); } if (ngx_show_configure) { #ifdef NGX_COMPILER ngx_log_stderr(0, "built by " NGX_COMPILER); #endif #if (NGX_SSL) #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME ngx_log_stderr(0, "TLS SNI support enabled"); #else ngx_log_stderr(0, "TLS SNI support disabled"); #endif #endif ngx_log_stderr(0, "configure arguments:" NGX_CONFIGURE); } if (!ngx_test_config) { return 0; } } #if (NGX_FREEBSD) ngx_debug_init(); #endif /* TODO */ ngx_max_sockets = -1; ngx_time_init(); #if (NGX_PCRE) ngx_regex_init(); #endif ngx_pid = ngx_getpid(); log = ngx_log_init(ngx_prefix); if (log == NULL) { return 1; } /* STUB */ #if (NGX_OPENSSL) ngx_ssl_init(log); #endif /* * init_cycle->log is required for signal handlers and * ngx_process_options() */ ngx_memzero(&init_cycle, sizeof(ngx_cycle_t)); init_cycle.log = log; ngx_cycle = &init_cycle; init_cycle.pool = ngx_create_pool(1024, log); if (init_cycle.pool == NULL) { return 1; } if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) { return 1; } if (ngx_process_options(&init_cycle) != NGX_OK) { return 1; } if (ngx_os_init(log) != NGX_OK) { return 1; } /* * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init() */ if (ngx_crc32_table_init() != NGX_OK) { return 1; } if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) { return 1; } ngx_max_module = 0; for (i = 0; ngx_modules[i]; i++) { ngx_modules[i]->index = ngx_max_module++; } cycle = ngx_init_cycle(&init_cycle); if (cycle == NULL) { if (ngx_test_config) { ngx_log_stderr(0, "configuration file %s test failed", init_cycle.conf_file.data); } return 1; } if (ngx_test_config) { ngx_log_stderr(0, "configuration file %s test is successful", cycle->conf_file.data); return 0; } if (ngx_signal) { return ngx_signal_process(cycle, ngx_signal); } ngx_os_status(cycle->log); ngx_cycle = cycle; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) { ngx_process = NGX_PROCESS_MASTER; } #if !(NGX_WIN32) if (geteuid() == 0) { if (ccf->rlimit_nofile != NGX_CONF_UNSET) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_nofile; rlmt.rlim_max = (rlim_t) ccf->rlimit_nofile; if (setrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setrlimit(RLIMIT_NOFILE, %i) failed", ccf->rlimit_nofile); } } if (ccf->rlimit_core != NGX_CONF_UNSET_SIZE) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_core; rlmt.rlim_max = (rlim_t) ccf->rlimit_core; if (setrlimit(RLIMIT_CORE, &rlmt) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setrlimit(RLIMIT_CORE, %i) failed", ccf->rlimit_core); } } #ifdef RLIMIT_SIGPENDING if (ccf->rlimit_sigpending != NGX_CONF_UNSET) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_sigpending; rlmt.rlim_max = (rlim_t) ccf->rlimit_sigpending; if (setrlimit(RLIMIT_SIGPENDING, &rlmt) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setrlimit(RLIMIT_SIGPENDING, %i) failed", ccf->rlimit_sigpending); } } #endif if (setgid(ccf->group) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setgid(%d) failed", ccf->group); /* fatal */ exit(2); } if (initgroups(ccf->username, ccf->group) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "initgroups(%s, %d) failed", ccf->username, ccf->group); } if (setuid(ccf->user) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setuid(%d) failed", ccf->user); /* fatal */ exit(2); } } if (ngx_init_signals(cycle->log) != NGX_OK) { return 1; } if (!ngx_inherited && ccf->daemon) { if (ngx_daemon(cycle->log) != NGX_OK) { return 1; } ngx_daemonized = 1; } #endif if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) { return 1; } if (cycle->log->file->fd != ngx_stderr) { if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, ngx_set_stderr_n " failed"); return 1; } } if (log->file->fd != ngx_stderr) { if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_close_file_n " built-in log failed"); } } ngx_use_stderr = 0; if (ngx_process == NGX_PROCESS_SINGLE) { ngx_single_process_cycle(cycle); } else { ngx_master_process_cycle(cycle); } return 0; }
int ngx_cdecl main(int argc, char *const *argv) { ngx_int_t i; ngx_log_t *log; ngx_cycle_t *cycle, init_cycle; ngx_core_conf_t *ccf; ngx_debug_init(); if (ngx_strerror_init() != NGX_OK) { return 1; } if (ngx_get_options(argc, argv) != NGX_OK) { return 1; } if (ngx_show_version) { ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED); if (ngx_show_help) { ngx_write_stderr( "Usage: nginx [-?hvVtq] [-s signal] [-c filename] " "[-p prefix] [-g directives]" NGX_LINEFEED NGX_LINEFEED "Options:" NGX_LINEFEED " -?,-h : this help" NGX_LINEFEED " -v : show version and exit" NGX_LINEFEED " -V : show version and configure options then exit" NGX_LINEFEED " -t : test configuration and exit" NGX_LINEFEED " -q : suppress non-error messages " "during configuration testing" NGX_LINEFEED " -s signal : send signal to a master process: " "stop, quit, reopen, reload" NGX_LINEFEED #ifdef NGX_PREFIX " -p prefix : set prefix path (default: " NGX_PREFIX ")" NGX_LINEFEED #else " -p prefix : set prefix path (default: NONE)" NGX_LINEFEED #endif " -c filename : set configuration file (default: " NGX_CONF_PATH ")" NGX_LINEFEED " -g directives : set global directives out of configuration " "file" NGX_LINEFEED NGX_LINEFEED ); } if (ngx_show_configure) { ngx_write_stderr( #ifdef NGX_COMPILER "built by " NGX_COMPILER NGX_LINEFEED #endif #if (NGX_SSL) #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME "TLS SNI support enabled" NGX_LINEFEED #else "TLS SNI support disabled" NGX_LINEFEED #endif #endif "configure arguments:" NGX_CONFIGURE NGX_LINEFEED); } if (!ngx_test_config) { return 0; } } /* TODO */ ngx_max_sockets = -1; ngx_time_init(); #if (NGX_PCRE) ngx_regex_init(); #endif ngx_pid = ngx_getpid(); log = ngx_log_init(ngx_prefix); if (log == NULL) { return 1; } /* STUB */ #if (NGX_OPENSSL) ngx_ssl_init(log); #endif /* * init_cycle->log is required for signal handlers and * ngx_process_options() */ ngx_memzero(&init_cycle, sizeof(ngx_cycle_t)); init_cycle.log = log; ngx_cycle = &init_cycle; init_cycle.pool = ngx_create_pool(1024, log); if (init_cycle.pool == NULL) { return 1; } if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) { return 1; } if (ngx_process_options(&init_cycle) != NGX_OK) { return 1; } if (ngx_os_init(log) != NGX_OK) { return 1; } /* * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init() */ if (ngx_crc32_table_init() != NGX_OK) { return 1; } if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) { return 1; } ngx_max_module = 0; for (i = 0; ngx_modules[i]; i++) { ngx_modules[i]->index = ngx_max_module++; } cycle = ngx_init_cycle(&init_cycle); if (cycle == NULL) { if (ngx_test_config) { ngx_log_stderr(0, "configuration file %s test failed", init_cycle.conf_file.data); } return 1; } if (ngx_test_config) { if (!ngx_quiet_mode) { ngx_log_stderr(0, "configuration file %s test is successful", cycle->conf_file.data); } return 0; } if (ngx_signal) { return ngx_signal_process(cycle, ngx_signal); } ngx_os_status(cycle->log); ngx_cycle = cycle; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) { ngx_process = NGX_PROCESS_MASTER; } #if !(NGX_WIN32) if (ngx_init_signals(cycle->log) != NGX_OK) { return 1; } if (!ngx_inherited && ccf->daemon) { if (ngx_daemon(cycle->log) != NGX_OK) { return 1; } ngx_daemonized = 1; } if (ngx_inherited) { ngx_daemonized = 1; } #endif if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) { return 1; } if (cycle->log->file->fd != ngx_stderr) { if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, ngx_set_stderr_n " failed"); return 1; } } if (log->file->fd != ngx_stderr) { if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_close_file_n " built-in log failed"); } } ngx_use_stderr = 0; if (ngx_process == NGX_PROCESS_SINGLE) { ngx_single_process_cycle(cycle); } else { ngx_master_process_cycle(cycle); } return 0; }
static int ngx_lua_http_btt_announce(lua_State *l) { size_t size; u_char *p, *last, *buf, ip[NGX_INET_ADDRSTRLEN]; uint32_t n; ngx_int_t rc; ngx_btt_ctx_t *ctx; ngx_btt_conf_t *bcf; ngx_lua_thread_t *thr; ngx_lua_http_ctx_t *hctx; ngx_http_request_t *r; ngx_btt_peer_info_t *pi; thr = ngx_lua_thread(l); ngx_log_debug0(NGX_LOG_DEBUG_HTTP, thr->log, 0, "lua http btt announce"); ctx = ngx_pcalloc(thr->pool, sizeof(ngx_btt_ctx_t)); if (ctx == NULL) { lua_pushboolean(l, 0); return 1; } ctx->pool = thr->pool; ctx->log = thr->log; hctx = thr->module_ctx; r = hctx->r; if (ngx_lua_http_btt_parse_args(r, ctx) != NGX_OK) { lua_pushboolean(l, 0); return 1; } /* Checking the value of the uri arguments */ if (ngx_lua_http_btt_check_args(r, ctx) != NGX_OK) { lua_pushboolean(l, 0); return 1; } bcf = (ngx_btt_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, ngx_lua_btt_module); /* Insert or update peer information in peer list */ /* TODO: Checking ctx->event */ rc = ngx_btt_update_peer(bcf, ctx); if (rc != NGX_OK) { lua_pushboolean(l, 0); return 1; } /* Querying the peer list */ if (ctx->event != NGX_BTT_EVENT_STOPPED) { ctx->peers = ngx_palloc(thr->pool, sizeof(ngx_btt_peer_info_t) * ctx->numwant); if (ctx->peers == NULL) { lua_pushboolean(l, 0); return 1; } rc = ngx_btt_query_peers(bcf, ctx); if (rc != NGX_OK) { lua_pushboolean(l, 0); return 1; } } /* Calculating the size of the response */ /* TODO: * * 8:completei2e * 10:downloadedi4e * 10:incompletei1e * * 12:min intervali811e */ size = sizeof("d8:intervalie5:peerse") - 1 + NGX_TIME_T_LEN; if (ctx->compact) { size += NGX_INT_T_LEN + 1 + 6 * ctx->peers_n; } else { size += sizeof("le") - 1; if (!ctx->no_peer_id) { size += (sizeof("7:peer_id20:") - 1 + 20) * ctx->peers_n; } size += (sizeof("d2:ip4:portiee") - 1 + NGX_INT_T_LEN + 1 + NGX_INET_ADDRSTRLEN + NGX_INT_T_LEN) * ctx->peers_n; } buf = ngx_palloc(thr->pool, size); if (buf == NULL) { lua_pushboolean(l, 0); return 1; } p = buf; last = p + size; /* Building the response */ p = ngx_slprintf(p, last, "d8:intervali%Te5:peers", bcf->interval); if (ctx->compact) { p = ngx_slprintf(p, last, "%uz:", 6 * ctx->peers_n); } else { *p++ = 'l'; } for (n = 0; n < ctx->peers_n; n++) { pi = &ctx->peers[n]; if (ctx->compact) { p = ngx_cpymem(p, &pi->external_ip, sizeof(pi->external_ip)); pi->internal_port = htons(pi->internal_port); p = ngx_cpymem(p, &pi->internal_port, sizeof(pi->internal_port)); } else { *p++ = 'd'; if (!ctx->no_peer_id) { p = ngx_slprintf(p, last, "7:peer_id20:%*s", sizeof(pi->peer_id), pi->peer_id); } size = ngx_inet_ntop(AF_INET, &pi->external_ip, ip, sizeof(ip)); p = ngx_slprintf(p, last, "2:ip%uz:%*s4:porti%uDe", size, size, ip, (uint32_t) pi->internal_port); *p++ = 'e'; } } if (!ctx->compact) { *p++ = 'e'; } *p++ = 'e'; ngx_lua_output(thr, buf, p - buf); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua http btt announce response:%N%*s", p - buf, buf); lua_pushboolean(l, 1); return 1; }
static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) { ngx_int_t worker = (intptr_t) data; ngx_uint_t i; ngx_connection_t *c; ngx_process = NGX_PROCESS_WORKER; ngx_worker_process_init(cycle, worker); ngx_setproctitle("worker process"); #if (NGX_THREADS) { ngx_int_t n; ngx_err_t err; ngx_core_conf_t *ccf; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ngx_threads_n) { if (ngx_init_threads(ngx_threads_n, ccf->thread_stack_size, cycle) == NGX_ERROR) { /* fatal */ exit(2); } err = ngx_thread_key_create(&ngx_core_tls_key); if (err != 0) { ngx_log_error(NGX_LOG_ALERT, cycle->log, err, ngx_thread_key_create_n " failed"); /* fatal */ exit(2); } for (n = 0; n < ngx_threads_n; n++) { ngx_threads[n].cv = ngx_cond_init(cycle->log); if (ngx_threads[n].cv == NULL) { /* fatal */ exit(2); } if (ngx_create_thread((ngx_tid_t *) &ngx_threads[n].tid, ngx_worker_thread_cycle, (void *) &ngx_threads[n], cycle->log) != 0) { /* fatal */ exit(2); } } } } #endif for ( ;; ) { if (ngx_exiting) { c = cycle->connections; for (i = 0; i < cycle->connection_n; i++) { /* THREAD: lock */ if (c[i].fd != -1 && c[i].idle) { c[i].close = 1; c[i].read->handler(c[i].read); } } if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); ngx_worker_process_exit(cycle); } } ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); ngx_process_events_and_timers(cycle); if (ngx_terminate) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); ngx_worker_process_exit(cycle); } if (ngx_quit) { ngx_quit = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "gracefully shutting down"); ngx_setproctitle("worker process is shutting down"); if (!ngx_exiting) { ngx_close_listening_sockets(cycle); ngx_exiting = 1; } } if (ngx_reopen) { ngx_reopen = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs"); ngx_reopen_files(cycle, -1); } } }
static ngx_int_t ngx_regex_module_init(ngx_cycle_t *cycle) { int opt; const char *errstr; ngx_uint_t i; ngx_list_part_t *part; ngx_regex_elt_t *elts; opt = 0; #if (NGX_HAVE_PCRE_JIT) { ngx_regex_conf_t *rcf; ngx_pool_cleanup_t *cln; rcf = (ngx_regex_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_regex_module); if (rcf->pcre_jit) { opt = PCRE_STUDY_JIT_COMPILE; /* * The PCRE JIT compiler uses mmap for its executable codes, so we * have to explicitly call the pcre_free_study() function to free * this memory. */ cln = ngx_pool_cleanup_add(cycle->pool, 0); if (cln == NULL) { return NGX_ERROR; } cln->handler = ngx_pcre_free_studies; cln->data = ngx_pcre_studies; } } #endif ngx_regex_malloc_init(cycle->pool); part = &ngx_pcre_studies->part; elts = part->elts; for (i = 0 ; /* void */ ; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; elts = part->elts; i = 0; } elts[i].regex->extra = pcre_study(elts[i].regex->code, opt, &errstr); if (errstr != NULL) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "pcre_study() failed: %s in \"%s\"", errstr, elts[i].name); } #if (NGX_HAVE_PCRE_JIT) if (opt & PCRE_STUDY_JIT_COMPILE) { int jit, n; jit = 0; n = pcre_fullinfo(elts[i].regex->code, elts[i].regex->extra, PCRE_INFO_JIT, &jit); if (n != 0 || jit != 1) { ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "JIT compiler does not support pattern: \"%s\"", elts[i].name); } } #endif } ngx_regex_malloc_done(); ngx_pcre_studies = NULL; return NGX_OK; }
static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker) { sigset_t set; uint64_t cpu_affinity; ngx_int_t n; ngx_uint_t i; struct rlimit rlmt; ngx_core_conf_t *ccf; ngx_listening_t *ls; if (ngx_set_environment(cycle, NULL) == NULL) { /* fatal */ exit(2); } ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (worker >= 0 && ccf->priority != 0) { if (setpriority(PRIO_PROCESS, 0, ccf->priority) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setpriority(%d) failed", ccf->priority); } } if (ccf->rlimit_nofile != NGX_CONF_UNSET) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_nofile; rlmt.rlim_max = (rlim_t) ccf->rlimit_nofile; if (setrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setrlimit(RLIMIT_NOFILE, %i) failed", ccf->rlimit_nofile); } } if (ccf->rlimit_core != NGX_CONF_UNSET) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_core; rlmt.rlim_max = (rlim_t) ccf->rlimit_core; if (setrlimit(RLIMIT_CORE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setrlimit(RLIMIT_CORE, %O) failed", ccf->rlimit_core); } } #ifdef RLIMIT_SIGPENDING if (ccf->rlimit_sigpending != NGX_CONF_UNSET) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_sigpending; rlmt.rlim_max = (rlim_t) ccf->rlimit_sigpending; if (setrlimit(RLIMIT_SIGPENDING, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setrlimit(RLIMIT_SIGPENDING, %i) failed", ccf->rlimit_sigpending); } } #endif if (geteuid() == 0) { if (setgid(ccf->group) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setgid(%d) failed", ccf->group); /* fatal */ exit(2); } if (initgroups(ccf->username, ccf->group) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "initgroups(%s, %d) failed", ccf->username, ccf->group); } if (setuid(ccf->user) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setuid(%d) failed", ccf->user); /* fatal */ exit(2); } } if (worker >= 0) { cpu_affinity = ngx_get_cpu_affinity(worker); if (cpu_affinity) { ngx_setaffinity(cpu_affinity, cycle->log); } } #if (NGX_HAVE_PR_SET_DUMPABLE) /* allow coredump after setuid() in Linux 2.4.x */ if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "prctl(PR_SET_DUMPABLE) failed"); } #endif if (ccf->working_directory.len) { if (chdir((char *) ccf->working_directory.data) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "chdir(\"%s\") failed", ccf->working_directory.data); /* fatal */ exit(2); } } sigemptyset(&set); if (sigprocmask(SIG_SETMASK, &set, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sigprocmask() failed"); } srandom((ngx_pid << 16) ^ ngx_time()); /* * disable deleting previous events for the listening sockets because * in the worker processes there are no events at all at this point */ ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { ls[i].previous = NULL; } for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->init_process) { if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) { /* fatal */ exit(2); } } } for (n = 0; n < ngx_last_process; n++) { if (ngx_processes[n].pid == -1) { continue; } if (n == ngx_process_slot) { continue; } if (ngx_processes[n].channel[1] == -1) { continue; } if (close(ngx_processes[n].channel[1]) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "close() channel failed"); } } if (close(ngx_processes[ngx_process_slot].channel[0]) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "close() channel failed"); } #if 0 ngx_last_process = 0; #endif if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT, ngx_channel_handler) == NGX_ERROR) { /* fatal */ exit(2); } }
void ngx_master_process_cycle(ngx_cycle_t *cycle) { char *title; u_char *p; size_t size; ngx_int_t i; ngx_uint_t n, sigio; sigset_t set; struct itimerval itv; ngx_uint_t live; ngx_msec_t delay; ngx_listening_t *ls; ngx_core_conf_t *ccf; sigemptyset(&set); sigaddset(&set, SIGCHLD); sigaddset(&set, SIGALRM); sigaddset(&set, SIGIO); sigaddset(&set, SIGINT); sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL)); if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sigprocmask() failed"); } sigemptyset(&set); size = sizeof(master_process); for (i = 0; i < ngx_argc; i++) { size += ngx_strlen(ngx_argv[i]) + 1; } title = ngx_pnalloc(cycle->pool, size); p = ngx_cpymem(title, master_process, sizeof(master_process) - 1); for (i = 0; i < ngx_argc; i++) { *p++ = ' '; p = ngx_cpystrn(p, (u_char *) ngx_argv[i], size); } ngx_setproctitle(title); ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); ngx_start_worker_processes(cycle, ccf->worker_processes, NGX_PROCESS_RESPAWN); ngx_start_cache_manager_processes(cycle, 0); ngx_new_binary = 0; delay = 0; sigio = 0; live = 1; for ( ;; ) { if (delay) { if (ngx_sigalrm) { sigio = 0; delay *= 2; ngx_sigalrm = 0; } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "termination cycle: %d", delay); itv.it_interval.tv_sec = 0; itv.it_interval.tv_usec = 0; itv.it_value.tv_sec = delay / 1000; itv.it_value.tv_usec = (delay % 1000 ) * 1000; if (setitimer(ITIMER_REAL, &itv, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setitimer() failed"); } } ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "sigsuspend"); sigsuspend(&set); ngx_time_update(); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "wake up, sigio %i", sigio); if (ngx_reap) { ngx_reap = 0; ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children"); live = ngx_reap_children(cycle); } if (!live && (ngx_terminate || ngx_quit)) { ngx_master_process_exit(cycle); } if (ngx_terminate) { if (delay == 0) { delay = 50; } if (sigio) { sigio--; continue; } sigio = ccf->worker_processes + 2 /* cache processes */; if (delay > 1000) { ngx_signal_worker_processes(cycle, SIGKILL); } else { ngx_signal_worker_processes(cycle, ngx_signal_value(NGX_TERMINATE_SIGNAL)); } continue; } if (ngx_quit) { ngx_signal_worker_processes(cycle, ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); ls = cycle->listening.elts; for (n = 0; n < cycle->listening.nelts; n++) { if (ngx_close_socket(ls[n].fd) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno, ngx_close_socket_n " %V failed", &ls[n].addr_text); } } cycle->listening.nelts = 0; continue; } if (ngx_reconfigure) { ngx_reconfigure = 0; if (ngx_new_binary) { ngx_start_worker_processes(cycle, ccf->worker_processes, NGX_PROCESS_RESPAWN); ngx_start_cache_manager_processes(cycle, 0); ngx_noaccepting = 0; continue; } ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring"); cycle = ngx_init_cycle(cycle); if (cycle == NULL) { cycle = (ngx_cycle_t *) ngx_cycle; continue; } ngx_cycle = cycle; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); ngx_start_worker_processes(cycle, ccf->worker_processes, NGX_PROCESS_JUST_RESPAWN); ngx_start_cache_manager_processes(cycle, 1); /* allow new processes to start */ ngx_msleep(100); live = 1; ngx_signal_worker_processes(cycle, ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); } if (ngx_restart) { ngx_restart = 0; ngx_start_worker_processes(cycle, ccf->worker_processes, NGX_PROCESS_RESPAWN); ngx_start_cache_manager_processes(cycle, 0); live = 1; } if (ngx_reopen) { ngx_reopen = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs"); ngx_reopen_files(cycle, ccf->user); ngx_signal_worker_processes(cycle, ngx_signal_value(NGX_REOPEN_SIGNAL)); } if (ngx_change_binary) { ngx_change_binary = 0; ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "changing binary"); ngx_new_binary = ngx_exec_new_binary(cycle, ngx_argv); } if (ngx_noaccept) { ngx_noaccept = 0; ngx_noaccepting = 1; ngx_signal_worker_processes(cycle, ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); } } }