xref: /unit/src/nxt_application.c (revision 2050:d1298cc3f385)
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 
26216Sigor@sysoev.ru typedef struct {
27356Svbart@nginx.com     nxt_app_type_t  type;
28356Svbart@nginx.com     nxt_str_t       version;
29356Svbart@nginx.com     nxt_str_t       file;
301489St.nateldemoura@f5.com     nxt_array_t     *mounts;
31216Sigor@sysoev.ru } nxt_module_t;
32216Sigor@sysoev.ru 
33216Sigor@sysoev.ru 
341488St.nateldemoura@f5.com static nxt_int_t nxt_discovery_start(nxt_task_t *task,
351488St.nateldemoura@f5.com     nxt_process_data_t *data);
36216Sigor@sysoev.ru static nxt_buf_t *nxt_discovery_modules(nxt_task_t *task, const char *path);
37216Sigor@sysoev.ru static nxt_int_t nxt_discovery_module(nxt_task_t *task, nxt_mp_t *mp,
38216Sigor@sysoev.ru     nxt_array_t *modules, const char *name);
39549Svbart@nginx.com static void nxt_discovery_completion_handler(nxt_task_t *task, void *obj,
40549Svbart@nginx.com     void *data);
41549Svbart@nginx.com static void nxt_discovery_quit(nxt_task_t *task, nxt_port_recv_msg_t *msg,
42549Svbart@nginx.com     void *data);
43216Sigor@sysoev.ru static nxt_app_module_t *nxt_app_module_load(nxt_task_t *task,
44216Sigor@sysoev.ru     const char *name);
451998St.nateldemoura@f5.com static nxt_int_t nxt_proto_setup(nxt_task_t *task, nxt_process_t *process);
461998St.nateldemoura@f5.com static nxt_int_t nxt_proto_start(nxt_task_t *task, nxt_process_data_t *data);
471488St.nateldemoura@f5.com static nxt_int_t nxt_app_setup(nxt_task_t *task, nxt_process_t *process);
48678Svbart@nginx.com static nxt_int_t nxt_app_set_environment(nxt_conf_value_t *environment);
491998St.nateldemoura@f5.com static void nxt_proto_start_process_handler(nxt_task_t *task,
501998St.nateldemoura@f5.com     nxt_port_recv_msg_t *msg);
511998St.nateldemoura@f5.com static void nxt_proto_quit_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg);
521998St.nateldemoura@f5.com static void nxt_proto_process_created_handler(nxt_task_t *task,
531998St.nateldemoura@f5.com     nxt_port_recv_msg_t *msg);
541998St.nateldemoura@f5.com static void nxt_proto_quit_children(nxt_task_t *task);
551998St.nateldemoura@f5.com static nxt_process_t *nxt_proto_process_find(nxt_task_t *task, nxt_pid_t pid);
561998St.nateldemoura@f5.com static void nxt_proto_process_add(nxt_task_t *task, nxt_process_t *process);
571998St.nateldemoura@f5.com static nxt_process_t *nxt_proto_process_remove(nxt_task_t *task, nxt_pid_t pid);
581489St.nateldemoura@f5.com static u_char *nxt_cstr_dup(nxt_mp_t *mp, u_char *dst, u_char *src);
591998St.nateldemoura@f5.com static void nxt_proto_signal_handler(nxt_task_t *task, void *obj, void *data);
601998St.nateldemoura@f5.com static void nxt_proto_sigterm_handler(nxt_task_t *task, void *obj, void *data);
611998St.nateldemoura@f5.com static void nxt_proto_sigchld_handler(nxt_task_t *task, void *obj, void *data);
621489St.nateldemoura@f5.com 
631489St.nateldemoura@f5.com 
641488St.nateldemoura@f5.com nxt_str_t  nxt_server = nxt_string(NXT_SERVER);
650Sigor@sysoev.ru 
66216Sigor@sysoev.ru 
67258Sigor@sysoev.ru static uint32_t  compat[] = {
68360Sigor@sysoev.ru     NXT_VERNUM, NXT_DEBUG,
69258Sigor@sysoev.ru };
70258Sigor@sysoev.ru 
71258Sigor@sysoev.ru 
721998St.nateldemoura@f5.com static nxt_lvlhsh_t           nxt_proto_processes;
731998St.nateldemoura@f5.com static nxt_queue_t            nxt_proto_children;
741998St.nateldemoura@f5.com static nxt_bool_t             nxt_proto_exiting;
751998St.nateldemoura@f5.com 
761998St.nateldemoura@f5.com static nxt_app_module_t       *nxt_app;
771998St.nateldemoura@f5.com static nxt_common_app_conf_t  *nxt_app_conf;
78417Svbart@nginx.com 
79417Svbart@nginx.com 
801488St.nateldemoura@f5.com static const nxt_port_handlers_t  nxt_discovery_process_port_handlers = {
811488St.nateldemoura@f5.com     .quit         = nxt_signal_quit_handler,
821488St.nateldemoura@f5.com     .new_port     = nxt_port_new_port_handler,
831488St.nateldemoura@f5.com     .change_file  = nxt_port_change_log_file_handler,
841488St.nateldemoura@f5.com     .mmap         = nxt_port_mmap_handler,
851488St.nateldemoura@f5.com     .data         = nxt_port_data_handler,
861488St.nateldemoura@f5.com     .remove_pid   = nxt_port_remove_pid_handler,
871488St.nateldemoura@f5.com     .rpc_ready    = nxt_port_rpc_handler,
881488St.nateldemoura@f5.com     .rpc_error    = nxt_port_rpc_handler,
891488St.nateldemoura@f5.com };
901488St.nateldemoura@f5.com 
911488St.nateldemoura@f5.com 
921998St.nateldemoura@f5.com const nxt_sig_event_t  nxt_prototype_signals[] = {
931998St.nateldemoura@f5.com     nxt_event_signal(SIGHUP,  nxt_proto_signal_handler),
941998St.nateldemoura@f5.com     nxt_event_signal(SIGINT,  nxt_proto_sigterm_handler),
951998St.nateldemoura@f5.com     nxt_event_signal(SIGQUIT, nxt_proto_sigterm_handler),
961998St.nateldemoura@f5.com     nxt_event_signal(SIGTERM, nxt_proto_sigterm_handler),
971998St.nateldemoura@f5.com     nxt_event_signal(SIGCHLD, nxt_proto_sigchld_handler),
981998St.nateldemoura@f5.com     nxt_event_signal_end,
991998St.nateldemoura@f5.com };
1001998St.nateldemoura@f5.com 
1011998St.nateldemoura@f5.com 
1021998St.nateldemoura@f5.com static const nxt_port_handlers_t  nxt_proto_process_port_handlers = {
1031998St.nateldemoura@f5.com     .quit            = nxt_proto_quit_handler,
1041998St.nateldemoura@f5.com     .change_file     = nxt_port_change_log_file_handler,
1051998St.nateldemoura@f5.com     .new_port        = nxt_port_new_port_handler,
1061998St.nateldemoura@f5.com     .process_created = nxt_proto_process_created_handler,
1071998St.nateldemoura@f5.com     .process_ready   = nxt_port_process_ready_handler,
1081998St.nateldemoura@f5.com     .remove_pid      = nxt_port_remove_pid_handler,
1091998St.nateldemoura@f5.com     .start_process   = nxt_proto_start_process_handler,
1101998St.nateldemoura@f5.com     .rpc_ready       = nxt_port_rpc_handler,
1111998St.nateldemoura@f5.com     .rpc_error       = nxt_port_rpc_handler,
1121998St.nateldemoura@f5.com };
1131998St.nateldemoura@f5.com 
1141998St.nateldemoura@f5.com 
1151488St.nateldemoura@f5.com static const nxt_port_handlers_t  nxt_app_process_port_handlers = {
1161488St.nateldemoura@f5.com     .quit         = nxt_signal_quit_handler,
1171488St.nateldemoura@f5.com     .rpc_ready    = nxt_port_rpc_handler,
1181488St.nateldemoura@f5.com     .rpc_error    = nxt_port_rpc_handler,
1191488St.nateldemoura@f5.com };
1201488St.nateldemoura@f5.com 
1211488St.nateldemoura@f5.com 
1221488St.nateldemoura@f5.com const nxt_process_init_t  nxt_discovery_process = {
1231488St.nateldemoura@f5.com     .name           = "discovery",
1241488St.nateldemoura@f5.com     .type           = NXT_PROCESS_DISCOVERY,
1251488St.nateldemoura@f5.com     .prefork        = NULL,
1261488St.nateldemoura@f5.com     .restart        = 0,
1271488St.nateldemoura@f5.com     .setup          = nxt_process_core_setup,
1281488St.nateldemoura@f5.com     .start          = nxt_discovery_start,
1291488St.nateldemoura@f5.com     .port_handlers  = &nxt_discovery_process_port_handlers,
1301488St.nateldemoura@f5.com     .signals        = nxt_process_signals,
1311488St.nateldemoura@f5.com };
1321488St.nateldemoura@f5.com 
1331488St.nateldemoura@f5.com 
1341998St.nateldemoura@f5.com const nxt_process_init_t  nxt_proto_process = {
1351998St.nateldemoura@f5.com     .type           = NXT_PROCESS_PROTOTYPE,
1361998St.nateldemoura@f5.com     .prefork        = nxt_isolation_main_prefork,
1371998St.nateldemoura@f5.com     .restart        = 0,
1381998St.nateldemoura@f5.com     .setup          = nxt_proto_setup,
1391998St.nateldemoura@f5.com     .start          = nxt_proto_start,
1401998St.nateldemoura@f5.com     .port_handlers  = &nxt_proto_process_port_handlers,
1411998St.nateldemoura@f5.com     .signals        = nxt_prototype_signals,
1421998St.nateldemoura@f5.com };
1431998St.nateldemoura@f5.com 
1441998St.nateldemoura@f5.com 
1451488St.nateldemoura@f5.com const nxt_process_init_t  nxt_app_process = {
1461488St.nateldemoura@f5.com     .type           = NXT_PROCESS_APP,
1471488St.nateldemoura@f5.com     .setup          = nxt_app_setup,
1481998St.nateldemoura@f5.com     .start          = NULL,
1491998St.nateldemoura@f5.com     .prefork        = NULL,
1501488St.nateldemoura@f5.com     .restart        = 0,
1511488St.nateldemoura@f5.com     .port_handlers  = &nxt_app_process_port_handlers,
1521488St.nateldemoura@f5.com     .signals        = nxt_process_signals,
1531488St.nateldemoura@f5.com };
1541488St.nateldemoura@f5.com 
1551488St.nateldemoura@f5.com 
1561488St.nateldemoura@f5.com static nxt_int_t
nxt_discovery_start(nxt_task_t * task,nxt_process_data_t * data)1571488St.nateldemoura@f5.com nxt_discovery_start(nxt_task_t *task, nxt_process_data_t *data)
158216Sigor@sysoev.ru {
159549Svbart@nginx.com     uint32_t       stream;
160549Svbart@nginx.com     nxt_buf_t      *b;
161549Svbart@nginx.com     nxt_int_t      ret;
162549Svbart@nginx.com     nxt_port_t     *main_port, *discovery_port;
163549Svbart@nginx.com     nxt_runtime_t  *rt;
164216Sigor@sysoev.ru 
1651488St.nateldemoura@f5.com     nxt_log(task, NXT_LOG_INFO, "discovery started");
166216Sigor@sysoev.ru 
167233Sigor@sysoev.ru     rt = task->thread->runtime;
168216Sigor@sysoev.ru 
169233Sigor@sysoev.ru     b = nxt_discovery_modules(task, rt->modules);
170250Sigor@sysoev.ru     if (nxt_slow_path(b == NULL)) {
171549Svbart@nginx.com         return NXT_ERROR;
172250Sigor@sysoev.ru     }
173233Sigor@sysoev.ru 
174240Sigor@sysoev.ru     main_port = rt->port_by_type[NXT_PROCESS_MAIN];
175549Svbart@nginx.com     discovery_port = rt->port_by_type[NXT_PROCESS_DISCOVERY];
176216Sigor@sysoev.ru 
177549Svbart@nginx.com     stream = nxt_port_rpc_register_handler(task, discovery_port,
178549Svbart@nginx.com                                            nxt_discovery_quit,
179549Svbart@nginx.com                                            nxt_discovery_quit,
180549Svbart@nginx.com                                            main_port->pid, NULL);
181549Svbart@nginx.com 
182645Svbart@nginx.com     if (nxt_slow_path(stream == 0)) {
183645Svbart@nginx.com         return NXT_ERROR;
184645Svbart@nginx.com     }
185645Svbart@nginx.com 
186549Svbart@nginx.com     ret = nxt_port_socket_write(task, main_port, NXT_PORT_MSG_MODULES, -1,
187549Svbart@nginx.com                                 stream, discovery_port->id, b);
188549Svbart@nginx.com 
189549Svbart@nginx.com     if (nxt_slow_path(ret != NXT_OK)) {
190549Svbart@nginx.com         nxt_port_rpc_cancel(task, discovery_port, stream);
191549Svbart@nginx.com         return NXT_ERROR;
192549Svbart@nginx.com     }
193216Sigor@sysoev.ru 
194216Sigor@sysoev.ru     return NXT_OK;
195216Sigor@sysoev.ru }
196216Sigor@sysoev.ru 
197216Sigor@sysoev.ru 
198216Sigor@sysoev.ru static nxt_buf_t *
nxt_discovery_modules(nxt_task_t * task,const char * path)199216Sigor@sysoev.ru nxt_discovery_modules(nxt_task_t *task, const char *path)
200216Sigor@sysoev.ru {
2011489St.nateldemoura@f5.com     char            *name;
2021489St.nateldemoura@f5.com     u_char          *p, *end;
2031489St.nateldemoura@f5.com     size_t          size;
2041489St.nateldemoura@f5.com     glob_t          glb;
2051489St.nateldemoura@f5.com     nxt_mp_t        *mp;
2061489St.nateldemoura@f5.com     nxt_buf_t       *b;
2071489St.nateldemoura@f5.com     nxt_int_t       ret;
2081489St.nateldemoura@f5.com     nxt_uint_t      i, n, j;
2091489St.nateldemoura@f5.com     nxt_array_t     *modules, *mounts;
2101489St.nateldemoura@f5.com     nxt_module_t    *module;
2111489St.nateldemoura@f5.com     nxt_fs_mount_t  *mnt;
212216Sigor@sysoev.ru 
213216Sigor@sysoev.ru     b = NULL;
214216Sigor@sysoev.ru 
215216Sigor@sysoev.ru     mp = nxt_mp_create(1024, 128, 256, 32);
216216Sigor@sysoev.ru     if (mp == NULL) {
217216Sigor@sysoev.ru         return b;
218216Sigor@sysoev.ru     }
219216Sigor@sysoev.ru 
220216Sigor@sysoev.ru     ret = glob(path, 0, NULL, &glb);
221216Sigor@sysoev.ru 
222250Sigor@sysoev.ru     n = glb.gl_pathc;
223250Sigor@sysoev.ru 
224250Sigor@sysoev.ru     if (ret != 0) {
225250Sigor@sysoev.ru         nxt_log(task, NXT_LOG_NOTICE,
226250Sigor@sysoev.ru                 "no modules matching: \"%s\" found", path);
227250Sigor@sysoev.ru         n = 0;
228250Sigor@sysoev.ru     }
229216Sigor@sysoev.ru 
230250Sigor@sysoev.ru     modules = nxt_array_create(mp, n, sizeof(nxt_module_t));
231250Sigor@sysoev.ru     if (modules == NULL) {
232250Sigor@sysoev.ru         goto fail;
233250Sigor@sysoev.ru     }
234250Sigor@sysoev.ru 
235250Sigor@sysoev.ru     for (i = 0; i < n; i++) {
236250Sigor@sysoev.ru         name = glb.gl_pathv[i];
237250Sigor@sysoev.ru 
238250Sigor@sysoev.ru         ret = nxt_discovery_module(task, mp, modules, name);
239250Sigor@sysoev.ru         if (ret != NXT_OK) {
240216Sigor@sysoev.ru             goto fail;
241216Sigor@sysoev.ru         }
242250Sigor@sysoev.ru     }
243216Sigor@sysoev.ru 
244703Svbart@nginx.com     size = nxt_length("[]");
245250Sigor@sysoev.ru     module = modules->elts;
246250Sigor@sysoev.ru     n = modules->nelts;
247216Sigor@sysoev.ru 
248250Sigor@sysoev.ru     for (i = 0; i < n; i++) {
249356Svbart@nginx.com         nxt_debug(task, "module: %d %V %V",
250356Svbart@nginx.com                   module[i].type, &module[i].version, &module[i].file);
251216Sigor@sysoev.ru 
252703Svbart@nginx.com         size += nxt_length("{\"type\": ,");
253703Svbart@nginx.com         size += nxt_length(" \"version\": \"\",");
2541489St.nateldemoura@f5.com         size += nxt_length(" \"file\": \"\",");
2551489St.nateldemoura@f5.com         size += nxt_length(" \"mounts\": []},");
256216Sigor@sysoev.ru 
257356Svbart@nginx.com         size += NXT_INT_T_LEN
258250Sigor@sysoev.ru                 + module[i].version.length
259250Sigor@sysoev.ru                 + module[i].file.length;
2601489St.nateldemoura@f5.com 
2611489St.nateldemoura@f5.com         mounts = module[i].mounts;
2621489St.nateldemoura@f5.com 
2631489St.nateldemoura@f5.com         size += mounts->nelts * nxt_length("{\"src\": \"\", \"dst\": \"\", "
2641673St.nateldemoura@f5.com                                             "\"type\": , \"name\": \"\", "
2651673St.nateldemoura@f5.com                                             "\"flags\": , \"data\": \"\"},");
2661489St.nateldemoura@f5.com 
2671489St.nateldemoura@f5.com         mnt = mounts->elts;
2681489St.nateldemoura@f5.com 
2691489St.nateldemoura@f5.com         for (j = 0; j < mounts->nelts; j++) {
2701489St.nateldemoura@f5.com             size += nxt_strlen(mnt[j].src) + nxt_strlen(mnt[j].dst)
2711673St.nateldemoura@f5.com                     + nxt_strlen(mnt[j].name) + (2 * NXT_INT_T_LEN)
2721489St.nateldemoura@f5.com                     + (mnt[j].data == NULL ? 0 : nxt_strlen(mnt[j].data));
2731489St.nateldemoura@f5.com         }
274250Sigor@sysoev.ru     }
275216Sigor@sysoev.ru 
276250Sigor@sysoev.ru     b = nxt_buf_mem_alloc(mp, size, 0);
277250Sigor@sysoev.ru     if (b == NULL) {
278250Sigor@sysoev.ru         goto fail;
279250Sigor@sysoev.ru     }
280216Sigor@sysoev.ru 
281250Sigor@sysoev.ru     b->completion_handler = nxt_discovery_completion_handler;
282216Sigor@sysoev.ru 
283250Sigor@sysoev.ru     p = b->mem.free;
284250Sigor@sysoev.ru     end = b->mem.end;
285250Sigor@sysoev.ru     *p++ = '[';
286216Sigor@sysoev.ru 
287250Sigor@sysoev.ru     for (i = 0; i < n; i++) {
2881489St.nateldemoura@f5.com         mounts = module[i].mounts;
2891489St.nateldemoura@f5.com 
2901489St.nateldemoura@f5.com         p = nxt_sprintf(p, end, "{\"type\": %d, \"version\": \"%V\", "
2911489St.nateldemoura@f5.com                         "\"file\": \"%V\", \"mounts\": [",
2921489St.nateldemoura@f5.com                         module[i].type, &module[i].version, &module[i].file);
2931489St.nateldemoura@f5.com 
2941489St.nateldemoura@f5.com         mnt = mounts->elts;
2951489St.nateldemoura@f5.com         for (j = 0; j < mounts->nelts; j++) {
2961489St.nateldemoura@f5.com             p = nxt_sprintf(p, end,
2971489St.nateldemoura@f5.com                             "{\"src\": \"%s\", \"dst\": \"%s\", "
2981673St.nateldemoura@f5.com                             "\"name\": \"%s\", \"type\": %d, \"flags\": %d, "
2991489St.nateldemoura@f5.com                             "\"data\": \"%s\"},",
3001673St.nateldemoura@f5.com                             mnt[j].src, mnt[j].dst, mnt[j].name, mnt[j].type,
3011673St.nateldemoura@f5.com                             mnt[j].flags,
3021489St.nateldemoura@f5.com                             mnt[j].data == NULL ? (u_char *) "" : mnt[j].data);
3031489St.nateldemoura@f5.com         }
3041489St.nateldemoura@f5.com 
3051489St.nateldemoura@f5.com         *p++ = ']';
3061489St.nateldemoura@f5.com         *p++ = '}';
3071489St.nateldemoura@f5.com         *p++ = ',';
308250Sigor@sysoev.ru     }
309216Sigor@sysoev.ru 
310250Sigor@sysoev.ru     *p++ = ']';
3111489St.nateldemoura@f5.com 
3121515Smax.romanov@nginx.com     if (nxt_slow_path(p > end)) {
3131489St.nateldemoura@f5.com         nxt_alert(task, "discovery write past the buffer");
3141489St.nateldemoura@f5.com         goto fail;
3151489St.nateldemoura@f5.com     }
3161489St.nateldemoura@f5.com 
317250Sigor@sysoev.ru     b->mem.free = p;
318216Sigor@sysoev.ru 
319216Sigor@sysoev.ru fail:
320216Sigor@sysoev.ru 
321216Sigor@sysoev.ru     globfree(&glb);
322216Sigor@sysoev.ru 
323216Sigor@sysoev.ru     return b;
324216Sigor@sysoev.ru }
325216Sigor@sysoev.ru 
326216Sigor@sysoev.ru 
327216Sigor@sysoev.ru static nxt_int_t
nxt_discovery_module(nxt_task_t * task,nxt_mp_t * mp,nxt_array_t * modules,const char * name)328216Sigor@sysoev.ru nxt_discovery_module(nxt_task_t *task, nxt_mp_t *mp, nxt_array_t *modules,
329216Sigor@sysoev.ru     const char *name)
330216Sigor@sysoev.ru {
3311489St.nateldemoura@f5.com     void                  *dl;
3321489St.nateldemoura@f5.com     nxt_str_t             version;
3331489St.nateldemoura@f5.com     nxt_int_t             ret;
3341489St.nateldemoura@f5.com     nxt_uint_t            i, j, n;
3351489St.nateldemoura@f5.com     nxt_array_t           *mounts;
3361489St.nateldemoura@f5.com     nxt_module_t          *module;
3371489St.nateldemoura@f5.com     nxt_app_type_t        type;
3381489St.nateldemoura@f5.com     nxt_fs_mount_t        *to;
3391489St.nateldemoura@f5.com     nxt_app_module_t      *app;
3401489St.nateldemoura@f5.com     const nxt_fs_mount_t  *from;
341216Sigor@sysoev.ru 
342216Sigor@sysoev.ru     /*
343216Sigor@sysoev.ru      * Only memory allocation failure should return NXT_ERROR.
344216Sigor@sysoev.ru      * Any module processing errors are ignored.
345216Sigor@sysoev.ru      */
346216Sigor@sysoev.ru     ret = NXT_ERROR;
347216Sigor@sysoev.ru 
348216Sigor@sysoev.ru     dl = dlopen(name, RTLD_GLOBAL | RTLD_NOW);
349216Sigor@sysoev.ru 
350216Sigor@sysoev.ru     if (dl == NULL) {
351564Svbart@nginx.com         nxt_alert(task, "dlopen(\"%s\"), failed: \"%s\"", name, dlerror());
352216Sigor@sysoev.ru         return NXT_OK;
353216Sigor@sysoev.ru     }
354216Sigor@sysoev.ru 
355216Sigor@sysoev.ru     app = dlsym(dl, "nxt_app_module");
356216Sigor@sysoev.ru 
357216Sigor@sysoev.ru     if (app != NULL) {
358612Salexander.borisov@nginx.com         nxt_log(task, NXT_LOG_NOTICE, "module: %V %s \"%s\"",
359612Salexander.borisov@nginx.com                 &app->type, app->version, name);
360258Sigor@sysoev.ru 
361258Sigor@sysoev.ru         if (app->compat_length != sizeof(compat)
362258Sigor@sysoev.ru             || nxt_memcmp(app->compat, compat, sizeof(compat)) != 0)
363258Sigor@sysoev.ru         {
364258Sigor@sysoev.ru             nxt_log(task, NXT_LOG_NOTICE, "incompatible module %s", name);
365258Sigor@sysoev.ru 
366258Sigor@sysoev.ru             goto done;
367258Sigor@sysoev.ru         }
368216Sigor@sysoev.ru 
369356Svbart@nginx.com         type = nxt_app_parse_type(app->type.start, app->type.length);
370356Svbart@nginx.com 
371356Svbart@nginx.com         if (type == NXT_APP_UNKNOWN) {
372494Spluknet@nginx.com             nxt_log(task, NXT_LOG_NOTICE, "unknown module type %V", &app->type);
373356Svbart@nginx.com 
374356Svbart@nginx.com             goto done;
375356Svbart@nginx.com         }
376356Svbart@nginx.com 
377216Sigor@sysoev.ru         module = modules->elts;
378216Sigor@sysoev.ru         n = modules->nelts;
379216Sigor@sysoev.ru 
380612Salexander.borisov@nginx.com         version.start = (u_char *) app->version;
381612Salexander.borisov@nginx.com         version.length = nxt_strlen(app->version);
382612Salexander.borisov@nginx.com 
383216Sigor@sysoev.ru         for (i = 0; i < n; i++) {
384356Svbart@nginx.com             if (type == module[i].type
385612Salexander.borisov@nginx.com                 && nxt_strstr_eq(&module[i].version, &version))
386258Sigor@sysoev.ru             {
387216Sigor@sysoev.ru                 nxt_log(task, NXT_LOG_NOTICE,
388216Sigor@sysoev.ru                         "ignoring %s module with the same "
389267Sigor@sysoev.ru                         "application language version %V %V as in %V",
390655Svbart@nginx.com                         name, &app->type, &version, &module[i].file);
391216Sigor@sysoev.ru 
392216Sigor@sysoev.ru                 goto done;
393216Sigor@sysoev.ru             }
394216Sigor@sysoev.ru         }
395216Sigor@sysoev.ru 
396216Sigor@sysoev.ru         module = nxt_array_add(modules);
397216Sigor@sysoev.ru         if (module == NULL) {
398216Sigor@sysoev.ru             goto fail;
399216Sigor@sysoev.ru         }
400216Sigor@sysoev.ru 
401356Svbart@nginx.com         module->type = type;
402216Sigor@sysoev.ru 
403612Salexander.borisov@nginx.com         nxt_str_dup(mp, &module->version, &version);
404612Salexander.borisov@nginx.com         if (module->version.start == NULL) {
405216Sigor@sysoev.ru             goto fail;
406216Sigor@sysoev.ru         }
407216Sigor@sysoev.ru 
408216Sigor@sysoev.ru         module->file.length = nxt_strlen(name);
409216Sigor@sysoev.ru 
410216Sigor@sysoev.ru         module->file.start = nxt_mp_alloc(mp, module->file.length);
411216Sigor@sysoev.ru         if (module->file.start == NULL) {
412216Sigor@sysoev.ru             goto fail;
413216Sigor@sysoev.ru         }
414216Sigor@sysoev.ru 
415216Sigor@sysoev.ru         nxt_memcpy(module->file.start, name, module->file.length);
416216Sigor@sysoev.ru 
4171489St.nateldemoura@f5.com         module->mounts = nxt_array_create(mp, app->nmounts,
4181489St.nateldemoura@f5.com                                           sizeof(nxt_fs_mount_t));
4191489St.nateldemoura@f5.com 
4201489St.nateldemoura@f5.com         if (nxt_slow_path(module->mounts == NULL)) {
4211489St.nateldemoura@f5.com             goto fail;
4221489St.nateldemoura@f5.com         }
4231489St.nateldemoura@f5.com 
4241489St.nateldemoura@f5.com         mounts = module->mounts;
4251489St.nateldemoura@f5.com 
4261489St.nateldemoura@f5.com         for (j = 0; j < app->nmounts; j++) {
4271489St.nateldemoura@f5.com             from = &app->mounts[j];
4281489St.nateldemoura@f5.com             to = nxt_array_zero_add(mounts);
4291489St.nateldemoura@f5.com             if (nxt_slow_path(to == NULL)) {
4301489St.nateldemoura@f5.com                 goto fail;
4311489St.nateldemoura@f5.com             }
4321489St.nateldemoura@f5.com 
4331489St.nateldemoura@f5.com             to->src = nxt_cstr_dup(mp, to->src, from->src);
4341489St.nateldemoura@f5.com             if (nxt_slow_path(to->src == NULL)) {
4351489St.nateldemoura@f5.com                 goto fail;
4361489St.nateldemoura@f5.com             }
4371489St.nateldemoura@f5.com 
4381489St.nateldemoura@f5.com             to->dst = nxt_cstr_dup(mp, to->dst, from->dst);
4391489St.nateldemoura@f5.com             if (nxt_slow_path(to->dst == NULL)) {
4401489St.nateldemoura@f5.com                 goto fail;
4411489St.nateldemoura@f5.com             }
4421489St.nateldemoura@f5.com 
4431673St.nateldemoura@f5.com             to->name = nxt_cstr_dup(mp, to->name, from->name);
4441673St.nateldemoura@f5.com             if (nxt_slow_path(to->name == NULL)) {
4451489St.nateldemoura@f5.com                 goto fail;
4461489St.nateldemoura@f5.com             }
4471489St.nateldemoura@f5.com 
4481673St.nateldemoura@f5.com             to->type = from->type;
4491673St.nateldemoura@f5.com 
4501489St.nateldemoura@f5.com             if (from->data != NULL) {
4511489St.nateldemoura@f5.com                 to->data = nxt_cstr_dup(mp, to->data, from->data);
4521489St.nateldemoura@f5.com                 if (nxt_slow_path(to->data == NULL)) {
4531489St.nateldemoura@f5.com                     goto fail;
4541489St.nateldemoura@f5.com                 }
4551489St.nateldemoura@f5.com             }
4561489St.nateldemoura@f5.com 
4571489St.nateldemoura@f5.com             to->flags = from->flags;
4581489St.nateldemoura@f5.com         }
4591489St.nateldemoura@f5.com 
460216Sigor@sysoev.ru     } else {
461564Svbart@nginx.com         nxt_alert(task, "dlsym(\"%s\"), failed: \"%s\"", name, dlerror());
462216Sigor@sysoev.ru     }
463216Sigor@sysoev.ru 
464216Sigor@sysoev.ru done:
465216Sigor@sysoev.ru 
466216Sigor@sysoev.ru     ret = NXT_OK;
467216Sigor@sysoev.ru 
468216Sigor@sysoev.ru fail:
469216Sigor@sysoev.ru 
470216Sigor@sysoev.ru     if (dlclose(dl) != 0) {
471564Svbart@nginx.com         nxt_alert(task, "dlclose(\"%s\"), failed: \"%s\"", name, dlerror());
472216Sigor@sysoev.ru     }
473216Sigor@sysoev.ru 
474216Sigor@sysoev.ru     return ret;
475216Sigor@sysoev.ru }
476216Sigor@sysoev.ru 
477216Sigor@sysoev.ru 
478549Svbart@nginx.com static void
nxt_discovery_completion_handler(nxt_task_t * task,void * obj,void * data)479549Svbart@nginx.com nxt_discovery_completion_handler(nxt_task_t *task, void *obj, void *data)
480549Svbart@nginx.com {
481549Svbart@nginx.com     nxt_mp_t   *mp;
482549Svbart@nginx.com     nxt_buf_t  *b;
483549Svbart@nginx.com 
484549Svbart@nginx.com     b = obj;
485549Svbart@nginx.com     mp = b->data;
486549Svbart@nginx.com 
487549Svbart@nginx.com     nxt_mp_destroy(mp);
488549Svbart@nginx.com }
489549Svbart@nginx.com 
490549Svbart@nginx.com 
491549Svbart@nginx.com static void
nxt_discovery_quit(nxt_task_t * task,nxt_port_recv_msg_t * msg,void * data)492549Svbart@nginx.com nxt_discovery_quit(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data)
493549Svbart@nginx.com {
4941488St.nateldemoura@f5.com     nxt_signal_quit_handler(task, msg);
495549Svbart@nginx.com }
496549Svbart@nginx.com 
497549Svbart@nginx.com 
4981488St.nateldemoura@f5.com static nxt_int_t
nxt_proto_setup(nxt_task_t * task,nxt_process_t * process)4991998St.nateldemoura@f5.com nxt_proto_setup(nxt_task_t *task, nxt_process_t *process)
5000Sigor@sysoev.ru {
501216Sigor@sysoev.ru     nxt_int_t              ret;
502216Sigor@sysoev.ru     nxt_app_lang_module_t  *lang;
503216Sigor@sysoev.ru     nxt_common_app_conf_t  *app_conf;
504141Smax.romanov@nginx.com 
5051488St.nateldemoura@f5.com     app_conf = process->data.app;
506141Smax.romanov@nginx.com 
5071998St.nateldemoura@f5.com     nxt_queue_init(&nxt_proto_children);
5081998St.nateldemoura@f5.com 
5091998St.nateldemoura@f5.com     nxt_app_conf = app_conf;
5101998St.nateldemoura@f5.com 
511216Sigor@sysoev.ru     lang = nxt_app_lang_module(task->thread->runtime, &app_conf->type);
512216Sigor@sysoev.ru     if (nxt_slow_path(lang == NULL)) {
513564Svbart@nginx.com         nxt_alert(task, "unknown application type: \"%V\"", &app_conf->type);
514216Sigor@sysoev.ru         return NXT_ERROR;
515216Sigor@sysoev.ru     }
516216Sigor@sysoev.ru 
517216Sigor@sysoev.ru     nxt_app = lang->module;
518216Sigor@sysoev.ru 
519216Sigor@sysoev.ru     if (nxt_app == NULL) {
520354Svbart@nginx.com         nxt_debug(task, "application language module: %s \"%s\"",
521354Svbart@nginx.com                   lang->version, lang->file);
522216Sigor@sysoev.ru 
523216Sigor@sysoev.ru         nxt_app = nxt_app_module_load(task, lang->file);
5241239Smax.romanov@nginx.com         if (nxt_slow_path(nxt_app == NULL)) {
5251239Smax.romanov@nginx.com             return NXT_ERROR;
5261239Smax.romanov@nginx.com         }
527216Sigor@sysoev.ru     }
528216Sigor@sysoev.ru 
5291489St.nateldemoura@f5.com     if (nxt_slow_path(nxt_app_set_environment(app_conf->environment)
5301489St.nateldemoura@f5.com                       != NXT_OK))
5311489St.nateldemoura@f5.com     {
5321489St.nateldemoura@f5.com         nxt_alert(task, "failed to set environment");
5331489St.nateldemoura@f5.com         return NXT_ERROR;
5341489St.nateldemoura@f5.com     }
5351489St.nateldemoura@f5.com 
5361488St.nateldemoura@f5.com     if (nxt_app->setup != NULL) {
5371488St.nateldemoura@f5.com         ret = nxt_app->setup(task, process, app_conf);
538977Smax.romanov@gmail.com         if (nxt_slow_path(ret != NXT_OK)) {
5391104Smax.romanov@nginx.com             return ret;
540977Smax.romanov@gmail.com         }
541977Smax.romanov@gmail.com     }
542977Smax.romanov@gmail.com 
5431489St.nateldemoura@f5.com #if (NXT_HAVE_ISOLATION_ROOTFS)
5441489St.nateldemoura@f5.com     if (process->isolation.rootfs != NULL) {
5451489St.nateldemoura@f5.com         if (process->isolation.mounts != NULL) {
5461579St.nateldemoura@f5.com             ret = nxt_isolation_prepare_rootfs(task, process);
5471489St.nateldemoura@f5.com             if (nxt_slow_path(ret != NXT_OK)) {
5481489St.nateldemoura@f5.com                 return ret;
5491489St.nateldemoura@f5.com             }
5501489St.nateldemoura@f5.com         }
5511489St.nateldemoura@f5.com 
5521579St.nateldemoura@f5.com         ret = nxt_isolation_change_root(task, process);
5531489St.nateldemoura@f5.com         if (nxt_slow_path(ret != NXT_OK)) {
5541489St.nateldemoura@f5.com             return NXT_ERROR;
5551489St.nateldemoura@f5.com         }
5561489St.nateldemoura@f5.com     }
5571489St.nateldemoura@f5.com #endif
5581489St.nateldemoura@f5.com 
559277Sigor@sysoev.ru     if (app_conf->working_directory != NULL
560277Sigor@sysoev.ru         && app_conf->working_directory[0] != 0)
561271Smax.romanov@nginx.com     {
562271Smax.romanov@nginx.com         ret = chdir(app_conf->working_directory);
563271Smax.romanov@nginx.com 
564271Smax.romanov@nginx.com         if (nxt_slow_path(ret != 0)) {
565271Smax.romanov@nginx.com             nxt_log(task, NXT_LOG_WARN, "chdir(%s) failed %E",
566271Smax.romanov@nginx.com                     app_conf->working_directory, nxt_errno);
567271Smax.romanov@nginx.com 
568271Smax.romanov@nginx.com             return NXT_ERROR;
569271Smax.romanov@nginx.com         }
570271Smax.romanov@nginx.com     }
571271Smax.romanov@nginx.com 
5721998St.nateldemoura@f5.com     process->state = NXT_PROCESS_STATE_CREATED;
5731998St.nateldemoura@f5.com 
5741998St.nateldemoura@f5.com     return NXT_OK;
5751998St.nateldemoura@f5.com }
5761998St.nateldemoura@f5.com 
5771998St.nateldemoura@f5.com 
5781998St.nateldemoura@f5.com static nxt_int_t
nxt_proto_start(nxt_task_t * task,nxt_process_data_t * data)5791998St.nateldemoura@f5.com nxt_proto_start(nxt_task_t *task, nxt_process_data_t *data)
5801998St.nateldemoura@f5.com {
5811998St.nateldemoura@f5.com     nxt_debug(task, "prototype waiting for clone messages");
5821998St.nateldemoura@f5.com 
5831998St.nateldemoura@f5.com     return NXT_OK;
5841998St.nateldemoura@f5.com }
5851998St.nateldemoura@f5.com 
5861998St.nateldemoura@f5.com 
5871998St.nateldemoura@f5.com static void
nxt_proto_start_process_handler(nxt_task_t * task,nxt_port_recv_msg_t * msg)5881998St.nateldemoura@f5.com nxt_proto_start_process_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
5891998St.nateldemoura@f5.com {
5901998St.nateldemoura@f5.com     u_char              *p;
5911998St.nateldemoura@f5.com     nxt_int_t           ret;
5921998St.nateldemoura@f5.com     nxt_port_t          *port;
5931998St.nateldemoura@f5.com     nxt_runtime_t       *rt;
5941998St.nateldemoura@f5.com     nxt_process_t       *process;
5951998St.nateldemoura@f5.com     nxt_process_init_t  *init;
5961998St.nateldemoura@f5.com 
5971998St.nateldemoura@f5.com     rt = task->thread->runtime;
5981998St.nateldemoura@f5.com 
5991998St.nateldemoura@f5.com     process = nxt_process_new(rt);
6001998St.nateldemoura@f5.com     if (nxt_slow_path(process == NULL)) {
6011998St.nateldemoura@f5.com         goto failed;
6021998St.nateldemoura@f5.com     }
6031998St.nateldemoura@f5.com 
6041998St.nateldemoura@f5.com     process->mem_pool = nxt_mp_create(1024, 128, 256, 32);
6051998St.nateldemoura@f5.com     if (nxt_slow_path(process->mem_pool == NULL)) {
6061998St.nateldemoura@f5.com         nxt_process_use(task, process, -1);
6071998St.nateldemoura@f5.com         goto failed;
6081998St.nateldemoura@f5.com     }
6091998St.nateldemoura@f5.com 
6101998St.nateldemoura@f5.com     process->parent_port = rt->port_by_type[NXT_PROCESS_PROTOTYPE];
6111998St.nateldemoura@f5.com 
6121488St.nateldemoura@f5.com     init = nxt_process_init(process);
6131998St.nateldemoura@f5.com     *init = nxt_app_process;
6141998St.nateldemoura@f5.com 
6151998St.nateldemoura@f5.com     process->name = nxt_mp_alloc(process->mem_pool, nxt_app_conf->name.length
6161998St.nateldemoura@f5.com                                  + sizeof("\"\" application") + 1);
6171998St.nateldemoura@f5.com 
6181998St.nateldemoura@f5.com     if (nxt_slow_path(process->name == NULL)) {
6191998St.nateldemoura@f5.com         nxt_process_use(task, process, -1);
6201998St.nateldemoura@f5.com 
6211998St.nateldemoura@f5.com         goto failed;
6221998St.nateldemoura@f5.com     }
623141Smax.romanov@nginx.com 
6241488St.nateldemoura@f5.com     init->start = nxt_app->start;
625141Smax.romanov@nginx.com 
6261998St.nateldemoura@f5.com     init->name = (const char *) nxt_app_conf->name.start;
6271998St.nateldemoura@f5.com 
6281998St.nateldemoura@f5.com     p = (u_char *) process->name;
6291998St.nateldemoura@f5.com     *p++ = '"';
6301998St.nateldemoura@f5.com     p = nxt_cpymem(p, nxt_app_conf->name.start, nxt_app_conf->name.length);
6311998St.nateldemoura@f5.com     p = nxt_cpymem(p, "\" application", 13);
6321998St.nateldemoura@f5.com     *p = '\0';
6331998St.nateldemoura@f5.com 
6341998St.nateldemoura@f5.com     process->user_cred = &rt->user_cred;
6351998St.nateldemoura@f5.com 
6361998St.nateldemoura@f5.com     process->data.app = nxt_app_conf;
6371998St.nateldemoura@f5.com     process->stream = msg->port_msg.stream;
6381998St.nateldemoura@f5.com 
6391998St.nateldemoura@f5.com     ret = nxt_process_start(task, process);
6401998St.nateldemoura@f5.com     if (nxt_slow_path(ret == NXT_ERROR)) {
6411998St.nateldemoura@f5.com         nxt_process_use(task, process, -1);
6421998St.nateldemoura@f5.com 
6431998St.nateldemoura@f5.com         goto failed;
6441998St.nateldemoura@f5.com     }
6451998St.nateldemoura@f5.com 
6461998St.nateldemoura@f5.com     nxt_proto_process_add(task, process);
6471998St.nateldemoura@f5.com 
6481998St.nateldemoura@f5.com     return;
6491998St.nateldemoura@f5.com 
6501998St.nateldemoura@f5.com failed:
6511998St.nateldemoura@f5.com 
6521998St.nateldemoura@f5.com     port = nxt_runtime_port_find(rt, msg->port_msg.pid,
6531998St.nateldemoura@f5.com                                  msg->port_msg.reply_port);
6541998St.nateldemoura@f5.com 
6551998St.nateldemoura@f5.com     if (nxt_fast_path(port != NULL)) {
6561998St.nateldemoura@f5.com         nxt_port_socket_write(task, port, NXT_PORT_MSG_RPC_ERROR,
6571998St.nateldemoura@f5.com                               -1, msg->port_msg.stream, 0, NULL);
6581998St.nateldemoura@f5.com     }
6591998St.nateldemoura@f5.com }
6601998St.nateldemoura@f5.com 
6611998St.nateldemoura@f5.com 
6621998St.nateldemoura@f5.com static void
nxt_proto_quit_handler(nxt_task_t * task,nxt_port_recv_msg_t * msg)6631998St.nateldemoura@f5.com nxt_proto_quit_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
6641998St.nateldemoura@f5.com {
6651998St.nateldemoura@f5.com     nxt_debug(task, "prototype quit handler");
6661998St.nateldemoura@f5.com 
6671998St.nateldemoura@f5.com     nxt_proto_quit_children(task);
6681998St.nateldemoura@f5.com 
6691998St.nateldemoura@f5.com     nxt_proto_exiting = 1;
6701998St.nateldemoura@f5.com 
6711998St.nateldemoura@f5.com     if (nxt_queue_is_empty(&nxt_proto_children)) {
6721998St.nateldemoura@f5.com         nxt_process_quit(task, 0);
6731998St.nateldemoura@f5.com     }
6741998St.nateldemoura@f5.com }
6751998St.nateldemoura@f5.com 
6761998St.nateldemoura@f5.com 
6771998St.nateldemoura@f5.com static void
nxt_proto_quit_children(nxt_task_t * task)6781998St.nateldemoura@f5.com nxt_proto_quit_children(nxt_task_t *task)
6791998St.nateldemoura@f5.com {
6801998St.nateldemoura@f5.com     nxt_port_t     *port;
6811998St.nateldemoura@f5.com     nxt_process_t  *process;
6821998St.nateldemoura@f5.com 
6831998St.nateldemoura@f5.com     nxt_queue_each(process, &nxt_proto_children, nxt_process_t, link) {
6841998St.nateldemoura@f5.com         port = nxt_process_port_first(process);
6851998St.nateldemoura@f5.com 
6861998St.nateldemoura@f5.com         (void) nxt_port_socket_write(task, port, NXT_PORT_MSG_QUIT,
6871998St.nateldemoura@f5.com                                      -1, 0, 0, NULL);
6881998St.nateldemoura@f5.com     }
6891998St.nateldemoura@f5.com     nxt_queue_loop;
6901998St.nateldemoura@f5.com }
6911998St.nateldemoura@f5.com 
6921998St.nateldemoura@f5.com 
6931998St.nateldemoura@f5.com static void
nxt_proto_process_created_handler(nxt_task_t * task,nxt_port_recv_msg_t * msg)6941998St.nateldemoura@f5.com nxt_proto_process_created_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
6951998St.nateldemoura@f5.com {
6961998St.nateldemoura@f5.com     nxt_pid_t      isolated_pid, pid;
6971998St.nateldemoura@f5.com     nxt_process_t  *process;
6981998St.nateldemoura@f5.com 
6991998St.nateldemoura@f5.com     isolated_pid = nxt_recv_msg_cmsg_pid(msg);
7001998St.nateldemoura@f5.com 
7011998St.nateldemoura@f5.com     process = nxt_proto_process_find(task, isolated_pid);
7021998St.nateldemoura@f5.com     if (nxt_slow_path(process == NULL)) {
7031998St.nateldemoura@f5.com         return;
7041998St.nateldemoura@f5.com     }
7051998St.nateldemoura@f5.com 
7061488St.nateldemoura@f5.com     process->state = NXT_PROCESS_STATE_CREATED;
70720Sigor@sysoev.ru 
7081998St.nateldemoura@f5.com     pid = msg->port_msg.pid;
7091998St.nateldemoura@f5.com 
7101998St.nateldemoura@f5.com     if (process->pid != pid) {
7111998St.nateldemoura@f5.com         nxt_debug(task, "app process %PI (aka %PI) is created", isolated_pid,
7121998St.nateldemoura@f5.com                   pid);
7131998St.nateldemoura@f5.com 
7141998St.nateldemoura@f5.com         nxt_runtime_process_remove(task->thread->runtime, process);
7151998St.nateldemoura@f5.com 
7161998St.nateldemoura@f5.com         process->pid = pid;
7171998St.nateldemoura@f5.com 
7181998St.nateldemoura@f5.com         nxt_runtime_process_add(task, process);
7191998St.nateldemoura@f5.com 
7201998St.nateldemoura@f5.com     } else {
7211998St.nateldemoura@f5.com         nxt_debug(task, "app process %PI is created", isolated_pid);
7221998St.nateldemoura@f5.com     }
7231998St.nateldemoura@f5.com }
7241998St.nateldemoura@f5.com 
7251998St.nateldemoura@f5.com 
7261998St.nateldemoura@f5.com static void
nxt_proto_signal_handler(nxt_task_t * task,void * obj,void * data)7271998St.nateldemoura@f5.com nxt_proto_signal_handler(nxt_task_t *task, void *obj, void *data)
7281998St.nateldemoura@f5.com {
7291998St.nateldemoura@f5.com     nxt_trace(task, "signal signo:%d (%s) received, ignored",
7301998St.nateldemoura@f5.com               (int) (uintptr_t) obj, data);
7311998St.nateldemoura@f5.com }
7321998St.nateldemoura@f5.com 
7331998St.nateldemoura@f5.com 
7341998St.nateldemoura@f5.com static void
nxt_proto_sigterm_handler(nxt_task_t * task,void * obj,void * data)7351998St.nateldemoura@f5.com nxt_proto_sigterm_handler(nxt_task_t *task, void *obj, void *data)
736