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 34240Sigor@sysoev.ru static nxt_int_t nxt_main_process_port_create(nxt_task_t *task, 35240Sigor@sysoev.ru nxt_runtime_t *rt); 36240Sigor@sysoev.ru static void nxt_main_process_title(nxt_task_t *task); 371488St.nateldemoura@f5.com static nxt_int_t nxt_main_process_create(nxt_task_t *task, 381488St.nateldemoura@f5.com const nxt_process_init_t init); 391488St.nateldemoura@f5.com static nxt_int_t nxt_main_start_process(nxt_task_t *task, 401488St.nateldemoura@f5.com nxt_process_t *process); 411488St.nateldemoura@f5.com static nxt_process_t *nxt_main_process_new(nxt_task_t *task, nxt_runtime_t *rt); 42240Sigor@sysoev.ru static void nxt_main_process_sigterm_handler(nxt_task_t *task, void *obj, 43240Sigor@sysoev.ru void *data); 44240Sigor@sysoev.ru static void nxt_main_process_sigquit_handler(nxt_task_t *task, void *obj, 45240Sigor@sysoev.ru void *data); 46240Sigor@sysoev.ru static void nxt_main_process_sigusr1_handler(nxt_task_t *task, void *obj, 47240Sigor@sysoev.ru void *data); 48240Sigor@sysoev.ru static void nxt_main_process_sigchld_handler(nxt_task_t *task, void *obj, 49240Sigor@sysoev.ru void *data); 50944Sigor@sysoev.ru static void nxt_main_process_signal_handler(nxt_task_t *task, void *obj, 51944Sigor@sysoev.ru void *data); 521488St.nateldemoura@f5.com static void nxt_main_cleanup_process(nxt_task_t *task, nxt_pid_t pid); 53240Sigor@sysoev.ru static void nxt_main_port_socket_handler(nxt_task_t *task, 54240Sigor@sysoev.ru nxt_port_recv_msg_t *msg); 55240Sigor@sysoev.ru static nxt_int_t nxt_main_listening_socket(nxt_sockaddr_t *sa, 56240Sigor@sysoev.ru nxt_listening_socket_t *ls); 57240Sigor@sysoev.ru static void nxt_main_port_modules_handler(nxt_task_t *task, 58240Sigor@sysoev.ru nxt_port_recv_msg_t *msg); 59240Sigor@sysoev.ru static int nxt_cdecl nxt_app_lang_compare(const void *v1, const void *v2); 60314Svbart@nginx.com static void nxt_main_port_conf_store_handler(nxt_task_t *task, 61314Svbart@nginx.com nxt_port_recv_msg_t *msg); 621969Sz.hong@f5.com static nxt_int_t nxt_main_file_store(nxt_task_t *task, const char *tmp_name, 631969Sz.hong@f5.com const char *name, u_char *buf, size_t size); 64630Svbart@nginx.com static void nxt_main_port_access_log_handler(nxt_task_t *task, 65630Svbart@nginx.com nxt_port_recv_msg_t *msg); 66240Sigor@sysoev.ru 67240Sigor@sysoev.ru const nxt_sig_event_t nxt_main_process_signals[] = { 68944Sigor@sysoev.ru nxt_event_signal(SIGHUP, nxt_main_process_signal_handler), 69240Sigor@sysoev.ru nxt_event_signal(SIGINT, nxt_main_process_sigterm_handler), 70240Sigor@sysoev.ru nxt_event_signal(SIGQUIT, nxt_main_process_sigquit_handler), 71240Sigor@sysoev.ru nxt_event_signal(SIGTERM, nxt_main_process_sigterm_handler), 72240Sigor@sysoev.ru nxt_event_signal(SIGCHLD, nxt_main_process_sigchld_handler), 73240Sigor@sysoev.ru nxt_event_signal(SIGUSR1, nxt_main_process_sigusr1_handler), 74240Sigor@sysoev.ru nxt_event_signal_end, 75240Sigor@sysoev.ru }; 76240Sigor@sysoev.ru 77240Sigor@sysoev.ru 781969Sz.hong@f5.com nxt_uint_t nxt_conf_ver; 791969Sz.hong@f5.com 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 1571980Smax.romanov@nginx.com { 1581980Smax.romanov@nginx.com nxt_string("requests"), 1591980Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 1601980Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, request_limit), 1611980Smax.romanov@nginx.com }, 1621980Smax.romanov@nginx.com 163510Salexander.borisov@nginx.com }; 164271Smax.romanov@nginx.com 165510Salexander.borisov@nginx.com 166804Svbart@nginx.com static nxt_conf_map_t nxt_external_app_conf[] = { 167804Svbart@nginx.com { 168804Svbart@nginx.com nxt_string("executable"), 169804Svbart@nginx.com NXT_CONF_MAP_CSTRZ, 170804Svbart@nginx.com offsetof(nxt_common_app_conf_t, u.external.executable), 171804Svbart@nginx.com }, 172804Svbart@nginx.com 173804Svbart@nginx.com { 174804Svbart@nginx.com nxt_string("arguments"), 175804Svbart@nginx.com NXT_CONF_MAP_PTR, 176804Svbart@nginx.com offsetof(nxt_common_app_conf_t, u.external.arguments), 177804Svbart@nginx.com }, 178804Svbart@nginx.com 179804Svbart@nginx.com }; 180804Svbart@nginx.com 181804Svbart@nginx.com 182546Smax.romanov@nginx.com static nxt_conf_map_t nxt_python_app_conf[] = { 183271Smax.romanov@nginx.com { 184394Smax.romanov@nginx.com nxt_string("home"), 185394Smax.romanov@nginx.com NXT_CONF_MAP_CSTRZ, 186394Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.python.home), 187394Smax.romanov@nginx.com }, 188394Smax.romanov@nginx.com 189394Smax.romanov@nginx.com { 190240Sigor@sysoev.ru nxt_string("path"), 1911759Svbart@nginx.com NXT_CONF_MAP_PTR, 192240Sigor@sysoev.ru offsetof(nxt_common_app_conf_t, u.python.path), 193240Sigor@sysoev.ru }, 194240Sigor@sysoev.ru 195240Sigor@sysoev.ru { 196240Sigor@sysoev.ru nxt_string("module"), 197240Sigor@sysoev.ru NXT_CONF_MAP_STR, 198240Sigor@sysoev.ru offsetof(nxt_common_app_conf_t, u.python.module), 199240Sigor@sysoev.ru }, 2001601Smax.romanov@nginx.com 2011601Smax.romanov@nginx.com { 2021601Smax.romanov@nginx.com nxt_string("callable"), 2031601Smax.romanov@nginx.com NXT_CONF_MAP_CSTRZ, 2041601Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.python.callable), 2051601Smax.romanov@nginx.com }, 2061681Smax.romanov@nginx.com 2071681Smax.romanov@nginx.com { 2081697Smax.romanov@nginx.com nxt_string("protocol"), 2091697Smax.romanov@nginx.com NXT_CONF_MAP_STR, 2101697Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.python.protocol), 2111697Smax.romanov@nginx.com }, 2121697Smax.romanov@nginx.com 2131697Smax.romanov@nginx.com { 2141681Smax.romanov@nginx.com nxt_string("threads"), 2151681Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 2161681Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.python.threads), 2171681Smax.romanov@nginx.com }, 2181681Smax.romanov@nginx.com 2191681Smax.romanov@nginx.com { 2201872So.canty@f5.com nxt_string("targets"), 2211872So.canty@f5.com NXT_CONF_MAP_PTR, 2221872So.canty@f5.com offsetof(nxt_common_app_conf_t, u.python.targets), 2231872So.canty@f5.com }, 2241872So.canty@f5.com 2251872So.canty@f5.com { 2261681Smax.romanov@nginx.com nxt_string("thread_stack_size"), 2271681Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 2281681Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.python.thread_stack_size), 2291681Smax.romanov@nginx.com }, 230510Salexander.borisov@nginx.com }; 231240Sigor@sysoev.ru 232510Salexander.borisov@nginx.com 233546Smax.romanov@nginx.com static nxt_conf_map_t nxt_php_app_conf[] = { 234240Sigor@sysoev.ru { 2351473Svbart@nginx.com nxt_string("targets"), 2361473Svbart@nginx.com NXT_CONF_MAP_PTR, 2371473Svbart@nginx.com offsetof(nxt_common_app_conf_t, u.php.targets), 238240Sigor@sysoev.ru }, 239687Svbart@nginx.com 240687Svbart@nginx.com { 241687Svbart@nginx.com nxt_string("options"), 242687Svbart@nginx.com NXT_CONF_MAP_PTR, 243687Svbart@nginx.com offsetof(nxt_common_app_conf_t, u.php.options), 244687Svbart@nginx.com }, 245510Salexander.borisov@nginx.com }; 246240Sigor@sysoev.ru 247510Salexander.borisov@nginx.com 248546Smax.romanov@nginx.com static nxt_conf_map_t nxt_perl_app_conf[] = { 249510Salexander.borisov@nginx.com { 250510Salexander.borisov@nginx.com nxt_string("script"), 251510Salexander.borisov@nginx.com NXT_CONF_MAP_CSTRZ, 252510Salexander.borisov@nginx.com offsetof(nxt_common_app_conf_t, u.perl.script), 253510Salexander.borisov@nginx.com }, 2541689Smax.romanov@nginx.com 2551689Smax.romanov@nginx.com { 2561689Smax.romanov@nginx.com nxt_string("threads"), 2571689Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 2581689Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.perl.threads), 2591689Smax.romanov@nginx.com }, 2601689Smax.romanov@nginx.com 2611689Smax.romanov@nginx.com { 2621689Smax.romanov@nginx.com nxt_string("thread_stack_size"), 2631689Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 2641689Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.perl.thread_stack_size), 2651689Smax.romanov@nginx.com }, 266510Salexander.borisov@nginx.com }; 267510Salexander.borisov@nginx.com 268510Salexander.borisov@nginx.com 269584Salexander.borisov@nginx.com static nxt_conf_map_t nxt_ruby_app_conf[] = { 270584Salexander.borisov@nginx.com { 271584Salexander.borisov@nginx.com nxt_string("script"), 272584Salexander.borisov@nginx.com NXT_CONF_MAP_STR, 273584Salexander.borisov@nginx.com offsetof(nxt_common_app_conf_t, u.ruby.script), 274584Salexander.borisov@nginx.com }, 2751687Smax.romanov@nginx.com { 2761687Smax.romanov@nginx.com nxt_string("threads"), 2771687Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 2781687Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.ruby.threads), 2791687Smax.romanov@nginx.com }, 2801910So.canty@f5.com { 2811910So.canty@f5.com nxt_string("hooks"), 2821910So.canty@f5.com NXT_CONF_MAP_STR, 2831910So.canty@f5.com offsetof(nxt_common_app_conf_t, u.ruby.hooks), 2841910So.canty@f5.com } 285584Salexander.borisov@nginx.com }; 286584Salexander.borisov@nginx.com 287584Salexander.borisov@nginx.com 288977Smax.romanov@gmail.com static nxt_conf_map_t nxt_java_app_conf[] = { 289977Smax.romanov@gmail.com { 290977Smax.romanov@gmail.com nxt_string("classpath"), 291977Smax.romanov@gmail.com NXT_CONF_MAP_PTR, 292977Smax.romanov@gmail.com offsetof(nxt_common_app_conf_t, u.java.classpath), 293977Smax.romanov@gmail.com }, 294977Smax.romanov@gmail.com { 295977Smax.romanov@gmail.com nxt_string("webapp"), 296977Smax.romanov@gmail.com NXT_CONF_MAP_CSTRZ, 297977Smax.romanov@gmail.com offsetof(nxt_common_app_conf_t, u.java.webapp), 298977Smax.romanov@gmail.com }, 299977Smax.romanov@gmail.com { 300977Smax.romanov@gmail.com nxt_string("options"), 301977Smax.romanov@gmail.com NXT_CONF_MAP_PTR, 302977Smax.romanov@gmail.com offsetof(nxt_common_app_conf_t, u.java.options), 303977Smax.romanov@gmail.com }, 304977Smax.romanov@gmail.com { 305977Smax.romanov@gmail.com nxt_string("unit_jars"), 306977Smax.romanov@gmail.com NXT_CONF_MAP_CSTRZ, 307977Smax.romanov@gmail.com offsetof(nxt_common_app_conf_t, u.java.unit_jars), 308977Smax.romanov@gmail.com }, 3091684Smax.romanov@nginx.com { 3101684Smax.romanov@nginx.com nxt_string("threads"), 3111684Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 3121684Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.java.threads), 3131684Smax.romanov@nginx.com }, 3141684Smax.romanov@nginx.com { 3151684Smax.romanov@nginx.com nxt_string("thread_stack_size"), 3161684Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 3171684Smax.romanov@nginx.com offsetof(nxt_common_app_conf_t, u.java.thread_stack_size), 3181684Smax.romanov@nginx.com }, 319977Smax.romanov@gmail.com 320977Smax.romanov@gmail.com }; 321977Smax.romanov@gmail.com 322977Smax.romanov@gmail.com 323546Smax.romanov@nginx.com static nxt_conf_app_map_t nxt_app_maps[] = { 324804Svbart@nginx.com { nxt_nitems(nxt_external_app_conf), nxt_external_app_conf }, 325804Svbart@nginx.com { nxt_nitems(nxt_python_app_conf), nxt_python_app_conf }, 326804Svbart@nginx.com { nxt_nitems(nxt_php_app_conf), nxt_php_app_conf }, 327804Svbart@nginx.com { nxt_nitems(nxt_perl_app_conf), nxt_perl_app_conf }, 328804Svbart@nginx.com { nxt_nitems(nxt_ruby_app_conf), nxt_ruby_app_conf }, 329977Smax.romanov@gmail.com { nxt_nitems(nxt_java_app_conf), nxt_java_app_conf }, 330510Salexander.borisov@nginx.com }; 331510Salexander.borisov@nginx.com 332510Salexander.borisov@nginx.com 333240Sigor@sysoev.ru static void 334240Sigor@sysoev.ru nxt_port_main_data_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 335240Sigor@sysoev.ru { 336240Sigor@sysoev.ru nxt_debug(task, "main data: %*s", 337240Sigor@sysoev.ru nxt_buf_mem_used_size(&msg->buf->mem), msg->buf->mem.pos); 338240Sigor@sysoev.ru } 339240Sigor@sysoev.ru 340240Sigor@sysoev.ru 341240Sigor@sysoev.ru static void 3421488St.nateldemoura@f5.com nxt_port_main_start_process_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 343240Sigor@sysoev.ru { 3441488St.nateldemoura@f5.com u_char *start, *p, ch; 345536Svbart@nginx.com size_t type_len; 346536Svbart@nginx.com nxt_int_t ret; 347240Sigor@sysoev.ru nxt_buf_t *b; 348318Smax.romanov@nginx.com nxt_port_t *port; 3491182St.nateldemoura@f5.com nxt_runtime_t *rt; 3501488St.nateldemoura@f5.com nxt_process_t *process; 351536Svbart@nginx.com nxt_app_type_t idx; 352240Sigor@sysoev.ru nxt_conf_value_t *conf; 3531488St.nateldemoura@f5.com nxt_process_init_t *init; 3541488St.nateldemoura@f5.com nxt_common_app_conf_t *app_conf; 355240Sigor@sysoev.ru 3561488St.nateldemoura@f5.com rt = task->thread->runtime; 357352Smax.romanov@nginx.com 358*1996St.nateldemoura@f5.com port = rt->port_by_type[NXT_PROCESS_ROUTER]; 359*1996St.nateldemoura@f5.com if (nxt_slow_path(port == NULL)) { 360*1996St.nateldemoura@f5.com nxt_alert(task, "router port not found"); 361*1996St.nateldemoura@f5.com return; 362*1996St.nateldemoura@f5.com } 363*1996St.nateldemoura@f5.com 364*1996St.nateldemoura@f5.com if (nxt_slow_path(port->pid != nxt_recv_msg_cmsg_pid(msg))) { 365*1996St.nateldemoura@f5.com nxt_alert(task, "process %PI cannot start processes", 366*1996St.nateldemoura@f5.com nxt_recv_msg_cmsg_pid(msg)); 367*1996St.nateldemoura@f5.com 368*1996St.nateldemoura@f5.com return; 369*1996St.nateldemoura@f5.com } 370*1996St.nateldemoura@f5.com 3711488St.nateldemoura@f5.com process = nxt_main_process_new(task, rt); 3721488St.nateldemoura@f5.com if (nxt_slow_path(process == NULL)) { 373352Smax.romanov@nginx.com return; 374352Smax.romanov@nginx.com } 375352Smax.romanov@nginx.com 3761488St.nateldemoura@f5.com init = nxt_process_init(process); 3771488St.nateldemoura@f5.com 3781488St.nateldemoura@f5.com *init = nxt_app_process; 379352Smax.romanov@nginx.com 3801488St.nateldemoura@f5.com b = nxt_buf_chk_make_plain(process->mem_pool, msg->buf, msg->size); 381352Smax.romanov@nginx.com if (b == NULL) { 3821488St.nateldemoura@f5.com goto failed; 383352Smax.romanov@nginx.com } 384240Sigor@sysoev.ru 3851488St.nateldemoura@f5.com nxt_debug(task, "main start process: %*s", b->mem.free - b->mem.pos, 386240Sigor@sysoev.ru b->mem.pos); 387240Sigor@sysoev.ru 3881488St.nateldemoura@f5.com app_conf = nxt_mp_zalloc(process->mem_pool, sizeof(nxt_common_app_conf_t)); 3891488St.nateldemoura@f5.com if (nxt_slow_path(app_conf == NULL)) { 3901488St.nateldemoura@f5.com goto failed; 3911488St.nateldemoura@f5.com } 392240Sigor@sysoev.ru 393240Sigor@sysoev.ru start = b->mem.pos; 394240Sigor@sysoev.ru 3951488St.nateldemoura@f5.com app_conf->name.start = start; 3961488St.nateldemoura@f5.com app_conf->name.length = nxt_strlen(start); 3971488St.nateldemoura@f5.com 3981488St.nateldemoura@f5.com init->name = (const char *) start; 3991488St.nateldemoura@f5.com 4001488St.nateldemoura@f5.com process->name = nxt_mp_alloc(process->mem_pool, app_conf->name.length 4011488St.nateldemoura@f5.com + sizeof("\"\" application") + 1); 4021488St.nateldemoura@f5.com 4031488St.nateldemoura@f5.com if (nxt_slow_path(process->name == NULL)) { 4041488St.nateldemoura@f5.com goto failed; 4051488St.nateldemoura@f5.com } 406240Sigor@sysoev.ru 4071488St.nateldemoura@f5.com p = (u_char *) process->name; 4081488St.nateldemoura@f5.com *p++ = '"'; 4091488St.nateldemoura@f5.com p = nxt_cpymem(p, init->name, app_conf->name.length); 4101488St.nateldemoura@f5.com p = nxt_cpymem(p, "\" application", 13); 4111488St.nateldemoura@f5.com *p = '\0'; 412240Sigor@sysoev.ru 4131488St.nateldemoura@f5.com app_conf->shm_limit = 100 * 1024 * 1024; 4141980Smax.romanov@nginx.com app_conf->request_limit = 0; 415240Sigor@sysoev.ru 4161488St.nateldemoura@f5.com start += app_conf->name.length + 1; 4171488St.nateldemoura@f5.com 4181488St.nateldemoura@f5.com conf = nxt_conf_json_parse(process->mem_pool, start, b->mem.free, NULL); 419240Sigor@sysoev.ru if (conf == NULL) { 420564Svbart@nginx.com nxt_alert(task, "router app configuration parsing error"); 421318Smax.romanov@nginx.com 422318Smax.romanov@nginx.com goto failed; 423240Sigor@sysoev.ru } 424240Sigor@sysoev.ru 4251182St.nateldemoura@f5.com rt = task->thread->runtime; 4261182St.nateldemoura@f5.com 4271488St.nateldemoura@f5.com app_conf->user.start = (u_char*)rt->user_cred.user; 4281488St.nateldemoura@f5.com app_conf->user.length = nxt_strlen(rt->user_cred.user); 429240Sigor@sysoev.ru 4301488St.nateldemoura@f5.com ret = nxt_conf_map_object(process->mem_pool, conf, nxt_common_app_conf, 4311488St.nateldemoura@f5.com nxt_nitems(nxt_common_app_conf), app_conf); 4321488St.nateldemoura@f5.com 433240Sigor@sysoev.ru if (ret != NXT_OK) { 434564Svbart@nginx.com nxt_alert(task, "failed to map common app conf received from router"); 435318Smax.romanov@nginx.com goto failed; 436240Sigor@sysoev.ru } 437240Sigor@sysoev.ru 4381488St.nateldemoura@f5.com for (type_len = 0; type_len != app_conf->type.length; type_len++) { 4391488St.nateldemoura@f5.com ch = app_conf->type.start[type_len]; 440536Svbart@nginx.com 441536Svbart@nginx.com if (ch == ' ' || nxt_isdigit(ch)) { 442536Svbart@nginx.com break; 443536Svbart@nginx.com } 444536Svbart@nginx.com } 445536Svbart@nginx.com 4461488St.nateldemoura@f5.com idx = nxt_app_parse_type(app_conf->type.start, type_len); 447510Salexander.borisov@nginx.com 448546Smax.romanov@nginx.com if (nxt_slow_path(idx >= nxt_nitems(nxt_app_maps))) { 449564Svbart@nginx.com nxt_alert(task, "invalid app type %d received from router", (int) idx); 450546Smax.romanov@nginx.com goto failed; 451546Smax.romanov@nginx.com } 452510Salexander.borisov@nginx.com 4531488St.nateldemoura@f5.com ret = nxt_conf_map_object(process->mem_pool, conf, nxt_app_maps[idx].map, 4541488St.nateldemoura@f5.com nxt_app_maps[idx].size, app_conf); 455510Salexander.borisov@nginx.com 456546Smax.romanov@nginx.com if (nxt_slow_path(ret != NXT_OK)) { 457564Svbart@nginx.com nxt_alert(task, "failed to map app conf received from router"); 458546Smax.romanov@nginx.com goto failed; 459546Smax.romanov@nginx.com } 460510Salexander.borisov@nginx.com 4611488St.nateldemoura@f5.com if (app_conf->limits != NULL) { 4621488St.nateldemoura@f5.com ret = nxt_conf_map_object(process->mem_pool, app_conf->limits, 4631320Smax.romanov@nginx.com nxt_common_app_limits_conf, 4641320Smax.romanov@nginx.com nxt_nitems(nxt_common_app_limits_conf), 4651488St.nateldemoura@f5.com app_conf); 4661320Smax.romanov@nginx.com 4671320Smax.romanov@nginx.com if (nxt_slow_path(ret != NXT_OK)) { 4681320Smax.romanov@nginx.com nxt_alert(task, "failed to map app limits received from router"); 4691320Smax.romanov@nginx.com goto failed; 4701320Smax.romanov@nginx.com } 4711320Smax.romanov@nginx.com } 4721320Smax.romanov@nginx.com 4731488St.nateldemoura@f5.com app_conf->self = conf; 4741488St.nateldemoura@f5.com 4751488St.nateldemoura@f5.com process->stream = msg->port_msg.stream; 4761488St.nateldemoura@f5.com process->data.app = app_conf; 4771473Svbart@nginx.com 4781488St.nateldemoura@f5.com ret = nxt_main_start_process(task, process); 4791488St.nateldemoura@f5.com if (nxt_fast_path(ret == NXT_OK || ret == NXT_AGAIN)) { 4801488St.nateldemoura@f5.com return; 4811488St.nateldemoura@f5.com } 482240Sigor@sysoev.ru 483318Smax.romanov@nginx.com failed: 484318Smax.romanov@nginx.com 4851488St.nateldemoura@f5.com nxt_process_use(task, process, -1); 4861488St.nateldemoura@f5.com 4871488St.nateldemoura@f5.com port = nxt_runtime_port_find(rt, msg->port_msg.pid, 4881488St.nateldemoura@f5.com msg->port_msg.reply_port); 4891488St.nateldemoura@f5.com 4901488St.nateldemoura@f5.com if (nxt_fast_path(port != NULL)) { 4911488St.nateldemoura@f5.com nxt_port_socket_write(task, port, NXT_PORT_MSG_RPC_ERROR, 4921488St.nateldemoura@f5.com -1, msg->port_msg.stream, 0, NULL); 4931488St.nateldemoura@f5.com } 4941488St.nateldemoura@f5.com } 4951488St.nateldemoura@f5.com 4961488St.nateldemoura@f5.com 4971488St.nateldemoura@f5.com static void 4981488St.nateldemoura@f5.com nxt_main_process_created_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 4991488St.nateldemoura@f5.com { 5001488St.nateldemoura@f5.com nxt_port_t *port; 5011488St.nateldemoura@f5.com nxt_process_t *process; 5021488St.nateldemoura@f5.com nxt_runtime_t *rt; 5031488St.nateldemoura@f5.com 5041488St.nateldemoura@f5.com rt = task->thread->runtime; 5051488St.nateldemoura@f5.com 5061488St.nateldemoura@f5.com process = nxt_runtime_process_find(rt, msg->port_msg.pid); 5071488St.nateldemoura@f5.com if (nxt_slow_path(process == NULL)) { 5081488St.nateldemoura@f5.com return; 509318Smax.romanov@nginx.com } 510318Smax.romanov@nginx.com 5111488St.nateldemoura@f5.com nxt_assert(process->state == NXT_PROCESS_STATE_CREATING); 5121488St.nateldemoura@f5.com 5131488St.nateldemoura@f5.com port = nxt_runtime_port_find(rt, msg->port_msg.pid, 5141488St.nateldemoura@f5.com msg->port_msg.reply_port); 5151488St.nateldemoura@f5.com 5161488St.nateldemoura@f5.com 5171488St.nateldemoura@f5.com if (nxt_slow_path(port == NULL)) { 5181488St.nateldemoura@f5.com return; 5191488St.nateldemoura@f5.com } 5201488St.nateldemoura@f5.com 5211488St.nateldemoura@f5.com #if (NXT_HAVE_CLONE && NXT_HAVE_CLONE_NEWUSER) 5221488St.nateldemoura@f5.com if (nxt_is_clone_flag_set(process->isolation.clone.flags, NEWUSER)) { 5231488St.nateldemoura@f5.com if (nxt_slow_path(nxt_clone_credential_map(task, process->pid, 5241488St.nateldemoura@f5.com process->user_cred, 5251488St.nateldemoura@f5.com &process->isolation.clone) 5261488St.nateldemoura@f5.com != NXT_OK)) 5271488St.nateldemoura@f5.com { 5281488St.nateldemoura@f5.com (void) nxt_port_socket_write(task, port, NXT_PORT_MSG_RPC_ERROR, 5291488St.nateldemoura@f5.com -1, msg->port_msg.stream, 0, NULL); 5301488St.nateldemoura@f5.com return; 5311488St.nateldemoura@f5.com } 5321488St.nateldemoura@f5.com } 5331488St.nateldemoura@f5.com 5341488St.nateldemoura@f5.com #endif 5351488St.nateldemoura@f5.com 5361488St.nateldemoura@f5.com process->state = NXT_PROCESS_STATE_CREATED; 5371488St.nateldemoura@f5.com 5381488St.nateldemoura@f5.com (void) nxt_port_socket_write(task, port, NXT_PORT_MSG_RPC_READY_LAST, 5391488St.nateldemoura@f5.com -1, msg->port_msg.stream, 0, NULL); 540240Sigor@sysoev.ru } 541240Sigor@sysoev.ru 542240Sigor@sysoev.ru 543320Smax.romanov@nginx.com static nxt_port_handlers_t nxt_main_process_port_handlers = { 5441488St.nateldemoura@f5.com .data = nxt_port_main_data_handler, 5451488St.nateldemoura@f5.com .process_created = nxt_main_process_created_handler, 5461488St.nateldemoura@f5.com .process_ready = nxt_port_process_ready_handler, 5471488St.nateldemoura@f5.com .start_process = nxt_port_main_start_process_handler, 5481488St.nateldemoura@f5.com .socket = nxt_main_port_socket_handler, 5491488St.nateldemoura@f5.com .modules = nxt_main_port_modules_handler, 5501488St.nateldemoura@f5.com .conf_store = nxt_main_port_conf_store_handler, 551774Svbart@nginx.com #if (NXT_TLS) 5521488St.nateldemoura@f5.com .cert_get = nxt_cert_store_get_handler, 5531488St.nateldemoura@f5.com .cert_delete = nxt_cert_store_delete_handler, 554774Svbart@nginx.com #endif 5551488St.nateldemoura@f5.com .access_log = nxt_main_port_access_log_handler, 5561488St.nateldemoura@f5.com .rpc_ready = nxt_port_rpc_handler, 5571488St.nateldemoura@f5.com .rpc_error = nxt_port_rpc_handler, 558240Sigor@sysoev.ru }; 559240Sigor@sysoev.ru 560240Sigor@sysoev.ru 561240Sigor@sysoev.ru static nxt_int_t 562240Sigor@sysoev.ru nxt_main_process_port_create(nxt_task_t *task, nxt_runtime_t *rt) 563240Sigor@sysoev.ru { 564240Sigor@sysoev.ru nxt_int_t ret; 565240Sigor@sysoev.ru nxt_port_t *port; 566240Sigor@sysoev.ru nxt_process_t *process; 567240Sigor@sysoev.ru 5681254Shongzhidao@gmail.com port = nxt_runtime_process_port_create(task, rt, nxt_pid, 0, 5691254Shongzhidao@gmail.com NXT_PROCESS_MAIN); 570240Sigor@sysoev.ru if (nxt_slow_path(port == NULL)) { 571240Sigor@sysoev.ru return NXT_ERROR; 572240Sigor@sysoev.ru } 573240Sigor@sysoev.ru 5741254Shongzhidao@gmail.com process = port->process; 575349Smax.romanov@nginx.com 576240Sigor@sysoev.ru ret = nxt_port_socket_init(task, port, 0); 577240Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) { 5781488St.nateldemoura@f5.com nxt_port_use(task, port, -1); 579240Sigor@sysoev.ru return ret; 580240Sigor@sysoev.ru } 581240Sigor@sysoev.ru 582240Sigor@sysoev.ru /* 583240Sigor@sysoev.ru * A main process port. A write port is not closed 5841488St.nateldemoura@f5.com * since it should be inherited by processes. 585240Sigor@sysoev.ru */ 586320Smax.romanov@nginx.com nxt_port_enable(task, port, &nxt_main_process_port_handlers); 587240Sigor@sysoev.ru 5881488St.nateldemoura@f5.com process->state = NXT_PROCESS_STATE_READY; 589240Sigor@sysoev.ru 590240Sigor@sysoev.ru return NXT_OK; 591240Sigor@sysoev.ru } 592240Sigor@sysoev.ru 593240Sigor@sysoev.ru 594240Sigor@sysoev.ru static void 595240Sigor@sysoev.ru nxt_main_process_title(nxt_task_t *task) 596240Sigor@sysoev.ru { 597240Sigor@sysoev.ru u_char *p, *end; 598240Sigor@sysoev.ru nxt_uint_t i; 599240Sigor@sysoev.ru u_char title[2048]; 600240Sigor@sysoev.ru 601240Sigor@sysoev.ru end = title + sizeof(title) - 1; 602240Sigor@sysoev.ru 603680Sigor@sysoev.ru p = nxt_sprintf(title, end, "unit: main v" NXT_VERSION " [%s", 604680Sigor@sysoev.ru nxt_process_argv[0]); 605240Sigor@sysoev.ru 606240Sigor@sysoev.ru for (i = 1; nxt_process_argv[i] != NULL; i++) { 607240Sigor@sysoev.ru p = nxt_sprintf(p, end, " %s", nxt_process_argv[i]); 608240Sigor@sysoev.ru } 609240Sigor@sysoev.ru 610240Sigor@sysoev.ru if (p < end) { 611240Sigor@sysoev.ru *p++ = ']'; 612240Sigor@sysoev.ru } 613240Sigor@sysoev.ru 614240Sigor@sysoev.ru *p = '\0'; 615240Sigor@sysoev.ru 616240Sigor@sysoev.ru nxt_process_title(task, "%s", title); 617240Sigor@sysoev.ru } 618240Sigor@sysoev.ru 619240Sigor@sysoev.ru 620240Sigor@sysoev.ru static nxt_int_t 6211488St.nateldemoura@f5.com nxt_main_process_create(nxt_task_t *task, const nxt_process_init_t init) 622240Sigor@sysoev.ru { 6231488St.nateldemoura@f5.com nxt_int_t ret; 6241488St.nateldemoura@f5.com nxt_runtime_t *rt; 6251488St.nateldemoura@f5.com nxt_process_t *process; 6261488St.nateldemoura@f5.com nxt_process_init_t *pinit; 627240Sigor@sysoev.ru 6281488St.nateldemoura@f5.com rt = task->thread->runtime; 6291302St.nateldemoura@f5.com 6301488St.nateldemoura@f5.com process = nxt_main_process_new(task, rt); 6311488St.nateldemoura@f5.com if (nxt_slow_path(process == NULL)) { 632368Svbart@nginx.com return NXT_ERROR; 633368Svbart@nginx.com } 634368Svbart@nginx.com 6351488St.nateldemoura@f5.com process->name = init.name; 6361488St.nateldemoura@f5.com process->user_cred = &rt->user_cred; 637314Svbart@nginx.com 6381488St.nateldemoura@f5.com pinit = nxt_process_init(process); 6391488St.nateldemoura@f5.com *pinit = init; 640314Svbart@nginx.com 6411488St.nateldemoura@f5.com ret = nxt_main_start_process(task, process); 6421488St.nateldemoura@f5.com if (nxt_slow_path(ret == NXT_ERROR)) { 6431488St.nateldemoura@f5.com nxt_process_use(task, process, -1); 644314Svbart@nginx.com } 645314Svbart@nginx.com 646314Svbart@nginx.com return ret; 647240Sigor@sysoev.ru } 648240Sigor@sysoev.ru 649240Sigor@sysoev.ru 6501488St.nateldemoura@f5.com static nxt_process_t * 6511488St.nateldemoura@f5.com nxt_main_process_new(nxt_task_t *task, nxt_runtime_t *rt) 652240Sigor@sysoev.ru { 6531488St.nateldemoura@f5.com nxt_process_t *process; 654240Sigor@sysoev.ru 6551488St.nateldemoura@f5.com process = nxt_runtime_process_new(rt); 6561488St.nateldemoura@f5.com if (nxt_slow_path(process == NULL)) { 6571488St.nateldemoura@f5.com return NULL; 658240Sigor@sysoev.ru } 659240Sigor@sysoev.ru 6601488St.nateldemoura@f5.com process->mem_pool = nxt_mp_create(1024, 128, 256, 32); 6611488St.nateldemoura@f5.com if (process->mem_pool == NULL) { 6621488St.nateldemoura@f5.com nxt_process_use(task, process, -1); 6631488St.nateldemoura@f5.com return NULL; 664240Sigor@sysoev.ru } 665240Sigor@sysoev.ru 6661488St.nateldemoura@f5.com return process; 667240Sigor@sysoev.ru } 668240Sigor@sysoev.ru 6691302St.nateldemoura@f5.com 670240Sigor@sysoev.ru static nxt_int_t 6711488St.nateldemoura@f5.com nxt_main_start_process(nxt_task_t *task, nxt_process_t *process) 672240Sigor@sysoev.ru { 6731488St.nateldemoura@f5.com nxt_mp_t *tmp_mp; 6741182St.nateldemoura@f5.com nxt_int_t ret; 6751488St.nateldemoura@f5.com nxt_pid_t pid; 6761488St.nateldemoura@f5.com nxt_port_t *port; 677240Sigor@sysoev.ru nxt_process_init_t *init; 678240Sigor@sysoev.ru 6791488St.nateldemoura@f5.com init = nxt_process_init(process); 680240Sigor@sysoev.ru 681240Sigor@sysoev.ru port = nxt_port_new(task, 0, 0, init->type); 682240Sigor@sysoev.ru if (nxt_slow_path(port == NULL)) { 683240Sigor@sysoev.ru return NXT_ERROR; 684240Sigor@sysoev.ru } 685240Sigor@sysoev.ru 686240Sigor@sysoev.ru nxt_process_port_add(task, process, port); 687240Sigor@sysoev.ru 688240Sigor@sysoev.ru ret = nxt_port_socket_init(task, port, 0); 689240Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) { 6901565St.nateldemoura@f5.com goto free_port; 6911488St.nateldemoura@f5.com } 6921488St.nateldemoura@f5.com 6931488St.nateldemoura@f5.com tmp_mp = nxt_mp_create(1024, 128, 256, 32); 6941565St.nateldemoura@f5.com if (nxt_slow_path(tmp_mp == NULL)) { 6951565St.nateldemoura@f5.com ret = NXT_ERROR; 6961565St.nateldemoura@f5.com 6971565St.nateldemoura@f5.com goto close_port; 6981488St.nateldemoura@f5.com } 6991488St.nateldemoura@f5.com 7001488St.nateldemoura@f5.com if (init->prefork) { 7011488St.nateldemoura@f5.com ret = init->prefork(task, process, tmp_mp); 7021488St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) { 7031565St.nateldemoura@f5.com goto free_mempool; 7041488St.nateldemoura@f5.com } 705240Sigor@sysoev.ru } 706240Sigor@sysoev.ru 707240Sigor@sysoev.ru pid = nxt_process_create(task, process); 708240Sigor@sysoev.ru 709240Sigor@sysoev.ru switch (pid) { 710240Sigor@sysoev.ru 711240Sigor@sysoev.ru case -1: 7121565St.nateldemoura@f5.com ret = NXT_ERROR; 7131488St.nateldemoura@f5.com break; 714240Sigor@sysoev.ru 715240Sigor@sysoev.ru case 0: 7161488St.nateldemoura@f5.com /* The child process: return to the event engine work queue loop. */ 7171180Smax.romanov@nginx.com 7181565St.nateldemoura@f5.com nxt_process_use(task, process, -1); 7191565St.nateldemoura@f5.com 7201488St.nateldemoura@f5.com ret = NXT_AGAIN; 7211488St.nateldemoura@f5.com break; 722240Sigor@sysoev.ru 723240Sigor@sysoev.ru default: 724240Sigor@sysoev.ru /* The main process created a new process. */ 725240Sigor@sysoev.ru 7261565St.nateldemoura@f5.com nxt_process_use(task, process, -1); 7271565St.nateldemoura@f5.com 728240Sigor@sysoev.ru nxt_port_read_close(port); 729240Sigor@sysoev.ru nxt_port_write_enable(task, port); 730240Sigor@sysoev.ru 7311488St.nateldemoura@f5.com ret = NXT_OK; 7321488St.nateldemoura@f5.com break; 733240Sigor@sysoev.ru } 734240Sigor@sysoev.ru 7351565St.nateldemoura@f5.com free_mempool: 7361565St.nateldemoura@f5.com 7371565St.nateldemoura@f5.com nxt_mp_destroy(tmp_mp); 7381565St.nateldemoura@f5.com 7391565St.nateldemoura@f5.com close_port: 7401565St.nateldemoura@f5.com 7411565St.nateldemoura@f5.com if (nxt_slow_path(ret == NXT_ERROR)) { 7421565St.nateldemoura@f5.com nxt_port_close(task, port); 7431565St.nateldemoura@f5.com } 7441565St.nateldemoura@f5.com 7451565St.nateldemoura@f5.com free_port: 746240Sigor@sysoev.ru 7471488St.nateldemoura@f5.com nxt_port_use(task, port, -1); 748240Sigor@sysoev.ru 7491488St.nateldemoura@f5.com return ret; 750240Sigor@sysoev.ru } 751240Sigor@sysoev.ru 752240Sigor@sysoev.ru 753240Sigor@sysoev.ru static void 754240Sigor@sysoev.ru nxt_main_process_sigterm_handler(nxt_task_t *task, void *obj, void *data) 755240Sigor@sysoev.ru { 756240Sigor@sysoev.ru nxt_debug(task, "sigterm handler signo:%d (%s)", 757240Sigor@sysoev.ru (int) (uintptr_t) obj, data); 758240Sigor@sysoev.ru 759240Sigor@sysoev.ru /* TODO: fast exit. */ 760240Sigor@sysoev.ru 761240Sigor@sysoev.ru nxt_exiting = 1; 762240Sigor@sysoev.ru 763697Sigor@sysoev.ru nxt_runtime_quit(task, 0); 764240Sigor@sysoev.ru } 765240Sigor@sysoev.ru 766240Sigor@sysoev.ru 767240Sigor@sysoev.ru static void 768240Sigor@sysoev.ru nxt_main_process_sigquit_handler(nxt_task_t *task, void *obj, void *data) 769240Sigor@sysoev.ru { 770240Sigor@sysoev.ru nxt_debug(task, "sigquit handler signo:%d (%s)", 771240Sigor@sysoev.ru (int) (uintptr_t) obj, data); 772240Sigor@sysoev.ru 773240Sigor@sysoev.ru /* TODO: graceful exit. */ 774240Sigor@sysoev.ru 775240Sigor@sysoev.ru nxt_exiting = 1; 776240Sigor@sysoev.ru 777697Sigor@sysoev.ru nxt_runtime_quit(task, 0); 778240Sigor@sysoev.ru } 779240Sigor@sysoev.ru 780240Sigor@sysoev.ru 781240Sigor@sysoev.ru static void 782240Sigor@sysoev.ru nxt_main_process_sigusr1_handler(nxt_task_t *task, void *obj, void *data) 783240Sigor@sysoev.ru { 784240Sigor@sysoev.ru nxt_mp_t *mp; 785240Sigor@sysoev.ru nxt_int_t ret; 786240Sigor@sysoev.ru nxt_uint_t n; 787631Svbart@nginx.com nxt_port_t *port; 788240Sigor@sysoev.ru nxt_file_t *file, *new_file; 789631Svbart@nginx.com nxt_array_t *new_files; 790240Sigor@sysoev.ru nxt_runtime_t *rt; 791240Sigor@sysoev.ru 792240Sigor@sysoev.ru nxt_log(task, NXT_LOG_NOTICE, "signal %d (%s) recevied, %s", 793240Sigor@sysoev.ru (int) (uintptr_t) obj, data, "log files rotation"); 794240Sigor@sysoev.ru 795631Svbart@nginx.com rt = task->thread->runtime; 796631Svbart@nginx.com 797631Svbart@nginx.com port = rt->port_by_type[NXT_PROCESS_ROUTER]; 798631Svbart@nginx.com 799631Svbart@nginx.com if (nxt_fast_path(port != NULL)) { 800631Svbart@nginx.com (void) nxt_port_socket_write(task, port, NXT_PORT_MSG_ACCESS_LOG, 801631Svbart@nginx.com -1, 0, 0, NULL); 802631Svbart@nginx.com } 803631Svbart@nginx.com 804240Sigor@sysoev.ru mp = nxt_mp_create(1024, 128, 256, 32); 805240Sigor@sysoev.ru if (mp == NULL) { 806240Sigor@sysoev.ru return; 807240Sigor@sysoev.ru } 808240Sigor@sysoev.ru 809240Sigor@sysoev.ru n = nxt_list_nelts(rt->log_files); 810240Sigor@sysoev.ru 811240Sigor@sysoev.ru new_files = nxt_array_create(mp, n, sizeof(nxt_file_t)); 812240Sigor@sysoev.ru if (new_files == NULL) { 813240Sigor@sysoev.ru nxt_mp_destroy(mp); 814240Sigor@sysoev.ru return; 815240Sigor@sysoev.ru } 816240Sigor@sysoev.ru 817240Sigor@sysoev.ru nxt_list_each(file, rt->log_files) { 818240Sigor@sysoev.ru 819240Sigor@sysoev.ru /* This allocation cannot fail. */ 820240Sigor@sysoev.ru new_file = nxt_array_add(new_files); 821240Sigor@sysoev.ru 822240Sigor@sysoev.ru new_file->name = file->name; 823240Sigor@sysoev.ru new_file->fd = NXT_FILE_INVALID; 824564Svbart@nginx.com new_file->log_level = NXT_LOG_ALERT; 825240Sigor@sysoev.ru 826240Sigor@sysoev.ru ret = nxt_file_open(task, new_file, O_WRONLY | O_APPEND, O_CREAT, 827240Sigor@sysoev.ru NXT_FILE_OWNER_ACCESS); 828240Sigor@sysoev.ru 829240Sigor@sysoev.ru if (ret != NXT_OK) { 830240Sigor@sysoev.ru goto fail; 831240Sigor@sysoev.ru } 832240Sigor@sysoev.ru 833240Sigor@sysoev.ru } nxt_list_loop; 834240Sigor@sysoev.ru 835240Sigor@sysoev.ru new_file = new_files->elts; 836240Sigor@sysoev.ru 837240Sigor@sysoev.ru ret = nxt_file_stderr(&new_file[0]); 838240Sigor@sysoev.ru 839240Sigor@sysoev.ru if (ret == NXT_OK) { 840240Sigor@sysoev.ru n = 0; 841240Sigor@sysoev.ru 842240Sigor@sysoev.ru nxt_list_each(file, rt->log_files) { 843240Sigor@sysoev.ru 844240Sigor@sysoev.ru nxt_port_change_log_file(task, rt, n, new_file[n].fd); 845240Sigor@sysoev.ru /* 846240Sigor@sysoev.ru * The old log file descriptor must be closed at the moment 847240Sigor@sysoev.ru * when no other threads use it. dup2() allows to use the 848240Sigor@sysoev.ru * old file descriptor for new log file. This change is 849240Sigor@sysoev.ru * performed atomically in the kernel. 850240Sigor@sysoev.ru */ 851240Sigor@sysoev.ru (void) nxt_file_redirect(file, new_file[n].fd); 852240Sigor@sysoev.ru 853240Sigor@sysoev.ru n++; 854240Sigor@sysoev.ru 855240Sigor@sysoev.ru } nxt_list_loop; 856240Sigor@sysoev.ru 857240Sigor@sysoev.ru nxt_mp_destroy(mp); 858240Sigor@sysoev.ru return; 8591008Szelenkov@nginx.com } 860240Sigor@sysoev.ru 861240Sigor@sysoev.ru fail: 862240Sigor@sysoev.ru 863240Sigor@sysoev.ru new_file = new_files->elts; 864240Sigor@sysoev.ru n = new_files->nelts; 865240Sigor@sysoev.ru 866240Sigor@sysoev.ru while (n != 0) { 867240Sigor@sysoev.ru if (new_file->fd != NXT_FILE_INVALID) { 868240Sigor@sysoev.ru nxt_file_close(task, new_file); 869240Sigor@sysoev.ru } 870240Sigor@sysoev.ru 871240Sigor@sysoev.ru new_file++; 872240Sigor@sysoev.ru n--; 873240Sigor@sysoev.ru } 874240Sigor@sysoev.ru 875240Sigor@sysoev.ru nxt_mp_destroy(mp); 876240Sigor@sysoev.ru } 877240Sigor@sysoev.ru 878240Sigor@sysoev.ru 879240Sigor@sysoev.ru static void 880240Sigor@sysoev.ru nxt_main_process_sigchld_handler(nxt_task_t *task, void *obj, void *data) 881240Sigor@sysoev.ru { 882240Sigor@sysoev.ru int status; 883240Sigor@sysoev.ru nxt_err_t err; 884240Sigor@sysoev.ru nxt_pid_t pid; 885240Sigor@sysoev.ru 886240Sigor@sysoev.ru nxt_debug(task, "sigchld handler signo:%d (%s)", 887240Sigor@sysoev.ru (int) (uintptr_t) obj, data); 888240Sigor@sysoev.ru 889240Sigor@sysoev.ru for ( ;; ) { 890240Sigor@sysoev.ru pid = waitpid(-1, &status, WNOHANG); 891240Sigor@sysoev.ru 892240Sigor@sysoev.ru if (pid == -1) { 893240Sigor@sysoev.ru 894240Sigor@sysoev.ru switch (err = nxt_errno) { 895240Sigor@sysoev.ru 896240Sigor@sysoev.ru case NXT_ECHILD: 897240Sigor@sysoev.ru return; 898240Sigor@sysoev.ru 899240Sigor@sysoev.ru case NXT_EINTR: 900240Sigor@sysoev.ru continue; 901240Sigor@sysoev.ru 902240Sigor@sysoev.ru default: 903564Svbart@nginx.com nxt_alert(task, "waitpid() failed: %E", err); 904240Sigor@sysoev.ru return; 905240Sigor@sysoev.ru } 906240Sigor@sysoev.ru } 907240Sigor@sysoev.ru 908240Sigor@sysoev.ru nxt_debug(task, "waitpid(): %PI", pid); 909240Sigor@sysoev.ru 910240Sigor@sysoev.ru if (pid == 0) { 911240Sigor@sysoev.ru return; 912240Sigor@sysoev.ru } 913240Sigor@sysoev.ru 914240Sigor@sysoev.ru if (WTERMSIG(status)) { 915240Sigor@sysoev.ru #ifdef WCOREDUMP 916564Svbart@nginx.com nxt_alert(task, "process %PI exited on signal %d%s", 917564Svbart@nginx.com pid, WTERMSIG(status), 918564Svbart@nginx.com WCOREDUMP(status) ? " (core dumped)" : ""); 919240Sigor@sysoev.ru #else 920564Svbart@nginx.com nxt_alert(task, "process %PI exited on signal %d", 921564Svbart@nginx.com pid, WTERMSIG(status)); 922240Sigor@sysoev.ru #endif 923240Sigor@sysoev.ru 924240Sigor@sysoev.ru } else { 925240Sigor@sysoev.ru nxt_trace(task, "process %PI exited with code %d", 926240Sigor@sysoev.ru pid, WEXITSTATUS(status)); 927240Sigor@sysoev.ru } 928240Sigor@sysoev.ru 9291488St.nateldemoura@f5.com nxt_main_cleanup_process(task, pid); 930240Sigor@sysoev.ru } 931240Sigor@sysoev.ru } 932240Sigor@sysoev.ru 933240Sigor@sysoev.ru 934240Sigor@sysoev.ru static void 935944Sigor@sysoev.ru nxt_main_process_signal_handler(nxt_task_t *task, void *obj, void *data) 936944Sigor@sysoev.ru { 937944Sigor@sysoev.ru nxt_trace(task, "signal signo:%d (%s) recevied, ignored", 938944Sigor@sysoev.ru (int) (uintptr_t) obj, data); 939944Sigor@sysoev.ru } 940944Sigor@sysoev.ru 941944Sigor@sysoev.ru 942944Sigor@sysoev.ru static void 9431488St.nateldemoura@f5.com nxt_main_cleanup_process(nxt_task_t *task, nxt_pid_t pid) 944240Sigor@sysoev.ru { 9451488St.nateldemoura@f5.com int stream; 9461488St.nateldemoura@f5.com nxt_int_t ret; 9471488St.nateldemoura@f5.com nxt_buf_t *buf; 9481488St.nateldemoura@f5.com nxt_port_t *port; 9491488St.nateldemoura@f5.com const char *name; 9501488St.nateldemoura@f5.com nxt_runtime_t *rt; 9511488St.nateldemoura@f5.com nxt_process_t *process; 9521488St.nateldemoura@f5.com nxt_process_init_t init; 953240Sigor@sysoev.ru 954240Sigor@sysoev.ru rt = task->thread->runtime; 955240Sigor@sysoev.ru 956240Sigor@sysoev.ru process = nxt_runtime_process_find(rt, pid); 9571488St.nateldemoura@f5.com if (!process) { 9581488St.nateldemoura@f5.com return; 9591488St.nateldemoura@f5.com } 960240Sigor@sysoev.ru 9611579St.nateldemoura@f5.com if (process->isolation.cleanup != NULL) { 9621579St.nateldemoura@f5.com process->isolation.cleanup(task, process); 9631489St.nateldemoura@f5.com } 9641489St.nateldemoura@f5.com 9651488St.nateldemoura@f5.com name = process->name; 9661488St.nateldemoura@f5.com stream = process->stream; 9671488St.nateldemoura@f5.com init = *((nxt_process_init_t *) nxt_process_init(process)); 968366Smax.romanov@nginx.com 9691488St.nateldemoura@f5.com if (process->state == NXT_PROCESS_STATE_READY) { 9701488St.nateldemoura@f5.com process->stream = 0; 9711488St.nateldemoura@f5.com } 972240Sigor@sysoev.ru 9731488St.nateldemoura@f5.com nxt_process_close_ports(task, process); 9741302St.nateldemoura@f5.com 9751488St.nateldemoura@f5.com if (nxt_exiting) { 9761488St.nateldemoura@f5.com if (rt->nprocesses <= 1) { 9771488St.nateldemoura@f5.com nxt_runtime_quit(task, 0); 9781211Smax.romanov@nginx.com } 9791211Smax.romanov@nginx.com 9801488St.nateldemoura@f5.com return; 981240Sigor@sysoev.ru } 982754Smax.romanov@nginx.com 983754Smax.romanov@nginx.com nxt_runtime_process_each(rt, process) { 984754Smax.romanov@nginx.com 9851488St.nateldemoura@f5.com if (process->pid == nxt_pid 9861488St.nateldemoura@f5.com || process->pid == pid 9871488St.nateldemoura@f5.com || nxt_queue_is_empty(&process->ports)) 9881488St.nateldemoura@f5.com { 9891488St.nateldemoura@f5.com continue; 9901488St.nateldemoura@f5.com } 9911488St.nateldemoura@f5.com 9921488St.nateldemoura@f5.com port = nxt_process_port_first(process); 993754Smax.romanov@nginx.com 9941488St.nateldemoura@f5.com if (nxt_proc_remove_notify_matrix[init.type][port->type] == 0) { 9951488St.nateldemoura@f5.com continue; 9961488St.nateldemoura@f5.com } 9971488St.nateldemoura@f5.com 9981488St.nateldemoura@f5.com buf = nxt_buf_mem_ts_alloc(task, task->thread->engine->mem_pool, 9991488St.nateldemoura@f5.com sizeof(pid)); 1000754Smax.romanov@nginx.com 10011488St.nateldemoura@f5.com if (nxt_slow_path(buf == NULL)) { 10021488St.nateldemoura@f5.com continue; 10031488St.nateldemoura@f5.com } 10041488St.nateldemoura@f5.com 10051488St.nateldemoura@f5.com buf->mem.free = nxt_cpymem(buf->mem.free, &pid, sizeof(pid)); 10061488St.nateldemoura@f5.com 10071488St.nateldemoura@f5.com nxt_port_socket_write(task, port, NXT_PORT_MSG_REMOVE_PID, -1, 10081488St.nateldemoura@f5.com stream, 0, buf); 1009754Smax.romanov@nginx.com 1010754Smax.romanov@nginx.com } nxt_runtime_process_loop; 10111488St.nateldemoura@f5.com 10121488St.nateldemoura@f5.com if (init.restart) { 10131488St.nateldemoura@f5.com ret = nxt_main_process_create(task, init); 10141488St.nateldemoura@f5.com if (nxt_slow_path(ret == NXT_ERROR)) { 10151488St.nateldemoura@f5.com nxt_alert(task, "failed to restart %s", name); 10161488St.nateldemoura@f5.com } 10171488St.nateldemoura@f5.com } 1018754Smax.romanov@nginx.com } 1019754Smax.romanov@nginx.com 1020754Smax.romanov@nginx.com 1021754Smax.romanov@nginx.com static void 1022240Sigor@sysoev.ru nxt_main_port_socket_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 1023240Sigor@sysoev.ru { 1024240Sigor@sysoev.ru size_t size; 1025240Sigor@sysoev.ru nxt_int_t ret; 1026240Sigor@sysoev.ru nxt_buf_t *b, *out; 1027240Sigor@sysoev.ru nxt_port_t *port; 1028240Sigor@sysoev.ru nxt_sockaddr_t *sa; 1029240Sigor@sysoev.ru nxt_port_msg_type_t type; 1030240Sigor@sysoev.ru nxt_listening_socket_t ls; 1031240Sigor@sysoev.ru u_char message[2048]; 1032240Sigor@sysoev.ru 10331788Smax.romanov@nginx.com port = nxt_runtime_port_find(task->thread->runtime, msg->port_msg.pid, 10341788Smax.romanov@nginx.com msg->port_msg.reply_port); 10351788Smax.romanov@nginx.com if (nxt_slow_path(port == NULL)) { 10361788Smax.romanov@nginx.com return; 10371788Smax.romanov@nginx.com } 10381788Smax.romanov@nginx.com 1039*1996St.nateldemoura@f5.com if (nxt_slow_path(port->type != NXT_PROCESS_ROUTER)) { 1040*1996St.nateldemoura@f5.com nxt_alert(task, "process %PI cannot create listener sockets", 1041*1996St.nateldemoura@f5.com msg->port_msg.pid); 1042*1996St.nateldemoura@f5.com 1043*1996St.nateldemoura@f5.com return; 1044*1996St.nateldemoura@f5.com } 1045*1996St.nateldemoura@f5.com 1046240Sigor@sysoev.ru b = msg->buf; 1047240Sigor@sysoev.ru sa = (nxt_sockaddr_t *) b->mem.pos; 1048240Sigor@sysoev.ru 1049352Smax.romanov@nginx.com /* TODO check b size and make plain */ 1050352Smax.romanov@nginx.com 1051240Sigor@sysoev.ru ls.socket = -1; 1052240Sigor@sysoev.ru ls.error = NXT_SOCKET_ERROR_SYSTEM; 1053240Sigor@sysoev.ru ls.start = message; 1054240Sigor@sysoev.ru ls.end = message + sizeof(message); 1055240Sigor@sysoev.ru 1056240Sigor@sysoev.ru nxt_debug(task, "listening socket \"%*s\"", 1057493Spluknet@nginx.com (size_t) sa->length, nxt_sockaddr_start(sa)); 1058240Sigor@sysoev.ru 1059240Sigor@sysoev.ru ret = nxt_main_listening_socket(sa, &ls); 1060240Sigor@sysoev.ru 1061240Sigor@sysoev.ru if (ret == NXT_OK) { 1062240Sigor@sysoev.ru nxt_debug(task, "socket(\"%*s\"): %d", 1063493Spluknet@nginx.com (size_t) sa->length, nxt_sockaddr_start(sa), ls.socket); 1064240Sigor@sysoev.ru 10651788Smax.romanov@nginx.com out = NULL; 10661788Smax.romanov@nginx.com 1067240Sigor@sysoev.ru type = NXT_PORT_MSG_RPC_READY_LAST | NXT_PORT_MSG_CLOSE_FD; 1068240Sigor@sysoev.ru 1069240Sigor@sysoev.ru } else { 1070240Sigor@sysoev.ru size = ls.end - ls.start; 1071240Sigor@sysoev.ru 1072564Svbart@nginx.com nxt_alert(task, "%*s", size, ls.start); 1073240Sigor@sysoev.ru 1074342Smax.romanov@nginx.com out = nxt_buf_mem_ts_alloc(task, task->thread->engine->mem_pool, 1075342Smax.romanov@nginx.com size + 1); 10761788Smax.romanov@nginx.com if (nxt_fast_path(out != NULL)) { 10771788Smax.romanov@nginx.com *out->mem.free++ = (uint8_t) ls.error; 1078240Sigor@sysoev.ru 10791788Smax.romanov@nginx.com out->mem.free = nxt_cpymem(out->mem.free, ls.start, size); 10801788Smax.romanov@nginx.com } 1081240Sigor@sysoev.ru 1082240Sigor@sysoev.ru type = NXT_PORT_MSG_RPC_ERROR; 1083240Sigor@sysoev.ru } 1084240Sigor@sysoev.ru 1085240Sigor@sysoev.ru nxt_port_socket_write(task, port, type, ls.socket, msg->port_msg.stream, 1086240Sigor@sysoev.ru 0, out); 1087240Sigor@sysoev.ru } 1088240Sigor@sysoev.ru 1089240Sigor@sysoev.ru 1090240Sigor@sysoev.ru static nxt_int_t 1091240Sigor@sysoev.ru nxt_main_listening_socket(nxt_sockaddr_t *sa, nxt_listening_socket_t *ls) 1092240Sigor@sysoev.ru { 1093240Sigor@sysoev.ru nxt_err_t err; 1094240Sigor@sysoev.ru nxt_socket_t s; 1095240Sigor@sysoev.ru 1096240Sigor@sysoev.ru const socklen_t length = sizeof(int); 1097240Sigor@sysoev.ru static const int enable = 1; 1098240Sigor@sysoev.ru 1099240Sigor@sysoev.ru s = socket(sa->u.sockaddr.sa_family, sa->type, 0); 1100240Sigor@sysoev.ru 1101240Sigor@sysoev.ru if (nxt_slow_path(s == -1)) { 1102240Sigor@sysoev.ru err = nxt_errno; 1103240Sigor@sysoev.ru 1104240Sigor@sysoev.ru #if (NXT_INET6) 1105240Sigor@sysoev.ru 1106240Sigor@sysoev.ru if (err == EAFNOSUPPORT && sa->u.sockaddr.sa_family == AF_INET6) { 1107240Sigor@sysoev.ru ls->error = NXT_SOCKET_ERROR_NOINET6; 1108240Sigor@sysoev.ru } 1109240Sigor@sysoev.ru 1110240Sigor@sysoev.ru #endif 1111240Sigor@sysoev.ru 1112240Sigor@sysoev.ru ls->end = nxt_sprintf(ls->start, ls->end, 1113240Sigor@sysoev.ru "socket(\\\"%*s\\\") failed %E", 1114493Spluknet@nginx.com (size_t) sa->length, nxt_sockaddr_start(sa), err); 1115240Sigor@sysoev.ru 1116240Sigor@sysoev.ru return NXT_ERROR; 1117240Sigor@sysoev.ru } 1118240Sigor@sysoev.ru 1119240Sigor@sysoev.ru if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &enable, length) != 0) { 1120240Sigor@sysoev.ru ls->end = nxt_sprintf(ls->start, ls->end, 1121240Sigor@sysoev.ru "setsockopt(\\\"%*s\\\", SO_REUSEADDR) failed %E", 1122493Spluknet@nginx.com (size_t) sa->length, nxt_sockaddr_start(sa), 1123493Spluknet@nginx.com nxt_errno); 1124240Sigor@sysoev.ru goto fail; 1125240Sigor@sysoev.ru } 1126240Sigor@sysoev.ru 1127240Sigor@sysoev.ru #if (NXT_INET6) 1128240Sigor@sysoev.ru 1129240Sigor@sysoev.ru if (sa->u.sockaddr.sa_family == AF_INET6) { 1130240Sigor@sysoev.ru 1131240Sigor@sysoev.ru if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &enable, length) != 0) { 1132240Sigor@sysoev.ru ls->end = nxt_sprintf(ls->start, ls->end, 1133240Sigor@sysoev.ru "setsockopt(\\\"%*s\\\", IPV6_V6ONLY) failed %E", 1134493Spluknet@nginx.com (size_t) sa->length, nxt_sockaddr_start(sa), 1135493Spluknet@nginx.com nxt_errno); 1136240Sigor@sysoev.ru goto fail; 1137240Sigor@sysoev.ru } 1138240Sigor@sysoev.ru } 1139240Sigor@sysoev.ru 1140240Sigor@sysoev.ru #endif 1141240Sigor@sysoev.ru 1142240Sigor@sysoev.ru if (bind(s, &sa->u.sockaddr, sa->socklen) != 0) { 1143240Sigor@sysoev.ru err = nxt_errno; 1144240Sigor@sysoev.ru 1145240Sigor@sysoev.ru #if (NXT_HAVE_UNIX_DOMAIN) 1146240Sigor@sysoev.ru 1147240Sigor@sysoev.ru if (sa->u.sockaddr.sa_family == AF_UNIX) { 1148240Sigor@sysoev.ru switch (err) { 1149240Sigor@sysoev.ru 1150240Sigor@sysoev.ru case EACCES: 1151240Sigor@sysoev.ru ls->error = NXT_SOCKET_ERROR_ACCESS; 1152240Sigor@sysoev.ru break; 1153240Sigor@sysoev.ru 1154240Sigor@sysoev.ru case ENOENT: 1155240Sigor@sysoev.ru case ENOTDIR: 1156240Sigor@sysoev.ru ls->error = NXT_SOCKET_ERROR_PATH; 1157240Sigor@sysoev.ru break; 1158240Sigor@sysoev.ru } 1159240Sigor@sysoev.ru 1160908Sigor@sysoev.ru } else 1161908Sigor@sysoev.ru #endif 1162908Sigor@sysoev.ru { 1163908Sigor@sysoev.ru switch (err) { 1164240Sigor@sysoev.ru 1165908Sigor@sysoev.ru case EACCES: 1166908Sigor@sysoev.ru ls->error = NXT_SOCKET_ERROR_PORT; 1167908Sigor@sysoev.ru break; 1168240Sigor@sysoev.ru 1169908Sigor@sysoev.ru case EADDRINUSE: 1170908Sigor@sysoev.ru ls->error = NXT_SOCKET_ERROR_INUSE; 1171908Sigor@sysoev.ru break; 1172240Sigor@sysoev.ru 1173908Sigor@sysoev.ru case EADDRNOTAVAIL: 1174908Sigor@sysoev.ru ls->error = NXT_SOCKET_ERROR_NOADDR; 1175908Sigor@sysoev.ru break; 1176908Sigor@sysoev.ru } 1177240Sigor@sysoev.ru } 1178240Sigor@sysoev.ru 1179240Sigor@sysoev.ru ls->end = nxt_sprintf(ls->start, ls->end, "bind(\\\"%*s\\\") failed %E", 1180493Spluknet@nginx.com (size_t) sa->length, nxt_sockaddr_start(sa), err); 1181240Sigor@sysoev.ru goto fail; 1182240Sigor@sysoev.ru } 1183240Sigor@sysoev.ru 1184240Sigor@sysoev.ru #if (NXT_HAVE_UNIX_DOMAIN) 1185240Sigor@sysoev.ru 1186240Sigor@sysoev.ru if (sa->u.sockaddr.sa_family == AF_UNIX) { 1187240Sigor@sysoev.ru char *filename; 1188240Sigor@sysoev.ru mode_t access; 1189240Sigor@sysoev.ru 1190240Sigor@sysoev.ru filename = sa->u.sockaddr_un.sun_path; 1191240Sigor@sysoev.ru access = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); 1192240Sigor@sysoev.ru 1193240Sigor@sysoev.ru if (chmod(filename, access) != 0) { 1194240Sigor@sysoev.ru ls->end = nxt_sprintf(ls->start, ls->end, 1195494Spluknet@nginx.com "chmod(\\\"%s\\\") failed %E", 1196240Sigor@sysoev.ru filename, nxt_errno); 1197240Sigor@sysoev.ru goto fail; 1198240Sigor@sysoev.ru } 1199240Sigor@sysoev.ru } 1200240Sigor@sysoev.ru 1201240Sigor@sysoev.ru #endif 1202240Sigor@sysoev.ru 1203240Sigor@sysoev.ru ls->socket = s; 1204240Sigor@sysoev.ru 1205240Sigor@sysoev.ru return NXT_OK; 1206240Sigor@sysoev.ru 1207240Sigor@sysoev.ru fail: 1208240Sigor@sysoev.ru 1209240Sigor@sysoev.ru (void) close(s); 1210240Sigor@sysoev.ru 1211240Sigor@sysoev.ru return NXT_ERROR; 1212240Sigor@sysoev.ru } 1213240Sigor@sysoev.ru 1214240Sigor@sysoev.ru 1215240Sigor@sysoev.ru static nxt_conf_map_t nxt_app_lang_module_map[] = { 1216240Sigor@sysoev.ru { 1217240Sigor@sysoev.ru nxt_string("type"), 1218356Svbart@nginx.com NXT_CONF_MAP_INT, 1219240Sigor@sysoev.ru offsetof(nxt_app_lang_module_t, type), 1220240Sigor@sysoev.ru }, 1221240Sigor@sysoev.ru 1222240Sigor@sysoev.ru { 1223240Sigor@sysoev.ru nxt_string("version"), 1224354Svbart@nginx.com NXT_CONF_MAP_CSTRZ, 1225240Sigor@sysoev.ru offsetof(nxt_app_lang_module_t, version), 1226240Sigor@sysoev.ru }, 1227240Sigor@sysoev.ru 1228240Sigor@sysoev.ru { 1229240Sigor@sysoev.ru nxt_string("file"), 1230240Sigor@sysoev.ru NXT_CONF_MAP_CSTRZ, 1231240Sigor@sysoev.ru offsetof(nxt_app_lang_module_t, file), 1232240Sigor@sysoev.ru }, 1233240Sigor@sysoev.ru }; 1234240Sigor@sysoev.ru 1235240Sigor@sysoev.ru 12361489St.nateldemoura@f5.com static nxt_conf_map_t nxt_app_lang_mounts_map[] = { 12371489St.nateldemoura@f5.com { 12381489St.nateldemoura@f5.com nxt_string("src"), 12391489St.nateldemoura@f5.com NXT_CONF_MAP_CSTRZ, 12401489St.nateldemoura@f5.com offsetof(nxt_fs_mount_t, src), 12411489St.nateldemoura@f5.com }, 12421489St.nateldemoura@f5.com { 12431489St.nateldemoura@f5.com nxt_string("dst"), 12441489St.nateldemoura@f5.com NXT_CONF_MAP_CSTRZ, 12451489St.nateldemoura@f5.com offsetof(nxt_fs_mount_t, dst), 12461489St.nateldemoura@f5.com }, 12471489St.nateldemoura@f5.com { 12481673St.nateldemoura@f5.com nxt_string("name"), 12491489St.nateldemoura@f5.com NXT_CONF_MAP_CSTRZ, 12501673St.nateldemoura@f5.com offsetof(nxt_fs_mount_t, name), 12511673St.nateldemoura@f5.com }, 12521673St.nateldemoura@f5.com { 12531673St.nateldemoura@f5.com nxt_string("type"), 12541673St.nateldemoura@f5.com NXT_CONF_MAP_INT, 12551673St.nateldemoura@f5.com offsetof(nxt_fs_mount_t, type), 12561489St.nateldemoura@f5.com }, 12571489St.nateldemoura@f5.com { 12581489St.nateldemoura@f5.com nxt_string("flags"), 12591489St.nateldemoura@f5.com NXT_CONF_MAP_INT, 12601489St.nateldemoura@f5.com offsetof(nxt_fs_mount_t, flags), 12611489St.nateldemoura@f5.com }, 12621489St.nateldemoura@f5.com { 12631489St.nateldemoura@f5.com nxt_string("data"), 12641489St.nateldemoura@f5.com NXT_CONF_MAP_CSTRZ, 12651489St.nateldemoura@f5.com offsetof(nxt_fs_mount_t, data), 12661489St.nateldemoura@f5.com }, 12671489St.nateldemoura@f5.com }; 12681489St.nateldemoura@f5.com 12691489St.nateldemoura@f5.com 1270240Sigor@sysoev.ru static void 1271240Sigor@sysoev.ru nxt_main_port_modules_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 1272240Sigor@sysoev.ru { 12731489St.nateldemoura@f5.com uint32_t index, jindex, nmounts; 1274240Sigor@sysoev.ru nxt_mp_t *mp; 1275240Sigor@sysoev.ru nxt_int_t ret; 1276240Sigor@sysoev.ru nxt_buf_t *b; 1277549Svbart@nginx.com nxt_port_t *port; 1278240Sigor@sysoev.ru nxt_runtime_t *rt; 12791489St.nateldemoura@f5.com nxt_fs_mount_t *mnt; 12801489St.nateldemoura@f5.com nxt_conf_value_t *conf, *root, *value, *mounts; 1281240Sigor@sysoev.ru nxt_app_lang_module_t *lang; 1282240Sigor@sysoev.ru 12831182St.nateldemoura@f5.com static nxt_str_t root_path = nxt_string("/"); 12841489St.nateldemoura@f5.com static nxt_str_t mounts_name = nxt_string("mounts"); 1285240Sigor@sysoev.ru 1286240Sigor@sysoev.ru rt = task->thread->runtime; 1287240Sigor@sysoev.ru 1288240Sigor@sysoev.ru if (msg->port_msg.pid != rt->port_by_type[NXT_PROCESS_DISCOVERY]->pid) { 1289*1996St.nateldemoura@f5.com nxt_alert(task, "process %PI cannot send modules", msg->port_msg.pid); 1290240Sigor@sysoev.ru return; 1291240Sigor@sysoev.ru } 1292240Sigor@sysoev.ru 12931211Smax.romanov@nginx.com if (nxt_exiting) { 12941211Smax.romanov@nginx.com nxt_debug(task, "ignoring discovered modules, exiting"); 12951211Smax.romanov@nginx.com return; 12961211Smax.romanov@nginx.com } 12971211Smax.romanov@nginx.com 1298549Svbart@nginx.com port = nxt_runtime_port_find(task->thread->runtime, msg->port_msg.pid, 1299549Svbart@nginx.com msg->port_msg.reply_port); 1300549Svbart@nginx.com 1301549Svbart@nginx.com if (nxt_fast_path(port != NULL)) { 1302549Svbart@nginx.com (void) nxt_port_socket_write(task, port, NXT_PORT_MSG_RPC_ERROR, -1, 1303549Svbart@nginx.com msg->port_msg.stream, 0, NULL); 1304549Svbart@nginx.com } 1305549Svbart@nginx.com 1306240Sigor@sysoev.ru b = msg->buf; 1307240Sigor@sysoev.ru 1308240Sigor@sysoev.ru if (b == NULL) { 1309240Sigor@sysoev.ru return; 1310240Sigor@sysoev.ru } 1311240Sigor@sysoev.ru 1312240Sigor@sysoev.ru mp = nxt_mp_create(1024, 128, 256, 32); 1313240Sigor@sysoev.ru if (mp == NULL) { 1314240Sigor@sysoev.ru return; 1315240Sigor@sysoev.ru } 1316240Sigor@sysoev.ru 1317352Smax.romanov@nginx.com b = nxt_buf_chk_make_plain(mp, b, msg->size); 1318352Smax.romanov@nginx.com 1319352Smax.romanov@nginx.com if (b == NULL) { 1320352Smax.romanov@nginx.com return; 1321352Smax.romanov@nginx.com } 1322352Smax.romanov@nginx.com 1323352Smax.romanov@nginx.com nxt_debug(task, "application languages: \"%*s\"", 1324352Smax.romanov@nginx.com b->mem.free - b->mem.pos, b->mem.pos); 1325352Smax.romanov@nginx.com 1326240Sigor@sysoev.ru conf = nxt_conf_json_parse(mp, b->mem.pos, b->mem.free, NULL); 1327240Sigor@sysoev.ru if (conf == NULL) { 1328240Sigor@sysoev.ru goto fail; 1329240Sigor@sysoev.ru } 1330240Sigor@sysoev.ru 1331240Sigor@sysoev.ru root = nxt_conf_get_path(conf, &root_path); 1332240Sigor@sysoev.ru if (root == NULL) { 1333240Sigor@sysoev.ru goto fail; 1334240Sigor@sysoev.ru } 1335240Sigor@sysoev.ru 1336240Sigor@sysoev.ru for (index = 0; /* void */ ; index++) { 1337240Sigor@sysoev.ru value = nxt_conf_get_array_element(root, index); 1338240Sigor@sysoev.ru if (value == NULL) { 1339240Sigor@sysoev.ru break; 1340240Sigor@sysoev.ru } 1341240Sigor@sysoev.ru 13421489St.nateldemoura@f5.com lang = nxt_array_zero_add(rt->languages); 1343240Sigor@sysoev.ru if (lang == NULL) { 1344240Sigor@sysoev.ru goto fail; 1345240Sigor@sysoev.ru } 1346240Sigor@sysoev.ru 1347240Sigor@sysoev.ru lang->module = NULL; 1348240Sigor@sysoev.ru 1349240Sigor@sysoev.ru ret = nxt_conf_map_object(rt->mem_pool, value, nxt_app_lang_module_map, 1350240Sigor@sysoev.ru nxt_nitems(nxt_app_lang_module_map), lang); 1351240Sigor@sysoev.ru 1352240Sigor@sysoev.ru if (ret != NXT_OK) { 1353240Sigor@sysoev.ru goto fail; 1354240Sigor@sysoev.ru } 1355240Sigor@sysoev.ru 13561489St.nateldemoura@f5.com mounts = nxt_conf_get_object_member(value, &mounts_name, NULL); 13571489St.nateldemoura@f5.com if (mounts == NULL) { 13581489St.nateldemoura@f5.com nxt_alert(task, "missing mounts from discovery message."); 13591489St.nateldemoura@f5.com goto fail; 13601489St.nateldemoura@f5.com } 13611489St.nateldemoura@f5.com 13621489St.nateldemoura@f5.com if (nxt_conf_type(mounts) != NXT_CONF_ARRAY) { 13631489St.nateldemoura@f5.com nxt_alert(task, "invalid mounts type from discovery message."); 13641489St.nateldemoura@f5.com goto fail; 13651489St.nateldemoura@f5.com } 13661489St.nateldemoura@f5.com 13671489St.nateldemoura@f5.com nmounts = nxt_conf_array_elements_count(mounts); 13681489St.nateldemoura@f5.com 13691489St.nateldemoura@f5.com lang->mounts = nxt_array_create(rt->mem_pool, nmounts, 13701489St.nateldemoura@f5.com sizeof(nxt_fs_mount_t)); 13711489St.nateldemoura@f5.com 13721489St.nateldemoura@f5.com if (lang->mounts == NULL) { 13731489St.nateldemoura@f5.com goto fail; 13741489St.nateldemoura@f5.com } 13751489St.nateldemoura@f5.com 13761489St.nateldemoura@f5.com for (jindex = 0; /* */; jindex++) { 13771489St.nateldemoura@f5.com value = nxt_conf_get_array_element(mounts, jindex); 13781489St.nateldemoura@f5.com if (value == NULL) { 13791489St.nateldemoura@f5.com break; 13801489St.nateldemoura@f5.com } 13811489St.nateldemoura@f5.com 13821489St.nateldemoura@f5.com mnt = nxt_array_zero_add(lang->mounts); 13831489St.nateldemoura@f5.com if (mnt == NULL) { 13841489St.nateldemoura@f5.com goto fail; 13851489St.nateldemoura@f5.com } 13861489St.nateldemoura@f5.com 13871585St.nateldemoura@f5.com mnt->builtin = 1; 13881673St.nateldemoura@f5.com mnt->deps = 1; 13891585St.nateldemoura@f5.com 13901489St.nateldemoura@f5.com ret = nxt_conf_map_object(rt->mem_pool, value, 13911489St.nateldemoura@f5.com nxt_app_lang_mounts_map, 13921489St.nateldemoura@f5.com nxt_nitems(nxt_app_lang_mounts_map), mnt); 13931489St.nateldemoura@f5.com 13941489St.nateldemoura@f5.com if (ret != NXT_OK) { 13951489St.nateldemoura@f5.com goto fail; 13961489St.nateldemoura@f5.com } 13971489St.nateldemoura@f5.com } 13981489St.nateldemoura@f5.com 13991489St.nateldemoura@f5.com nxt_debug(task, "lang %d %s \"%s\" (%d mounts)", 14001489St.nateldemoura@f5.com lang->type, lang->version, lang->file, lang->mounts->nelts); 1401240Sigor@sysoev.ru } 1402240Sigor@sysoev.ru 1403240Sigor@sysoev.ru qsort(rt->languages->elts, rt->languages->nelts, 1404240Sigor@sysoev.ru sizeof(nxt_app_lang_module_t), nxt_app_lang_compare); 1405240Sigor@sysoev.ru 1406240Sigor@sysoev.ru fail: 1407240Sigor@sysoev.ru 1408240Sigor@sysoev.ru nxt_mp_destroy(mp); 1409240Sigor@sysoev.ru 14101488St.nateldemoura@f5.com ret = nxt_main_process_create(task, nxt_controller_process); 14111488St.nateldemoura@f5.com if (ret == NXT_OK) { 14121488St.nateldemoura@f5.com ret = nxt_main_process_create(task, nxt_router_process); 14131488St.nateldemoura@f5.com } 1414240Sigor@sysoev.ru 14151488St.nateldemoura@f5.com if (nxt_slow_path(ret == NXT_ERROR)) { 14161488St.nateldemoura@f5.com nxt_exiting = 1; 14171488St.nateldemoura@f5.com 14181488St.nateldemoura@f5.com nxt_runtime_quit(task, 1); 1419240Sigor@sysoev.ru } 1420240Sigor@sysoev.ru } 1421240Sigor@sysoev.ru 1422240Sigor@sysoev.ru 1423240Sigor@sysoev.ru static int nxt_cdecl 1424240Sigor@sysoev.ru nxt_app_lang_compare(const void *v1, const void *v2) 1425240Sigor@sysoev.ru { 1426240Sigor@sysoev.ru int n; 1427240Sigor@sysoev.ru const nxt_app_lang_module_t *lang1, *lang2; 1428240Sigor@sysoev.ru 1429240Sigor@sysoev.ru lang1 = v1; 1430240Sigor@sysoev.ru lang2 = v2; 1431240Sigor@sysoev.ru 1432356Svbart@nginx.com n = lang1->type - lang2->type; 1433258Sigor@sysoev.ru 1434258Sigor@sysoev.ru if (n != 0) { 1435258Sigor@sysoev.ru return n; 1436258Sigor@sysoev.ru } 1437258Sigor@sysoev.ru 1438354Svbart@nginx.com n = nxt_strverscmp(lang1->version, lang2->version); 1439240Sigor@sysoev.ru 1440240Sigor@sysoev.ru /* Negate result to move higher versions to the beginning. */ 1441240Sigor@sysoev.ru 1442240Sigor@sysoev.ru return -n; 1443240Sigor@sysoev.ru } 1444314Svbart@nginx.com 1445314Svbart@nginx.com 1446314Svbart@nginx.com static void 1447314Svbart@nginx.com nxt_main_port_conf_store_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 1448314Svbart@nginx.com { 14491787Smax.romanov@nginx.com void *p; 14501969Sz.hong@f5.com size_t n, size; 1451314Svbart@nginx.com nxt_int_t ret; 1452*1996St.nateldemoura@f5.com nxt_port_t *ctl_port; 1453314Svbart@nginx.com nxt_runtime_t *rt; 14541969Sz.hong@f5.com u_char ver[NXT_INT_T_LEN]; 1455314Svbart@nginx.com 1456*1996St.nateldemoura@f5.com rt = task->thread->runtime; 1457*1996St.nateldemoura@f5.com 1458*1996St.nateldemoura@f5.com ctl_port = rt->port_by_type[NXT_PROCESS_CONTROLLER]; 1459*1996St.nateldemoura@f5.com 1460*1996St.nateldemoura@f5.com if (nxt_slow_path(msg->port_msg.pid != ctl_port->pid)) { 1461*1996St.nateldemoura@f5.com nxt_alert(task, "process %PI cannot store conf", msg->port_msg.pid); 1462*1996St.nateldemoura@f5.com return; 1463*1996St.nateldemoura@f5.com } 1464*1996St.nateldemoura@f5.com 14651787Smax.romanov@nginx.com p = MAP_FAILED; 14661787Smax.romanov@nginx.com 14671787Smax.romanov@nginx.com /* 14681787Smax.romanov@nginx.com * Ancient compilers like gcc 4.8.5 on CentOS 7 wants 'size' to be 14691787Smax.romanov@nginx.com * initialized in 'cleanup' section. 14701787Smax.romanov@nginx.com */ 14711787Smax.romanov@nginx.com size = 0; 14721787Smax.romanov@nginx.com 14731787Smax.romanov@nginx.com if (nxt_slow_path(msg->fd[0] == -1)) { 14741787Smax.romanov@nginx.com nxt_alert(task, "conf_store_handler: invalid shm fd"); 14751787Smax.romanov@nginx.com goto error; 14761787Smax.romanov@nginx.com } 14771787Smax.romanov@nginx.com 14781787Smax.romanov@nginx.com if (nxt_buf_mem_used_size(&msg->buf->mem) != sizeof(size_t)) { 14791787Smax.romanov@nginx.com nxt_alert(task, "conf_store_handler: unexpected buffer size (%d)", 14801787Smax.romanov@nginx.com (int) nxt_buf_mem_used_size(&msg->buf->mem)); 14811787Smax.romanov@nginx.com goto error; 14821787Smax.romanov@nginx.com } 14831787Smax.romanov@nginx.com 14841787Smax.romanov@nginx.com nxt_memcpy(&size, msg->buf->mem.pos, sizeof(size_t)); 14851787Smax.romanov@nginx.com 14861787Smax.romanov@nginx.com p = nxt_mem_mmap(NULL, size, PROT_READ, MAP_SHARED, msg->fd[0], 0); 14871787Smax.romanov@nginx.com 14881787Smax.romanov@nginx.com nxt_fd_close(msg->fd[0]); 14891787Smax.romanov@nginx.com msg->fd[0] = -1; 14901787Smax.romanov@nginx.com 14911787Smax.romanov@nginx.com if (nxt_slow_path(p == MAP_FAILED)) { 14921787Smax.romanov@nginx.com goto error; 14931787Smax.romanov@nginx.com } 14941787Smax.romanov@nginx.com 14951787Smax.romanov@nginx.com nxt_debug(task, "conf_store_handler(%uz): %*s", size, size, p); 14961787Smax.romanov@nginx.com 14971969Sz.hong@f5.com if (nxt_conf_ver != NXT_VERNUM) { 14981969Sz.hong@f5.com n = nxt_sprintf(ver, ver + NXT_INT_T_LEN, "%d", NXT_VERNUM) - ver; 1499314Svbart@nginx.com 15001969Sz.hong@f5.com ret = nxt_main_file_store(task, rt->ver_tmp, rt->ver, ver, n); 15011969Sz.hong@f5.com if (nxt_slow_path(ret != NXT_OK)) { 15021969Sz.hong@f5.com goto error; 15031969Sz.hong@f5.com } 15041969Sz.hong@f5.com 15051969Sz.hong@f5.com nxt_conf_ver = NXT_VERNUM; 1506314Svbart@nginx.com } 1507314Svbart@nginx.com 15081969Sz.hong@f5.com ret = nxt_main_file_store(task, rt->conf_tmp, rt->conf, p, size); 1509314Svbart@nginx.com 1510314Svbart@nginx.com if (nxt_fast_path(ret == NXT_OK)) { 15111787Smax.romanov@nginx.com goto cleanup; 1512314Svbart@nginx.com } 1513314Svbart@nginx.com 1514314Svbart@nginx.com error: 1515314Svbart@nginx.com 1516564Svbart@nginx.com nxt_alert(task, "failed to store current configuration"); 15171787Smax.romanov@nginx.com 15181787Smax.romanov@nginx.com cleanup: 15191787Smax.romanov@nginx.com 15201787Smax.romanov@nginx.com if (p != MAP_FAILED) { 15211787Smax.romanov@nginx.com nxt_mem_munmap(p, size); 15221787Smax.romanov@nginx.com } 15231787Smax.romanov@nginx.com 15241787Smax.romanov@nginx.com if (msg->fd[0] != -1) { 15251787Smax.romanov@nginx.com nxt_fd_close(msg->fd[0]); 15261787Smax.romanov@nginx.com msg->fd[0] = -1; 15271787Smax.romanov@nginx.com } 1528314Svbart@nginx.com } 1529630Svbart@nginx.com 1530630Svbart@nginx.com 15311969Sz.hong@f5.com static nxt_int_t 15321969Sz.hong@f5.com nxt_main_file_store(nxt_task_t *task, const char *tmp_name, const char *name, 15331969Sz.hong@f5.com u_char *buf, size_t size) 15341969Sz.hong@f5.com { 15351969Sz.hong@f5.com ssize_t n; 15361969Sz.hong@f5.com nxt_int_t ret; 15371969Sz.hong@f5.com nxt_file_t file; 15381969Sz.hong@f5.com 15391969Sz.hong@f5.com nxt_memzero(&file, sizeof(nxt_file_t)); 15401969Sz.hong@f5.com 15411969Sz.hong@f5.com file.name = (nxt_file_name_t *) name; 15421969Sz.hong@f5.com 15431969Sz.hong@f5.com ret = nxt_file_open(task, &file, NXT_FILE_WRONLY, NXT_FILE_TRUNCATE, 15441969Sz.hong@f5.com NXT_FILE_OWNER_ACCESS); 15451969Sz.hong@f5.com if (nxt_slow_path(ret != NXT_OK)) { 15461969Sz.hong@f5.com return NXT_ERROR; 15471969Sz.hong@f5.com } 15481969Sz.hong@f5.com 15491969Sz.hong@f5.com n = nxt_file_write(&file, buf, size, 0); 15501969Sz.hong@f5.com 15511969Sz.hong@f5.com nxt_file_close(task, &file); 15521969Sz.hong@f5.com 15531969Sz.hong@f5.com if (nxt_slow_path(n != (ssize_t) size)) { 15541969Sz.hong@f5.com (void) nxt_file_delete(file.name); 15551969Sz.hong@f5.com return NXT_ERROR; 15561969Sz.hong@f5.com } 15571969Sz.hong@f5.com 15581969Sz.hong@f5.com return nxt_file_rename(file.name, (nxt_file_name_t *) name); 15591969Sz.hong@f5.com } 15601969Sz.hong@f5.com 15611969Sz.hong@f5.com 1562630Svbart@nginx.com static void 1563630Svbart@nginx.com nxt_main_port_access_log_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 1564630Svbart@nginx.com { 1565630Svbart@nginx.com u_char *path; 1566630Svbart@nginx.com nxt_int_t ret; 1567630Svbart@nginx.com nxt_file_t file; 1568630Svbart@nginx.com nxt_port_t *port; 1569630Svbart@nginx.com nxt_port_msg_type_t type; 1570630Svbart@nginx.com 1571630Svbart@nginx.com nxt_debug(task, "opening access log file"); 1572630Svbart@nginx.com 1573630Svbart@nginx.com path = msg->buf->mem.pos; 1574630Svbart@nginx.com 1575630Svbart@nginx.com nxt_memzero(&file, sizeof(nxt_file_t)); 1576630Svbart@nginx.com 1577630Svbart@nginx.com file.name = (nxt_file_name_t *) path; 1578630Svbart@nginx.com file.log_level = NXT_LOG_ERR; 1579630Svbart@nginx.com 1580630Svbart@nginx.com ret = nxt_file_open(task, &file, O_WRONLY | O_APPEND, O_CREAT, 1581630Svbart@nginx.com NXT_FILE_OWNER_ACCESS); 1582630Svbart@nginx.com 1583630Svbart@nginx.com type = (ret == NXT_OK) ? NXT_PORT_MSG_RPC_READY_LAST | NXT_PORT_MSG_CLOSE_FD 1584630Svbart@nginx.com : NXT_PORT_MSG_RPC_ERROR; 1585630Svbart@nginx.com 1586630Svbart@nginx.com port = nxt_runtime_port_find(task->thread->runtime, msg->port_msg.pid, 1587630Svbart@nginx.com msg->port_msg.reply_port); 1588630Svbart@nginx.com 1589630Svbart@nginx.com if (nxt_fast_path(port != NULL)) { 1590630Svbart@nginx.com (void) nxt_port_socket_write(task, port, type, file.fd, 1591630Svbart@nginx.com msg->port_msg.stream, 0, NULL); 1592630Svbart@nginx.com } 1593630Svbart@nginx.com } 1594