10Sigor@sysoev.ru
20Sigor@sysoev.ru /*
384Smax.romanov@nginx.com * Copyright (C) Max Romanov
40Sigor@sysoev.ru * Copyright (C) Igor Sysoev
50Sigor@sysoev.ru * Copyright (C) Valentin V. Bartenev
60Sigor@sysoev.ru * Copyright (C) NGINX, Inc.
70Sigor@sysoev.ru */
80Sigor@sysoev.ru
90Sigor@sysoev.ru #include <nxt_main.h>
1020Sigor@sysoev.ru #include <nxt_runtime.h>
11240Sigor@sysoev.ru #include <nxt_main_process.h>
12431Sigor@sysoev.ru #include <nxt_router.h>
13431Sigor@sysoev.ru #include <nxt_http.h>
14444Sigor@sysoev.ru #include <nxt_application.h>
15743Smax.romanov@nginx.com #include <nxt_unit.h>
16723Smax.romanov@nginx.com #include <nxt_port_memory_int.h>
171579St.nateldemoura@f5.com #include <nxt_isolation.h>
180Sigor@sysoev.ru
19216Sigor@sysoev.ru #include <glob.h>
200Sigor@sysoev.ru
211489St.nateldemoura@f5.com #if (NXT_HAVE_PR_SET_NO_NEW_PRIVS)
221489St.nateldemoura@f5.com #include <sys/prctl.h>
231489St.nateldemoura@f5.com #endif
241489St.nateldemoura@f5.com
25216Sigor@sysoev.ru
262174Smax.romanov@gmail.com #ifdef WCOREDUMP
272174Smax.romanov@gmail.com #define NXT_WCOREDUMP(s) WCOREDUMP(s)
282174Smax.romanov@gmail.com #else
292174Smax.romanov@gmail.com #define NXT_WCOREDUMP(s) 0
302174Smax.romanov@gmail.com #endif
312174Smax.romanov@gmail.com
322174Smax.romanov@gmail.com
33216Sigor@sysoev.ru typedef struct {
34356Svbart@nginx.com nxt_app_type_t type;
35356Svbart@nginx.com nxt_str_t version;
36356Svbart@nginx.com nxt_str_t file;
371489St.nateldemoura@f5.com nxt_array_t *mounts;
38216Sigor@sysoev.ru } nxt_module_t;
39216Sigor@sysoev.ru
40216Sigor@sysoev.ru
411488St.nateldemoura@f5.com static nxt_int_t nxt_discovery_start(nxt_task_t *task,
421488St.nateldemoura@f5.com nxt_process_data_t *data);
43216Sigor@sysoev.ru static nxt_buf_t *nxt_discovery_modules(nxt_task_t *task, const char *path);
44216Sigor@sysoev.ru static nxt_int_t nxt_discovery_module(nxt_task_t *task, nxt_mp_t *mp,
45216Sigor@sysoev.ru nxt_array_t *modules, const char *name);
46549Svbart@nginx.com static void nxt_discovery_completion_handler(nxt_task_t *task, void *obj,
47549Svbart@nginx.com void *data);
48549Svbart@nginx.com static void nxt_discovery_quit(nxt_task_t *task, nxt_port_recv_msg_t *msg,
49549Svbart@nginx.com void *data);
50216Sigor@sysoev.ru static nxt_app_module_t *nxt_app_module_load(nxt_task_t *task,
51216Sigor@sysoev.ru const char *name);
521998St.nateldemoura@f5.com static nxt_int_t nxt_proto_setup(nxt_task_t *task, nxt_process_t *process);
531998St.nateldemoura@f5.com static nxt_int_t nxt_proto_start(nxt_task_t *task, nxt_process_data_t *data);
541488St.nateldemoura@f5.com static nxt_int_t nxt_app_setup(nxt_task_t *task, nxt_process_t *process);
55678Svbart@nginx.com static nxt_int_t nxt_app_set_environment(nxt_conf_value_t *environment);
561998St.nateldemoura@f5.com static void nxt_proto_start_process_handler(nxt_task_t *task,
571998St.nateldemoura@f5.com nxt_port_recv_msg_t *msg);
581998St.nateldemoura@f5.com static void nxt_proto_quit_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg);
591998St.nateldemoura@f5.com static void nxt_proto_process_created_handler(nxt_task_t *task,
601998St.nateldemoura@f5.com nxt_port_recv_msg_t *msg);
611998St.nateldemoura@f5.com static void nxt_proto_quit_children(nxt_task_t *task);
621998St.nateldemoura@f5.com static nxt_process_t *nxt_proto_process_find(nxt_task_t *task, nxt_pid_t pid);
631998St.nateldemoura@f5.com static void nxt_proto_process_add(nxt_task_t *task, nxt_process_t *process);
641998St.nateldemoura@f5.com static nxt_process_t *nxt_proto_process_remove(nxt_task_t *task, nxt_pid_t pid);
651489St.nateldemoura@f5.com static u_char *nxt_cstr_dup(nxt_mp_t *mp, u_char *dst, u_char *src);
661998St.nateldemoura@f5.com static void nxt_proto_signal_handler(nxt_task_t *task, void *obj, void *data);
671998St.nateldemoura@f5.com static void nxt_proto_sigterm_handler(nxt_task_t *task, void *obj, void *data);
681998St.nateldemoura@f5.com static void nxt_proto_sigchld_handler(nxt_task_t *task, void *obj, void *data);
691489St.nateldemoura@f5.com
701489St.nateldemoura@f5.com
711488St.nateldemoura@f5.com nxt_str_t nxt_server = nxt_string(NXT_SERVER);
720Sigor@sysoev.ru
73216Sigor@sysoev.ru
74258Sigor@sysoev.ru static uint32_t compat[] = {
75360Sigor@sysoev.ru NXT_VERNUM, NXT_DEBUG,
76258Sigor@sysoev.ru };
77258Sigor@sysoev.ru
78258Sigor@sysoev.ru
791998St.nateldemoura@f5.com static nxt_lvlhsh_t nxt_proto_processes;
801998St.nateldemoura@f5.com static nxt_queue_t nxt_proto_children;
811998St.nateldemoura@f5.com static nxt_bool_t nxt_proto_exiting;
821998St.nateldemoura@f5.com
831998St.nateldemoura@f5.com static nxt_app_module_t *nxt_app;
841998St.nateldemoura@f5.com static nxt_common_app_conf_t *nxt_app_conf;
85417Svbart@nginx.com
86417Svbart@nginx.com
871488St.nateldemoura@f5.com static const nxt_port_handlers_t nxt_discovery_process_port_handlers = {
881488St.nateldemoura@f5.com .quit = nxt_signal_quit_handler,
891488St.nateldemoura@f5.com .new_port = nxt_port_new_port_handler,
901488St.nateldemoura@f5.com .change_file = nxt_port_change_log_file_handler,
911488St.nateldemoura@f5.com .mmap = nxt_port_mmap_handler,
921488St.nateldemoura@f5.com .data = nxt_port_data_handler,
931488St.nateldemoura@f5.com .remove_pid = nxt_port_remove_pid_handler,
941488St.nateldemoura@f5.com .rpc_ready = nxt_port_rpc_handler,
951488St.nateldemoura@f5.com .rpc_error = nxt_port_rpc_handler,
961488St.nateldemoura@f5.com };
971488St.nateldemoura@f5.com
981488St.nateldemoura@f5.com
991998St.nateldemoura@f5.com const nxt_sig_event_t nxt_prototype_signals[] = {
1001998St.nateldemoura@f5.com nxt_event_signal(SIGHUP, nxt_proto_signal_handler),
1011998St.nateldemoura@f5.com nxt_event_signal(SIGINT, nxt_proto_sigterm_handler),
1021998St.nateldemoura@f5.com nxt_event_signal(SIGQUIT, nxt_proto_sigterm_handler),
1031998St.nateldemoura@f5.com nxt_event_signal(SIGTERM, nxt_proto_sigterm_handler),
1041998St.nateldemoura@f5.com nxt_event_signal(SIGCHLD, nxt_proto_sigchld_handler),
1051998St.nateldemoura@f5.com nxt_event_signal_end,
1061998St.nateldemoura@f5.com };
1071998St.nateldemoura@f5.com
1081998St.nateldemoura@f5.com
1091998St.nateldemoura@f5.com static const nxt_port_handlers_t nxt_proto_process_port_handlers = {
1101998St.nateldemoura@f5.com .quit = nxt_proto_quit_handler,
1111998St.nateldemoura@f5.com .change_file = nxt_port_change_log_file_handler,
1121998St.nateldemoura@f5.com .new_port = nxt_port_new_port_handler,
1131998St.nateldemoura@f5.com .process_created = nxt_proto_process_created_handler,
1141998St.nateldemoura@f5.com .process_ready = nxt_port_process_ready_handler,
1151998St.nateldemoura@f5.com .remove_pid = nxt_port_remove_pid_handler,
1161998St.nateldemoura@f5.com .start_process = nxt_proto_start_process_handler,
1171998St.nateldemoura@f5.com .rpc_ready = nxt_port_rpc_handler,
1181998St.nateldemoura@f5.com .rpc_error = nxt_port_rpc_handler,
1191998St.nateldemoura@f5.com };
1201998St.nateldemoura@f5.com
1211998St.nateldemoura@f5.com
1221488St.nateldemoura@f5.com static const nxt_port_handlers_t nxt_app_process_port_handlers = {
1231488St.nateldemoura@f5.com .quit = nxt_signal_quit_handler,
1241488St.nateldemoura@f5.com .rpc_ready = nxt_port_rpc_handler,
1251488St.nateldemoura@f5.com .rpc_error = nxt_port_rpc_handler,
1261488St.nateldemoura@f5.com };
1271488St.nateldemoura@f5.com
1281488St.nateldemoura@f5.com
1291488St.nateldemoura@f5.com const nxt_process_init_t nxt_discovery_process = {
1301488St.nateldemoura@f5.com .name = "discovery",
1311488St.nateldemoura@f5.com .type = NXT_PROCESS_DISCOVERY,
1321488St.nateldemoura@f5.com .prefork = NULL,
1331488St.nateldemoura@f5.com .restart = 0,
1341488St.nateldemoura@f5.com .setup = nxt_process_core_setup,
1351488St.nateldemoura@f5.com .start = nxt_discovery_start,
1361488St.nateldemoura@f5.com .port_handlers = &nxt_discovery_process_port_handlers,
1371488St.nateldemoura@f5.com .signals = nxt_process_signals,
1381488St.nateldemoura@f5.com };
1391488St.nateldemoura@f5.com
1401488St.nateldemoura@f5.com
1411998St.nateldemoura@f5.com const nxt_process_init_t nxt_proto_process = {
1421998St.nateldemoura@f5.com .type = NXT_PROCESS_PROTOTYPE,
1431998St.nateldemoura@f5.com .prefork = nxt_isolation_main_prefork,
1441998St.nateldemoura@f5.com .restart = 0,
1451998St.nateldemoura@f5.com .setup = nxt_proto_setup,
1461998St.nateldemoura@f5.com .start = nxt_proto_start,
1471998St.nateldemoura@f5.com .port_handlers = &nxt_proto_process_port_handlers,
1481998St.nateldemoura@f5.com .signals = nxt_prototype_signals,
1491998St.nateldemoura@f5.com };
1501998St.nateldemoura@f5.com
1511998St.nateldemoura@f5.com
1521488St.nateldemoura@f5.com const nxt_process_init_t nxt_app_process = {
1531488St.nateldemoura@f5.com .type = NXT_PROCESS_APP,
1541488St.nateldemoura@f5.com .setup = nxt_app_setup,
1551998St.nateldemoura@f5.com .start = NULL,
1561998St.nateldemoura@f5.com .prefork = NULL,
1571488St.nateldemoura@f5.com .restart = 0,
1581488St.nateldemoura@f5.com .port_handlers = &nxt_app_process_port_handlers,
1591488St.nateldemoura@f5.com .signals = nxt_process_signals,
1601488St.nateldemoura@f5.com };
1611488St.nateldemoura@f5.com
1621488St.nateldemoura@f5.com
1631488St.nateldemoura@f5.com static nxt_int_t
nxt_discovery_start(nxt_task_t * task,nxt_process_data_t * data)1641488St.nateldemoura@f5.com nxt_discovery_start(nxt_task_t *task, nxt_process_data_t *data)
165216Sigor@sysoev.ru {
166549Svbart@nginx.com uint32_t stream;
167549Svbart@nginx.com nxt_buf_t *b;
168549Svbart@nginx.com nxt_int_t ret;
169549Svbart@nginx.com nxt_port_t *main_port, *discovery_port;
170549Svbart@nginx.com nxt_runtime_t *rt;
171216Sigor@sysoev.ru
1721488St.nateldemoura@f5.com nxt_log(task, NXT_LOG_INFO, "discovery started");
173216Sigor@sysoev.ru
174233Sigor@sysoev.ru rt = task->thread->runtime;
175216Sigor@sysoev.ru
176233Sigor@sysoev.ru b = nxt_discovery_modules(task, rt->modules);
177250Sigor@sysoev.ru if (nxt_slow_path(b == NULL)) {
178549Svbart@nginx.com return NXT_ERROR;
179250Sigor@sysoev.ru }
180233Sigor@sysoev.ru
181240Sigor@sysoev.ru main_port = rt->port_by_type[NXT_PROCESS_MAIN];
182549Svbart@nginx.com discovery_port = rt->port_by_type[NXT_PROCESS_DISCOVERY];
183216Sigor@sysoev.ru
184549Svbart@nginx.com stream = nxt_port_rpc_register_handler(task, discovery_port,
185549Svbart@nginx.com nxt_discovery_quit,
186549Svbart@nginx.com nxt_discovery_quit,
187549Svbart@nginx.com main_port->pid, NULL);
188549Svbart@nginx.com
189645Svbart@nginx.com if (nxt_slow_path(stream == 0)) {
190645Svbart@nginx.com return NXT_ERROR;
191645Svbart@nginx.com }
192645Svbart@nginx.com
193549Svbart@nginx.com ret = nxt_port_socket_write(task, main_port, NXT_PORT_MSG_MODULES, -1,
194549Svbart@nginx.com stream, discovery_port->id, b);
195549Svbart@nginx.com
196549Svbart@nginx.com if (nxt_slow_path(ret != NXT_OK)) {
197549Svbart@nginx.com nxt_port_rpc_cancel(task, discovery_port, stream);
198549Svbart@nginx.com return NXT_ERROR;
199549Svbart@nginx.com }
200216Sigor@sysoev.ru
201216Sigor@sysoev.ru return NXT_OK;
202216Sigor@sysoev.ru }
203216Sigor@sysoev.ru
204216Sigor@sysoev.ru
205216Sigor@sysoev.ru static nxt_buf_t *
nxt_discovery_modules(nxt_task_t * task,const char * path)206216Sigor@sysoev.ru nxt_discovery_modules(nxt_task_t *task, const char *path)
207216Sigor@sysoev.ru {
2081489St.nateldemoura@f5.com char *name;
2091489St.nateldemoura@f5.com u_char *p, *end;
2101489St.nateldemoura@f5.com size_t size;
2111489St.nateldemoura@f5.com glob_t glb;
2121489St.nateldemoura@f5.com nxt_mp_t *mp;
2131489St.nateldemoura@f5.com nxt_buf_t *b;
2141489St.nateldemoura@f5.com nxt_int_t ret;
2151489St.nateldemoura@f5.com nxt_uint_t i, n, j;
2161489St.nateldemoura@f5.com nxt_array_t *modules, *mounts;
2171489St.nateldemoura@f5.com nxt_module_t *module;
2181489St.nateldemoura@f5.com nxt_fs_mount_t *mnt;
219216Sigor@sysoev.ru
220216Sigor@sysoev.ru b = NULL;
221216Sigor@sysoev.ru
222216Sigor@sysoev.ru mp = nxt_mp_create(1024, 128, 256, 32);
223216Sigor@sysoev.ru if (mp == NULL) {
224216Sigor@sysoev.ru return b;
225216Sigor@sysoev.ru }
226216Sigor@sysoev.ru
227216Sigor@sysoev.ru ret = glob(path, 0, NULL, &glb);
228216Sigor@sysoev.ru
229250Sigor@sysoev.ru n = glb.gl_pathc;
230250Sigor@sysoev.ru
231250Sigor@sysoev.ru if (ret != 0) {
232250Sigor@sysoev.ru nxt_log(task, NXT_LOG_NOTICE,
233250Sigor@sysoev.ru "no modules matching: \"%s\" found", path);
234250Sigor@sysoev.ru n = 0;
235250Sigor@sysoev.ru }
236216Sigor@sysoev.ru
237250Sigor@sysoev.ru modules = nxt_array_create(mp, n, sizeof(nxt_module_t));
238250Sigor@sysoev.ru if (modules == NULL) {
239250Sigor@sysoev.ru goto fail;
240250Sigor@sysoev.ru }
241250Sigor@sysoev.ru
242250Sigor@sysoev.ru for (i = 0; i < n; i++) {
243250Sigor@sysoev.ru name = glb.gl_pathv[i];
244250Sigor@sysoev.ru
245250Sigor@sysoev.ru ret = nxt_discovery_module(task, mp, modules, name);
246250Sigor@sysoev.ru if (ret != NXT_OK) {
247216Sigor@sysoev.ru goto fail;
248216Sigor@sysoev.ru }
249250Sigor@sysoev.ru }
250216Sigor@sysoev.ru
251703Svbart@nginx.com size = nxt_length("[]");
252250Sigor@sysoev.ru module = modules->elts;
253250Sigor@sysoev.ru n = modules->nelts;
254216Sigor@sysoev.ru
255250Sigor@sysoev.ru for (i = 0; i < n; i++) {
256356Svbart@nginx.com nxt_debug(task, "module: %d %V %V",
257356Svbart@nginx.com module[i].type, &module[i].version, &module[i].file);
258216Sigor@sysoev.ru
259703Svbart@nginx.com size += nxt_length("{\"type\": ,");
260703Svbart@nginx.com size += nxt_length(" \"version\": \"\",");
2611489St.nateldemoura@f5.com size += nxt_length(" \"file\": \"\",");
2621489St.nateldemoura@f5.com size += nxt_length(" \"mounts\": []},");
263216Sigor@sysoev.ru
264356Svbart@nginx.com size += NXT_INT_T_LEN
265250Sigor@sysoev.ru + module[i].version.length
266250Sigor@sysoev.ru + module[i].file.length;
2671489St.nateldemoura@f5.com
2681489St.nateldemoura@f5.com mounts = module[i].mounts;
2691489St.nateldemoura@f5.com
2701489St.nateldemoura@f5.com size += mounts->nelts * nxt_length("{\"src\": \"\", \"dst\": \"\", "
2711673St.nateldemoura@f5.com "\"type\": , \"name\": \"\", "
2721673St.nateldemoura@f5.com "\"flags\": , \"data\": \"\"},");
2731489St.nateldemoura@f5.com
2741489St.nateldemoura@f5.com mnt = mounts->elts;
2751489St.nateldemoura@f5.com
2761489St.nateldemoura@f5.com for (j = 0; j < mounts->nelts; j++) {
2771489St.nateldemoura@f5.com size += nxt_strlen(mnt[j].src) + nxt_strlen(mnt[j].dst)
2781673St.nateldemoura@f5.com + nxt_strlen(mnt[j].name) + (2 * NXT_INT_T_LEN)
2791489St.nateldemoura@f5.com + (mnt[j].data == NULL ? 0 : nxt_strlen(mnt[j].data));
2801489St.nateldemoura@f5.com }
281250Sigor@sysoev.ru }
282216Sigor@sysoev.ru
283250Sigor@sysoev.ru b = nxt_buf_mem_alloc(mp, size, 0);
284250Sigor@sysoev.ru if (b == NULL) {
285250Sigor@sysoev.ru goto fail;
286250Sigor@sysoev.ru }
287216Sigor@sysoev.ru
288250Sigor@sysoev.ru b->completion_handler = nxt_discovery_completion_handler;
289216Sigor@sysoev.ru
290250Sigor@sysoev.ru p = b->mem.free;
291250Sigor@sysoev.ru end = b->mem.end;
292250Sigor@sysoev.ru *p++ = '[';
293216Sigor@sysoev.ru
294250Sigor@sysoev.ru for (i = 0; i < n; i++) {
2951489St.nateldemoura@f5.com mounts = module[i].mounts;
2961489St.nateldemoura@f5.com
2971489St.nateldemoura@f5.com p = nxt_sprintf(p, end, "{\"type\": %d, \"version\": \"%V\", "
2981489St.nateldemoura@f5.com "\"file\": \"%V\", \"mounts\": [",
2991489St.nateldemoura@f5.com module[i].type, &module[i].version, &module[i].file);
3001489St.nateldemoura@f5.com
3011489St.nateldemoura@f5.com mnt = mounts->elts;
3021489St.nateldemoura@f5.com for (j = 0; j < mounts->nelts; j++) {
3031489St.nateldemoura@f5.com p = nxt_sprintf(p, end,
3041489St.nateldemoura@f5.com "{\"src\": \"%s\", \"dst\": \"%s\", "
3051673St.nateldemoura@f5.com "\"name\": \"%s\", \"type\": %d, \"flags\": %d, "
3061489St.nateldemoura@f5.com "\"data\": \"%s\"},",
3071673St.nateldemoura@f5.com mnt[j].src, mnt[j].dst, mnt[j].name, mnt[j].type,
3081673St.nateldemoura@f5.com mnt[j].flags,
3091489St.nateldemoura@f5.com mnt[j].data == NULL ? (u_char *) "" : mnt[j].data);
3101489St.nateldemoura@f5.com }
3111489St.nateldemoura@f5.com
3121489St.nateldemoura@f5.com *p++ = ']';
3131489St.nateldemoura@f5.com *p++ = '}';
3141489St.nateldemoura@f5.com *p++ = ',';
315250Sigor@sysoev.ru }
316216Sigor@sysoev.ru
317250Sigor@sysoev.ru *p++ = ']';
3181489St.nateldemoura@f5.com
3191515Smax.romanov@nginx.com if (nxt_slow_path(p > end)) {
3201489St.nateldemoura@f5.com nxt_alert(task, "discovery write past the buffer");
3211489St.nateldemoura@f5.com goto fail;
3221489St.nateldemoura@f5.com }
3231489St.nateldemoura@f5.com
324250Sigor@sysoev.ru b->mem.free = p;
325216Sigor@sysoev.ru
326216Sigor@sysoev.ru fail:
327216Sigor@sysoev.ru
328216Sigor@sysoev.ru globfree(&glb);
329216Sigor@sysoev.ru
330216Sigor@sysoev.ru return b;
331216Sigor@sysoev.ru }
332216Sigor@sysoev.ru
333216Sigor@sysoev.ru
334216Sigor@sysoev.ru static nxt_int_t
nxt_discovery_module(nxt_task_t * task,nxt_mp_t * mp,nxt_array_t * modules,const char * name)335216Sigor@sysoev.ru nxt_discovery_module(nxt_task_t *task, nxt_mp_t *mp, nxt_array_t *modules,
336216Sigor@sysoev.ru const char *name)
337216Sigor@sysoev.ru {
3381489St.nateldemoura@f5.com void *dl;
3391489St.nateldemoura@f5.com nxt_str_t version;
3401489St.nateldemoura@f5.com nxt_int_t ret;
3411489St.nateldemoura@f5.com nxt_uint_t i, j, n;
3421489St.nateldemoura@f5.com nxt_array_t *mounts;
3431489St.nateldemoura@f5.com nxt_module_t *module;
3441489St.nateldemoura@f5.com nxt_app_type_t type;
3451489St.nateldemoura@f5.com nxt_fs_mount_t *to;
3461489St.nateldemoura@f5.com nxt_app_module_t *app;
3471489St.nateldemoura@f5.com const nxt_fs_mount_t *from;
348216Sigor@sysoev.ru
349216Sigor@sysoev.ru /*
350216Sigor@sysoev.ru * Only memory allocation failure should return NXT_ERROR.
351216Sigor@sysoev.ru * Any module processing errors are ignored.
352216Sigor@sysoev.ru */
353216Sigor@sysoev.ru ret = NXT_ERROR;
354216Sigor@sysoev.ru
355216Sigor@sysoev.ru dl = dlopen(name, RTLD_GLOBAL | RTLD_NOW);
356216Sigor@sysoev.ru
357216Sigor@sysoev.ru if (dl == NULL) {
358564Svbart@nginx.com nxt_alert(task, "dlopen(\"%s\"), failed: \"%s\"", name, dlerror());
359216Sigor@sysoev.ru return NXT_OK;
360216Sigor@sysoev.ru }
361216Sigor@sysoev.ru
362216Sigor@sysoev.ru app = dlsym(dl, "nxt_app_module");
363216Sigor@sysoev.ru
364216Sigor@sysoev.ru if (app != NULL) {
365612Salexander.borisov@nginx.com nxt_log(task, NXT_LOG_NOTICE, "module: %V %s \"%s\"",
366612Salexander.borisov@nginx.com &app->type, app->version, name);
367258Sigor@sysoev.ru
368258Sigor@sysoev.ru if (app->compat_length != sizeof(compat)
3692231Salx@nginx.com || memcmp(app->compat, compat, sizeof(compat)) != 0)
370258Sigor@sysoev.ru {
371258Sigor@sysoev.ru nxt_log(task, NXT_LOG_NOTICE, "incompatible module %s", name);
372258Sigor@sysoev.ru
373258Sigor@sysoev.ru goto done;
374258Sigor@sysoev.ru }
375216Sigor@sysoev.ru
376356Svbart@nginx.com type = nxt_app_parse_type(app->type.start, app->type.length);
377356Svbart@nginx.com
378356Svbart@nginx.com if (type == NXT_APP_UNKNOWN) {
379494Spluknet@nginx.com nxt_log(task, NXT_LOG_NOTICE, "unknown module type %V", &app->type);
380356Svbart@nginx.com
381356Svbart@nginx.com goto done;
382356Svbart@nginx.com }
383356Svbart@nginx.com
384216Sigor@sysoev.ru module = modules->elts;
385216Sigor@sysoev.ru n = modules->nelts;
386216Sigor@sysoev.ru
387612Salexander.borisov@nginx.com version.start = (u_char *) app->version;
388612Salexander.borisov@nginx.com version.length = nxt_strlen(app->version);
389612Salexander.borisov@nginx.com
390216Sigor@sysoev.ru for (i = 0; i < n; i++) {
391356Svbart@nginx.com if (type == module[i].type
392612Salexander.borisov@nginx.com && nxt_strstr_eq(&module[i].version, &version))
393258Sigor@sysoev.ru {
394216Sigor@sysoev.ru nxt_log(task, NXT_LOG_NOTICE,
395216Sigor@sysoev.ru "ignoring %s module with the same "
396267Sigor@sysoev.ru "application language version %V %V as in %V",
397655Svbart@nginx.com name, &app->type, &version, &module[i].file);
398216Sigor@sysoev.ru
399216Sigor@sysoev.ru goto done;
400216Sigor@sysoev.ru }
401216Sigor@sysoev.ru }
402216Sigor@sysoev.ru
403216Sigor@sysoev.ru module = nxt_array_add(modules);
404216Sigor@sysoev.ru if (module == NULL) {
405216Sigor@sysoev.ru goto fail;
406216Sigor@sysoev.ru }
407216Sigor@sysoev.ru
408356Svbart@nginx.com module->type = type;
409216Sigor@sysoev.ru
410612Salexander.borisov@nginx.com nxt_str_dup(mp, &module->version, &version);
411612Salexander.borisov@nginx.com if (module->version.start == NULL) {
412216Sigor@sysoev.ru goto fail;
413216Sigor@sysoev.ru }
414216Sigor@sysoev.ru
415216Sigor@sysoev.ru module->file.length = nxt_strlen(name);
416216Sigor@sysoev.ru
417216Sigor@sysoev.ru module->file.start = nxt_mp_alloc(mp, module->file.length);
418216Sigor@sysoev.ru if (module->file.start == NULL) {
419216Sigor@sysoev.ru goto fail;
420216Sigor@sysoev.ru }
421216Sigor@sysoev.ru
422216Sigor@sysoev.ru nxt_memcpy(module->file.start, name, module->file.length);
423216Sigor@sysoev.ru
4241489St.nateldemoura@f5.com module->mounts = nxt_array_create(mp, app->nmounts,
4251489St.nateldemoura@f5.com sizeof(nxt_fs_mount_t));
4261489St.nateldemoura@f5.com
4271489St.nateldemoura@f5.com if (nxt_slow_path(module->mounts == NULL)) {
4281489St.nateldemoura@f5.com goto fail;
4291489St.nateldemoura@f5.com }
4301489St.nateldemoura@f5.com
4311489St.nateldemoura@f5.com mounts = module->mounts;
4321489St.nateldemoura@f5.com
4331489St.nateldemoura@f5.com for (j = 0; j < app->nmounts; j++) {
4341489St.nateldemoura@f5.com from = &app->mounts[j];
4351489St.nateldemoura@f5.com to = nxt_array_zero_add(mounts);
4361489St.nateldemoura@f5.com if (nxt_slow_path(to == NULL)) {
4371489St.nateldemoura@f5.com goto fail;
4381489St.nateldemoura@f5.com }
4391489St.nateldemoura@f5.com
4401489St.nateldemoura@f5.com to->src = nxt_cstr_dup(mp, to->src, from->src);
4411489St.nateldemoura@f5.com if (nxt_slow_path(to->src == NULL)) {
4421489St.nateldemoura@f5.com goto fail;
4431489St.nateldemoura@f5.com }
4441489St.nateldemoura@f5.com
4451489St.nateldemoura@f5.com to->dst = nxt_cstr_dup(mp, to->dst, from->dst);
4461489St.nateldemoura@f5.com if (nxt_slow_path(to->dst == NULL)) {
4471489St.nateldemoura@f5.com goto fail;
4481489St.nateldemoura@f5.com }
4491489St.nateldemoura@f5.com
4501673St.nateldemoura@f5.com to->name = nxt_cstr_dup(mp, to->name, from->name);
4511673St.nateldemoura@f5.com if (nxt_slow_path(to->name == NULL)) {
4521489St.nateldemoura@f5.com goto fail;
4531489St.nateldemoura@f5.com }
4541489St.nateldemoura@f5.com
4551673St.nateldemoura@f5.com to->type = from->type;
4561673St.nateldemoura@f5.com
4571489St.nateldemoura@f5.com if (from->data != NULL) {
4581489St.nateldemoura@f5.com to->data = nxt_cstr_dup(mp, to->data, from->data);
4591489St.nateldemoura@f5.com if (nxt_slow_path(to->data == NULL)) {
4601489St.nateldemoura@f5.com goto fail;
4611489St.nateldemoura@f5.com }
4621489St.nateldemoura@f5.com }
4631489St.nateldemoura@f5.com
4641489St.nateldemoura@f5.com to->flags = from->flags;
4651489St.nateldemoura@f5.com }
4661489St.nateldemoura@f5.com
467216Sigor@sysoev.ru } else {
468564Svbart@nginx.com nxt_alert(task, "dlsym(\"%s\"), failed: \"%s\"", name, dlerror());
469216Sigor@sysoev.ru }
470216Sigor@sysoev.ru
471216Sigor@sysoev.ru done:
472216Sigor@sysoev.ru
473216Sigor@sysoev.ru ret = NXT_OK;
474216Sigor@sysoev.ru
475216Sigor@sysoev.ru fail:
476216Sigor@sysoev.ru
477216Sigor@sysoev.ru if (dlclose(dl) != 0) {
478564Svbart@nginx.com nxt_alert(task, "dlclose(\"%s\"), failed: \"%s\"", name, dlerror());
479216Sigor@sysoev.ru }
480216Sigor@sysoev.ru
481216Sigor@sysoev.ru return ret;
482216Sigor@sysoev.ru }
483216Sigor@sysoev.ru
484216Sigor@sysoev.ru
485549Svbart@nginx.com static void
nxt_discovery_completion_handler(nxt_task_t * task,void * obj,void * data)486549Svbart@nginx.com nxt_discovery_completion_handler(nxt_task_t *task, void *obj, void *data)
487549Svbart@nginx.com {
488549Svbart@nginx.com nxt_mp_t *mp;
489549Svbart@nginx.com nxt_buf_t *b;
490549Svbart@nginx.com
491549Svbart@nginx.com b = obj;
492549Svbart@nginx.com mp = b->data;
493549Svbart@nginx.com
494549Svbart@nginx.com nxt_mp_destroy(mp);
495549Svbart@nginx.com }
496549Svbart@nginx.com
497549Svbart@nginx.com
498549Svbart@nginx.com static void
nxt_discovery_quit(nxt_task_t * task,nxt_port_recv_msg_t * msg,void * data)499549Svbart@nginx.com nxt_discovery_quit(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data)
500549Svbart@nginx.com {
5011488St.nateldemoura@f5.com nxt_signal_quit_handler(task, msg);
502549Svbart@nginx.com }
503549Svbart@nginx.com
504549Svbart@nginx.com
5051488St.nateldemoura@f5.com static nxt_int_t
nxt_proto_setup(nxt_task_t * task,nxt_process_t * process)5061998St.nateldemoura@f5.com nxt_proto_setup(nxt_task_t *task, nxt_process_t *process)
5070Sigor@sysoev.ru {
508216Sigor@sysoev.ru nxt_int_t ret;
509216Sigor@sysoev.ru nxt_app_lang_module_t *lang;
510216Sigor@sysoev.ru nxt_common_app_conf_t *app_conf;
511141Smax.romanov@nginx.com
5121488St.nateldemoura@f5.com app_conf = process->data.app;
513141Smax.romanov@nginx.com
5141998St.nateldemoura@f5.com nxt_queue_init(&nxt_proto_children);
5151998St.nateldemoura@f5.com
5161998St.nateldemoura@f5.com nxt_app_conf = app_conf;
5171998St.nateldemoura@f5.com
518216Sigor@sysoev.ru lang = nxt_app_lang_module(task->thread->runtime, &app_conf->type);
519216Sigor@sysoev.ru if (nxt_slow_path(lang == NULL)) {
520564Svbart@nginx.com nxt_alert(task, "unknown application type: \"%V\"", &app_conf->type);
521216Sigor@sysoev.ru return NXT_ERROR;
522216Sigor@sysoev.ru }
523216Sigor@sysoev.ru
524216Sigor@sysoev.ru nxt_app = lang->module;
525216Sigor@sysoev.ru
526216Sigor@sysoev.ru if (nxt_app == NULL) {
527354Svbart@nginx.com nxt_debug(task, "application language module: %s \"%s\"",
528354Svbart@nginx.com lang->version, lang->file);
529216Sigor@sysoev.ru
530216Sigor@sysoev.ru nxt_app = nxt_app_module_load(task, lang->file);
5311239Smax.romanov@nginx.com if (nxt_slow_path(nxt_app == NULL)) {
5321239Smax.romanov@nginx.com return NXT_ERROR;
5331239Smax.romanov@nginx.com }
534216Sigor@sysoev.ru }
535216Sigor@sysoev.ru
5361489St.nateldemoura@f5.com if (nxt_slow_path(nxt_app_set_environment(app_conf->environment)
5371489St.nateldemoura@f5.com != NXT_OK))
5381489St.nateldemoura@f5.com {
5391489St.nateldemoura@f5.com nxt_alert(task, "failed to set environment");
5401489St.nateldemoura@f5.com return NXT_ERROR;
5411489St.nateldemoura@f5.com }
5421489St.nateldemoura@f5.com
5431488St.nateldemoura@f5.com if (nxt_app->setup != NULL) {
5441488St.nateldemoura@f5.com ret = nxt_app->setup(task, process, app_conf);
545977Smax.romanov@gmail.com if (nxt_slow_path(ret != NXT_OK)) {
5461104Smax.romanov@nginx.com return ret;
547977Smax.romanov@gmail.com }
548977Smax.romanov@gmail.com }
549977Smax.romanov@gmail.com
5501489St.nateldemoura@f5.com #if (NXT_HAVE_ISOLATION_ROOTFS)
5511489St.nateldemoura@f5.com if (process->isolation.rootfs != NULL) {
5521489St.nateldemoura@f5.com if (process->isolation.mounts != NULL) {
5531579St.nateldemoura@f5.com ret = nxt_isolation_prepare_rootfs(task, process);
5541489St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
5551489St.nateldemoura@f5.com return ret;
5561489St.nateldemoura@f5.com }
5571489St.nateldemoura@f5.com }
5581489St.nateldemoura@f5.com
5591579St.nateldemoura@f5.com ret = nxt_isolation_change_root(task, process);
5601489St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
5611489St.nateldemoura@f5.com return NXT_ERROR;
5621489St.nateldemoura@f5.com }
5631489St.nateldemoura@f5.com }
5641489St.nateldemoura@f5.com #endif
5651489St.nateldemoura@f5.com
566277Sigor@sysoev.ru if (app_conf->working_directory != NULL
567277Sigor@sysoev.ru && app_conf->working_directory[0] != 0)
568271Smax.romanov@nginx.com {
569271Smax.romanov@nginx.com ret = chdir(app_conf->working_directory);
570271Smax.romanov@nginx.com
571271Smax.romanov@nginx.com if (nxt_slow_path(ret != 0)) {
572271Smax.romanov@nginx.com nxt_log(task, NXT_LOG_WARN, "chdir(%s) failed %E",
573271Smax.romanov@nginx.com app_conf->working_directory, nxt_errno);
574271Smax.romanov@nginx.com
575271Smax.romanov@nginx.com return NXT_ERROR;
576271Smax.romanov@nginx.com }
577271Smax.romanov@nginx.com }
578271Smax.romanov@nginx.com
5791998St.nateldemoura@f5.com process->state = NXT_PROCESS_STATE_CREATED;
5801998St.nateldemoura@f5.com
5811998St.nateldemoura@f5.com return NXT_OK;
5821998St.nateldemoura@f5.com }
5831998St.nateldemoura@f5.com
5841998St.nateldemoura@f5.com
5851998St.nateldemoura@f5.com static nxt_int_t
nxt_proto_start(nxt_task_t * task,nxt_process_data_t * data)5861998St.nateldemoura@f5.com nxt_proto_start(nxt_task_t *task, nxt_process_data_t *data)
5871998St.nateldemoura@f5.com {
5881998St.nateldemoura@f5.com nxt_debug(task, "prototype waiting for clone messages");
5891998St.nateldemoura@f5.com
5901998St.nateldemoura@f5.com return NXT_OK;
5911998St.nateldemoura@f5.com }
5921998St.nateldemoura@f5.com
5931998St.nateldemoura@f5.com
5941998St.nateldemoura@f5.com static void
nxt_proto_start_process_handler(nxt_task_t * task,nxt_port_recv_msg_t * msg)5951998St.nateldemoura@f5.com nxt_proto_start_process_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
5961998St.nateldemoura@f5.com {
5971998St.nateldemoura@f5.com u_char *p;
5981998St.nateldemoura@f5.com nxt_int_t ret;
5991998St.nateldemoura@f5.com nxt_port_t *port;
6001998St.nateldemoura@f5.com nxt_runtime_t *rt;
6011998St.nateldemoura@f5.com nxt_process_t *process;
6021998St.nateldemoura@f5.com nxt_process_init_t *init;
6031998St.nateldemoura@f5.com
6041998St.nateldemoura@f5.com rt = task->thread->runtime;
6051998St.nateldemoura@f5.com
6061998St.nateldemoura@f5.com process = nxt_process_new(rt);
6071998St.nateldemoura@f5.com if (nxt_slow_path(process == NULL)) {
6081998St.nateldemoura@f5.com goto failed;
6091998St.nateldemoura@f5.com }
6101998St.nateldemoura@f5.com
6111998St.nateldemoura@f5.com process->mem_pool = nxt_mp_create(1024, 128, 256, 32);
6121998St.nateldemoura@f5.com if (nxt_slow_path(process->mem_pool == NULL)) {
6131998St.nateldemoura@f5.com nxt_process_use(task, process, -1);
6141998St.nateldemoura@f5.com goto failed;
6151998St.nateldemoura@f5.com }
6161998St.nateldemoura@f5.com
6171998St.nateldemoura@f5.com process->parent_port = rt->port_by_type[NXT_PROCESS_PROTOTYPE];
6181998St.nateldemoura@f5.com
6191488St.nateldemoura@f5.com init = nxt_process_init(process);
6201998St.nateldemoura@f5.com *init = nxt_app_process;
6211998St.nateldemoura@f5.com
6221998St.nateldemoura@f5.com process->name = nxt_mp_alloc(process->mem_pool, nxt_app_conf->name.length
6231998St.nateldemoura@f5.com + sizeof("\"\" application") + 1);
6241998St.nateldemoura@f5.com
6251998St.nateldemoura@f5.com if (nxt_slow_path(process->name == NULL)) {
6261998St.nateldemoura@f5.com nxt_process_use(task, process, -1);
6271998St.nateldemoura@f5.com
6281998St.nateldemoura@f5.com goto failed;
6291998St.nateldemoura@f5.com }
630141Smax.romanov@nginx.com
6311488St.nateldemoura@f5.com init->start = nxt_app->start;
632141Smax.romanov@nginx.com
6331998St.nateldemoura@f5.com init->name = (const char *) nxt_app_conf->name.start;
6341998St.nateldemoura@f5.com
6351998St.nateldemoura@f5.com p = (u_char *) process->name;
6361998St.nateldemoura@f5.com *p++ = '"';
6371998St.nateldemoura@f5.com p = nxt_cpymem(p, nxt_app_conf->name.start, nxt_app_conf->name.length);
6381998St.nateldemoura@f5.com p = nxt_cpymem(p, "\" application", 13);
6391998St.nateldemoura@f5.com *p = '\0';
6401998St.nateldemoura@f5.com
6411998St.nateldemoura@f5.com process->user_cred = &rt->user_cred;
6421998St.nateldemoura@f5.com
6431998St.nateldemoura@f5.com process->data.app = nxt_app_conf;
6441998St.nateldemoura@f5.com process->stream = msg->port_msg.stream;
6451998St.nateldemoura@f5.com
6462174Smax.romanov@gmail.com init->siblings = &nxt_proto_children;
6472174Smax.romanov@gmail.com
6481998St.nateldemoura@f5.com ret = nxt_process_start(task, process);
6491998St.nateldemoura@f5.com if (nxt_slow_path(ret == NXT_ERROR)) {
6501998St.nateldemoura@f5.com nxt_process_use(task, process, -1);
6511998St.nateldemoura@f5.com
6521998St.nateldemoura@f5.com goto failed;
6531998St.nateldemoura@f5.com }
6541998St.nateldemoura@f5.com
6551998St.nateldemoura@f5.com nxt_proto_process_add(task, process);
6561998St.nateldemoura@f5.com
6571998St.nateldemoura@f5.com return;
6581998St.nateldemoura@f5.com
6591998St.nateldemoura@f5.com failed:
6601998St.nateldemoura@f5.com
6611998St.nateldemoura@f5.com port = nxt_runtime_port_find(rt, msg->port_msg.pid,
6621998St.nateldemoura@f5.com msg->port_msg.reply_port);
6631998St.nateldemoura@f5.com
6641998St.nateldemoura@f5.com if (nxt_fast_path(port != NULL)) {
6651998St.nateldemoura@f5.com nxt_port_socket_write(task, port, NXT_PORT_MSG_RPC_ERROR,
6661998St.nateldemoura@f5.com -1, msg->port_msg.stream, 0, NULL);
6671998St.nateldemoura@f5.com }
6681998St.nateldemoura@f5.com }
6691998St.nateldemoura@f5.com
6701998St.nateldemoura@f5.com
6711998St.nateldemoura@f5.com static void
nxt_proto_quit_handler(nxt_task_t * task,nxt_port_recv_msg_t * msg)6721998St.nateldemoura@f5.com nxt_proto_quit_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
6731998St.nateldemoura@f5.com {
6741998St.nateldemoura@f5.com nxt_debug(task, "prototype quit handler");
6751998St.nateldemoura@f5.com
6761998St.nateldemoura@f5.com nxt_proto_quit_children(task);
6771998St.nateldemoura@f5.com
6781998St.nateldemoura@f5.com nxt_proto_exiting = 1;
6791998St.nateldemoura@f5.com
6801998St.nateldemoura@f5.com if (nxt_queue_is_empty(&nxt_proto_children)) {
6811998St.nateldemoura@f5.com nxt_process_quit(task, 0);
6821998St.nateldemoura@f5.com }
6831998St.nateldemoura@f5.com }
6841998St.nateldemoura@f5.com
6851998St.nateldemoura@f5.com
6861998St.nateldemoura@f5.com static void
nxt_proto_quit_children(nxt_task_t * task)6871998St.nateldemoura@f5.com nxt_proto_quit_children(nxt_task_t *task)
6881998St.nateldemoura@f5.com {
6891998St.nateldemoura@f5.com nxt_port_t *port;
6901998St.nateldemoura@f5.com nxt_process_t *process;
6911998St.nateldemoura@f5.com
6921998St.nateldemoura@f5.com nxt_queue_each(process, &nxt_proto_children, nxt_process_t, link) {
6931998St.nateldemoura@f5.com port = nxt_process_port_first(process);
6941998St.nateldemoura@f5.com
6951998St.nateldemoura@f5.com (void) nxt_port_socket_write(task, port, NXT_PORT_MSG_QUIT,
6961998St.nateldemoura@f5.com -1, 0, 0, NULL);
6971998St.nateldemoura@f5.com }
6981998St.nateldemoura@f5.com nxt_queue_loop;
6991998St.nateldemoura@f5.com }
7001998St.nateldemoura@f5.com
7011998St.nateldemoura@f5.com
7021998St.nateldemoura@f5.com static void
nxt_proto_process_created_handler(nxt_task_t * task,nxt_port_recv_msg_t * msg)7031998St.nateldemoura@f5.com nxt_proto_process_created_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
7041998St.nateldemoura@f5.com {
7051998St.nateldemoura@f5.com nxt_pid_t isolated_pid, pid;
7061998St.nateldemoura@f5.com nxt_process_t *process;
7071998St.nateldemoura@f5.com
7081998St.nateldemoura@f5.com isolated_pid = nxt_recv_msg_cmsg_pid(msg);
7091998St.nateldemoura@f5.com
7101998St.nateldemoura@f5.com process = nxt_proto_process_find(task, isolated_pid);
7111998St.nateldemoura@f5.com if (nxt_slow_path(process == NULL)) {
7121998St.nateldemoura@f5.com return;
7131998St.nateldemoura@f5.com }
7141998St.nateldemoura@f5.com
7151488St.nateldemoura@f5.com process->state = NXT_PROCESS_STATE_CREATED;
71620Sigor@sysoev.ru
7171998St.nateldemoura@f5.com pid = msg->port_msg.pid;
7181998St.nateldemoura@f5.com
7191998St.nateldemoura@f5.com if (process->pid != pid) {
7201998St.nateldemoura@f5.com nxt_debug(task, "app process %PI (aka %PI) is created", isolated_pid,
7211998St.nateldemoura@f5.com pid);
7221998St.nateldemoura@f5.com
7232174Smax.romanov@gmail.com process->pid = pid;
7241998St.nateldemoura@f5.com
7252174Smax.romanov@gmail.com } else {
7262174Smax.romanov@gmail.com nxt_debug(task, "app process %PI is created", isolated_pid);
7272174Smax.romanov@gmail.com }
7282174Smax.romanov@gmail.com
7292174Smax.romanov@gmail.com if (!process->registered) {
7302174Smax.romanov@gmail.com nxt_assert(!nxt_queue_is_empty(&process->ports));
7311998St.nateldemoura@f5.com
7321998St.nateldemoura@f5.com nxt_runtime_process_add(task, process);
7331998St.nateldemoura@f5.com
7342174Smax.romanov@gmail.com nxt_port_use(task, nxt_process_port_first(process), -1);
7351998St.nateldemoura@f5.com }
7361998St.nateldemoura@f5.com }
7371998St.nateldemoura@f5.com
7381998St.nateldemoura@f5.com
7391998St.nateldemoura@f5.com static void
nxt_proto_signal_handler(nxt_task_t * task,void * obj,void * data)7401998St.nateldemoura@f5.com nxt_proto_signal_handler(nxt_task_t *task, void *obj, void *data)
7411998St.nateldemoura@f5.com {
7421998St.nateldemoura@f5.com nxt_trace(task, "signal signo:%d (%s) received, ignored",
7431998St.nateldemoura@f5.com (int) (uintptr_t) obj, data);
7441998St.nateldemoura@f5.com }
7451998St.nateldemoura@f5.com
7461998St.nateldemoura@f5.com
7471998St.nateldemoura@f5.com static void
nxt_proto_sigterm_handler(nxt_task_t * task,void * obj,void * data)7481998St.nateldemoura@f5.com nxt_proto_sigterm_handler(nxt_task_t *task, void *obj, void *data)
7491998St.nateldemoura@f5.com {
7501998St.nateldemoura@f5.com nxt_trace(task, "signal signo:%d (%s) received",
7511998St.nateldemoura@f5.com (int) (uintptr_t) obj, data);
7521998St.nateldemoura@f5.com
7531998St.nateldemoura@f5.com nxt_proto_quit_children(task);
7541998St.nateldemoura@f5.com
7551998St.nateldemoura@f5.com nxt_proto_exiting = 1;
7561998St.nateldemoura@f5.com
7571998St.nateldemoura@f5.com if (nxt_queue_is_empty(&nxt_proto_children)) {
7581998St.nateldemoura@f5.com nxt_process_quit(task, 0);
7591998St.nateldemoura@f5.com }
7601998St.nateldemoura@f5.com }
7611998St.nateldemoura@f5.com
7621998St.nateldemoura@f5.com
7631998St.nateldemoura@f5.com static void
nxt_proto_sigchld_handler(nxt_task_t * task,void * obj,void * data)7641998St.nateldemoura@f5.com nxt_proto_sigchld_handler(nxt_task_t *task, void *obj, void *data)
7651998St.nateldemoura@f5.com {
7661998St.nateldemoura@f5.com int status;
7671998St.nateldemoura@f5.com nxt_err_t err;
7681998St.nateldemoura@f5.com nxt_pid_t pid;
7692174Smax.romanov@gmail.com nxt_port_t *port;
7701998St.nateldemoura@f5.com nxt_process_t *process;
7712174Smax.romanov@gmail.com nxt_runtime_t *rt;
7722174Smax.romanov@gmail.com
7732174Smax.romanov@gmail.com rt = task->thread->runtime;
7741998St.nateldemoura@f5.com
7751998St.nateldemoura@f5.com nxt_debug(task, "proto sigchld handler signo:%d (%s)",
7761998St.nateldemoura@f5.com (int) (uintptr_t) obj, data);
7771998St.nateldemoura@f5.com
7781998St.nateldemoura@f5.com for ( ;; ) {
7791998St.nateldemoura@f5.com pid = waitpid(-1, &status, WNOHANG);
7801998St.nateldemoura@f5.com
7811998St.nateldemoura@f5.com if (pid == -1) {
7821998St.nateldemoura@f5.com
7831998St.nateldemoura@f5.com switch (err = nxt_errno) {
7841998St.nateldemoura@f5.com
7851998St.nateldemoura@f5.com case NXT_ECHILD:
7861998St.nateldemoura@f5.com return;
7871998St.nateldemoura@f5.com
7881998St.nateldemoura@f5.com case NXT_EINTR:
7891998St.nateldemoura@f5.com continue;
7901998St.nateldemoura@f5.com
7911998St.nateldemoura@f5.com default:
7921998St.nateldemoura@f5.com nxt_alert(task, "waitpid() failed: %E", err);
7931998St.nateldemoura@f5.com return;
7941998St.nateldemoura@f5.com }
7951998St.nateldemoura@f5.com }
7961998St.nateldemoura@f5.com
7971998St.nateldemoura@f5.com nxt_debug(task, "waitpid(): %PI", pid);
7981998St.nateldemoura@f5.com
7991998St.nateldemoura@f5.com if (pid == 0) {
8001998St.nateldemoura@f5.com return;
8011998St.nateldemoura@f5.com }
8021998St.nateldemoura@f5.com
8032174Smax.romanov@gmail.com process = nxt_proto_process_remove(task, pid);
8042174Smax.romanov@gmail.com
8051998St.nateldemoura@f5.com if (WTERMSIG(status)) {
8062174Smax.romanov@gmail.com if (rt->is_pid_isolated) {
8072174Smax.romanov@gmail.com nxt_alert(task, "app process %PI (isolated %PI) "
8082174Smax.romanov@gmail.com "exited on signal %d%s",
8092174Smax.romanov@gmail.com process != NULL ? process->pid : 0,
8102174Smax.romanov@gmail.com pid, WTERMSIG(status),
8112174Smax.romanov@gmail.com NXT_WCOREDUMP(status) ? " (core dumped)" : "");
8122174Smax.romanov@gmail.com
8132174Smax.romanov@gmail.com } else {
8142174Smax.romanov@gmail.com nxt_alert(task, "app process %PI exited on signal %d%s",
8152174Smax.romanov@gmail.com pid, WTERMSIG(status),
8162174Smax.romanov@gmail.com NXT_WCOREDUMP(status) ? " (core dumped)" : "");
8172174Smax.romanov@gmail.com }
8181998St.nateldemoura@f5.com
8191998St.nateldemoura@f5.com } else {
8202174Smax.romanov@gmail.com if (rt->is_pid_isolated) {
8212174Smax.romanov@gmail.com nxt_trace(task, "app process %PI (isolated %PI) "
8222174Smax.romanov@gmail.com "exited with code %d",
8232174Smax.romanov@gmail.com process != NULL ? process->pid : 0,
8242174Smax.romanov@gmail.com pid, WEXITSTATUS(status));
8252174Smax.romanov@gmail.com
8262174Smax.romanov@gmail.com } else {
8272174Smax.romanov@gmail.com nxt_trace(task, "app process %PI exited with code %d",
8282174Smax.romanov@gmail.com pid, WEXITSTATUS(status));
8292174Smax.romanov@gmail.com }
8301998St.nateldemoura@f5.com }
8311998St.nateldemoura@f5.com
8321998St.nateldemoura@f5.com if (process == NULL) {
8331998St.nateldemoura@f5.com continue;
8341998St.nateldemoura@f5.com }
8351998St.nateldemoura@f5.com
8362174Smax.romanov@gmail.com if (process->registered) {
8372174Smax.romanov@gmail.com port = NULL;
8382174Smax.romanov@gmail.com
8392174Smax.romanov@gmail.com } else {
8402174Smax.romanov@gmail.com nxt_assert(!nxt_queue_is_empty(&process->ports));
8412174Smax.romanov@gmail.com
8422174Smax.romanov@gmail.com port = nxt_process_port_first(process);
8432174Smax.romanov@gmail.com }
8442174Smax.romanov@gmail.com
8451998St.nateldemoura@f5.com if (process->state != NXT_PROCESS_STATE_CREATING) {
8461998St.nateldemoura@f5.com nxt_port_remove_notify_others(task, process);
8471998St.nateldemoura@f5.com }
8481998St.nateldemoura@f5.com
8491998St.nateldemoura@f5.com nxt_process_close_ports(task, process);
8501998St.nateldemoura@f5.com
8512174Smax.romanov@gmail.com if (port != NULL) {
8522174Smax.romanov@gmail.com nxt_port_use(task, port, -1);
8532174Smax.romanov@gmail.com }
8542174Smax.romanov@gmail.com
8551998St.nateldemoura@f5.com if (nxt_proto_exiting && nxt_queue_is_empty(&nxt_proto_children)) {
8561998St.nateldemoura@f5.com nxt_process_quit(task, 0);
8571998St.nateldemoura@f5.com return;
8581998St.nateldemoura@f5.com }
8591998St.nateldemoura@f5.com }
86020Sigor@sysoev.ru }
86120Sigor@sysoev.ru
86220Sigor@sysoev.ru
863216Sigor@sysoev.ru static nxt_app_module_t *
nxt_app_module_load(nxt_task_t * task,const char * name)864216Sigor@sysoev.ru nxt_app_module_load(nxt_task_t *task, const char *name)
865216Sigor@sysoev.ru {
8661983Svbart@nginx.com char *err;
8671983Svbart@nginx.com void *dl;
8681983Svbart@nginx.com nxt_app_module_t *app;
869216Sigor@sysoev.ru
870216Sigor@sysoev.ru dl = dlopen(name, RTLD_GLOBAL | RTLD_LAZY);
871216Sigor@sysoev.ru
8721983Svbart@nginx.com if (nxt_slow_path(dl == NULL)) {
8731983Svbart@nginx.com err = dlerror();
8741983Svbart@nginx.com nxt_alert(task, "dlopen(\"%s\") failed: \"%s\"",
8751983Svbart@nginx.com name, err != NULL ? err : "(null)");
8761983Svbart@nginx.com return NULL;
877216Sigor@sysoev.ru }
878216Sigor@sysoev.ru
8791983Svbart@nginx.com app = dlsym(dl, "nxt_app_module");
8801983Svbart@nginx.com
8811983Svbart@nginx.com if (nxt_slow_path(app == NULL)) {
8821983Svbart@nginx.com err = dlerror();
8831983Svbart@nginx.com nxt_alert(task, "dlsym(\"%s\", \"nxt_app_module\") failed: \"%s\"",
8841983Svbart@nginx.com name, err != NULL ? err : "(null)");
885216Sigor@sysoev.ru
8861983Svbart@nginx.com if (dlclose(dl) != 0) {
8871983Svbart@nginx.com err = dlerror();
8881983Svbart@nginx.com nxt_alert(task, "dlclose(\"%s\") failed: \"%s\"",
8891983Svbart@nginx.com name, err != NULL ? err : "(null)");
8901983Svbart@nginx.com }
8911983Svbart@nginx.com }
8921983Svbart@nginx.com
8931983Svbart@nginx.com return app;
894216Sigor@sysoev.ru }
895216Sigor@sysoev.ru
896216Sigor@sysoev.ru
897678Svbart@nginx.com static nxt_int_t
nxt_app_set_environment(nxt_conf_value_t * environment)898678Svbart@nginx.com nxt_app_set_environment(nxt_conf_value_t *environment)
899678Svbart@nginx.com {
900678Svbart@nginx.com char *env, *p;
901678Svbart@nginx.com uint32_t next;
902678Svbart@nginx.com nxt_str_t name, value;
903678Svbart@nginx.com nxt_conf_value_t *value_obj;
904678Svbart@nginx.com
905678Svbart@nginx.com if (environment != NULL) {
906678Svbart@nginx.com next = 0;
907678Svbart@nginx.com
908678Svbart@nginx.com for ( ;; ) {
909678Svbart@nginx.com value_obj = nxt_conf_next_object_member(environment, &name, &next);
910678Svbart@nginx.com if (value_obj == NULL) {
911678Svbart@nginx.com break;
912678Svbart@nginx.com }
913678Svbart@nginx.com
914678Svbart@nginx.com nxt_conf_get_string(value_obj, &value);
915678Svbart@nginx.com
916678Svbart@nginx.com env = nxt_malloc(name.length + value.length + 2);
917678Svbart@nginx.com if (nxt_slow_path(env == NULL)) {
918678Svbart@nginx.com return NXT_ERROR;
919678Svbart@nginx.com }
920678Svbart@nginx.com
921678Svbart@nginx.com p = nxt_cpymem(env, name.start, name.length);
922678Svbart@nginx.com *p++ = '=';
923678Svbart@nginx.com p = nxt_cpymem(p, value.start, value.length);
924678Svbart@nginx.com *p = '\0';
925678Svbart@nginx.com
926678Svbart@nginx.com if (nxt_slow_path(putenv(env) != 0)) {
927678Svbart@nginx.com return NXT_ERROR;
928678Svbart@nginx.com }
929678Svbart@nginx.com }
930678Svbart@nginx.com }
931678Svbart@nginx.com
932678Svbart@nginx.com return NXT_OK;
933678Svbart@nginx.com }
934678Svbart@nginx.com
935678Svbart@nginx.com
9362426Sa.clayton@nginx.com nxt_int_t
nxt_app_set_logs(void)9372426Sa.clayton@nginx.com nxt_app_set_logs(void)
9382426Sa.clayton@nginx.com {
9392426Sa.clayton@nginx.com nxt_int_t ret;
9402426Sa.clayton@nginx.com nxt_file_t file;
9412426Sa.clayton@nginx.com nxt_task_t *task;
9422426Sa.clayton@nginx.com nxt_thread_t *thr;
9432426Sa.clayton@nginx.com nxt_process_t *process;
9442426Sa.clayton@nginx.com nxt_runtime_t *rt;
9452426Sa.clayton@nginx.com nxt_common_app_conf_t *app_conf;
9462426Sa.clayton@nginx.com
9472426Sa.clayton@nginx.com thr = nxt_thread();
9482426Sa.clayton@nginx.com
9492426Sa.clayton@nginx.com task = thr->task;
9502426Sa.clayton@nginx.com
9512426Sa.clayton@nginx.com rt = task->thread->runtime;
9522426Sa.clayton@nginx.com if (!rt->daemon) {
9532426Sa.clayton@nginx.com return NXT_OK;
9542426Sa.clayton@nginx.com }
9552426Sa.clayton@nginx.com
9562426Sa.clayton@nginx.com process = rt->port_by_type[NXT_PROCESS_PROTOTYPE]->process;
9572426Sa.clayton@nginx.com app_conf = process->data.app;
9582426Sa.clayton@nginx.com
9592426Sa.clayton@nginx.com if (app_conf->stdout_log != NULL) {
9602426Sa.clayton@nginx.com nxt_memzero(&file, sizeof(nxt_file_t));
9612426Sa.clayton@nginx.com file.log_level = 1;
9622426Sa.clayton@nginx.com file.name = (u_char *) app_conf->stdout_log;
9632426Sa.clayton@nginx.com ret = nxt_file_open(task, &file, O_WRONLY | O_APPEND, O_CREAT, 0666);
9642426Sa.clayton@nginx.com if (ret == NXT_ERROR) {
9652426Sa.clayton@nginx.com return NXT_ERROR;
9662426Sa.clayton@nginx.com }
9672426Sa.clayton@nginx.com
9682426Sa.clayton@nginx.com nxt_file_stdout(&file);
9692426Sa.clayton@nginx.com nxt_file_close(task, &file);
9702426Sa.clayton@nginx.com }
9712426Sa.clayton@nginx.com
9722426Sa.clayton@nginx.com if (app_conf->stderr_log != NULL) {
9732426Sa.clayton@nginx.com nxt_memzero(&file, sizeof(nxt_file_t));
9742426Sa.clayton@nginx.com file.log_level = 1;
9752426Sa.clayton@nginx.com file.name = (u_char *) app_conf->stderr_log;
9762426Sa.clayton@nginx.com ret = nxt_file_open(task, &file, O_WRONLY | O_APPEND, O_CREAT, 0666);
9772426Sa.clayton@nginx.com if (ret == NXT_ERROR) {
9782426Sa.clayton@nginx.com return NXT_ERROR;
9792426Sa.clayton@nginx.com }
9802426Sa.clayton@nginx.com
9812426Sa.clayton@nginx.com nxt_file_stderr(&file);
9822426Sa.clayton@nginx.com nxt_file_close(task, &file);
9832426Sa.clayton@nginx.com }
9842426Sa.clayton@nginx.com
9852426Sa.clayton@nginx.com return NXT_OK;
9862426Sa.clayton@nginx.com }
9872426Sa.clayton@nginx.com
9882426Sa.clayton@nginx.com
9891489St.nateldemoura@f5.com static u_char *
nxt_cstr_dup(nxt_mp_t * mp,u_char * dst,u_char * src)9901489St.nateldemoura@f5.com nxt_cstr_dup(nxt_mp_t *mp, u_char *dst, u_char *src)
9911489St.nateldemoura@f5.com {
9921489St.nateldemoura@f5.com u_char *p;
9931489St.nateldemoura@f5.com size_t len;
9941489St.nateldemoura@f5.com
9951489St.nateldemoura@f5.com len = nxt_strlen(src);
9961489St.nateldemoura@f5.com
9971489St.nateldemoura@f5.com if (dst == NULL) {
9981489St.nateldemoura@f5.com dst = nxt_mp_alloc(mp, len + 1);
9991489St.nateldemoura@f5.com if (nxt_slow_path(dst == NULL)) {
10001489St.nateldemoura@f5.com return NULL;
10011489St.nateldemoura@f5.com }
10021489St.nateldemoura@f5.com }
10031489St.nateldemoura@f5.com
10041489St.nateldemoura@f5.com p = nxt_cpymem(dst, src, len);
10051489St.nateldemoura@f5.com *p = '\0';
10061489St.nateldemoura@f5.com
10071489St.nateldemoura@f5.com return dst;
10081489St.nateldemoura@f5.com }
10091489St.nateldemoura@f5.com
10101488St.nateldemoura@f5.com
10111998St.nateldemoura@f5.com static nxt_int_t
nxt_app_setup(nxt_task_t * task,nxt_process_t * process)10121998St.nateldemoura@f5.com nxt_app_setup(nxt_task_t *task, nxt_process_t *process)
10131998St.nateldemoura@f5.com {
10141998St.nateldemoura@f5.com nxt_process_init_t *init;
10151998St.nateldemoura@f5.com
10161998St.nateldemoura@f5.com process->state = NXT_PROCESS_STATE_CREATED;
10171998St.nateldemoura@f5.com
10181998St.nateldemoura@f5.com init = nxt_process_init(process);
10191998St.nateldemoura@f5.com
10201998St.nateldemoura@f5.com return init->start(task, &process->data);
10211998St.nateldemoura@f5.com }
10221998St.nateldemoura@f5.com
10231998St.nateldemoura@f5.com
1024216Sigor@sysoev.ru nxt_app_lang_module_t *
nxt_app_lang_module(nxt_runtime_t * rt,nxt_str_t * name)1025216Sigor@sysoev.ru nxt_app_lang_module(nxt_runtime_t *rt, nxt_str_t *name)
1026216Sigor@sysoev.ru {
1027216Sigor@sysoev.ru u_char *p, *end, *version;
1028356Svbart@nginx.com size_t version_length;
1029216Sigor@sysoev.ru nxt_uint_t i, n;
1030356Svbart@nginx.com nxt_app_type_t type;
1031216Sigor@sysoev.ru nxt_app_lang_module_t *lang;
1032216Sigor@sysoev.ru
1033216Sigor@sysoev.ru end = name->start + name->length;
1034216Sigor@sysoev.ru version = end;
1035216Sigor@sysoev.ru
1036216Sigor@sysoev.ru for (p = name->start; p < end; p++) {
1037216Sigor@sysoev.ru if (*p == ' ') {
1038216Sigor@sysoev.ru version = p + 1;
1039216Sigor@sysoev.ru break;
1040216Sigor@sysoev.ru }
1041216Sigor@sysoev.ru
1042216Sigor@sysoev.ru if (*p >= '0' && *p <= '9') {
1043216Sigor@sysoev.ru version = p;
1044216Sigor@sysoev.ru break;
1045216Sigor@sysoev.ru }
1046216Sigor@sysoev.ru }
1047216Sigor@sysoev.ru
1048356Svbart@nginx.com type = nxt_app_parse_type(name->start, p - name->start);
1049356Svbart@nginx.com
1050356Svbart@nginx.com if (type == NXT_APP_UNKNOWN) {
1051356Svbart@nginx.com return NULL;
1052356Svbart@nginx.com }
1053356Svbart@nginx.com
1054216Sigor@sysoev.ru version_length = end - version;
1055216Sigor@sysoev.ru
1056216Sigor@sysoev.ru lang = rt->languages->elts;
1057216Sigor@sysoev.ru n = rt->languages->nelts;
1058216Sigor@sysoev.ru
1059216Sigor@sysoev.ru for (i = 0; i < n; i++) {
1060354Svbart@nginx.com
1061354Svbart@nginx.com /*
1062354Svbart@nginx.com * Versions are sorted in descending order
1063354Svbart@nginx.com * so first match chooses the highest version.
1064354Svbart@nginx.com */
1065354Svbart@nginx.com
1066356Svbart@nginx.com if (lang[i].type == type
1067354Svbart@nginx.com && nxt_strvers_match(lang[i].version, version, version_length))
1068216Sigor@sysoev.ru {
1069216Sigor@sysoev.ru return &lang[i];
1070216Sigor@sysoev.ru }
1071216Sigor@sysoev.ru }
1072216Sigor@sysoev.ru
1073216Sigor@sysoev.ru return NULL;
1074216Sigor@sysoev.ru }
1075216Sigor@sysoev.ru
1076216Sigor@sysoev.ru
1077510Salexander.borisov@nginx.com nxt_app_type_t
nxt_app_parse_type(u_char * p,size_t length)1078356Svbart@nginx.com nxt_app_parse_type(u_char *p, size_t length)
1079141Smax.romanov@nginx.com {
1080356Svbart@nginx.com nxt_str_t str;
1081356Svbart@nginx.com
1082356Svbart@nginx.com str.length = length;
1083356Svbart@nginx.com str.start = p;
1084356Svbart@nginx.com
1085804Svbart@nginx.com if (nxt_str_eq(&str, "external", 8) || nxt_str_eq(&str, "go", 2)) {
1086804Svbart@nginx.com return NXT_APP_EXTERNAL;
1087804Svbart@nginx.com
1088804Svbart@nginx.com } else if (nxt_str_eq(&str, "python", 6)) {
1089141Smax.romanov@nginx.com return NXT_APP_PYTHON;
1090141Smax.romanov@nginx.com
1091356Svbart@nginx.com } else if (nxt_str_eq(&str, "php", 3)) {
1092141Smax.romanov@nginx.com return NXT_APP_PHP;
1093141Smax.romanov@nginx.com
1094510Salexander.borisov@nginx.com } else if (nxt_str_eq(&str, "perl", 4)) {
1095510Salexander.borisov@nginx.com return NXT_APP_PERL;
1096584Salexander.borisov@nginx.com
1097584Salexander.borisov@nginx.com } else if (nxt_str_eq(&str, "ruby", 4)) {
1098584Salexander.borisov@nginx.com return NXT_APP_RUBY;
1099977Smax.romanov@gmail.com
1100977Smax.romanov@gmail.com } else if (nxt_str_eq(&str, "java", 4)) {
1101977Smax.romanov@gmail.com return NXT_APP_JAVA;
11022518Sa.clayton@nginx.com
1103*2686Sa.clayton@nginx.com } else if (nxt_str_eq(&str, "wasm-wasi-component", 19)) {
1104*2686Sa.clayton@nginx.com return NXT_APP_WASM_WC;
1105*2686Sa.clayton@nginx.com
11062518Sa.clayton@nginx.com } else if (nxt_str_eq(&str, "wasm", 4)) {
11072518Sa.clayton@nginx.com return NXT_APP_WASM;
1108141Smax.romanov@nginx.com }
1109141Smax.romanov@nginx.com
1110141Smax.romanov@nginx.com return NXT_APP_UNKNOWN;
1111141Smax.romanov@nginx.com }
1112743Smax.romanov@nginx.com
1113743Smax.romanov@nginx.com
1114743Smax.romanov@nginx.com nxt_int_t
nxt_unit_default_init(nxt_task_t * task,nxt_unit_init_t * init,nxt_common_app_conf_t * conf)11151980Smax.romanov@nginx.com nxt_unit_default_init(nxt_task_t *task, nxt_unit_init_t *init,
11161980Smax.romanov@nginx.com nxt_common_app_conf_t *conf)
1117743Smax.romanov@nginx.com {
11181998St.nateldemoura@f5.com nxt_port_t *my_port, *proto_port, *router_port;
1119743Smax.romanov@nginx.com nxt_runtime_t *rt;
1120743Smax.romanov@nginx.com
1121743Smax.romanov@nginx.com nxt_memzero(init, sizeof(nxt_unit_init_t));
1122743Smax.romanov@nginx.com
1123743Smax.romanov@nginx.com rt = task->thread->runtime;
1124743Smax.romanov@nginx.com
11251998St.nateldemoura@f5.com proto_port = rt->port_by_type[NXT_PROCESS_PROTOTYPE];
11261998St.nateldemoura@f5.com if (nxt_slow_path(proto_port == NULL)) {
1127743Smax.romanov@nginx.com return NXT_ERROR;
1128743Smax.romanov@nginx.com }
1129743Smax.romanov@nginx.com
11301543Smax.romanov@nginx.com router_port = rt->port_by_type[NXT_PROCESS_ROUTER];
11311543Smax.romanov@nginx.com if (nxt_slow_path(router_port == NULL)) {
11321543Smax.romanov@nginx.com return NXT_ERROR;
11331543Smax.romanov@nginx.com }
11341543Smax.romanov@nginx.com
1135743Smax.romanov@nginx.com my_port = nxt_runtime_port_find(rt, nxt_pid, 0);
1136743Smax.romanov@nginx.com if (nxt_slow_path(my_port == NULL)) {
1137743Smax.romanov@nginx.com return NXT_ERROR;
1138743Smax.romanov@nginx.com }
1139743Smax.romanov@nginx.com
11401998St.nateldemoura@f5.com init->ready_port.id.pid = proto_port->pid;
11411998St.nateldemoura@f5.com init->ready_port.id.id = proto_port->id;
11421518Smax.romanov@nginx.com init->ready_port.in_fd = -1;
11431998St.nateldemoura@f5.com init->ready_port.out_fd = proto_port->pair[1];
1144743Smax.romanov@nginx.com
11451488St.nateldemoura@f5.com init->ready_stream = my_port->process->stream;
1146743Smax.romanov@nginx.com
11471543Smax.romanov@nginx.com init->router_port.id.pid = router_port->pid;
11481543Smax.romanov@nginx.com init->router_port.id.id = router_port->id;
11491543Smax.romanov@nginx.com init->router_port.in_fd = -1;
11501543Smax.romanov@nginx.com init->router_port.out_fd = router_port->pair[1];
11511543Smax.romanov@nginx.com
1152743Smax.romanov@nginx.com init->read_port.id.pid = my_port->pid;
1153743Smax.romanov@nginx.com init->read_port.id.id = my_port->id;
1154743Smax.romanov@nginx.com init->read_port.in_fd = my_port->pair[0];
11551668Smax.romanov@nginx.com init->read_port.out_fd = my_port->pair[1];
1156743Smax.romanov@nginx.com
11572014Smax.romanov@nginx.com init->shared_port_fd = conf->shared_port_fd;
11582014Smax.romanov@nginx.com init->shared_queue_fd = conf->shared_queue_fd;
11592014Smax.romanov@nginx.com
1160743Smax.romanov@nginx.com init->log_fd = 2;
1161743Smax.romanov@nginx.com
11621980Smax.romanov@nginx.com init->shm_limit = conf->shm_limit;
11631980Smax.romanov@nginx.com init->request_limit = conf->request_limit;
11641980Smax.romanov@nginx.com
1165743Smax.romanov@nginx.com return NXT_OK;
1166743Smax.romanov@nginx.com }
11671998St.nateldemoura@f5.com
11681998St.nateldemoura@f5.com
11691998St.nateldemoura@f5.com static nxt_int_t
nxt_proto_lvlhsh_isolated_pid_test(nxt_lvlhsh_query_t * lhq,void * data)11701998St.nateldemoura@f5.com nxt_proto_lvlhsh_isolated_pid_test(nxt_lvlhsh_query_t *lhq, void *data)
11711998St.nateldemoura@f5.com {
11721998St.nateldemoura@f5.com nxt_pid_t *qpid;
11731998St.nateldemoura@f5.com nxt_process_t *process;
11741998St.nateldemoura@f5.com
11751998St.nateldemoura@f5.com process = data;
11761998St.nateldemoura@f5.com qpid = (nxt_pid_t *) lhq->key.start;
11771998St.nateldemoura@f5.com
11781998St.nateldemoura@f5.com if (*qpid == process->isolated_pid) {
11791998St.nateldemoura@f5.com return NXT_OK;
11801998St.nateldemoura@f5.com }
11811998St.nateldemoura@f5.com
11821998St.nateldemoura@f5.com return NXT_DECLINED;
11831998St.nateldemoura@f5.com }
11841998St.nateldemoura@f5.com
11851998St.nateldemoura@f5.com
11861998St.nateldemoura@f5.com static const nxt_lvlhsh_proto_t lvlhsh_processes_proto nxt_aligned(64) = {
11871998St.nateldemoura@f5.com NXT_LVLHSH_DEFAULT,
11881998St.nateldemoura@f5.com nxt_proto_lvlhsh_isolated_pid_test,
11891998St.nateldemoura@f5.com nxt_lvlhsh_alloc,
11901998St.nateldemoura@f5.com nxt_lvlhsh_free,
11911998St.nateldemoura@f5.com };
11921998St.nateldemoura@f5.com
11931998St.nateldemoura@f5.com
11941998St.nateldemoura@f5.com nxt_inline void
nxt_proto_process_lhq_pid(nxt_lvlhsh_query_t * lhq,nxt_pid_t * pid)11951998St.nateldemoura@f5.com nxt_proto_process_lhq_pid(nxt_lvlhsh_query_t *lhq, nxt_pid_t *pid)
11961998St.nateldemoura@f5.com {
11971998St.nateldemoura@f5.com lhq->key_hash = nxt_murmur_hash2(pid, sizeof(nxt_pid_t));
11981998St.nateldemoura@f5.com lhq->key.length = sizeof(nxt_pid_t);
11991998St.nateldemoura@f5.com lhq->key.start = (u_char *) pid;
12001998St.nateldemoura@f5.com lhq->proto = &lvlhsh_processes_proto;
12011998St.nateldemoura@f5.com }
12021998St.nateldemoura@f5.com
12031998St.nateldemoura@f5.com
12041998St.nateldemoura@f5.com static void
nxt_proto_process_add(nxt_task_t * task,nxt_process_t * process)12051998St.nateldemoura@f5.com nxt_proto_process_add(nxt_task_t *task, nxt_process_t *process)
12061998St.nateldemoura@f5.com {
12071998St.nateldemoura@f5.com nxt_runtime_t *rt;
12081998St.nateldemoura@f5.com nxt_lvlhsh_query_t lhq;
12091998St.nateldemoura@f5.com
12101998St.nateldemoura@f5.com rt = task->thread->runtime;
12111998St.nateldemoura@f5.com
12121998St.nateldemoura@f5.com nxt_proto_process_lhq_pid(&lhq, &process->isolated_pid);
12131998St.nateldemoura@f5.com
12141998St.nateldemoura@f5.com lhq.replace = 0;
12151998St.nateldemoura@f5.com lhq.value = process;
12161998St.nateldemoura@f5.com lhq.pool = rt->mem_pool;
12171998St.nateldemoura@f5.com
12181998St.nateldemoura@f5.com switch (nxt_lvlhsh_insert(&nxt_proto_processes, &lhq)) {
12191998St.nateldemoura@f5.com
12201998St.nateldemoura@f5.com case NXT_OK:
12211998St.nateldemoura@f5.com nxt_debug(task, "process (isolated %PI) added", process->isolated_pid);
12221998St.nateldemoura@f5.com
12231998St.nateldemoura@f5.com nxt_queue_insert_tail(&nxt_proto_children, &process->link);
12241998St.nateldemoura@f5.com break;
12251998St.nateldemoura@f5.com
12261998St.nateldemoura@f5.com default:
12272174Smax.romanov@gmail.com nxt_alert(task, "process (isolated %PI) failed to add",
12281998St.nateldemoura@f5.com process->isolated_pid);
12291998St.nateldemoura@f5.com break;
12301998St.nateldemoura@f5.com }
12311998St.nateldemoura@f5.com }
12321998St.nateldemoura@f5.com
12331998St.nateldemoura@f5.com
12341998St.nateldemoura@f5.com static nxt_process_t *
nxt_proto_process_remove(nxt_task_t * task,nxt_pid_t pid)12351998St.nateldemoura@f5.com nxt_proto_process_remove(nxt_task_t *task, nxt_pid_t pid)
12361998St.nateldemoura@f5.com {
12371998St.nateldemoura@f5.com nxt_runtime_t *rt;
12381998St.nateldemoura@f5.com nxt_process_t *process;
12391998St.nateldemoura@f5.com nxt_lvlhsh_query_t lhq;
12401998St.nateldemoura@f5.com
12411998St.nateldemoura@f5.com nxt_proto_process_lhq_pid(&lhq, &pid);
12421998St.nateldemoura@f5.com
12431998St.nateldemoura@f5.com rt = task->thread->runtime;
12441998St.nateldemoura@f5.com
12451998St.nateldemoura@f5.com lhq.pool = rt->mem_pool;
12461998St.nateldemoura@f5.com
12471998St.nateldemoura@f5.com switch (nxt_lvlhsh_delete(&nxt_proto_processes, &lhq)) {
12481998St.nateldemoura@f5.com
12491998St.nateldemoura@f5.com case NXT_OK:
12501998St.nateldemoura@f5.com nxt_debug(task, "process (isolated %PI) removed", pid);
12511998St.nateldemoura@f5.com
12521998St.nateldemoura@f5.com process = lhq.value;
12531998St.nateldemoura@f5.com
12541998St.nateldemoura@f5.com nxt_queue_remove(&process->link);
12552040Smax.romanov@nginx.com process->link.next = NULL;
12562040Smax.romanov@nginx.com
12571998St.nateldemoura@f5.com break;
12581998St.nateldemoura@f5.com
12591998St.nateldemoura@f5.com default:
12601998St.nateldemoura@f5.com nxt_debug(task, "process (isolated %PI) remove failed", pid);
12611998St.nateldemoura@f5.com process = NULL;
12621998St.nateldemoura@f5.com break;
12631998St.nateldemoura@f5.com }
12641998St.nateldemoura@f5.com
12651998St.nateldemoura@f5.com return process;
12661998St.nateldemoura@f5.com }
12671998St.nateldemoura@f5.com
12681998St.nateldemoura@f5.com
12691998St.nateldemoura@f5.com static nxt_process_t *
nxt_proto_process_find(nxt_task_t * task,nxt_pid_t pid)12701998St.nateldemoura@f5.com nxt_proto_process_find(nxt_task_t *task, nxt_pid_t pid)
12711998St.nateldemoura@f5.com {
12721998St.nateldemoura@f5.com nxt_process_t *process;
12731998St.nateldemoura@f5.com nxt_lvlhsh_query_t lhq;
12741998St.nateldemoura@f5.com
12751998St.nateldemoura@f5.com nxt_proto_process_lhq_pid(&lhq, &pid);
12761998St.nateldemoura@f5.com
12771998St.nateldemoura@f5.com if (nxt_lvlhsh_find(&nxt_proto_processes, &lhq) == NXT_OK) {
12781998St.nateldemoura@f5.com process = lhq.value;
12791998St.nateldemoura@f5.com
12801998St.nateldemoura@f5.com } else {
12811998St.nateldemoura@f5.com nxt_debug(task, "process (isolated %PI) not found", pid);
12821998St.nateldemoura@f5.com
12831998St.nateldemoura@f5.com process = NULL;
12841998St.nateldemoura@f5.com }
12851998St.nateldemoura@f5.com
12861998St.nateldemoura@f5.com return process;
12871998St.nateldemoura@f5.com }
1288