mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-02 14:43:23 +00:00
lib: implement terminal monitor
for vtysh
Adds a new logging target that sends log messages to vtysh. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
b2dde56b2c
commit
0798d2760d
@ -113,6 +113,7 @@ lib_libfrr_la_SOURCES = \
|
|||||||
lib/zlog.c \
|
lib/zlog.c \
|
||||||
lib/zlog_5424.c \
|
lib/zlog_5424.c \
|
||||||
lib/zlog_5424_cli.c \
|
lib/zlog_5424_cli.c \
|
||||||
|
lib/zlog_live.c \
|
||||||
lib/zlog_targets.c \
|
lib/zlog_targets.c \
|
||||||
lib/printf/printf-pos.c \
|
lib/printf/printf-pos.c \
|
||||||
lib/printf/vfprintf.c \
|
lib/printf/vfprintf.c \
|
||||||
@ -287,6 +288,7 @@ pkginclude_HEADERS += \
|
|||||||
lib/zebra.h \
|
lib/zebra.h \
|
||||||
lib/zlog.h \
|
lib/zlog.h \
|
||||||
lib/zlog_5424.h \
|
lib/zlog_5424.h \
|
||||||
|
lib/zlog_live.h \
|
||||||
lib/zlog_targets.h \
|
lib/zlog_targets.h \
|
||||||
lib/pbr.h \
|
lib/pbr.h \
|
||||||
lib/routing_nb.h \
|
lib/routing_nb.h \
|
||||||
|
75
lib/vty.c
75
lib/vty.c
@ -1314,8 +1314,6 @@ static void vty_read(struct thread *thread)
|
|||||||
vty_event(VTY_READ, vty);
|
vty_event(VTY_READ, vty);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vty->monitor = 0; /* disable monitoring to avoid
|
|
||||||
infinite recursion */
|
|
||||||
flog_err(
|
flog_err(
|
||||||
EC_LIB_SOCKET,
|
EC_LIB_SOCKET,
|
||||||
"%s: read error on vty client fd %d, closing: %s",
|
"%s: read error on vty client fd %d, closing: %s",
|
||||||
@ -1529,8 +1527,6 @@ static void vty_flush(struct thread *thread)
|
|||||||
vty->lines >= 0 ? vty->lines : vty->height, erase, 0);
|
vty->lines >= 0 ? vty->lines : vty->height, erase, 0);
|
||||||
switch (flushrc) {
|
switch (flushrc) {
|
||||||
case BUFFER_ERROR:
|
case BUFFER_ERROR:
|
||||||
vty->monitor =
|
|
||||||
0; /* disable monitoring to avoid infinite recursion */
|
|
||||||
zlog_info("buffer_flush failed on vty client fd %d/%d, closing",
|
zlog_info("buffer_flush failed on vty client fd %d/%d, closing",
|
||||||
vty->fd, vty->wfd);
|
vty->fd, vty->wfd);
|
||||||
buffer_reset(vty->lbuf);
|
buffer_reset(vty->lbuf);
|
||||||
@ -2078,8 +2074,6 @@ static int vtysh_flush(struct vty *vty)
|
|||||||
vty_event(VTYSH_WRITE, vty);
|
vty_event(VTYSH_WRITE, vty);
|
||||||
break;
|
break;
|
||||||
case BUFFER_ERROR:
|
case BUFFER_ERROR:
|
||||||
vty->monitor =
|
|
||||||
0; /* disable monitoring to avoid infinite recursion */
|
|
||||||
flog_err(EC_LIB_SOCKET, "%s: write error to fd %d, closing",
|
flog_err(EC_LIB_SOCKET, "%s: write error to fd %d, closing",
|
||||||
__func__, vty->fd);
|
__func__, vty->fd);
|
||||||
buffer_reset(vty->lbuf);
|
buffer_reset(vty->lbuf);
|
||||||
@ -2119,8 +2113,6 @@ static void vtysh_read(struct thread *thread)
|
|||||||
vty_event(VTYSH_READ, vty);
|
vty_event(VTYSH_READ, vty);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vty->monitor = 0; /* disable monitoring to avoid
|
|
||||||
infinite recursion */
|
|
||||||
flog_err(
|
flog_err(
|
||||||
EC_LIB_SOCKET,
|
EC_LIB_SOCKET,
|
||||||
"%s: read failed on vtysh client fd %d, closing: %s",
|
"%s: read failed on vtysh client fd %d, closing: %s",
|
||||||
@ -2254,6 +2246,7 @@ void vty_close(struct vty *vty)
|
|||||||
close(vty->pass_fd);
|
close(vty->pass_fd);
|
||||||
vty->pass_fd = -1;
|
vty->pass_fd = -1;
|
||||||
}
|
}
|
||||||
|
zlog_live_close(&vty->live_log);
|
||||||
|
|
||||||
/* Flush buffer. */
|
/* Flush buffer. */
|
||||||
buffer_flush_all(vty->obuf, vty->wfd);
|
buffer_flush_all(vty->obuf, vty->wfd);
|
||||||
@ -2755,8 +2748,9 @@ DEFUN_NOSH (config_who,
|
|||||||
struct vty *v;
|
struct vty *v;
|
||||||
|
|
||||||
frr_each (vtys, vty_sessions, v)
|
frr_each (vtys, vty_sessions, v)
|
||||||
vty_out(vty, "%svty[%d] connected from %s.\n",
|
vty_out(vty, "%svty[%d] connected from %s%s.\n",
|
||||||
v->config ? "*" : " ", v->fd, v->address);
|
v->config ? "*" : " ", v->fd, v->address,
|
||||||
|
zlog_live_is_null(&v->live_log) ? "" : ", live log");
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2949,35 +2943,56 @@ DEFUN (no_service_advanced_vty,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN_NOSH (terminal_monitor,
|
DEFUN_NOSH(terminal_monitor,
|
||||||
terminal_monitor_cmd,
|
terminal_monitor_cmd,
|
||||||
"terminal monitor",
|
"terminal monitor [detach]",
|
||||||
"Set terminal line parameters\n"
|
"Set terminal line parameters\n"
|
||||||
"Copy debug output to the current terminal line\n")
|
"Copy debug output to the current terminal line\n"
|
||||||
|
"Keep logging feed open independent of VTY session\n")
|
||||||
{
|
{
|
||||||
vty->monitor = 1;
|
int fd_ret = -1;
|
||||||
|
|
||||||
|
if (vty->type != VTY_SHELL_SERV) {
|
||||||
|
vty_out(vty, "%% not supported\n");
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 3) {
|
||||||
|
struct zlog_live_cfg detach_log = {};
|
||||||
|
|
||||||
|
zlog_live_open(&detach_log, LOG_DEBUG, &fd_ret);
|
||||||
|
zlog_live_disown(&detach_log);
|
||||||
|
} else
|
||||||
|
zlog_live_open(&vty->live_log, LOG_DEBUG, &fd_ret);
|
||||||
|
|
||||||
|
if (fd_ret == -1) {
|
||||||
|
vty_out(vty, "%% error opening live log: %m\n");
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
vty_pass_fd(vty, fd_ret);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN_NOSH (terminal_no_monitor,
|
DEFUN_NOSH(no_terminal_monitor,
|
||||||
terminal_no_monitor_cmd,
|
no_terminal_monitor_cmd,
|
||||||
"terminal no monitor",
|
"no terminal monitor",
|
||||||
"Set terminal line parameters\n"
|
NO_STR
|
||||||
NO_STR
|
"Set terminal line parameters\n"
|
||||||
"Copy debug output to the current terminal line\n")
|
"Copy debug output to the current terminal line\n")
|
||||||
{
|
{
|
||||||
vty->monitor = 0;
|
zlog_live_close(&vty->live_log);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN_NOSH (no_terminal_monitor,
|
DEFUN_NOSH(terminal_no_monitor,
|
||||||
no_terminal_monitor_cmd,
|
terminal_no_monitor_cmd,
|
||||||
"no terminal monitor",
|
"terminal no monitor",
|
||||||
NO_STR
|
"Set terminal line parameters\n"
|
||||||
"Set terminal line parameters\n"
|
NO_STR
|
||||||
"Copy debug output to the current terminal line\n")
|
"Copy debug output to the current terminal line\n")
|
||||||
{
|
{
|
||||||
return terminal_no_monitor(self, vty, argc, argv);
|
return no_terminal_monitor(self, vty, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "qobj.h"
|
#include "qobj.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "northbound.h"
|
#include "northbound.h"
|
||||||
|
#include "zlog_live.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -175,6 +176,9 @@ struct vty {
|
|||||||
/* CLI command return value (likely CMD_SUCCESS) when pass_fd != -1 */
|
/* CLI command return value (likely CMD_SUCCESS) when pass_fd != -1 */
|
||||||
uint8_t pass_fd_status[4];
|
uint8_t pass_fd_status[4];
|
||||||
|
|
||||||
|
/* live logging target / terminal monitor */
|
||||||
|
struct zlog_live_cfg live_log;
|
||||||
|
|
||||||
/* IAC handling: was the last character received the
|
/* IAC handling: was the last character received the
|
||||||
IAC (interpret-as-command) escape character (and therefore the next
|
IAC (interpret-as-command) escape character (and therefore the next
|
||||||
character will be the command code)? Refer to Telnet RFC 854. */
|
character will be the command code)? Refer to Telnet RFC 854. */
|
||||||
@ -198,9 +202,6 @@ struct vty {
|
|||||||
/* Configure lines. */
|
/* Configure lines. */
|
||||||
int lines;
|
int lines;
|
||||||
|
|
||||||
/* Terminal monitor. */
|
|
||||||
int monitor;
|
|
||||||
|
|
||||||
/* Read and write thread. */
|
/* Read and write thread. */
|
||||||
struct thread *t_read;
|
struct thread *t_read;
|
||||||
struct thread *t_write;
|
struct thread *t_write;
|
||||||
|
245
lib/zlog_live.c
Normal file
245
lib/zlog_live.c
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-22 David Lamparter, for NetDEF, Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "zebra.h"
|
||||||
|
|
||||||
|
#include "zlog_live.h"
|
||||||
|
|
||||||
|
#include "memory.h"
|
||||||
|
#include "frrcu.h"
|
||||||
|
#include "zlog.h"
|
||||||
|
#include "printfrr.h"
|
||||||
|
|
||||||
|
DEFINE_MTYPE_STATIC(LOG, LOG_LIVE, "log vtysh live target");
|
||||||
|
|
||||||
|
enum {
|
||||||
|
STATE_NORMAL = 0,
|
||||||
|
STATE_FD_DEAD,
|
||||||
|
STATE_DISOWNED,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct zlt_live {
|
||||||
|
struct zlog_target zt;
|
||||||
|
|
||||||
|
atomic_uint_fast32_t fd;
|
||||||
|
struct rcu_head_close head_close;
|
||||||
|
struct rcu_head head_self;
|
||||||
|
|
||||||
|
atomic_uint_fast32_t state;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void zlog_live(struct zlog_target *zt, struct zlog_msg *msgs[],
|
||||||
|
size_t nmsgs)
|
||||||
|
{
|
||||||
|
struct zlt_live *zte = container_of(zt, struct zlt_live, zt);
|
||||||
|
struct zlog_live_hdr hdrs[nmsgs], *hdr = hdrs;
|
||||||
|
struct mmsghdr mmhs[nmsgs], *mmh = mmhs;
|
||||||
|
struct iovec iovs[nmsgs * 3], *iov = iovs;
|
||||||
|
struct timespec ts;
|
||||||
|
size_t i, textlen;
|
||||||
|
int fd;
|
||||||
|
uint_fast32_t state;
|
||||||
|
|
||||||
|
fd = atomic_load_explicit(&zte->fd, memory_order_relaxed);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memset(mmhs, 0, sizeof(mmhs));
|
||||||
|
memset(hdrs, 0, sizeof(hdrs));
|
||||||
|
|
||||||
|
for (i = 0; i < nmsgs; i++) {
|
||||||
|
const struct fmt_outpos *argpos;
|
||||||
|
size_t n_argpos, arghdrlen;
|
||||||
|
struct zlog_msg *msg = msgs[i];
|
||||||
|
int prio = zlog_msg_prio(msg);
|
||||||
|
|
||||||
|
if (prio > zt->prio_min)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
zlog_msg_args(msg, &arghdrlen, &n_argpos, &argpos);
|
||||||
|
|
||||||
|
mmh->msg_hdr.msg_iov = iov;
|
||||||
|
|
||||||
|
iov->iov_base = hdr;
|
||||||
|
iov->iov_len = sizeof(*hdr);
|
||||||
|
iov++;
|
||||||
|
|
||||||
|
if (n_argpos) {
|
||||||
|
iov->iov_base = (char *)argpos;
|
||||||
|
iov->iov_len = sizeof(*argpos) * n_argpos;
|
||||||
|
iov++;
|
||||||
|
}
|
||||||
|
|
||||||
|
iov->iov_base = (char *)zlog_msg_text(msg, &textlen);
|
||||||
|
iov->iov_len = textlen;
|
||||||
|
iov++;
|
||||||
|
|
||||||
|
zlog_msg_tsraw(msg, &ts);
|
||||||
|
|
||||||
|
hdr->ts_sec = ts.tv_sec;
|
||||||
|
hdr->ts_nsec = ts.tv_nsec;
|
||||||
|
hdr->prio = zlog_msg_prio(msg);
|
||||||
|
hdr->flags = 0;
|
||||||
|
hdr->textlen = textlen;
|
||||||
|
hdr->arghdrlen = arghdrlen;
|
||||||
|
hdr->n_argpos = n_argpos;
|
||||||
|
|
||||||
|
mmh->msg_hdr.msg_iovlen = iov - mmh->msg_hdr.msg_iov;
|
||||||
|
mmh++;
|
||||||
|
hdr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t msgtotal = mmh - mmhs;
|
||||||
|
ssize_t sent;
|
||||||
|
|
||||||
|
for (size_t msgpos = 0; msgpos < msgtotal; msgpos += sent) {
|
||||||
|
sent = sendmmsg(fd, mmhs + msgpos, msgtotal - msgpos, 0);
|
||||||
|
|
||||||
|
if (sent <= 0)
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
out_err:
|
||||||
|
fd = atomic_exchange_explicit(&zte->fd, -1, memory_order_relaxed);
|
||||||
|
if (fd < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rcu_close(&zte->head_close, fd);
|
||||||
|
zlog_target_replace(zt, NULL);
|
||||||
|
|
||||||
|
state = STATE_NORMAL;
|
||||||
|
atomic_compare_exchange_strong_explicit(
|
||||||
|
&zte->state, &state, STATE_FD_DEAD, memory_order_relaxed,
|
||||||
|
memory_order_relaxed);
|
||||||
|
if (state == STATE_DISOWNED)
|
||||||
|
rcu_free(MTYPE_LOG_LIVE, zte, head_self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void zlog_live_sigsafe(struct zlog_target *zt, const char *text,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
struct zlt_live *zte = container_of(zt, struct zlt_live, zt);
|
||||||
|
struct zlog_live_hdr hdr[1];
|
||||||
|
struct iovec iovs[2], *iov = iovs;
|
||||||
|
struct timespec ts;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = atomic_load_explicit(&zte->fd, memory_order_relaxed);
|
||||||
|
if (fd < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
|
||||||
|
hdr->ts_sec = ts.tv_sec;
|
||||||
|
hdr->ts_nsec = ts.tv_nsec;
|
||||||
|
hdr->prio = LOG_CRIT;
|
||||||
|
hdr->flags = 0;
|
||||||
|
hdr->textlen = len;
|
||||||
|
hdr->n_argpos = 0;
|
||||||
|
|
||||||
|
iov->iov_base = (char *)hdr;
|
||||||
|
iov->iov_len = sizeof(hdr);
|
||||||
|
iov++;
|
||||||
|
|
||||||
|
iov->iov_base = (char *)text;
|
||||||
|
iov->iov_len = len;
|
||||||
|
iov++;
|
||||||
|
|
||||||
|
writev(fd, iovs, iov - iovs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void zlog_live_open(struct zlog_live_cfg *cfg, int prio_min, int *other_fd)
|
||||||
|
{
|
||||||
|
int sockets[2];
|
||||||
|
struct zlt_live *zte;
|
||||||
|
struct zlog_target *zt;
|
||||||
|
|
||||||
|
if (cfg->target)
|
||||||
|
zlog_live_close(cfg);
|
||||||
|
|
||||||
|
*other_fd = -1;
|
||||||
|
if (prio_min == ZLOG_DISABLED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* the only reason for SEQPACKET here is getting close notifications.
|
||||||
|
* otherwise if you open a bunch of vtysh connections with live logs
|
||||||
|
* and close them all, the fds will stick around until we get an error
|
||||||
|
* when trying to log something to them at some later point -- which
|
||||||
|
* eats up fds and might be *much* later for some daemons.
|
||||||
|
*/
|
||||||
|
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) < 0) {
|
||||||
|
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) < 0) {
|
||||||
|
zlog_warn("%% could not open socket pair: %m");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
/* SEQPACKET only: try to zap read direction */
|
||||||
|
shutdown(sockets[0], SHUT_RD);
|
||||||
|
|
||||||
|
*other_fd = sockets[1];
|
||||||
|
|
||||||
|
zt = zlog_target_clone(MTYPE_LOG_LIVE, NULL, sizeof(*zte));
|
||||||
|
zte = container_of(zt, struct zlt_live, zt);
|
||||||
|
cfg->target = zte;
|
||||||
|
|
||||||
|
zte->fd = sockets[0];
|
||||||
|
zte->zt.prio_min = prio_min;
|
||||||
|
zte->zt.logfn = zlog_live;
|
||||||
|
zte->zt.logfn_sigsafe = zlog_live_sigsafe;
|
||||||
|
|
||||||
|
zlog_target_replace(NULL, zt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void zlog_live_close(struct zlog_live_cfg *cfg)
|
||||||
|
{
|
||||||
|
struct zlt_live *zte;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (!cfg->target)
|
||||||
|
return;
|
||||||
|
|
||||||
|
zte = cfg->target;
|
||||||
|
cfg->target = NULL;
|
||||||
|
|
||||||
|
fd = atomic_exchange_explicit(&zte->fd, -1, memory_order_relaxed);
|
||||||
|
|
||||||
|
if (fd >= 0) {
|
||||||
|
rcu_close(&zte->head_close, fd);
|
||||||
|
zlog_target_replace(&zte->zt, NULL);
|
||||||
|
}
|
||||||
|
rcu_free(MTYPE_LOG_LIVE, zte, head_self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void zlog_live_disown(struct zlog_live_cfg *cfg)
|
||||||
|
{
|
||||||
|
struct zlt_live *zte;
|
||||||
|
uint_fast32_t state;
|
||||||
|
|
||||||
|
if (!cfg->target)
|
||||||
|
return;
|
||||||
|
|
||||||
|
zte = cfg->target;
|
||||||
|
cfg->target = NULL;
|
||||||
|
|
||||||
|
state = STATE_NORMAL;
|
||||||
|
atomic_compare_exchange_strong_explicit(
|
||||||
|
&zte->state, &state, STATE_DISOWNED, memory_order_relaxed,
|
||||||
|
memory_order_relaxed);
|
||||||
|
if (state == STATE_FD_DEAD)
|
||||||
|
rcu_free(MTYPE_LOG_LIVE, zte, head_self);
|
||||||
|
}
|
53
lib/zlog_live.h
Normal file
53
lib/zlog_live.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-22 David Lamparter, for NetDEF, Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _FRR_ZLOG_LIVE_H
|
||||||
|
#define _FRR_ZLOG_LIVE_H
|
||||||
|
|
||||||
|
#include "printfrr.h"
|
||||||
|
|
||||||
|
struct zlog_live_hdr {
|
||||||
|
uint64_t ts_sec;
|
||||||
|
uint32_t ts_nsec;
|
||||||
|
uint32_t prio;
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t textlen;
|
||||||
|
|
||||||
|
uint32_t arghdrlen;
|
||||||
|
uint32_t n_argpos;
|
||||||
|
struct fmt_outpos argpos[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct zlt_live;
|
||||||
|
|
||||||
|
struct zlog_live_cfg {
|
||||||
|
struct zlt_live *target;
|
||||||
|
|
||||||
|
/* nothing else here */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void zlog_live_open(struct zlog_live_cfg *cfg, int prio_min,
|
||||||
|
int *other_fd);
|
||||||
|
|
||||||
|
static inline bool zlog_live_is_null(struct zlog_live_cfg *cfg)
|
||||||
|
{
|
||||||
|
return cfg->target == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void zlog_live_close(struct zlog_live_cfg *cfg);
|
||||||
|
extern void zlog_live_disown(struct zlog_live_cfg *cfg);
|
||||||
|
|
||||||
|
#endif /* _FRR_ZLOG_5424_H */
|
Loading…
Reference in New Issue
Block a user