1240Sigor@sysoev.ru 2240Sigor@sysoev.ru /* 3240Sigor@sysoev.ru * Copyright (C) Igor Sysoev 4240Sigor@sysoev.ru * Copyright (C) NGINX, Inc. 5240Sigor@sysoev.ru */ 6240Sigor@sysoev.ru 7240Sigor@sysoev.ru #include <nxt_main.h> 8240Sigor@sysoev.ru #include <nxt_runtime.h> 9240Sigor@sysoev.ru #include <nxt_port.h> 10240Sigor@sysoev.ru #include <nxt_main_process.h> 11240Sigor@sysoev.ru #include <nxt_conf.h> 12444Sigor@sysoev.ru #include <nxt_router.h> 13774Svbart@nginx.com #if (NXT_TLS) 14774Svbart@nginx.com #include <nxt_cert.h> 15774Svbart@nginx.com #endif 16240Sigor@sysoev.ru 171489St.nateldemoura@f5.com #include <sys/mount.h> 181489St.nateldemoura@f5.com 19240Sigor@sysoev.ru 20240Sigor@sysoev.ru typedef struct { 21240Sigor@sysoev.ru nxt_socket_t socket; 22240Sigor@sysoev.ru nxt_socket_error_t error; 23240Sigor@sysoev.ru u_char *start; 24240Sigor@sysoev.ru u_char *end; 25240Sigor@sysoev.ru } nxt_listening_socket_t; 26240Sigor@sysoev.ru 27240Sigor@sysoev.ru 28510Salexander.borisov@nginx.com typedef struct { 29536Svbart@nginx.com nxt_uint_t size; 30536Svbart@nginx.com nxt_conf_map_t *map; 31546Smax.romanov@nginx.com } nxt_conf_app_map_t; 32510Salexander.borisov@nginx.com 33510Salexander.borisov@nginx.com 341302St.nateldemoura@f5.com extern nxt_port_handlers_t nxt_controller_process_port_handlers; 351302St.nateldemoura@f5.com extern nxt_port_handlers_t nxt_router_process_port_handlers; 361302St.nateldemoura@f5.com 371302St.nateldemoura@f5.com 38240Sigor@sysoev.ru static nxt_int_t nxt_main_process_port_create(nxt_task_t *task, 39240Sigor@sysoev.ru nxt_runtime_t *rt); 40240Sigor@sysoev.ru static void nxt_main_process_title(nxt_task_t *task); 411488St.nateldemoura@f5.com static nxt_int_t nxt_main_process_create(nxt_task_t *task, 421488St.nateldemoura@f5.com const nxt_process_init_t init); 431488St.nateldemoura@f5.com static nxt_int_t nxt_main_start_process(nxt_task_t *task, 441488St.nateldemoura@f5.com nxt_process_t *process); 451488St.nateldemoura@f5.com static nxt_process_t *nxt_main_process_new(nxt_task_t *task, nxt_runtime_t *rt); 46240Sigor@sysoev.ru static void nxt_main_process_sigterm_handler(nxt_task_t *task, void *obj, 47240Sigor@sysoev.ru void *data); 48240Sigor@sysoev.ru static void nxt_main_process_sigquit_handler(nxt_task_t *task, void *obj, 49240Sigor@sysoev.ru void *data); 50240Sigor@sysoev.ru static void nxt_main_process_sigusr1_handler(nxt_task_t *task, void *obj, 51240Sigor@sysoev.ru void *data); 52240Sigor@sysoev.ru static void nxt_main_process_sigchld_handler(nxt_task_t *task, void *obj, 53240Sigor@sysoev.ru void *data); 54944Sigor@sysoev.ru static void nxt_main_process_signal_handler(nxt_task_t *task, void *obj, 55944Sigor@sysoev.ru void *data); 561488St.nateldemoura@f5.com static void nxt_main_cleanup_process(nxt_task_t *task, nxt_pid_t pid); 57240Sigor@sysoev.ru static void nxt_main_port_socket_handler(nxt_task_t *task, 58240Sigor@sysoev.ru nxt_port_recv_msg_t *msg); 59240Sigor@sysoev.ru static nxt_int_t nxt_main_listening_socket(nxt_sockaddr_t *sa, 60240Sigor@sysoev.ru nxt_listening_socket_t *ls); 61240Sigor@sysoev.ru static void nxt_main_port_modules_handler(nxt_task_t *task, 62240Sigor@sysoev.ru nxt_port_recv_msg_t *msg); 63240Sigor@sysoev.ru static int nxt_cdecl nxt_app_lang_compare(const void *v1, const void *v2); 64314Svbart@nginx.com static void nxt_main_port_conf_store_handler(nxt_task_t *task, 65314Svbart@nginx.com nxt_port_recv_msg_t *msg); 66630Svbart@nginx.com static void nxt_main_port_access_log_handler(nxt_task_t *task, 67630Svbart@nginx.com nxt_port_recv_msg_t *msg); 68240Sigor@sysoev.ru 69240Sigor@sysoev.ru const nxt_sig_event_t nxt_main_process_signals[] = { 70944Sigor@sysoev.ru nxt_event_signal(SIGHUP, nxt_main_process_signal_handler), 71240Sigor@sysoev.ru nxt_event_signal(SIGINT, nxt_main_process_sigterm_handler), 72240Sigor@sysoev.ru nxt_event_signal(SIGQUIT, nxt_main_process_sigquit_handler), 73240Sigor@sysoev.ru nxt_event_signal(SIGTERM, nxt_main_process_sigterm_handler), 74240Sigor@sysoev.ru nxt_event_signal(SIGCHLD, nxt_main_process_sigchld_handler), 75240Sigor@sysoev.ru nxt_event_signal(SIGUSR1, nxt_main_process_sigusr1_handler), 76240Sigor@sysoev.ru nxt_event_signal_end, 77240Sigor@sysoev.ru }; 78240Sigor@sysoev.ru 79240Sigor@sysoev.ru 80240Sigor@sysoev.ru static nxt_bool_t nxt_exiting; 81240Sigor@sysoev.ru 82240Sigor@sysoev.ru 83240Sigor@sysoev.ru nxt_int_t 84240Sigor@sysoev.ru nxt_main_process_start(nxt_thread_t *thr, nxt_task_t *task, 85240Sigor@sysoev.ru nxt_runtime_t *rt) 86240Sigor@sysoev.ru { 87696Sigor@sysoev.ru rt->type = NXT_PROCESS_MAIN; 88240Sigor@sysoev.ru 89240Sigor@sysoev.ru if (nxt_main_process_port_create(task, rt) != NXT_OK) { 90240Sigor@sysoev.ru return NXT_ERROR; 91240Sigor@sysoev.ru } 92240Sigor@sysoev.ru 93240Sigor@sysoev.ru nxt_main_process_title(task); 94240Sigor@sysoev.ru 95240Sigor@sysoev.ru /* 961488St.nateldemoura@f5.com * The discovery process will send a message processed by 97240Sigor@sysoev.ru * nxt_main_port_modules_handler() which starts the controller 98240Sigor@sysoev.ru * and router processes. 99240Sigor@sysoev.ru */ 1001488St.nateldemoura@f5.com return nxt_main_process_create(task, nxt_discovery_process); 101240Sigor@sysoev.ru } 102240Sigor@sysoev.ru 103240Sigor@sysoev.ru 104240Sigor@sysoev.ru static nxt_conf_map_t nxt_common_app_conf[] = { 105240Sigor@sysoev.ru { 106240Sigor@sysoev.ru nxt_string("type"), 107240Sigor@sysoev.ru NXT_CONF_MAP_STR, 108240Sigor@sysoev.ru offsetof(nxt_common_app_conf_t, type), 109240Sigor@sysoev.ru }, 110240Sigor@sysoev.ru 111240Sigor@sysoev.ru { 112240Sigor@sysoev.ru nxt_string("user"), 113240Sigor@sysoev.ru NXT_CONF_MAP_STR, 114240Sigor@sysoev.ru offsetof(nxt_common_app_conf_t, user), 115240Sigor@sysoev.ru }, 116240Sigor@sysoev.ru 117240Sigor@sysoev.ru { 118240Sigor@sysoev.ru nxt_string("group"), 119240Sigor@sysoev.ru NXT_CONF_MAP_STR, 120240Sigor@sysoev.ru offsetof(nxt_common_app_conf_t, group), 121240Sigor@sysoev.ru }, 122240Sigor@sysoev.ru 123240Sigor@sysoev.ru { 124271Smax.romanov@nginx.com nxt_string("working_directory"), 125271Smax.romanov@nginx.com NXT_CONF_MAP_CSTRZ, 126271Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, working_directory), 127271Smax.romanov@nginx.com }, 128678Svbart@nginx.com 129678Svbart@nginx.com { 130678Svbart@nginx.com nxt_string("environment"), 131678Svbart@nginx.com NXT_CONF_MAP_PTR, 132678Svbart@nginx.com offsetof(nxt_common_app_conf_t, environment), 133678Svbart@nginx.com }, 1341182St.nateldemoura@f5.com 1351182St.nateldemoura@f5.com { 1361182St.nateldemoura@f5.com nxt_string("isolation"), 1371182St.nateldemoura@f5.com NXT_CONF_MAP_PTR, 1381182St.nateldemoura@f5.com offsetof(nxt_common_app_conf_t, isolation), 1391320Smax.romanov@nginx.com }, 1401320Smax.romanov@nginx.com 1411320Smax.romanov@nginx.com { 1421320Smax.romanov@nginx.com nxt_string("limits"), 1431320Smax.romanov@nginx.com NXT_CONF_MAP_PTR, 1441320Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, limits), 1451320Smax.romanov@nginx.com }, 1461320Smax.romanov@nginx.com 1471320Smax.romanov@nginx.com }; 1481320Smax.romanov@nginx.com 1491320Smax.romanov@nginx.com 1501320Smax.romanov@nginx.com static nxt_conf_map_t nxt_common_app_limits_conf[] = { 1511320Smax.romanov@nginx.com { 1521320Smax.romanov@nginx.com nxt_string("shm"), 1531320Smax.romanov@nginx.com NXT_CONF_MAP_SIZE, 1541320Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, shm_limit), 1551320Smax.romanov@nginx.com }, 1561320Smax.romanov@nginx.com 157510Salexander.borisov@nginx.com }; 158271Smax.romanov@nginx.com 159510Salexander.borisov@nginx.com 160804Svbart@nginx.com static nxt_conf_map_t nxt_external_app_conf[] = { 161804Svbart@nginx.com { 162804Svbart@nginx.com nxt_string("executable"), 163804Svbart@nginx.com NXT_CONF_MAP_CSTRZ, 164804Svbart@nginx.com offsetof(nxt_common_app_conf_t, u.external.executable), 165804Svbart@nginx.com }, 166804Svbart@nginx.com 167804Svbart@nginx.com { 168804Svbart@nginx.com nxt_string("arguments"), 169804Svbart@nginx.com NXT_CONF_MAP_PTR, 170804Svbart@nginx.com offsetof(nxt_common_app_conf_t, u.external.arguments), 171804Svbart@nginx.com }, 172804Svbart@nginx.com 173804Svbart@nginx.com }; 174804Svbart@nginx.com 175804Svbart@nginx.com 176546Smax.romanov@nginx.com static nxt_conf_map_t nxt_python_app_conf[] = { 177271Smax.romanov@nginx.com { 178394Smax.romanov@nginx.com nxt_string("home"), 179394Smax.romanov@nginx.com NXT_CONF_MAP_CSTRZ, 180394Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.python.home), 181394Smax.romanov@nginx.com }, 182394Smax.romanov@nginx.com 183394Smax.romanov@nginx.com { 184240Sigor@sysoev.ru nxt_string("path"), 185240Sigor@sysoev.ru NXT_CONF_MAP_STR, 186240Sigor@sysoev.ru offsetof(nxt_common_app_conf_t, u.python.path), 187240Sigor@sysoev.ru }, 188240Sigor@sysoev.ru 189240Sigor@sysoev.ru { 190240Sigor@sysoev.ru nxt_string("module"), 191240Sigor@sysoev.ru NXT_CONF_MAP_STR, 192240Sigor@sysoev.ru offsetof(nxt_common_app_conf_t, u.python.module), 193240Sigor@sysoev.ru }, 1941601Smax.romanov@nginx.com 1951601Smax.romanov@nginx.com { 1961601Smax.romanov@nginx.com nxt_string("callable"), 1971601Smax.romanov@nginx.com NXT_CONF_MAP_CSTRZ, 1981601Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.python.callable), 1991601Smax.romanov@nginx.com }, 2001681Smax.romanov@nginx.com 2011681Smax.romanov@nginx.com { 202*1697Smax.romanov@nginx.com nxt_string("protocol"), 203*1697Smax.romanov@nginx.com NXT_CONF_MAP_STR, 204*1697Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.python.protocol), 205*1697Smax.romanov@nginx.com }, 206*1697Smax.romanov@nginx.com 207*1697Smax.romanov@nginx.com { 2081681Smax.romanov@nginx.com nxt_string("threads"), 2091681Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 2101681Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.python.threads), 2111681Smax.romanov@nginx.com }, 2121681Smax.romanov@nginx.com 2131681Smax.romanov@nginx.com { 2141681Smax.romanov@nginx.com nxt_string("thread_stack_size"), 2151681Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 2161681Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.python.thread_stack_size), 2171681Smax.romanov@nginx.com }, 218510Salexander.borisov@nginx.com }; 219240Sigor@sysoev.ru 220510Salexander.borisov@nginx.com 221546Smax.romanov@nginx.com static nxt_conf_map_t nxt_php_app_conf[] = { 222240Sigor@sysoev.ru { 2231473Svbart@nginx.com nxt_string("targets"), 2241473Svbart@nginx.com NXT_CONF_MAP_PTR, 2251473Svbart@nginx.com offsetof(nxt_common_app_conf_t, u.php.targets), 226240Sigor@sysoev.ru }, 227687Svbart@nginx.com 228687Svbart@nginx.com { 229687Svbart@nginx.com nxt_string("options"), 230687Svbart@nginx.com NXT_CONF_MAP_PTR, 231687Svbart@nginx.com offsetof(nxt_common_app_conf_t, u.php.options), 232687Svbart@nginx.com }, 233510Salexander.borisov@nginx.com }; 234240Sigor@sysoev.ru 235510Salexander.borisov@nginx.com 236546Smax.romanov@nginx.com static nxt_conf_map_t nxt_perl_app_conf[] = { 237510Salexander.borisov@nginx.com { 238510Salexander.borisov@nginx.com nxt_string("script"), 239510Salexander.borisov@nginx.com NXT_CONF_MAP_CSTRZ, 240510Salexander.borisov@nginx.com offsetof(nxt_common_app_conf_t, u.perl.script), 241510Salexander.borisov@nginx.com }, 2421689Smax.romanov@nginx.com 2431689Smax.romanov@nginx.com { 2441689Smax.romanov@nginx.com nxt_string("threads"), 2451689Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 2461689Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.perl.threads), 2471689Smax.romanov@nginx.com }, 2481689Smax.romanov@nginx.com 2491689Smax.romanov@nginx.com { 2501689Smax.romanov@nginx.com nxt_string("thread_stack_size"), 2511689Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 2521689Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.perl.thread_stack_size), 2531689Smax.romanov@nginx.com }, 254510Salexander.borisov@nginx.com }; 255510Salexander.borisov@nginx.com 256510Salexander.borisov@nginx.com 257584Salexander.borisov@nginx.com static nxt_conf_map_t nxt_ruby_app_conf[] = { 258584Salexander.borisov@nginx.com { 259584Salexander.borisov@nginx.com nxt_string("script"), 260584Salexander.borisov@nginx.com NXT_CONF_MAP_STR, 261584Salexander.borisov@nginx.com offsetof(nxt_common_app_conf_t, u.ruby.script), 262584Salexander.borisov@nginx.com }, 2631687Smax.romanov@nginx.com { 2641687Smax.romanov@nginx.com nxt_string("threads"), 2651687Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 2661687Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.ruby.threads), 2671687Smax.romanov@nginx.com }, 268584Salexander.borisov@nginx.com }; 269584Salexander.borisov@nginx.com 270584Salexander.borisov@nginx.com 271977Smax.romanov@gmail.com static nxt_conf_map_t nxt_java_app_conf[] = { 272977Smax.romanov@gmail.com { 273977Smax.romanov@gmail.com nxt_string("classpath"), 274977Smax.romanov@gmail.com NXT_CONF_MAP_PTR, 275977Smax.romanov@gmail.com offsetof(nxt_common_app_conf_t, u.java.classpath), 276977Smax.romanov@gmail.com }, 277977Smax.romanov@gmail.com { 278977Smax.romanov@gmail.com nxt_string("webapp"), 279977Smax.romanov@gmail.com NXT_CONF_MAP_CSTRZ, 280977Smax.romanov@gmail.com offsetof(nxt_common_app_conf_t, u.java.webapp), 281977Smax.romanov@gmail.com }, 282977Smax.romanov@gmail.com { 283977Smax.romanov@gmail.com nxt_string("options"), 284977Smax.romanov@gmail.com NXT_CONF_MAP_PTR, 285977Smax.romanov@gmail.com offsetof(nxt_common_app_conf_t, u.java.options), 286977Smax.romanov@gmail.com }, 287977Smax.romanov@gmail.com { 288977Smax.romanov@gmail.com nxt_string("unit_jars"), 289977Smax.romanov@gmail.com NXT_CONF_MAP_CSTRZ, 290977Smax.romanov@gmail.com offsetof(nxt_common_app_conf_t, u.java.unit_jars), 291977Smax.romanov@gmail.com }, 2921684Smax.romanov@nginx.com { 2931684Smax.romanov@nginx.com nxt_string("threads"), 2941684Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 2951684Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.java.threads), 2961684Smax.romanov@nginx.com }, 2971684Smax.romanov@nginx.com { 2981684Smax.romanov@nginx.com nxt_string("thread_stack_size"), 2991684Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 3001684Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.java.thread_stack_size), 3011684Smax.romanov@nginx.com }, 302977Smax.romanov@gmail.com 303977Smax.romanov@gmail.com }; 304977Smax.romanov@gmail.com 305977Smax.romanov@gmail.com 306546Smax.romanov@nginx.com static nxt_conf_app_map_t nxt_app_maps[] = { 307804Svbart@nginx.com { nxt_nitems(nxt_external_app_conf), nxt_external_app_conf }, 308804Svbart@nginx.com { nxt_nitems(nxt_python_app_conf), nxt_python_app_conf }, 309804Svbart@nginx.com { nxt_nitems(nxt_php_app_conf), nxt_php_app_conf }, 310804Svbart@nginx.com { nxt_nitems(nxt_perl_app_conf), nxt_perl_app_conf }, 311804Svbart@nginx.com { nxt_nitems(nxt_ruby_app_conf), nxt_ruby_app_conf }, 312977Smax.romanov@gmail.com { nxt_nitems(nxt_java_app_conf), nxt_java_app_conf }, 313510Salexander.borisov@nginx.com }; 314510Salexander.borisov@nginx.com 315510Salexander.borisov@nginx.com 316240Sigor@sysoev.ru static void 317240Sigor@sysoev.ru nxt_port_main_data_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 318240Sigor@sysoev.ru { 319240Sigor@sysoev.ru nxt_debug(task, "main data: %*s", 320240Sigor@sysoev.ru nxt_buf_mem_used_size(&msg->buf->mem), msg->buf->mem.pos); 321240Sigor@sysoev.ru } 322240Sigor@sysoev.ru 323240Sigor@sysoev.ru 324240Sigor@sysoev.ru static void 3251488St.nateldemoura@f5.com nxt_port_main_start_process_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 326240Sigor@sysoev.ru { 3271488St.nateldemoura@f5.com u_char *start, *p, ch; 328536Svbart@nginx.com size_t type_len; 329536Svbart@nginx.com nxt_int_t ret; 330240Sigor@sysoev.ru nxt_buf_t *b; 331318Smax.romanov@nginx.com nxt_port_t *port; 3321182St.nateldemoura@f5.com nxt_runtime_t *rt; 3331488St.nateldemoura@f5.com nxt_process_t *process; 334536Svbart@nginx.com nxt_app_type_t idx; 335240Sigor@sysoev.ru nxt_conf_value_t *conf; 3361488St.nateldemoura@f5.com nxt_process_init_t *init; 3371488St.nateldemoura@f5.com nxt_common_app_conf_t *app_conf; 338240Sigor@sysoev.ru 339318Smax.romanov@nginx.com ret = NXT_ERROR; 340318Smax.romanov@nginx.com 3411488St.nateldemoura@f5.com rt = task->thread->runtime; 342352Smax.romanov@nginx.com 3431488St.nateldemoura@f5.com process = nxt_main_process_new(task, rt); 3441488St.nateldemoura@f5.com if (nxt_slow_path(process == NULL)) { 345352Smax.romanov@nginx.com return; 346352Smax.romanov@nginx.com } 347352Smax.romanov@nginx.com 3481488St.nateldemoura@f5.com init = nxt_process_init(process); 3491488St.nateldemoura@f5.com 3501488St.nateldemoura@f5.com *init = nxt_app_process; 351352Smax.romanov@nginx.com 3521488St.nateldemoura@f5.com b = nxt_buf_chk_make_plain(process->mem_pool, msg->buf, msg->size); 353352Smax.romanov@nginx.com if (b == NULL) { 3541488St.nateldemoura@f5.com goto failed; 355352Smax.romanov@nginx.com } 356240Sigor@sysoev.ru 3571488St.nateldemoura@f5.com nxt_debug(task, "main start process: %*s", b->mem.free - b->mem.pos, 358240Sigor@sysoev.ru b->mem.pos); 359240Sigor@sysoev.ru 3601488St.nateldemoura@f5.com app_conf = nxt_mp_zalloc(process->mem_pool, sizeof(nxt_common_app_conf_t)); 3611488St.nateldemoura@f5.com if (nxt_slow_path(app_conf == NULL)) { 3621488St.nateldemoura@f5.com goto failed; 3631488St.nateldemoura@f5.com } 364240Sigor@sysoev.ru 365240Sigor@sysoev.ru start = b->mem.pos; 366240Sigor@sysoev.ru 3671488St.nateldemoura@f5.com app_conf->name.start = start; 3681488St.nateldemoura@f5.com app_conf->name.length = nxt_strlen(start); 3691488St.nateldemoura@f5.com 3701488St.nateldemoura@f5.com init->name = (const char *) start; 3711488St.nateldemoura@f5.com 3721488St.nateldemoura@f5.com process->name = nxt_mp_alloc(process->mem_pool, app_conf->name.length 3731488St.nateldemoura@f5.com + sizeof("\"\" application") + 1); 3741488St.nateldemoura@f5.com 3751488St.nateldemoura@f5.com if (nxt_slow_path(process->name == NULL)) { 3761488St.nateldemoura@f5.com goto failed; 3771488St.nateldemoura@f5.com } 378240Sigor@sysoev.ru 3791488St.nateldemoura@f5.com p = (u_char *) process->name; 3801488St.nateldemoura@f5.com *p++ = '"'; 3811488St.nateldemoura@f5.com p = nxt_cpymem(p, init->name, app_conf->name.length); 3821488St.nateldemoura@f5.com p = nxt_cpymem(p, "\" application", 13); 3831488St.nateldemoura@f5.com *p = '\0'; 384240Sigor@sysoev.ru 3851488St.nateldemoura@f5.com app_conf->shm_limit = 100 * 1024 * 1024; 386240Sigor@sysoev.ru 3871488St.nateldemoura@f5.com start += app_conf->name.length + 1; 3881488St.nateldemoura@f5.com 3891488St.nateldemoura@f5.com conf = nxt_conf_json_parse(process->mem_pool, start, b->mem.free, NULL); 390240Sigor@sysoev.ru if (conf == NULL) { 391564Svbart@nginx.com nxt_alert(task, "router app configuration parsing error"); 392318Smax.romanov@nginx.com 393318Smax.romanov@nginx.com goto failed; 394240Sigor@sysoev.ru } 395240Sigor@sysoev.ru 3961182St.nateldemoura@f5.com rt = task->thread->runtime; 3971182St.nateldemoura@f5.com 3981488St.nateldemoura@f5.com app_conf->user.start = (u_char*)rt->user_cred.user; 3991488St.nateldemoura@f5.com app_conf->user.length = nxt_strlen(rt->user_cred.user); 400240Sigor@sysoev.ru 4011488St.nateldemoura@f5.com ret = nxt_conf_map_object(process->mem_pool, conf, nxt_common_app_conf, 4021488St.nateldemoura@f5.com nxt_nitems(nxt_common_app_conf), app_conf); 4031488St.nateldemoura@f5.com 404240Sigor@sysoev.ru if (ret != NXT_OK) { 405564Svbart@nginx.com nxt_alert(task, "failed to map common app conf received from router"); 406318Smax.romanov@nginx.com goto failed; 407240Sigor@sysoev.ru } 408240Sigor@sysoev.ru 4091488St.nateldemoura@f5.com for (type_len = 0; type_len != app_conf->type.length; type_len++) { 4101488St.nateldemoura@f5.com ch = app_conf->type.start[type_len]; 411536Svbart@nginx.com 412536Svbart@nginx.com if (ch == ' ' || nxt_isdigit(ch)) { 413536Svbart@nginx.com break; 414536Svbart@nginx.com } 415536Svbart@nginx.com } 416536Svbart@nginx.com 4171488St.nateldemoura@f5.com idx = nxt_app_parse_type(app_conf->type.start, type_len); 418510Salexander.borisov@nginx.com 419546Smax.romanov@nginx.com if (nxt_slow_path(idx >= nxt_nitems(nxt_app_maps))) { 420564Svbart@nginx.com nxt_alert(task, "invalid app type %d received from router", (int) idx); 421546Smax.romanov@nginx.com goto failed; 422546Smax.romanov@nginx.com } 423510Salexander.borisov@nginx.com 4241488St.nateldemoura@f5.com ret = nxt_conf_map_object(process->mem_pool, conf, nxt_app_maps[idx].map, 4251488St.nateldemoura@f5.com nxt_app_maps[idx].size, app_conf); 426510Salexander.borisov@nginx.com 427546Smax.romanov@nginx.com if (nxt_slow_path(ret != NXT_OK)) { 428564Svbart@nginx.com nxt_alert(task, "failed to map app conf received from router"); 429546Smax.romanov@nginx.com goto failed; 430546Smax.romanov@nginx.com } 431510Salexander.borisov@nginx.com 4321488St.nateldemoura@f5.com if (app_conf->limits != NULL) { 4331488St.nateldemoura@f5.com ret = nxt_conf_map_object(process->mem_pool, app_conf->limits, 4341320Smax.romanov@nginx.com nxt_common_app_limits_conf, 4351320Smax.romanov@nginx.com nxt_nitems(nxt_common_app_limits_conf), 4361488St.nateldemoura@f5.com app_conf); 4371320Smax.romanov@nginx.com 4381320Smax.romanov@nginx.com if (nxt_slow_path(ret != NXT_OK)) { 4391320Smax.romanov@nginx.com nxt_alert(task, "failed to map app limits received from router"); 4401320Smax.romanov@nginx.com goto failed; 4411320Smax.romanov@nginx.com } 4421320Smax.romanov@nginx.com } 4431320Smax.romanov@nginx.com 4441488St.nateldemoura@f5.com app_conf->self = conf; 4451488St.nateldemoura@f5.com 4461488St.nateldemoura@f5.com process->stream = msg->port_msg.stream; 4471488St.nateldemoura@f5.com process->data.app = app_conf; 4481473Svbart@nginx.com 4491488St.nateldemoura@f5.com ret = nxt_main_start_process(task, process); 4501488St.nateldemoura@f5.com if (nxt_fast_path(ret == NXT_OK || ret == NXT_AGAIN)) { 4511488St.nateldemoura@f5.com return; 4521488St.nateldemoura@f5.com } 453240Sigor@sysoev.ru 454318Smax.romanov@nginx.com failed: 455318Smax.romanov@nginx.com 4561488St.nateldemoura@f5.com nxt_process_use(task, process, -1); 4571488St.nateldemoura@f5.com 4581488St.nateldemoura@f5.com port = nxt_runtime_port_find(rt, msg->port_msg.pid, 4591488St.nateldemoura@f5.com msg->port_msg.reply_port); 4601488St.nateldemoura@f5.com 4611488St.nateldemoura@f5.com if (nxt_fast_path(port != NULL)) { 4621488St.nateldemoura@f5.com nxt_port_socket_write(task, port, NXT_PORT_MSG_RPC_ERROR, 4631488St.nateldemoura@f5.com -1, msg->port_msg.stream, 0, NULL); 4641488St.nateldemoura@f5.com } 4651488St.nateldemoura@f5.com } 4661488St.nateldemoura@f5.com 4671488St.nateldemoura@f5.com 4681488St.nateldemoura@f5.com static void 4691488St.nateldemoura@f5.com nxt_main_process_created_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 4701488St.nateldemoura@f5.com { 4711488St.nateldemoura@f5.com nxt_port_t *port; 4721488St.nateldemoura@f5.com nxt_process_t *process; 4731488St.nateldemoura@f5.com nxt_runtime_t *rt; 4741488St.nateldemoura@f5.com 4751488St.nateldemoura@f5.com rt = task->thread->runtime; 4761488St.nateldemoura@f5.com 4771488St.nateldemoura@f5.com process = nxt_runtime_process_find(rt, msg->port_msg.pid); 4781488St.nateldemoura@f5.com if (nxt_slow_path(process == NULL)) { 4791488St.nateldemoura@f5.com return; 480318Smax.romanov@nginx.com } 481318Smax.romanov@nginx.com 4821488St.nateldemoura@f5.com nxt_assert(process->state == NXT_PROCESS_STATE_CREATING); 4831488St.nateldemoura@f5.com 4841488St.nateldemoura@f5.com port = nxt_runtime_port_find(rt, msg->port_msg.pid, 4851488St.nateldemoura@f5.com msg->port_msg.reply_port); 4861488St.nateldemoura@f5.com 4871488St.nateldemoura@f5.com 4881488St.nateldemoura@f5.com if (nxt_slow_path(port == NULL)) { 4891488St.nateldemoura@f5.com return; 4901488St.nateldemoura@f5.com } 4911488St.nateldemoura@f5.com 4921488St.nateldemoura@f5.com #if (NXT_HAVE_CLONE && NXT_HAVE_CLONE_NEWUSER) 4931488St.nateldemoura@f5.com if (nxt_is_clone_flag_set(process->isolation.clone.flags, NEWUSER)) { 4941488St.nateldemoura@f5.com if (nxt_slow_path(nxt_clone_credential_map(task, process->pid, 4951488St.nateldemoura@f5.com process->user_cred, 4961488St.nateldemoura@f5.com &process->isolation.clone) 4971488St.nateldemoura@f5.com != NXT_OK)) 4981488St.nateldemoura@f5.com { 4991488St.nateldemoura@f5.com (void) nxt_port_socket_write(task, port, NXT_PORT_MSG_RPC_ERROR, 5001488St.nateldemoura@f5.com -1, msg->port_msg.stream, 0, NULL); 5011488St.nateldemoura@f5.com return; 5021488St.nateldemoura@f5.com } 5031488St.nateldemoura@f5.com } 5041488St.nateldemoura@f5.com 5051488St.nateldemoura@f5.com #endif 5061488St.nateldemoura@f5.com 5071488St.nateldemoura@f5.com process->state = NXT_PROCESS_STATE_CREATED; 5081488St.nateldemoura@f5.com 5091488St.nateldemoura@f5.com (void) nxt_port_socket_write(task, port, NXT_PORT_MSG_RPC_READY_LAST, 5101488St.nateldemoura@f5.com -1, msg->port_msg.stream, 0, NULL); 511240Sigor@sysoev.ru } 512240Sigor@sysoev.ru 513240Sigor@sysoev.ru 514320Smax.romanov@nginx.com static nxt_port_handlers_t nxt_main_process_port_handlers = { 5151488St.nateldemoura@f5.com .data = nxt_port_main_data_handler, 5161488St.nateldemoura@f5.com .process_created = nxt_main_process_created_handler, 5171488St.nateldemoura@f5.com .process_ready = nxt_port_process_ready_handler, 5181488St.nateldemoura@f5.com .start_process = nxt_port_main_start_process_handler, 5191488St.nateldemoura@f5.com .socket = nxt_main_port_socket_handler, 5201488St.nateldemoura@f5.com .modules = nxt_main_port_modules_handler, 5211488St.nateldemoura@f5.com .conf_store = nxt_main_port_conf_store_handler, 522774Svbart@nginx.com #if (NXT_TLS) 5231488St.nateldemoura@f5.com .cert_get = nxt_cert_store_get_handler, 5241488St.nateldemoura@f5.com .cert_delete = nxt_cert_store_delete_handler, 525774Svbart@nginx.com #endif 5261488St.nateldemoura@f5.com .access_log = nxt_main_port_access_log_handler, 5271488St.nateldemoura@f5.com .rpc_ready = nxt_port_rpc_handler, 5281488St.nateldemoura@f5.com .rpc_error = nxt_port_rpc_handler, 529240Sigor@sysoev.ru }; 530240Sigor@sysoev.ru 531240Sigor@sysoev.ru 532240Sigor@sysoev.ru static nxt_int_t 533240Sigor@sysoev.ru nxt_main_process_port_create(nxt_task_t *task, nxt_runtime_t *rt) 534240Sigor@sysoev.ru { 535240Sigor@sysoev.ru nxt_int_t ret; 536240Sigor@sysoev.ru nxt_port_t *port; 537240Sigor@sysoev.ru nxt_process_t *process; 538240Sigor@sysoev.ru 5391254Shongzhidao@gmail.com port = nxt_runtime_process_port_create(task, rt, nxt_pid, 0, 5401254Shongzhidao@gmail.com NXT_PROCESS_MAIN); 541240Sigor@sysoev.ru if (nxt_slow_path(port == NULL)) { 542240Sigor@sysoev.ru return NXT_ERROR; 543240Sigor@sysoev.ru } 544240Sigor@sysoev.ru 5451254Shongzhidao@gmail.com process = port->process; 546349Smax.romanov@nginx.com 547240Sigor@sysoev.ru ret = nxt_port_socket_init(task, port, 0); 548240Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) { 5491488St.nateldemoura@f5.com nxt_port_use(task, port, -1); 550240Sigor@sysoev.ru return ret; 551240Sigor@sysoev.ru } 552240Sigor@sysoev.ru 553240Sigor@sysoev.ru /* 554240Sigor@sysoev.ru * A main process port. A write port is not closed 5551488St.nateldemoura@f5.com * since it should be inherited by processes. 556240Sigor@sysoev.ru */ 557320Smax.romanov@nginx.com nxt_port_enable(task, port, &nxt_main_process_port_handlers); 558240Sigor@sysoev.ru 5591488St.nateldemoura@f5.com process->state = NXT_PROCESS_STATE_READY; 560240Sigor@sysoev.ru 561240Sigor@sysoev.ru return NXT_OK; 562240Sigor@sysoev.ru } 563240Sigor@sysoev.ru 564240Sigor@sysoev.ru 565240Sigor@sysoev.ru static void 566240Sigor@sysoev.ru nxt_main_process_title(nxt_task_t *task) 567240Sigor@sysoev.ru { 568240Sigor@sysoev.ru u_char *p, *end; 569240Sigor@sysoev.ru nxt_uint_t i; 570240Sigor@sysoev.ru u_char title[2048]; 571240Sigor@sysoev.ru 572240Sigor@sysoev.ru end = title + sizeof(title) - 1; 573240Sigor@sysoev.ru 574680Sigor@sysoev.ru p = nxt_sprintf(title, end, "unit: main v" NXT_VERSION " [%s", 575680Sigor@sysoev.ru nxt_process_argv[0]); 576240Sigor@sysoev.ru 577240Sigor@sysoev.ru for (i = 1; nxt_process_argv[i] != NULL; i++) { 578240Sigor@sysoev.ru p = nxt_sprintf(p, end, " %s", nxt_process_argv[i]); 579240Sigor@sysoev.ru } 580240Sigor@sysoev.ru 581240Sigor@sysoev.ru if (p < end) { 582240Sigor@sysoev.ru *p++ = ']'; 583240Sigor@sysoev.ru } 584240Sigor@sysoev.ru 585240Sigor@sysoev.ru *p = '\0'; 586240Sigor@sysoev.ru 587240Sigor@sysoev.ru nxt_process_title(task, "%s", title); 588240Sigor@sysoev.ru } 589240Sigor@sysoev.ru 590240Sigor@sysoev.ru 591240Sigor@sysoev.ru static nxt_int_t 5921488St.nateldemoura@f5.com nxt_main_process_create(nxt_task_t *task, const nxt_process_init_t init) 593240Sigor@sysoev.ru { 5941488St.nateldemoura@f5.com nxt_int_t ret; 5951488St.nateldemoura@f5.com nxt_runtime_t *rt; 5961488St.nateldemoura@f5.com nxt_process_t *process; 5971488St.nateldemoura@f5.com nxt_process_init_t *pinit; 598240Sigor@sysoev.ru 5991488St.nateldemoura@f5.com rt = task->thread->runtime; 6001302St.nateldemoura@f5.com 6011488St.nateldemoura@f5.com process = nxt_main_process_new(task, rt); 6021488St.nateldemoura@f5.com if (nxt_slow_path(process == NULL)) { 603368Svbart@nginx.com return NXT_ERROR; 604368Svbart@nginx.com } 605368Svbart@nginx.com 6061488St.nateldemoura@f5.com process->name = init.name; 6071488St.nateldemoura@f5.com process->user_cred = &rt->user_cred; 608314Svbart@nginx.com 6091488St.nateldemoura@f5.com pinit = nxt_process_init(process); 6101488St.nateldemoura@f5.com *pinit = init; 611314Svbart@nginx.com 6121488St.nateldemoura@f5.com ret = nxt_main_start_process(task, process); 6131488St.nateldemoura@f5.com if (nxt_slow_path(ret == NXT_ERROR)) { 6141488St.nateldemoura@f5.com nxt_process_use(task, process, -1); 615314Svbart@nginx.com } 616314Svbart@nginx.com 617314Svbart@nginx.com return ret; 618240Sigor@sysoev.ru } 619240Sigor@sysoev.ru 620240Sigor@sysoev.ru 6211488St.nateldemoura@f5.com static nxt_process_t * 6221488St.nateldemoura@f5.com nxt_main_process_new(nxt_task_t *task, nxt_runtime_t *rt) 623240Sigor@sysoev.ru { 6241488St.nateldemoura@f5.com nxt_process_t *process; 625240Sigor@sysoev.ru 6261488St.nateldemoura@f5.com process = nxt_runtime_process_new(rt); 6271488St.nateldemoura@f5.com if (nxt_slow_path(process == NULL)) { 6281488St.nateldemoura@f5.com return NULL; 629240Sigor@sysoev.ru } 630240Sigor@sysoev.ru 6311488St.nateldemoura@f5.com process->mem_pool = nxt_mp_create(1024, 128, 256, 32); 6321488St.nateldemoura@f5.com if (process->mem_pool == NULL) { 6331488St.nateldemoura@f5.com nxt_process_use(task, process, -1); 6341488St.nateldemoura@f5.com return NULL; 635240Sigor@sysoev.ru } 636240Sigor@sysoev.ru 6371488St.nateldemoura@f5.com return process; 638240Sigor@sysoev.ru } 639240Sigor@sysoev.ru 6401302St.nateldemoura@f5.com 641240Sigor@sysoev.ru static nxt_int_t 6421488St.nateldemoura@f5.com nxt_main_start_process(nxt_task_t *task, nxt_process_t *process) 643240Sigor@sysoev.ru { 6441488St.nateldemoura@f5.com nxt_mp_t *tmp_mp; 6451182St.nateldemoura@f5.com nxt_int_t ret; 6461488St.nateldemoura@f5.com nxt_pid_t pid; 6471488St.nateldemoura@f5.com nxt_port_t *port; 648240Sigor@sysoev.ru nxt_process_init_t *init; 649240Sigor@sysoev.ru 6501488St.nateldemoura@f5.com init = nxt_process_init(process); 651240Sigor@sysoev.ru 652240Sigor@sysoev.ru port = nxt_port_new(task, 0, 0, init->type); 653240Sigor@sysoev.ru if (nxt_slow_path(port == NULL)) { 654240Sigor@sysoev.ru return NXT_ERROR; 655240Sigor@sysoev.ru } 656240Sigor@sysoev.ru 657240Sigor@sysoev.ru nxt_process_port_add(task, process, port); 658240Sigor@sysoev.ru 659240Sigor@sysoev.ru ret = nxt_port_socket_init(task, port, 0); 660240Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) { 6611565St.nateldemoura@f5.com goto free_port; 6621488St.nateldemoura@f5.com } 6631488St.nateldemoura@f5.com 6641488St.nateldemoura@f5.com tmp_mp = nxt_mp_create(1024, 128, 256, 32); 6651565St.nateldemoura@f5.com if (nxt_slow_path(tmp_mp == NULL)) { 6661565St.nateldemoura@f5.com ret = NXT_ERROR; 6671565St.nateldemoura@f5.com 6681565St.nateldemoura@f5.com goto close_port; 6691488St.nateldemoura@f5.com } 6701488St.nateldemoura@f5.com 6711488St.nateldemoura@f5.com if (init->prefork) { 6721488St.nateldemoura@f5.com ret = init->prefork(task, process, tmp_mp); 6731488St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) { 6741565St.nateldemoura@f5.com goto free_mempool; 6751488St.nateldemoura@f5.com } 676240Sigor@sysoev.ru } 677240Sigor@sysoev.ru 678240Sigor@sysoev.ru pid = nxt_process_create(task, process); 679240Sigor@sysoev.ru 680240Sigor@sysoev.ru switch (pid) { 681240Sigor@sysoev.ru 682240Sigor@sysoev.ru case -1: 6831565St.nateldemoura@f5.com ret = NXT_ERROR; 6841488St.nateldemoura@f5.com break; 685240Sigor@sysoev.ru 686240Sigor@sysoev.ru case 0: 6871488St.nateldemoura@f5.com /* The child process: return to the event engine work queue loop. */ 6881180Smax.romanov@nginx.com 6891565St.nateldemoura@f5.com nxt_process_use(task, process, -1); 6901565St.nateldemoura@f5.com 6911488St.nateldemoura@f5.com ret = NXT_AGAIN; 6921488St.nateldemoura@f5.com break; 693240Sigor@sysoev.ru 694240Sigor@sysoev.ru default: 695240Sigor@sysoev.ru /* The main process created a new process. */ 696240Sigor@sysoev.ru 6971565St.nateldemoura@f5.com nxt_process_use(task, process, -1); 6981565St.nateldemoura@f5.com 699240Sigor@sysoev.ru nxt_port_read_close(port); 700240Sigor@sysoev.ru nxt_port_write_enable(task, port); 701240Sigor@sysoev.ru 7021488St.nateldemoura@f5.com ret = NXT_OK; 7031488St.nateldemoura@f5.com break; 704240Sigor@sysoev.ru } 705240Sigor@sysoev.ru 7061565St.nateldemoura@f5.com free_mempool: 7071565St.nateldemoura@f5.com 7081565St.nateldemoura@f5.com nxt_mp_destroy(tmp_mp); 7091565St.nateldemoura@f5.com 7101565St.nateldemoura@f5.com close_port: 7111565St.nateldemoura@f5.com 7121565St.nateldemoura@f5.com if (nxt_slow_path(ret == NXT_ERROR)) { 7131565St.nateldemoura@f5.com nxt_port_close(task, port); 7141565St.nateldemoura@f5.com } 7151565St.nateldemoura@f5.com 7161565St.nateldemoura@f5.com free_port: 717240Sigor@sysoev.ru 7181488St.nateldemoura@f5.com nxt_port_use(task, port, -1); 719240Sigor@sysoev.ru 7201488St.nateldemoura@f5.com return ret; 721240Sigor@sysoev.ru } 722240Sigor@sysoev.ru 723240Sigor@sysoev.ru 724240Sigor@sysoev.ru static void 725240Sigor@sysoev.ru nxt_main_process_sigterm_handler(nxt_task_t *task, void *obj, void *data) 726240Sigor@sysoev.ru { 727240Sigor@sysoev.ru nxt_debug(task, "sigterm handler signo:%d (%s)", 728240Sigor@sysoev.ru (int) (uintptr_t) obj, data); 729240Sigor@sysoev.ru 730240Sigor@sysoev.ru /* TODO: fast exit. */ 731240Sigor@sysoev.ru 732240Sigor@sysoev.ru nxt_exiting = 1; 733240Sigor@sysoev.ru 734697Sigor@sysoev.ru nxt_runtime_quit(task, 0); 735240Sigor@sysoev.ru } 736240Sigor@sysoev.ru 737240Sigor@sysoev.ru 738240Sigor@sysoev.ru static void 739240Sigor@sysoev.ru nxt_main_process_sigquit_handler(nxt_task_t *task, void *obj, void *data) 740240Sigor@sysoev.ru { 741240Sigor@sysoev.ru nxt_debug(task, "sigquit handler signo:%d (%s)", 742240Sigor@sysoev.ru (int) (uintptr_t) obj, data); 743240Sigor@sysoev.ru 744240Sigor@sysoev.ru /* TODO: graceful exit. */ 745240Sigor@sysoev.ru 746240Sigor@sysoev.ru nxt_exiting = 1; 747240Sigor@sysoev.ru 748697Sigor@sysoev.ru nxt_runtime_quit(task, 0); 749240Sigor@sysoev.ru } 750240Sigor@sysoev.ru 751240Sigor@sysoev.ru 752240Sigor@sysoev.ru static void 753240Sigor@sysoev.ru nxt_main_process_sigusr1_handler(nxt_task_t *task, void *obj, void *data) 754240Sigor@sysoev.ru { 755240Sigor@sysoev.ru nxt_mp_t *mp; 756240Sigor@sysoev.ru nxt_int_t ret; 757240Sigor@sysoev.ru nxt_uint_t n; 758631Svbart@nginx.com nxt_port_t *port; 759240Sigor@sysoev.ru nxt_file_t *file, *new_file; 760631Svbart@nginx.com nxt_array_t *new_files; 761240Sigor@sysoev.ru nxt_runtime_t *rt; 762240Sigor@sysoev.ru 763240Sigor@sysoev.ru nxt_log(task, NXT_LOG_NOTICE, "signal %d (%s) recevied, %s", 764240Sigor@sysoev.ru (int) (uintptr_t) obj, data, "log files rotation"); 765240Sigor@sysoev.ru 766631Svbart@nginx.com rt = task->thread->runtime; 767631Svbart@nginx.com 768631Svbart@nginx.com port = rt->port_by_type[NXT_PROCESS_ROUTER]; 769631Svbart@nginx.com 770631Svbart@nginx.com if (nxt_fast_path(port != NULL)) { 771631Svbart@nginx.com (void) nxt_port_socket_write(task, port, NXT_PORT_MSG_ACCESS_LOG, 772631Svbart@nginx.com -1, 0, 0, NULL); 773631Svbart@nginx.com } 774631Svbart@nginx.com 775240Sigor@sysoev.ru mp = nxt_mp_create(1024, 128, 256, 32); 776240Sigor@sysoev.ru if (mp == NULL) { 777240Sigor@sysoev.ru return; 778240Sigor@sysoev.ru } 779240Sigor@sysoev.ru 780240Sigor@sysoev.ru n = nxt_list_nelts(rt->log_files); 781240Sigor@sysoev.ru 782240Sigor@sysoev.ru new_files = nxt_array_create(mp, n, sizeof(nxt_file_t)); 783240Sigor@sysoev.ru if (new_files == NULL) { 784240Sigor@sysoev.ru nxt_mp_destroy(mp); 785240Sigor@sysoev.ru return; 786240Sigor@sysoev.ru } 787240Sigor@sysoev.ru 788240Sigor@sysoev.ru nxt_list_each(file, rt->log_files) { 789240Sigor@sysoev.ru 790240Sigor@sysoev.ru /* This allocation cannot fail. */ 791240Sigor@sysoev.ru new_file = nxt_array_add(new_files); 792240Sigor@sysoev.ru 793240Sigor@sysoev.ru new_file->name = file->name; 794240Sigor@sysoev.ru new_file->fd = NXT_FILE_INVALID; 795564Svbart@nginx.com new_file->log_level = NXT_LOG_ALERT; 796240Sigor@sysoev.ru 797240Sigor@sysoev.ru ret = nxt_file_open(task, new_file, O_WRONLY | O_APPEND, O_CREAT, 798240Sigor@sysoev.ru NXT_FILE_OWNER_ACCESS); 799240Sigor@sysoev.ru 800240Sigor@sysoev.ru if (ret != NXT_OK) { 801240Sigor@sysoev.ru goto fail; 802240Sigor@sysoev.ru } 803240Sigor@sysoev.ru 804240Sigor@sysoev.ru } nxt_list_loop; 805240Sigor@sysoev.ru 806240Sigor@sysoev.ru new_file = new_files->elts; 807240Sigor@sysoev.ru 808240Sigor@sysoev.ru ret = nxt_file_stderr(&new_file[0]); 809240Sigor@sysoev.ru 810240Sigor@sysoev.ru if (ret == NXT_OK) { 811240Sigor@sysoev.ru n = 0; 812240Sigor@sysoev.ru 813240Sigor@sysoev.ru nxt_list_each(file, rt->log_files) { 814240Sigor@sysoev.ru 815240Sigor@sysoev.ru nxt_port_change_log_file(task, rt, n, new_file[n].fd); 816240Sigor@sysoev.ru /* 817240Sigor@sysoev.ru * The old log file descriptor must be closed at the moment 818240Sigor@sysoev.ru * when no other threads use it. dup2() allows to use the 819240Sigor@sysoev.ru * old file descriptor for new log file. This change is 820240Sigor@sysoev.ru * performed atomically in the kernel. 821240Sigor@sysoev.ru */ 822240Sigor@sysoev.ru (void) nxt_file_redirect(file, new_file[n].fd); 823240Sigor@sysoev.ru 824240Sigor@sysoev.ru n++; 825240Sigor@sysoev.ru 826240Sigor@sysoev.ru } nxt_list_loop; 827240Sigor@sysoev.ru 828240Sigor@sysoev.ru nxt_mp_destroy(mp); 829240Sigor@sysoev.ru return; 8301008Szelenkov@nginx.com } 831240Sigor@sysoev.ru 832240Sigor@sysoev.ru fail: 833240Sigor@sysoev.ru 834240Sigor@sysoev.ru new_file = new_files->elts; 835240Sigor@sysoev.ru n = new_files->nelts; 836240Sigor@sysoev.ru 837240Sigor@sysoev.ru while (n != 0) { 838240Sigor@sysoev.ru if (new_file->fd != NXT_FILE_INVALID) { 839240Sigor@sysoev.ru nxt_file_close(task, new_file); 840240Sigor@sysoev.ru } 841240Sigor@sysoev.ru 842240Sigor@sysoev.ru new_file++; 843240Sigor@sysoev.ru n--; 844240Sigor@sysoev.ru } 845240Sigor@sysoev.ru 846240Sigor@sysoev.ru nxt_mp_destroy(mp); 847240Sigor@sysoev.ru } 848240Sigor@sysoev.ru 849240Sigor@sysoev.ru 850240Sigor@sysoev.ru static void 851240Sigor@sysoev.ru nxt_main_process_sigchld_handler(nxt_task_t *task, void *obj, void *data) 852240Sigor@sysoev.ru { 853240Sigor@sysoev.ru int status; 854240Sigor@sysoev.ru nxt_err_t err; 855240Sigor@sysoev.ru nxt_pid_t pid; 856240Sigor@sysoev.ru 857240Sigor@sysoev.ru nxt_debug(task, "sigchld handler signo:%d (%s)", 858240Sigor@sysoev.ru (int) (uintptr_t) obj, data); 859240Sigor@sysoev.ru 860240Sigor@sysoev.ru for ( ;; ) { 861240Sigor@sysoev.ru pid = waitpid(-1, &status, WNOHANG); 862240Sigor@sysoev.ru 863240Sigor@sysoev.ru if (pid == -1) { 864240Sigor@sysoev.ru 865240Sigor@sysoev.ru switch (err = nxt_errno) { 866240Sigor@sysoev.ru 867240Sigor@sysoev.ru case NXT_ECHILD: 868240Sigor@sysoev.ru return; 869240Sigor@sysoev.ru 870240Sigor@sysoev.ru case NXT_EINTR: 871240Sigor@sysoev.ru continue; 872240Sigor@sysoev.ru 873240Sigor@sysoev.ru default: 874564Svbart@nginx.com nxt_alert(task, "waitpid() failed: %E", err); 875240Sigor@sysoev.ru return; 876240Sigor@sysoev.ru } 877240Sigor@sysoev.ru } 878240Sigor@sysoev.ru 879240Sigor@sysoev.ru nxt_debug(task, "waitpid(): %PI", pid); 880240Sigor@sysoev.ru 881240Sigor@sysoev.ru if (pid == 0) { 882240Sigor@sysoev.ru return; 883240Sigor@sysoev.ru } 884240Sigor@sysoev.ru 885240Sigor@sysoev.ru if (WTERMSIG(status)) { 886240Sigor@sysoev.ru #ifdef WCOREDUMP 887564Svbart@nginx.com nxt_alert(task, "process %PI exited on signal %d%s", 888564Svbart@nginx.com pid, WTERMSIG(status), 889564Svbart@nginx.com WCOREDUMP(status) ? " (core dumped)" : ""); 890240Sigor@sysoev.ru #else 891564Svbart@nginx.com nxt_alert(task, "process %PI exited on signal %d", 892564Svbart@nginx.com pid, WTERMSIG(status)); 893240Sigor@sysoev.ru #endif 894240Sigor@sysoev.ru 895240Sigor@sysoev.ru } else { 896240Sigor@sysoev.ru nxt_trace(task, "process %PI exited with code %d", 897240Sigor@sysoev.ru pid, WEXITSTATUS(status)); 898240Sigor@sysoev.ru } 899240Sigor@sysoev.ru 9001488St.nateldemoura@f5.com nxt_main_cleanup_process(task, pid); 901240Sigor@sysoev.ru } 902240Sigor@sysoev.ru } 903240Sigor@sysoev.ru 904240Sigor@sysoev.ru 905240Sigor@sysoev.ru static void 906944Sigor@sysoev.ru nxt_main_process_signal_handler(nxt_task_t *task, void *obj, void *data) 907944Sigor@sysoev.ru { 908944Sigor@sysoev.ru nxt_trace(task, "signal signo:%d (%s) recevied, ignored", 909944Sigor@sysoev.ru (int) (uintptr_t) obj, data); 910944Sigor@sysoev.ru } 911944Sigor@sysoev.ru 912944Sigor@sysoev.ru 913944Sigor@sysoev.ru static void 9141488St.nateldemoura@f5.com nxt_main_cleanup_process(nxt_task_t *task, nxt_pid_t pid) 915240Sigor@sysoev.ru { 9161488St.nateldemoura@f5.com int stream; 9171488St.nateldemoura@f5.com nxt_int_t ret; 9181488St.nateldemoura@f5.com nxt_buf_t *buf; 9191488St.nateldemoura@f5.com nxt_port_t *port; 9201488St.nateldemoura@f5.com const char *name; 9211488St.nateldemoura@f5.com nxt_runtime_t *rt; 9221488St.nateldemoura@f5.com nxt_process_t *process; 9231488St.nateldemoura@f5.com nxt_process_init_t init; 924240Sigor@sysoev.ru 925240Sigor@sysoev.ru rt = task->thread->runtime; 926240Sigor@sysoev.ru 927240Sigor@sysoev.ru process = nxt_runtime_process_find(rt, pid); 9281488St.nateldemoura@f5.com if (!process) { 9291488St.nateldemoura@f5.com return; 9301488St.nateldemoura@f5.com } 931240Sigor@sysoev.ru 9321579St.nateldemoura@f5.com if (process->isolation.cleanup != NULL) { 9331579St.nateldemoura@f5.com process->isolation.cleanup(task, process); 9341489St.nateldemoura@f5.com } 9351489St.nateldemoura@f5.com 9361488St.nateldemoura@f5.com name = process->name; 9371488St.nateldemoura@f5.com stream = process->stream; 9381488St.nateldemoura@f5.com init = *((nxt_process_init_t *) nxt_process_init(process)); 939366Smax.romanov@nginx.com 9401488St.nateldemoura@f5.com if (process->state == NXT_PROCESS_STATE_READY) { 9411488St.nateldemoura@f5.com process->stream = 0; 9421488St.nateldemoura@f5.com } 943240Sigor@sysoev.ru 9441488St.nateldemoura@f5.com nxt_process_close_ports(task, process); 9451302St.nateldemoura@f5.com 9461488St.nateldemoura@f5.com if (nxt_exiting) { 9471488St.nateldemoura@f5.com if (rt->nprocesses <= 1) { 9481488St.nateldemoura@f5.com nxt_runtime_quit(task, 0); 9491211Smax.romanov@nginx.com } 9501211Smax.romanov@nginx.com 9511488St.nateldemoura@f5.com return; 952240Sigor@sysoev.ru } 953754Smax.romanov@nginx.com 954754Smax.romanov@nginx.com nxt_runtime_process_each(rt, process) { 955754Smax.romanov@nginx.com 9561488St.nateldemoura@f5.com if (process->pid == nxt_pid 9571488St.nateldemoura@f5.com || process->pid == pid 9581488St.nateldemoura@f5.com || nxt_queue_is_empty(&process->ports)) 9591488St.nateldemoura@f5.com { 9601488St.nateldemoura@f5.com continue; 9611488St.nateldemoura@f5.com } 9621488St.nateldemoura@f5.com 9631488St.nateldemoura@f5.com port = nxt_process_port_first(process); 964754Smax.romanov@nginx.com 9651488St.nateldemoura@f5.com if (nxt_proc_remove_notify_matrix[init.type][port->type] == 0) { 9661488St.nateldemoura@f5.com continue; 9671488St.nateldemoura@f5.com } 9681488St.nateldemoura@f5.com 9691488St.nateldemoura@f5.com buf = nxt_buf_mem_ts_alloc(task, task->thread->engine->mem_pool, 9701488St.nateldemoura@f5.com sizeof(pid)); 971754Smax.romanov@nginx.com 9721488St.nateldemoura@f5.com if (nxt_slow_path(buf == NULL)) { 9731488St.nateldemoura@f5.com continue; 9741488St.nateldemoura@f5.com } 9751488St.nateldemoura@f5.com 9761488St.nateldemoura@f5.com buf->mem.free = nxt_cpymem(buf->mem.free, &pid, sizeof(pid)); 9771488St.nateldemoura@f5.com 9781488St.nateldemoura@f5.com nxt_port_socket_write(task, port, NXT_PORT_MSG_REMOVE_PID, -1, 9791488St.nateldemoura@f5.com stream, 0, buf); 980754Smax.romanov@nginx.com 981754Smax.romanov@nginx.com } nxt_runtime_process_loop; 9821488St.nateldemoura@f5.com 9831488St.nateldemoura@f5.com if (init.restart) { 9841488St.nateldemoura@f5.com ret = nxt_main_process_create(task, init); 9851488St.nateldemoura@f5.com if (nxt_slow_path(ret == NXT_ERROR)) { 9861488St.nateldemoura@f5.com nxt_alert(task, "failed to restart %s", name); 9871488St.nateldemoura@f5.com } 9881488St.nateldemoura@f5.com } 989754Smax.romanov@nginx.com } 990754Smax.romanov@nginx.com 991754Smax.romanov@nginx.com 992754Smax.romanov@nginx.com static void 993240Sigor@sysoev.ru nxt_main_port_socket_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 994240Sigor@sysoev.ru { 995240Sigor@sysoev.ru size_t size; 996240Sigor@sysoev.ru nxt_int_t ret; 997240Sigor@sysoev.ru nxt_buf_t *b, *out; 998240Sigor@sysoev.ru nxt_port_t *port; 999240Sigor@sysoev.ru nxt_sockaddr_t *sa; 1000240Sigor@sysoev.ru nxt_port_msg_type_t type; 1001240Sigor@sysoev.ru nxt_listening_socket_t ls; 1002240Sigor@sysoev.ru u_char message[2048]; 1003240Sigor@sysoev.ru 1004240Sigor@sysoev.ru b = msg->buf; 1005240Sigor@sysoev.ru sa = (nxt_sockaddr_t *) b->mem.pos; 1006240Sigor@sysoev.ru 1007352Smax.romanov@nginx.com /* TODO check b size and make plain */ 1008352Smax.romanov@nginx.com 1009240Sigor@sysoev.ru out = NULL; 1010240Sigor@sysoev.ru 1011240Sigor@sysoev.ru ls.socket = -1; 1012240Sigor@sysoev.ru ls.error = NXT_SOCKET_ERROR_SYSTEM; 1013240Sigor@sysoev.ru ls.start = message; 1014240Sigor@sysoev.ru ls.end = message + sizeof(message); 1015240Sigor@sysoev.ru 1016240Sigor@sysoev.ru port = nxt_runtime_port_find(task->thread->runtime, msg->port_msg.pid, 1017240Sigor@sysoev.ru msg->port_msg.reply_port); 1018240Sigor@sysoev.ru 1019240Sigor@sysoev.ru nxt_debug(task, "listening socket \"%*s\"", 1020493Spluknet@nginx.com (size_t) sa->length, nxt_sockaddr_start(sa)); 1021240Sigor@sysoev.ru 1022240Sigor@sysoev.ru ret = nxt_main_listening_socket(sa, &ls); 1023240Sigor@sysoev.ru 1024240Sigor@sysoev.ru if (ret == NXT_OK) { 1025240Sigor@sysoev.ru nxt_debug(task, "socket(\"%*s\"): %d", 1026493Spluknet@nginx.com (size_t) sa->length, nxt_sockaddr_start(sa), ls.socket); 1027240Sigor@sysoev.ru 1028240Sigor@sysoev.ru type = NXT_PORT_MSG_RPC_READY_LAST | NXT_PORT_MSG_CLOSE_FD; 1029240Sigor@sysoev.ru 1030240Sigor@sysoev.ru } else { 1031240Sigor@sysoev.ru size = ls.end - ls.start; 1032240Sigor@sysoev.ru 1033564Svbart@nginx.com nxt_alert(task, "%*s", size, ls.start); 1034240Sigor@sysoev.ru 1035342Smax.romanov@nginx.com out = nxt_buf_mem_ts_alloc(task, task->thread->engine->mem_pool, 1036342Smax.romanov@nginx.com size + 1); 1037240Sigor@sysoev.ru if (nxt_slow_path(out == NULL)) { 1038240Sigor@sysoev.ru return; 1039240Sigor@sysoev.ru } 1040240Sigor@sysoev.ru 1041240Sigor@sysoev.ru *out->mem.free++ = (uint8_t) ls.error; 1042240Sigor@sysoev.ru 1043240Sigor@sysoev.ru out->mem.free = nxt_cpymem(out->mem.free, ls.start, size); 1044240Sigor@sysoev.ru 1045240Sigor@sysoev.ru type = NXT_PORT_MSG_RPC_ERROR; 1046240Sigor@sysoev.ru } 1047240Sigor@sysoev.ru 1048240Sigor@sysoev.ru nxt_port_socket_write(task, port, type, ls.socket, msg->port_msg.stream, 1049240Sigor@sysoev.ru 0, out); 1050240Sigor@sysoev.ru } 1051240Sigor@sysoev.ru 1052240Sigor@sysoev.ru 1053240Sigor@sysoev.ru static nxt_int_t 1054240Sigor@sysoev.ru nxt_main_listening_socket(nxt_sockaddr_t *sa, nxt_listening_socket_t *ls) 1055240Sigor@sysoev.ru { 1056240Sigor@sysoev.ru nxt_err_t err; 1057240Sigor@sysoev.ru nxt_socket_t s; 1058240Sigor@sysoev.ru 1059240Sigor@sysoev.ru const socklen_t length = sizeof(int); 1060240Sigor@sysoev.ru static const int enable = 1; 1061240Sigor@sysoev.ru 1062240Sigor@sysoev.ru s = socket(sa->u.sockaddr.sa_family, sa->type, 0); 1063240Sigor@sysoev.ru 1064240Sigor@sysoev.ru if (nxt_slow_path(s == -1)) { 1065240Sigor@sysoev.ru err = nxt_errno; 1066240Sigor@sysoev.ru 1067240Sigor@sysoev.ru #if (NXT_INET6) 1068240Sigor@sysoev.ru 1069240Sigor@sysoev.ru if (err == EAFNOSUPPORT && sa->u.sockaddr.sa_family == AF_INET6) { 1070240Sigor@sysoev.ru ls->error = NXT_SOCKET_ERROR_NOINET6; 1071240Sigor@sysoev.ru } 1072240Sigor@sysoev.ru 1073240Sigor@sysoev.ru #endif 1074240Sigor@sysoev.ru 1075240Sigor@sysoev.ru ls->end = nxt_sprintf(ls->start, ls->end, 1076240Sigor@sysoev.ru "socket(\\\"%*s\\\") failed %E", 1077493Spluknet@nginx.com (size_t) sa->length, nxt_sockaddr_start(sa), err); 1078240Sigor@sysoev.ru 1079240Sigor@sysoev.ru return NXT_ERROR; 1080240Sigor@sysoev.ru } 1081240Sigor@sysoev.ru 1082240Sigor@sysoev.ru if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &enable, length) != 0) { 1083240Sigor@sysoev.ru ls->end = nxt_sprintf(ls->start, ls->end, 1084240Sigor@sysoev.ru "setsockopt(\\\"%*s\\\", SO_REUSEADDR) failed %E", 1085493Spluknet@nginx.com (size_t) sa->length, nxt_sockaddr_start(sa), 1086493Spluknet@nginx.com nxt_errno); 1087240Sigor@sysoev.ru goto fail; 1088240Sigor@sysoev.ru } 1089240Sigor@sysoev.ru 1090240Sigor@sysoev.ru #if (NXT_INET6) 1091240Sigor@sysoev.ru 1092240Sigor@sysoev.ru if (sa->u.sockaddr.sa_family == AF_INET6) { 1093240Sigor@sysoev.ru 1094240Sigor@sysoev.ru if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &enable, length) != 0) { 1095240Sigor@sysoev.ru ls->end = nxt_sprintf(ls->start, ls->end, 1096240Sigor@sysoev.ru "setsockopt(\\\"%*s\\\", IPV6_V6ONLY) failed %E", 1097493Spluknet@nginx.com (size_t) sa->length, nxt_sockaddr_start(sa), 1098493Spluknet@nginx.com nxt_errno); 1099240Sigor@sysoev.ru goto fail; 1100240Sigor@sysoev.ru } 1101240Sigor@sysoev.ru } 1102240Sigor@sysoev.ru 1103240Sigor@sysoev.ru #endif 1104240Sigor@sysoev.ru 1105240Sigor@sysoev.ru if (bind(s, &sa->u.sockaddr, sa->socklen) != 0) { 1106240Sigor@sysoev.ru err = nxt_errno; 1107240Sigor@sysoev.ru 1108240Sigor@sysoev.ru #if (NXT_HAVE_UNIX_DOMAIN) 1109240Sigor@sysoev.ru 1110240Sigor@sysoev.ru if (sa->u.sockaddr.sa_family == AF_UNIX) { 1111240Sigor@sysoev.ru switch (err) { 1112240Sigor@sysoev.ru 1113240Sigor@sysoev.ru case EACCES: 1114240Sigor@sysoev.ru ls->error = NXT_SOCKET_ERROR_ACCESS; 1115240Sigor@sysoev.ru break; 1116240Sigor@sysoev.ru 1117240Sigor@sysoev.ru case ENOENT: 1118240Sigor@sysoev.ru case ENOTDIR: 1119240Sigor@sysoev.ru ls->error = NXT_SOCKET_ERROR_PATH; 1120240Sigor@sysoev.ru break; 1121240Sigor@sysoev.ru } 1122240Sigor@sysoev.ru 1123908Sigor@sysoev.ru } else 1124908Sigor@sysoev.ru #endif 1125908Sigor@sysoev.ru { 1126908Sigor@sysoev.ru switch (err) { 1127240Sigor@sysoev.ru 1128908Sigor@sysoev.ru case EACCES: 1129908Sigor@sysoev.ru ls->error = NXT_SOCKET_ERROR_PORT; 1130908Sigor@sysoev.ru break; 1131240Sigor@sysoev.ru 1132908Sigor@sysoev.ru case EADDRINUSE: 1133908Sigor@sysoev.ru ls->error = NXT_SOCKET_ERROR_INUSE; 1134908Sigor@sysoev.ru break; 1135240Sigor@sysoev.ru 1136908Sigor@sysoev.ru case EADDRNOTAVAIL: 1137908Sigor@sysoev.ru ls->error = NXT_SOCKET_ERROR_NOADDR; 1138908Sigor@sysoev.ru break; 1139908Sigor@sysoev.ru } 1140240Sigor@sysoev.ru } 1141240Sigor@sysoev.ru 1142240Sigor@sysoev.ru ls->end = nxt_sprintf(ls->start, ls->end, "bind(\\\"%*s\\\") failed %E", 1143493Spluknet@nginx.com (size_t) sa->length, nxt_sockaddr_start(sa), err); 1144240Sigor@sysoev.ru goto fail; 1145240Sigor@sysoev.ru } 1146240Sigor@sysoev.ru 1147240Sigor@sysoev.ru #if (NXT_HAVE_UNIX_DOMAIN) 1148240Sigor@sysoev.ru 1149240Sigor@sysoev.ru if (sa->u.sockaddr.sa_family == AF_UNIX) { 1150240Sigor@sysoev.ru char *filename; 1151240Sigor@sysoev.ru mode_t access; 1152240Sigor@sysoev.ru 1153240Sigor@sysoev.ru filename = sa->u.sockaddr_un.sun_path; 1154240Sigor@sysoev.ru access = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); 1155240Sigor@sysoev.ru 1156240Sigor@sysoev.ru if (chmod(filename, access) != 0) { 1157240Sigor@sysoev.ru ls->end = nxt_sprintf(ls->start, ls->end, 1158494Spluknet@nginx.com "chmod(\\\"%s\\\") failed %E", 1159240Sigor@sysoev.ru filename, nxt_errno); 1160240Sigor@sysoev.ru goto fail; 1161240Sigor@sysoev.ru } 1162240Sigor@sysoev.ru } 1163240Sigor@sysoev.ru 1164240Sigor@sysoev.ru #endif 1165240Sigor@sysoev.ru 1166240Sigor@sysoev.ru ls->socket = s; 1167240Sigor@sysoev.ru 1168240Sigor@sysoev.ru return NXT_OK; 1169240Sigor@sysoev.ru 1170240Sigor@sysoev.ru fail: 1171240Sigor@sysoev.ru 1172240Sigor@sysoev.ru (void) close(s); 1173240Sigor@sysoev.ru 1174240Sigor@sysoev.ru return NXT_ERROR; 1175240Sigor@sysoev.ru } 1176240Sigor@sysoev.ru 1177240Sigor@sysoev.ru 1178240Sigor@sysoev.ru static nxt_conf_map_t nxt_app_lang_module_map[] = { 1179240Sigor@sysoev.ru { 1180240Sigor@sysoev.ru nxt_string("type"), 1181356Svbart@nginx.com NXT_CONF_MAP_INT, 1182240Sigor@sysoev.ru offsetof(nxt_app_lang_module_t, type), 1183240Sigor@sysoev.ru }, 1184240Sigor@sysoev.ru 1185240Sigor@sysoev.ru { 1186240Sigor@sysoev.ru nxt_string("version"), 1187354Svbart@nginx.com NXT_CONF_MAP_CSTRZ, 1188240Sigor@sysoev.ru offsetof(nxt_app_lang_module_t, version), 1189240Sigor@sysoev.ru }, 1190240Sigor@sysoev.ru 1191240Sigor@sysoev.ru { 1192240Sigor@sysoev.ru nxt_string("file"), 1193240Sigor@sysoev.ru NXT_CONF_MAP_CSTRZ, 1194240Sigor@sysoev.ru offsetof(nxt_app_lang_module_t, file), 1195240Sigor@sysoev.ru }, 1196240Sigor@sysoev.ru }; 1197240Sigor@sysoev.ru 1198240Sigor@sysoev.ru 11991489St.nateldemoura@f5.com static nxt_conf_map_t nxt_app_lang_mounts_map[] = { 12001489St.nateldemoura@f5.com { 12011489St.nateldemoura@f5.com nxt_string("src"), 12021489St.nateldemoura@f5.com NXT_CONF_MAP_CSTRZ, 12031489St.nateldemoura@f5.com offsetof(nxt_fs_mount_t, src), 12041489St.nateldemoura@f5.com }, 12051489St.nateldemoura@f5.com { 12061489St.nateldemoura@f5.com nxt_string("dst"), 12071489St.nateldemoura@f5.com NXT_CONF_MAP_CSTRZ, 12081489St.nateldemoura@f5.com offsetof(nxt_fs_mount_t, dst), 12091489St.nateldemoura@f5.com }, 12101489St.nateldemoura@f5.com { 12111673St.nateldemoura@f5.com nxt_string("name"), 12121489St.nateldemoura@f5.com NXT_CONF_MAP_CSTRZ, 12131673St.nateldemoura@f5.com offsetof(nxt_fs_mount_t, name), 12141673St.nateldemoura@f5.com }, 12151673St.nateldemoura@f5.com { 12161673St.nateldemoura@f5.com nxt_string("type"), 12171673St.nateldemoura@f5.com NXT_CONF_MAP_INT, 12181673St.nateldemoura@f5.com offsetof(nxt_fs_mount_t, type), 12191489St.nateldemoura@f5.com }, 12201489St.nateldemoura@f5.com { 12211489St.nateldemoura@f5.com nxt_string("flags"), 12221489St.nateldemoura@f5.com NXT_CONF_MAP_INT, 12231489St.nateldemoura@f5.com offsetof(nxt_fs_mount_t, flags), 12241489St.nateldemoura@f5.com }, 12251489St.nateldemoura@f5.com { 12261489St.nateldemoura@f5.com nxt_string("data"), 12271489St.nateldemoura@f5.com NXT_CONF_MAP_CSTRZ, 12281489St.nateldemoura@f5.com offsetof(nxt_fs_mount_t, data), 12291489St.nateldemoura@f5.com }, 12301489St.nateldemoura@f5.com }; 12311489St.nateldemoura@f5.com 12321489St.nateldemoura@f5.com 1233240Sigor@sysoev.ru static void 1234240Sigor@sysoev.ru nxt_main_port_modules_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 1235240Sigor@sysoev.ru { 12361489St.nateldemoura@f5.com uint32_t index, jindex, nmounts; 1237240Sigor@sysoev.ru nxt_mp_t *mp; 1238240Sigor@sysoev.ru nxt_int_t ret; 1239240Sigor@sysoev.ru nxt_buf_t *b; 1240549Svbart@nginx.com nxt_port_t *port; 1241240Sigor@sysoev.ru nxt_runtime_t *rt; 12421489St.nateldemoura@f5.com nxt_fs_mount_t *mnt; 12431489St.nateldemoura@f5.com nxt_conf_value_t *conf, *root, *value, *mounts; 1244240Sigor@sysoev.ru nxt_app_lang_module_t *lang; 1245240Sigor@sysoev.ru 12461182St.nateldemoura@f5.com static nxt_str_t root_path = nxt_string("/"); 12471489St.nateldemoura@f5.com static nxt_str_t mounts_name = nxt_string("mounts"); 1248240Sigor@sysoev.ru 1249240Sigor@sysoev.ru rt = task->thread->runtime; 1250240Sigor@sysoev.ru 1251240Sigor@sysoev.ru if (msg->port_msg.pid != rt->port_by_type[NXT_PROCESS_DISCOVERY]->pid) { 1252240Sigor@sysoev.ru return; 1253240Sigor@sysoev.ru } 1254240Sigor@sysoev.ru 12551211Smax.romanov@nginx.com if (nxt_exiting) { 12561211Smax.romanov@nginx.com nxt_debug(task, "ignoring discovered modules, exiting"); 12571211Smax.romanov@nginx.com return; 12581211Smax.romanov@nginx.com } 12591211Smax.romanov@nginx.com 1260549Svbart@nginx.com port = nxt_runtime_port_find(task->thread->runtime, msg->port_msg.pid, 1261549Svbart@nginx.com msg->port_msg.reply_port); 1262549Svbart@nginx.com 1263549Svbart@nginx.com if (nxt_fast_path(port != NULL)) { 1264549Svbart@nginx.com (void) nxt_port_socket_write(task, port, NXT_PORT_MSG_RPC_ERROR, -1, 1265549Svbart@nginx.com msg->port_msg.stream, 0, NULL); 1266549Svbart@nginx.com } 1267549Svbart@nginx.com 1268240Sigor@sysoev.ru b = msg->buf; 1269240Sigor@sysoev.ru 1270240Sigor@sysoev.ru if (b == NULL) { 1271240Sigor@sysoev.ru return; 1272240Sigor@sysoev.ru } 1273240Sigor@sysoev.ru 1274240Sigor@sysoev.ru mp = nxt_mp_create(1024, 128, 256, 32); 1275240Sigor@sysoev.ru if (mp == NULL) { 1276240Sigor@sysoev.ru return; 1277240Sigor@sysoev.ru } 1278240Sigor@sysoev.ru 1279352Smax.romanov@nginx.com b = nxt_buf_chk_make_plain(mp, b, msg->size); 1280352Smax.romanov@nginx.com 1281352Smax.romanov@nginx.com if (b == NULL) { 1282352Smax.romanov@nginx.com return; 1283352Smax.romanov@nginx.com } 1284352Smax.romanov@nginx.com 1285352Smax.romanov@nginx.com nxt_debug(task, "application languages: \"%*s\"", 1286352Smax.romanov@nginx.com b->mem.free - b->mem.pos, b->mem.pos); 1287352Smax.romanov@nginx.com 1288240Sigor@sysoev.ru conf = nxt_conf_json_parse(mp, b->mem.pos, b->mem.free, NULL); 1289240Sigor@sysoev.ru if (conf == NULL) { 1290240Sigor@sysoev.ru goto fail; 1291240Sigor@sysoev.ru } 1292240Sigor@sysoev.ru 1293240Sigor@sysoev.ru root = nxt_conf_get_path(conf, &root_path); 1294240Sigor@sysoev.ru if (root == NULL) { 1295240Sigor@sysoev.ru goto fail; 1296240Sigor@sysoev.ru } 1297240Sigor@sysoev.ru 1298240Sigor@sysoev.ru for (index = 0; /* void */ ; index++) { 1299240Sigor@sysoev.ru value = nxt_conf_get_array_element(root, index); 1300240Sigor@sysoev.ru if (value == NULL) { 1301240Sigor@sysoev.ru break; 1302240Sigor@sysoev.ru } 1303240Sigor@sysoev.ru 13041489St.nateldemoura@f5.com lang = nxt_array_zero_add(rt->languages); 1305240Sigor@sysoev.ru if (lang == NULL) { 1306240Sigor@sysoev.ru goto fail; 1307240Sigor@sysoev.ru } 1308240Sigor@sysoev.ru 1309240Sigor@sysoev.ru lang->module = NULL; 1310240Sigor@sysoev.ru 1311240Sigor@sysoev.ru ret = nxt_conf_map_object(rt->mem_pool, value, nxt_app_lang_module_map, 1312240Sigor@sysoev.ru nxt_nitems(nxt_app_lang_module_map), lang); 1313240Sigor@sysoev.ru 1314240Sigor@sysoev.ru if (ret != NXT_OK) { 1315240Sigor@sysoev.ru goto fail; 1316240Sigor@sysoev.ru } 1317240Sigor@sysoev.ru 13181489St.nateldemoura@f5.com mounts = nxt_conf_get_object_member(value, &mounts_name, NULL); 13191489St.nateldemoura@f5.com if (mounts == NULL) { 13201489St.nateldemoura@f5.com nxt_alert(task, "missing mounts from discovery message."); 13211489St.nateldemoura@f5.com goto fail; 13221489St.nateldemoura@f5.com } 13231489St.nateldemoura@f5.com 13241489St.nateldemoura@f5.com if (nxt_conf_type(mounts) != NXT_CONF_ARRAY) { 13251489St.nateldemoura@f5.com nxt_alert(task, "invalid mounts type from discovery message."); 13261489St.nateldemoura@f5.com goto fail; 13271489St.nateldemoura@f5.com } 13281489St.nateldemoura@f5.com 13291489St.nateldemoura@f5.com nmounts = nxt_conf_array_elements_count(mounts); 13301489St.nateldemoura@f5.com 13311489St.nateldemoura@f5.com lang->mounts = nxt_array_create(rt->mem_pool, nmounts, 13321489St.nateldemoura@f5.com sizeof(nxt_fs_mount_t)); 13331489St.nateldemoura@f5.com 13341489St.nateldemoura@f5.com if (lang->mounts == NULL) { 13351489St.nateldemoura@f5.com goto fail; 13361489St.nateldemoura@f5.com } 13371489St.nateldemoura@f5.com 13381489St.nateldemoura@f5.com for (jindex = 0; /* */; jindex++) { 13391489St.nateldemoura@f5.com value = nxt_conf_get_array_element(mounts, jindex); 13401489St.nateldemoura@f5.com if (value == NULL) { 13411489St.nateldemoura@f5.com break; 13421489St.nateldemoura@f5.com } 13431489St.nateldemoura@f5.com 13441489St.nateldemoura@f5.com mnt = nxt_array_zero_add(lang->mounts); 13451489St.nateldemoura@f5.com if (mnt == NULL) { 13461489St.nateldemoura@f5.com goto fail; 13471489St.nateldemoura@f5.com } 13481489St.nateldemoura@f5.com 13491585St.nateldemoura@f5.com mnt->builtin = 1; 13501673St.nateldemoura@f5.com mnt->deps = 1; 13511585St.nateldemoura@f5.com 13521489St.nateldemoura@f5.com ret = nxt_conf_map_object(rt->mem_pool, value, 13531489St.nateldemoura@f5.com nxt_app_lang_mounts_map, 13541489St.nateldemoura@f5.com nxt_nitems(nxt_app_lang_mounts_map), mnt); 13551489St.nateldemoura@f5.com 13561489St.nateldemoura@f5.com if (ret != NXT_OK) { 13571489St.nateldemoura@f5.com goto fail; 13581489St.nateldemoura@f5.com } 13591489St.nateldemoura@f5.com } 13601489St.nateldemoura@f5.com 13611489St.nateldemoura@f5.com nxt_debug(task, "lang %d %s \"%s\" (%d mounts)", 13621489St.nateldemoura@f5.com lang->type, lang->version, lang->file, lang->mounts->nelts); 1363240Sigor@sysoev.ru } 1364240Sigor@sysoev.ru 1365240Sigor@sysoev.ru qsort(rt->languages->elts, rt->languages->nelts, 1366240Sigor@sysoev.ru sizeof(nxt_app_lang_module_t), nxt_app_lang_compare); 1367240Sigor@sysoev.ru 1368240Sigor@sysoev.ru fail: 1369240Sigor@sysoev.ru 1370240Sigor@sysoev.ru nxt_mp_destroy(mp); 1371240Sigor@sysoev.ru 13721488St.nateldemoura@f5.com ret = nxt_main_process_create(task, nxt_controller_process); 13731488St.nateldemoura@f5.com if (ret == NXT_OK) { 13741488St.nateldemoura@f5.com ret = nxt_main_process_create(task, nxt_router_process); 13751488St.nateldemoura@f5.com } 1376240Sigor@sysoev.ru 13771488St.nateldemoura@f5.com if (nxt_slow_path(ret == NXT_ERROR)) { 13781488St.nateldemoura@f5.com nxt_exiting = 1; 13791488St.nateldemoura@f5.com 13801488St.nateldemoura@f5.com nxt_runtime_quit(task, 1); 1381240Sigor@sysoev.ru } 1382240Sigor@sysoev.ru } 1383240Sigor@sysoev.ru 1384240Sigor@sysoev.ru 1385240Sigor@sysoev.ru static int nxt_cdecl 1386240Sigor@sysoev.ru nxt_app_lang_compare(const void *v1, const void *v2) 1387240Sigor@sysoev.ru { 1388240Sigor@sysoev.ru int n; 1389240Sigor@sysoev.ru const nxt_app_lang_module_t *lang1, *lang2; 1390240Sigor@sysoev.ru 1391240Sigor@sysoev.ru lang1 = v1; 1392240Sigor@sysoev.ru lang2 = v2; 1393240Sigor@sysoev.ru 1394356Svbart@nginx.com n = lang1->type - lang2->type; 1395258Sigor@sysoev.ru 1396258Sigor@sysoev.ru if (n != 0) { 1397258Sigor@sysoev.ru return n; 1398258Sigor@sysoev.ru } 1399258Sigor@sysoev.ru 1400354Svbart@nginx.com n = nxt_strverscmp(lang1->version, lang2->version); 1401240Sigor@sysoev.ru 1402240Sigor@sysoev.ru /* Negate result to move higher versions to the beginning. */ 1403240Sigor@sysoev.ru 1404240Sigor@sysoev.ru return -n; 1405240Sigor@sysoev.ru } 1406314Svbart@nginx.com 1407314Svbart@nginx.com 1408314Svbart@nginx.com static void 1409314Svbart@nginx.com nxt_main_port_conf_store_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 1410314Svbart@nginx.com { 1411352Smax.romanov@nginx.com ssize_t n, size, offset; 1412314Svbart@nginx.com nxt_buf_t *b; 1413314Svbart@nginx.com nxt_int_t ret; 1414314Svbart@nginx.com nxt_file_t file; 1415314Svbart@nginx.com nxt_runtime_t *rt; 1416314Svbart@nginx.com 1417314Svbart@nginx.com nxt_memzero(&file, sizeof(nxt_file_t)); 1418314Svbart@nginx.com 1419314Svbart@nginx.com rt = task->thread->runtime; 1420314Svbart@nginx.com 1421314Svbart@nginx.com file.name = (nxt_file_name_t *) rt->conf_tmp; 1422314Svbart@nginx.com 1423314Svbart@nginx.com if (nxt_slow_path(nxt_file_open(task, &file, NXT_FILE_WRONLY, 1424314Svbart@nginx.com NXT_FILE_TRUNCATE, NXT_FILE_OWNER_ACCESS) 1425314Svbart@nginx.com != NXT_OK)) 1426314Svbart@nginx.com { 1427314Svbart@nginx.com goto error; 1428314Svbart@nginx.com } 1429314Svbart@nginx.com 1430352Smax.romanov@nginx.com offset = 0; 1431352Smax.romanov@nginx.com 1432314Svbart@nginx.com for (b = msg->buf; b != NULL; b = b->next) { 1433314Svbart@nginx.com size = nxt_buf_mem_used_size(&b->mem); 1434314Svbart@nginx.com 1435352Smax.romanov@nginx.com n = nxt_file_write(&file, b->mem.pos, size, offset); 1436314Svbart@nginx.com 1437314Svbart@nginx.com if (nxt_slow_path(n != size)) { 1438314Svbart@nginx.com nxt_file_close(task, &file); 1439314Svbart@nginx.com (void) nxt_file_delete(file.name); 1440314Svbart@nginx.com goto error; 1441314Svbart@nginx.com } 1442352Smax.romanov@nginx.com 1443352Smax.romanov@nginx.com offset += n; 1444314Svbart@nginx.com } 1445314Svbart@nginx.com 1446314Svbart@nginx.com nxt_file_close(task, &file); 1447314Svbart@nginx.com 1448314Svbart@nginx.com ret = nxt_file_rename(file.name, (nxt_file_name_t *) rt->conf); 1449314Svbart@nginx.com 1450314Svbart@nginx.com if (nxt_fast_path(ret == NXT_OK)) { 1451314Svbart@nginx.com return; 1452314Svbart@nginx.com } 1453314Svbart@nginx.com 1454314Svbart@nginx.com error: 1455314Svbart@nginx.com 1456564Svbart@nginx.com nxt_alert(task, "failed to store current configuration"); 1457314Svbart@nginx.com } 1458630Svbart@nginx.com 1459630Svbart@nginx.com 1460630Svbart@nginx.com static void 1461630Svbart@nginx.com nxt_main_port_access_log_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 1462630Svbart@nginx.com { 1463630Svbart@nginx.com u_char *path; 1464630Svbart@nginx.com nxt_int_t ret; 1465630Svbart@nginx.com nxt_file_t file; 1466630Svbart@nginx.com nxt_port_t *port; 1467630Svbart@nginx.com nxt_port_msg_type_t type; 1468630Svbart@nginx.com 1469630Svbart@nginx.com nxt_debug(task, "opening access log file"); 1470630Svbart@nginx.com 1471630Svbart@nginx.com path = msg->buf->mem.pos; 1472630Svbart@nginx.com 1473630Svbart@nginx.com nxt_memzero(&file, sizeof(nxt_file_t)); 1474630Svbart@nginx.com 1475630Svbart@nginx.com file.name = (nxt_file_name_t *) path; 1476630Svbart@nginx.com file.log_level = NXT_LOG_ERR; 1477630Svbart@nginx.com 1478630Svbart@nginx.com ret = nxt_file_open(task, &file, O_WRONLY | O_APPEND, O_CREAT, 1479630Svbart@nginx.com NXT_FILE_OWNER_ACCESS); 1480630Svbart@nginx.com 1481630Svbart@nginx.com type = (ret == NXT_OK) ? NXT_PORT_MSG_RPC_READY_LAST | NXT_PORT_MSG_CLOSE_FD 1482630Svbart@nginx.com : NXT_PORT_MSG_RPC_ERROR; 1483630Svbart@nginx.com 1484630Svbart@nginx.com port = nxt_runtime_port_find(task->thread->runtime, msg->port_msg.pid, 1485630Svbart@nginx.com msg->port_msg.reply_port); 1486630Svbart@nginx.com 1487630Svbart@nginx.com if (nxt_fast_path(port != NULL)) { 1488630Svbart@nginx.com (void) nxt_port_socket_write(task, port, type, file.fd, 1489630Svbart@nginx.com msg->port_msg.stream, 0, NULL); 1490630Svbart@nginx.com } 1491630Svbart@nginx.com } 1492