xref: /unit/src/nxt_router_access_log.c (revision 2247:baa6b9879267)
12165Sz.hong@f5.com 
22165Sz.hong@f5.com /*
32165Sz.hong@f5.com  * Copyright (C) Igor Sysoev
42165Sz.hong@f5.com  * Copyright (C) Valentin V. Bartenev
52165Sz.hong@f5.com  * Copyright (C) NGINX, Inc.
62165Sz.hong@f5.com  */
72165Sz.hong@f5.com 
82165Sz.hong@f5.com #include <nxt_router.h>
92165Sz.hong@f5.com #include <nxt_conf.h>
102165Sz.hong@f5.com #include <nxt_http.h>
112165Sz.hong@f5.com 
122165Sz.hong@f5.com 
132166Sz.hong@f5.com typedef struct {
142166Sz.hong@f5.com     nxt_str_t                 path;
152166Sz.hong@f5.com     nxt_str_t                 format;
162166Sz.hong@f5.com } nxt_router_access_log_conf_t;
172166Sz.hong@f5.com 
182166Sz.hong@f5.com 
192166Sz.hong@f5.com typedef struct {
202166Sz.hong@f5.com     nxt_str_t                 text;
212166Sz.hong@f5.com     nxt_router_access_log_t   *access_log;
222166Sz.hong@f5.com } nxt_router_access_log_ctx_t;
232166Sz.hong@f5.com 
242166Sz.hong@f5.com 
252165Sz.hong@f5.com static void nxt_router_access_log_writer(nxt_task_t *task,
262166Sz.hong@f5.com     nxt_http_request_t *r, nxt_router_access_log_t *access_log,
272246Sz.hong@f5.com     nxt_tstr_t *format);
282166Sz.hong@f5.com static void nxt_router_access_log_write_ready(nxt_task_t *task, void *obj,
292166Sz.hong@f5.com     void *data);
302166Sz.hong@f5.com static void nxt_router_access_log_write_error(nxt_task_t *task, void *obj,
312166Sz.hong@f5.com     void *data);
322165Sz.hong@f5.com static void nxt_router_access_log_ready(nxt_task_t *task,
332165Sz.hong@f5.com     nxt_port_recv_msg_t *msg, void *data);
342165Sz.hong@f5.com static void nxt_router_access_log_error(nxt_task_t *task,
352165Sz.hong@f5.com     nxt_port_recv_msg_t *msg, void *data);
362165Sz.hong@f5.com static void nxt_router_access_log_reopen_completion(nxt_task_t *task, void *obj,
372165Sz.hong@f5.com     void *data);
382165Sz.hong@f5.com static void nxt_router_access_log_reopen_ready(nxt_task_t *task,
392165Sz.hong@f5.com     nxt_port_recv_msg_t *msg, void *data);
402165Sz.hong@f5.com static void nxt_router_access_log_reopen_error(nxt_task_t *task,
412165Sz.hong@f5.com     nxt_port_recv_msg_t *msg, void *data);
422165Sz.hong@f5.com 
432165Sz.hong@f5.com 
442166Sz.hong@f5.com static nxt_conf_map_t  nxt_router_access_log_conf[] = {
452166Sz.hong@f5.com     {
462166Sz.hong@f5.com         nxt_string("path"),
472166Sz.hong@f5.com         NXT_CONF_MAP_STR,
482166Sz.hong@f5.com         offsetof(nxt_router_access_log_conf_t, path),
492166Sz.hong@f5.com     },
502166Sz.hong@f5.com 
512166Sz.hong@f5.com     {
522166Sz.hong@f5.com         nxt_string("format"),
532166Sz.hong@f5.com         NXT_CONF_MAP_STR,
542166Sz.hong@f5.com         offsetof(nxt_router_access_log_conf_t, format),
552166Sz.hong@f5.com     },
562166Sz.hong@f5.com };
572166Sz.hong@f5.com 
582166Sz.hong@f5.com 
592165Sz.hong@f5.com nxt_int_t
nxt_router_access_log_create(nxt_task_t * task,nxt_router_conf_t * rtcf,nxt_conf_value_t * value)602165Sz.hong@f5.com nxt_router_access_log_create(nxt_task_t *task, nxt_router_conf_t *rtcf,
612165Sz.hong@f5.com     nxt_conf_value_t *value)
622165Sz.hong@f5.com {
632166Sz.hong@f5.com     u_char                        *p;
642166Sz.hong@f5.com     nxt_int_t                     ret;
652166Sz.hong@f5.com     nxt_str_t                     str;
662246Sz.hong@f5.com     nxt_tstr_t                    *format;
672166Sz.hong@f5.com     nxt_router_t                  *router;
682166Sz.hong@f5.com     nxt_router_access_log_t       *access_log;
692166Sz.hong@f5.com     nxt_router_access_log_conf_t  alcf;
702166Sz.hong@f5.com 
712166Sz.hong@f5.com     static nxt_str_t  log_format_str = nxt_string("$remote_addr - - "
722166Sz.hong@f5.com         "[$time_local] \"$request_line\" $status $body_bytes_sent "
732166Sz.hong@f5.com         "\"$header_referer\" \"$header_user_agent\"");
742166Sz.hong@f5.com 
752166Sz.hong@f5.com     alcf.format = log_format_str;
762166Sz.hong@f5.com 
772166Sz.hong@f5.com     if (nxt_conf_type(value) == NXT_CONF_STRING) {
782166Sz.hong@f5.com         nxt_conf_get_string(value, &alcf.path);
792166Sz.hong@f5.com 
802166Sz.hong@f5.com     } else {
812166Sz.hong@f5.com         ret = nxt_conf_map_object(rtcf->mem_pool, value,
822166Sz.hong@f5.com                                   nxt_router_access_log_conf,
832166Sz.hong@f5.com                                   nxt_nitems(nxt_router_access_log_conf),
842166Sz.hong@f5.com                                   &alcf);
852166Sz.hong@f5.com         if (ret != NXT_OK) {
862166Sz.hong@f5.com             nxt_alert(task, "access log map error");
872166Sz.hong@f5.com             return NXT_ERROR;
882166Sz.hong@f5.com         }
892166Sz.hong@f5.com     }
902165Sz.hong@f5.com 
912165Sz.hong@f5.com     router = nxt_router;
922165Sz.hong@f5.com 
932165Sz.hong@f5.com     access_log = router->access_log;
942165Sz.hong@f5.com 
952166Sz.hong@f5.com     if (access_log != NULL && nxt_strstr_eq(&alcf.path, &access_log->path)) {
962165Sz.hong@f5.com         nxt_router_access_log_use(&router->lock, access_log);
972165Sz.hong@f5.com 
982165Sz.hong@f5.com     } else {
992165Sz.hong@f5.com         access_log = nxt_malloc(sizeof(nxt_router_access_log_t)
1002166Sz.hong@f5.com                                 + alcf.path.length);
1012165Sz.hong@f5.com         if (access_log == NULL) {
1022165Sz.hong@f5.com             nxt_alert(task, "failed to allocate access log structure");
1032165Sz.hong@f5.com             return NXT_ERROR;
1042165Sz.hong@f5.com         }
1052165Sz.hong@f5.com 
1062165Sz.hong@f5.com         access_log->fd = -1;
1072165Sz.hong@f5.com         access_log->handler = &nxt_router_access_log_writer;
1082165Sz.hong@f5.com         access_log->count = 1;
1092165Sz.hong@f5.com 
1102166Sz.hong@f5.com         access_log->path.length = alcf.path.length;
1112165Sz.hong@f5.com         access_log->path.start = (u_char *) access_log
1122165Sz.hong@f5.com                                  + sizeof(nxt_router_access_log_t);
1132165Sz.hong@f5.com 
1142166Sz.hong@f5.com         nxt_memcpy(access_log->path.start, alcf.path.start, alcf.path.length);
1152166Sz.hong@f5.com     }
1162166Sz.hong@f5.com 
1172166Sz.hong@f5.com     str.length = alcf.format.length + 1;
1182166Sz.hong@f5.com 
1192166Sz.hong@f5.com     str.start = nxt_malloc(str.length);
1202166Sz.hong@f5.com     if (str.start == NULL) {
1212166Sz.hong@f5.com         nxt_alert(task, "failed to allocate log format structure");
1222166Sz.hong@f5.com         return NXT_ERROR;
1232166Sz.hong@f5.com     }
1242166Sz.hong@f5.com 
1252166Sz.hong@f5.com     p = nxt_cpymem(str.start, alcf.format.start, alcf.format.length);
1262166Sz.hong@f5.com     *p = '\n';
1272166Sz.hong@f5.com 
1282246Sz.hong@f5.com     format = nxt_tstr_compile(rtcf->tstr_state, &str, NXT_TSTR_LOGGING);
1292166Sz.hong@f5.com     if (nxt_slow_path(format == NULL)) {
1302166Sz.hong@f5.com         return NXT_ERROR;
1312165Sz.hong@f5.com     }
1322165Sz.hong@f5.com 
1332165Sz.hong@f5.com     rtcf->access_log = access_log;
1342166Sz.hong@f5.com     rtcf->log_format = format;
1352165Sz.hong@f5.com 
1362165Sz.hong@f5.com     return NXT_OK;
1372165Sz.hong@f5.com }
1382165Sz.hong@f5.com 
1392165Sz.hong@f5.com 
1402165Sz.hong@f5.com static void
nxt_router_access_log_writer(nxt_task_t * task,nxt_http_request_t * r,nxt_router_access_log_t * access_log,nxt_tstr_t * format)1412165Sz.hong@f5.com nxt_router_access_log_writer(nxt_task_t *task, nxt_http_request_t *r,
1422246Sz.hong@f5.com     nxt_router_access_log_t *access_log, nxt_tstr_t *format)
1432165Sz.hong@f5.com {
1442166Sz.hong@f5.com     nxt_int_t                    ret;
1452246Sz.hong@f5.com     nxt_router_conf_t            *rtcf;
1462166Sz.hong@f5.com     nxt_router_access_log_ctx_t  *ctx;
1472165Sz.hong@f5.com 
1482166Sz.hong@f5.com     ctx = nxt_mp_get(r->mem_pool, sizeof(nxt_router_access_log_ctx_t));
1492166Sz.hong@f5.com     if (nxt_slow_path(ctx == NULL)) {
1502165Sz.hong@f5.com         return;
1512165Sz.hong@f5.com     }
1522165Sz.hong@f5.com 
1532166Sz.hong@f5.com     ctx->access_log = access_log;
1542165Sz.hong@f5.com 
1552246Sz.hong@f5.com     if (nxt_tstr_is_const(format)) {
1562246Sz.hong@f5.com         nxt_tstr_str(format, &ctx->text);
1572165Sz.hong@f5.com 
1582166Sz.hong@f5.com         nxt_router_access_log_write_ready(task, r, ctx);
1592165Sz.hong@f5.com 
1602165Sz.hong@f5.com     } else {
1612246Sz.hong@f5.com         rtcf = r->conf->socket_conf->router_conf;
1622246Sz.hong@f5.com 
1632246Sz.hong@f5.com         ret = nxt_tstr_query_init(&r->tstr_query, rtcf->tstr_state,
164*2247Sz.hong@f5.com                                   &r->tstr_cache, r, r->mem_pool);
1652166Sz.hong@f5.com         if (nxt_slow_path(ret != NXT_OK)) {
1662166Sz.hong@f5.com             return;
1672166Sz.hong@f5.com         }
1682165Sz.hong@f5.com 
1692246Sz.hong@f5.com         nxt_tstr_query(task, r->tstr_query, format, &ctx->text);
1702246Sz.hong@f5.com         nxt_tstr_query_resolve(task, r->tstr_query, ctx,
1712246Sz.hong@f5.com                                nxt_router_access_log_write_ready,
1722246Sz.hong@f5.com                                nxt_router_access_log_write_error);
1732166Sz.hong@f5.com      }
1742165Sz.hong@f5.com }
1752165Sz.hong@f5.com 
1762165Sz.hong@f5.com 
1772166Sz.hong@f5.com static void
nxt_router_access_log_write_ready(nxt_task_t * task,void * obj,void * data)1782166Sz.hong@f5.com nxt_router_access_log_write_ready(nxt_task_t *task, void *obj, void *data)
1792165Sz.hong@f5.com {
1802166Sz.hong@f5.com     nxt_http_request_t           *r;
1812166Sz.hong@f5.com     nxt_router_access_log_ctx_t  *ctx;
1822165Sz.hong@f5.com 
1832166Sz.hong@f5.com     r = obj;
1842166Sz.hong@f5.com     ctx = data;
1852165Sz.hong@f5.com 
1862166Sz.hong@f5.com     nxt_fd_write(ctx->access_log->fd, ctx->text.start, ctx->text.length);
1872166Sz.hong@f5.com 
1882166Sz.hong@f5.com     nxt_http_request_close_handler(task, r, r->proto.any);
1892166Sz.hong@f5.com }
1902165Sz.hong@f5.com 
1912165Sz.hong@f5.com 
1922166Sz.hong@f5.com static void
nxt_router_access_log_write_error(nxt_task_t * task,void * obj,void * data)1932166Sz.hong@f5.com nxt_router_access_log_write_error(nxt_task_t *task, void *obj, void *data)
1942166Sz.hong@f5.com {
1952166Sz.hong@f5.com 
1962165Sz.hong@f5.com }
1972165Sz.hong@f5.com 
1982165Sz.hong@f5.com 
1992165Sz.hong@f5.com void
nxt_router_access_log_open(nxt_task_t * task,nxt_router_temp_conf_t * tmcf)2002165Sz.hong@f5.com nxt_router_access_log_open(nxt_task_t *task, nxt_router_temp_conf_t *tmcf)
2012165Sz.hong@f5.com {
2022165Sz.hong@f5.com     uint32_t                 stream;
2032165Sz.hong@f5.com     nxt_int_t                ret;
2042165Sz.hong@f5.com     nxt_buf_t                *b;
2052165Sz.hong@f5.com     nxt_port_t               *main_port, *router_port;
2062165Sz.hong@f5.com     nxt_runtime_t            *rt;
2072165Sz.hong@f5.com     nxt_router_access_log_t  *access_log;
2082165Sz.hong@f5.com 
2092165Sz.hong@f5.com     access_log = tmcf->router_conf->access_log;
2102165Sz.hong@f5.com 
2112165Sz.hong@f5.com     b = nxt_buf_mem_alloc(tmcf->mem_pool, access_log->path.length + 1, 0);
2122165Sz.hong@f5.com     if (nxt_slow_path(b == NULL)) {
2132165Sz.hong@f5.com         goto fail;
2142165Sz.hong@f5.com     }
2152165Sz.hong@f5.com 
2162165Sz.hong@f5.com     b->completion_handler = nxt_buf_dummy_completion;
2172165Sz.hong@f5.com 
2182165Sz.hong@f5.com     nxt_buf_cpystr(b, &access_log->path);
2192165Sz.hong@f5.com     *b->mem.free++ = '\0';
2202165Sz.hong@f5.com 
2212165Sz.hong@f5.com     rt = task->thread->runtime;
2222165Sz.hong@f5.com     main_port = rt->port_by_type[NXT_PROCESS_MAIN];
2232165Sz.hong@f5.com     router_port = rt->port_by_type[NXT_PROCESS_ROUTER];
2242165Sz.hong@f5.com 
2252165Sz.hong@f5.com     stream = nxt_port_rpc_register_handler(task, router_port,
2262165Sz.hong@f5.com                                            nxt_router_access_log_ready,
2272165Sz.hong@f5.com                                            nxt_router_access_log_error,
2282165Sz.hong@f5.com                                            -1, tmcf);
2292165Sz.hong@f5.com     if (nxt_slow_path(stream == 0)) {
2302165Sz.hong@f5.com         goto fail;
2312165Sz.hong@f5.com     }
2322165Sz.hong@f5.com 
2332165Sz.hong@f5.com     ret = nxt_port_socket_write(task, main_port, NXT_PORT_MSG_ACCESS_LOG, -1,
2342165Sz.hong@f5.com                                 stream, router_port->id, b);
2352165Sz.hong@f5.com 
2362165Sz.hong@f5.com     if (nxt_slow_path(ret != NXT_OK)) {
2372165Sz.hong@f5.com         nxt_port_rpc_cancel(task, router_port, stream);
2382165Sz.hong@f5.com         goto fail;
2392165Sz.hong@f5.com     }
2402165Sz.hong@f5.com 
2412165Sz.hong@f5.com     return;
2422165Sz.hong@f5.com 
2432165Sz.hong@f5.com fail:
2442165Sz.hong@f5.com 
2452165Sz.hong@f5.com     nxt_router_conf_error(task, tmcf);
2462165Sz.hong@f5.com }
2472165Sz.hong@f5.com 
2482165Sz.hong@f5.com 
2492165Sz.hong@f5.com static void
nxt_router_access_log_ready(nxt_task_t * task,nxt_port_recv_msg_t * msg,void * data)2502165Sz.hong@f5.com nxt_router_access_log_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg,
2512165Sz.hong@f5.com     void *data)
2522165Sz.hong@f5.com {
2532165Sz.hong@f5.com     nxt_router_temp_conf_t   *tmcf;
2542165Sz.hong@f5.com     nxt_router_access_log_t  *access_log;
2552165Sz.hong@f5.com 
2562165Sz.hong@f5.com     tmcf = data;
2572165Sz.hong@f5.com 
2582165Sz.hong@f5.com     access_log = tmcf->router_conf->access_log;
2592165Sz.hong@f5.com 
2602165Sz.hong@f5.com     access_log->fd = msg->fd[0];
2612165Sz.hong@f5.com 
2622165Sz.hong@f5.com     nxt_work_queue_add(&task->thread->engine->fast_work_queue,
2632165Sz.hong@f5.com                        nxt_router_conf_apply, task, tmcf, NULL);
2642165Sz.hong@f5.com }
2652165Sz.hong@f5.com 
2662165Sz.hong@f5.com 
2672165Sz.hong@f5.com static void
nxt_router_access_log_error(nxt_task_t * task,nxt_port_recv_msg_t * msg,void * data)2682165Sz.hong@f5.com nxt_router_access_log_error(nxt_task_t *task, nxt_port_recv_msg_t *msg,
2692165Sz.hong@f5.com     void *data)
2702165Sz.hong@f5.com {
2712165Sz.hong@f5.com     nxt_router_temp_conf_t  *tmcf;
2722165Sz.hong@f5.com 
2732165Sz.hong@f5.com     tmcf = data;
2742165Sz.hong@f5.com 
2752165Sz.hong@f5.com     nxt_router_conf_error(task, tmcf);
2762165Sz.hong@f5.com }
2772165Sz.hong@f5.com 
2782165Sz.hong@f5.com 
2792165Sz.hong@f5.com void
nxt_router_access_log_use(nxt_thread_spinlock_t * lock,nxt_router_access_log_t * access_log)2802165Sz.hong@f5.com nxt_router_access_log_use(nxt_thread_spinlock_t *lock,
2812165Sz.hong@f5.com     nxt_router_access_log_t *access_log)
2822165Sz.hong@f5.com {
2832165Sz.hong@f5.com     if (access_log == NULL) {
2842165Sz.hong@f5.com         return;
2852165Sz.hong@f5.com     }
2862165Sz.hong@f5.com 
2872165Sz.hong@f5.com     nxt_thread_spin_lock(lock);
2882165Sz.hong@f5.com 
2892165Sz.hong@f5.com     access_log->count++;
2902165Sz.hong@f5.com 
2912165Sz.hong@f5.com     nxt_thread_spin_unlock(lock);
2922165Sz.hong@f5.com }
2932165Sz.hong@f5.com 
2942165Sz.hong@f5.com 
2952165Sz.hong@f5.com void
nxt_router_access_log_release(nxt_task_t * task,nxt_thread_spinlock_t * lock,nxt_router_access_log_t * access_log)2962165Sz.hong@f5.com nxt_router_access_log_release(nxt_task_t *task, nxt_thread_spinlock_t *lock,
2972165Sz.hong@f5.com     nxt_router_access_log_t *access_log)
2982165Sz.hong@f5.com {
2992165Sz.hong@f5.com     if (access_log == NULL) {
3002165Sz.hong@f5.com         return;
3012165Sz.hong@f5.com     }
3022165Sz.hong@f5.com 
3032165Sz.hong@f5.com     nxt_thread_spin_lock(lock);
3042165Sz.hong@f5.com 
3052165Sz.hong@f5.com     if (--access_log->count != 0) {
3062165Sz.hong@f5.com         access_log = NULL;
3072165Sz.hong@f5.com     }
3082165Sz.hong@f5.com 
3092165Sz.hong@f5.com     nxt_thread_spin_unlock(lock);
3102165Sz.hong@f5.com 
3112165Sz.hong@f5.com     if (access_log != NULL) {
3122165Sz.hong@f5.com 
3132165Sz.hong@f5.com         if (access_log->fd != -1) {
3142165Sz.hong@f5.com             nxt_fd_close(access_log->fd);
3152165Sz.hong@f5.com         }
3162165Sz.hong@f5.com 
3172165Sz.hong@f5.com         nxt_free(access_log);
3182165Sz.hong@f5.com     }
3192165Sz.hong@f5.com }
3202165Sz.hong@f5.com 
3212165Sz.hong@f5.com 
3222165Sz.hong@f5.com typedef struct {
3232165Sz.hong@f5.com     nxt_mp_t                 *mem_pool;
3242165Sz.hong@f5.com     nxt_router_access_log_t  *access_log;
3252165Sz.hong@f5.com } nxt_router_access_log_reopen_t;
3262165Sz.hong@f5.com 
3272165Sz.hong@f5.com 
3282165Sz.hong@f5.com void
nxt_router_access_log_reopen_handler(nxt_task_t * task,nxt_port_recv_msg_t * msg)3292165Sz.hong@f5.com nxt_router_access_log_reopen_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
3302165Sz.hong@f5.com {
3312165Sz.hong@f5.com     nxt_mp_t                        *mp;
3322165Sz.hong@f5.com     uint32_t                        stream;
3332165Sz.hong@f5.com     nxt_int_t                       ret;
3342165Sz.hong@f5.com     nxt_buf_t                       *b;
3352165Sz.hong@f5.com     nxt_port_t                      *main_port, *router_port;
3362165Sz.hong@f5.com     nxt_runtime_t                   *rt;
3372165Sz.hong@f5.com     nxt_router_access_log_t         *access_log;
3382165Sz.hong@f5.com     nxt_router_access_log_reopen_t  *reopen;
3392165Sz.hong@f5.com 
3402165Sz.hong@f5.com     access_log = nxt_router->access_log;
3412165Sz.hong@f5.com 
3422165Sz.hong@f5.com     if (access_log == NULL) {
3432165Sz.hong@f5.com         return;
3442165Sz.hong@f5.com     }
3452165Sz.hong@f5.com 
3462165Sz.hong@f5.com     mp = nxt_mp_create(1024, 128, 256, 32);
3472165Sz.hong@f5.com     if (nxt_slow_path(mp == NULL)) {
3482165Sz.hong@f5.com         return;
3492165Sz.hong@f5.com     }
3502165Sz.hong@f5.com 
3512165Sz.hong@f5.com     reopen = nxt_mp_get(mp, sizeof(nxt_router_access_log_reopen_t));
3522165Sz.hong@f5.com     if (nxt_slow_path(reopen == NULL)) {
3532165Sz.hong@f5.com         goto fail;
3542165Sz.hong@f5.com     }
3552165Sz.hong@f5.com 
3562165Sz.hong@f5.com     reopen->mem_pool = mp;
3572165Sz.hong@f5.com     reopen->access_log = access_log;
3582165Sz.hong@f5.com 
3592165Sz.hong@f5.com     b = nxt_buf_mem_alloc(mp, access_log->path.length + 1, 0);
3602165Sz.hong@f5.com     if (nxt_slow_path(b == NULL)) {
3612165Sz.hong@f5.com         goto fail;
3622165Sz.hong@f5.com     }
3632165Sz.hong@f5.com 
3642165Sz.hong@f5.com     b->completion_handler = nxt_router_access_log_reopen_completion;
3652165Sz.hong@f5.com 
3662165Sz.hong@f5.com     nxt_buf_cpystr(b, &access_log->path);
3672165Sz.hong@f5.com     *b->mem.free++ = '\0';
3682165Sz.hong@f5.com 
3692165Sz.hong@f5.com     rt = task->thread->runtime;
3702165Sz.hong@f5.com     main_port = rt->port_by_type[NXT_PROCESS_MAIN];
3712165Sz.hong@f5.com     router_port = rt->port_by_type[NXT_PROCESS_ROUTER];
3722165Sz.hong@f5.com 
3732165Sz.hong@f5.com     stream = nxt_port_rpc_register_handler(task, router_port,
3742165Sz.hong@f5.com                                            nxt_router_access_log_reopen_ready,
3752165Sz.hong@f5.com                                            nxt_router_access_log_reopen_error,
3762165Sz.hong@f5.com                                            -1, reopen);
3772165Sz.hong@f5.com     if (nxt_slow_path(stream == 0)) {
3782165Sz.hong@f5.com         goto fail;
3792165Sz.hong@f5.com     }
3802165Sz.hong@f5.com 
3812165Sz.hong@f5.com     ret = nxt_port_socket_write(task, main_port, NXT_PORT_MSG_ACCESS_LOG, -1,
3822165Sz.hong@f5.com                                 stream, router_port->id, b);
3832165Sz.hong@f5.com 
3842165Sz.hong@f5.com     if (nxt_slow_path(ret != NXT_OK)) {
3852165Sz.hong@f5.com         nxt_port_rpc_cancel(task, router_port, stream);
3862165Sz.hong@f5.com         goto fail;
3872165Sz.hong@f5.com     }
3882165Sz.hong@f5.com 
3892165Sz.hong@f5.com     nxt_mp_retain(mp);
3902165Sz.hong@f5.com 
3912165Sz.hong@f5.com     return;
3922165Sz.hong@f5.com 
3932165Sz.hong@f5.com fail:
3942165Sz.hong@f5.com 
3952165Sz.hong@f5.com     nxt_mp_destroy(mp);
3962165Sz.hong@f5.com }
3972165Sz.hong@f5.com 
3982165Sz.hong@f5.com 
3992165Sz.hong@f5.com static void
nxt_router_access_log_reopen_completion(nxt_task_t * task,void * obj,void * data)4002165Sz.hong@f5.com nxt_router_access_log_reopen_completion(nxt_task_t *task, void *obj, void *data)
4012165Sz.hong@f5.com {
4022165Sz.hong@f5.com     nxt_mp_t   *mp;
4032165Sz.hong@f5.com     nxt_buf_t  *b;
4042165Sz.hong@f5.com 
4052165Sz.hong@f5.com     b = obj;
4062165Sz.hong@f5.com     mp = b->data;
4072165Sz.hong@f5.com 
4082165Sz.hong@f5.com     nxt_mp_release(mp);
4092165Sz.hong@f5.com }
4102165Sz.hong@f5.com 
4112165Sz.hong@f5.com 
4122165Sz.hong@f5.com static void
nxt_router_access_log_reopen_ready(nxt_task_t * task,nxt_port_recv_msg_t * msg,void * data)4132165Sz.hong@f5.com nxt_router_access_log_reopen_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg,
4142165Sz.hong@f5.com     void *data)
4152165Sz.hong@f5.com {
4162165Sz.hong@f5.com     nxt_router_access_log_t         *access_log;
4172165Sz.hong@f5.com     nxt_router_access_log_reopen_t  *reopen;
4182165Sz.hong@f5.com 
4192165Sz.hong@f5.com     reopen = data;
4202165Sz.hong@f5.com 
4212165Sz.hong@f5.com     access_log = reopen->access_log;
4222165Sz.hong@f5.com 
4232165Sz.hong@f5.com     if (access_log == nxt_router->access_log) {
4242165Sz.hong@f5.com 
4252165Sz.hong@f5.com         if (nxt_slow_path(dup2(msg->fd[0], access_log->fd) == -1)) {
4262165Sz.hong@f5.com             nxt_alert(task, "dup2(%FD, %FD) failed %E",
4272165Sz.hong@f5.com                       msg->fd[0], access_log->fd, nxt_errno);
4282165Sz.hong@f5.com         }
4292165Sz.hong@f5.com     }
4302165Sz.hong@f5.com 
4312165Sz.hong@f5.com     nxt_fd_close(msg->fd[0]);
4322165Sz.hong@f5.com     nxt_mp_release(reopen->mem_pool);
4332165Sz.hong@f5.com }
4342165Sz.hong@f5.com 
4352165Sz.hong@f5.com 
4362165Sz.hong@f5.com static void
nxt_router_access_log_reopen_error(nxt_task_t * task,nxt_port_recv_msg_t * msg,void * data)4372165Sz.hong@f5.com nxt_router_access_log_reopen_error(nxt_task_t *task, nxt_port_recv_msg_t *msg,
4382165Sz.hong@f5.com     void *data)
4392165Sz.hong@f5.com {
4402165Sz.hong@f5.com     nxt_router_access_log_reopen_t  *reopen;
4412165Sz.hong@f5.com 
4422165Sz.hong@f5.com     reopen = data;
4432165Sz.hong@f5.com 
4442165Sz.hong@f5.com     nxt_mp_release(reopen->mem_pool);
4452165Sz.hong@f5.com }
446