Move logging functions to a new file, log.c

Logging to file is going to add some further complexity that we don't
want to squeeze into util.c.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Stefano Brivio 2022-09-24 09:53:15 +02:00
parent c4101334e1
commit da152331cf
20 changed files with 187 additions and 138 deletions

View file

@ -33,8 +33,8 @@ FLAGS += -DRLIMIT_STACK_VAL=$(RLIMIT_STACK_VAL)
FLAGS += -DARCH=\"$(TARGET_ARCH)\" FLAGS += -DARCH=\"$(TARGET_ARCH)\"
PASST_SRCS = arch.c arp.c checksum.c conf.c dhcp.c dhcpv6.c icmp.c igmp.c \ PASST_SRCS = arch.c arp.c checksum.c conf.c dhcp.c dhcpv6.c icmp.c igmp.c \
isolation.c lineread.c mld.c ndp.c netlink.c packet.c passt.c pasta.c \ isolation.c lineread.c log.c mld.c ndp.c netlink.c packet.c passt.c \
pcap.c siphash.c tap.c tcp.c tcp_splice.c udp.c util.c pasta.c pcap.c siphash.c tap.c tcp.c tcp_splice.c udp.c util.c
QRAP_SRCS = qrap.c QRAP_SRCS = qrap.c
SRCS = $(PASST_SRCS) $(QRAP_SRCS) SRCS = $(PASST_SRCS) $(QRAP_SRCS)

1
conf.c
View file

@ -40,6 +40,7 @@
#include "pasta.h" #include "pasta.h"
#include "lineread.h" #include "lineread.h"
#include "isolation.h" #include "isolation.h"
#include "log.h"
/** /**
* get_bound_ports() - Get maps of ports with bound sockets * get_bound_ports() - Get maps of ports with bound sockets

1
dhcp.c
View file

@ -29,6 +29,7 @@
#include "packet.h" #include "packet.h"
#include "passt.h" #include "passt.h"
#include "tap.h" #include "tap.h"
#include "log.h"
#include "dhcp.h" #include "dhcp.h"
/** /**

View file

@ -30,6 +30,7 @@
#include "util.h" #include "util.h"
#include "passt.h" #include "passt.h"
#include "tap.h" #include "tap.h"
#include "log.h"
/** /**
* struct opt_hdr - DHCPv6 option header * struct opt_hdr - DHCPv6 option header

1
icmp.c
View file

@ -35,6 +35,7 @@
#include "util.h" #include "util.h"
#include "passt.h" #include "passt.h"
#include "tap.h" #include "tap.h"
#include "log.h"
#include "icmp.h" #include "icmp.h"
#define ICMP_ECHO_TIMEOUT 60 /* s, timeout for ICMP socket activity */ #define ICMP_ECHO_TIMEOUT 60 /* s, timeout for ICMP socket activity */

View file

@ -42,6 +42,7 @@
#include "util.h" #include "util.h"
#include "seccomp.h" #include "seccomp.h"
#include "passt.h" #include "passt.h"
#include "log.h"
#include "isolation.h" #include "isolation.h"
/** /**

143
log.c Normal file
View file

@ -0,0 +1,143 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
/* PASST - Plug A Simple Socket Transport
* for qemu/UNIX domain socket mode
*
* PASTA - Pack A Subtle Tap Abstraction
* for network namespace/tap device mode
*
* log.c - Logging functions
*
* Copyright (c) 2020-2022 Red Hat GmbH
* Author: Stefano Brivio <sbrivio@redhat.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <syslog.h>
#include <stdarg.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "log.h"
/* For __openlog() and __setlogmask() wrappers, and passt_vsyslog() */
static int log_mask;
static int log_sock = -1;
static char log_ident[BUFSIZ];
static int log_opt;
static time_t log_debug_start;
int log_trace;
#define logfn(name, level) \
void name(const char *format, ...) { \
struct timespec tp; \
va_list args; \
\
if (setlogmask(0) & LOG_MASK(LOG_DEBUG)) { \
clock_gettime(CLOCK_REALTIME, &tp); \
fprintf(stderr, "%li.%04li: ", \
tp.tv_sec - log_debug_start, \
tp.tv_nsec / (100L * 1000)); \
} else { \
va_start(args, format); \
passt_vsyslog(level, format, args); \
va_end(args); \
} \
\
if (setlogmask(0) & LOG_MASK(LOG_DEBUG) || \
setlogmask(0) == LOG_MASK(LOG_EMERG)) { \
va_start(args, format); \
(void)vfprintf(stderr, format, args); \
va_end(args); \
if (format[strlen(format)] != '\n') \
fprintf(stderr, "\n"); \
} \
}
logfn(err, LOG_ERR)
logfn(warn, LOG_WARNING)
logfn(info, LOG_INFO)
logfn(debug, LOG_DEBUG)
void trace_init(int enable)
{
log_trace = enable;
}
/**
* __openlog() - Non-optional openlog() wrapper, to allow custom vsyslog()
* @ident: openlog() identity (program name)
* @option: openlog() options
* @facility: openlog() facility (LOG_DAEMON)
*/
void __openlog(const char *ident, int option, int facility)
{
struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
log_debug_start = tp.tv_sec;
if (log_sock < 0) {
struct sockaddr_un a = { .sun_family = AF_UNIX, };
log_sock = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (log_sock < 0)
return;
strncpy(a.sun_path, _PATH_LOG, sizeof(a.sun_path));
if (connect(log_sock, (const struct sockaddr *)&a, sizeof(a))) {
close(log_sock);
log_sock = -1;
return;
}
}
log_mask |= facility;
strncpy(log_ident, ident, sizeof(log_ident) - 1);
log_opt = option;
openlog(ident, option, facility);
}
/**
* __setlogmask() - setlogmask() wrapper, to allow custom vsyslog()
* @mask: Same as setlogmask() mask
*/
void __setlogmask(int mask)
{
log_mask = mask;
setlogmask(mask);
}
/**
* passt_vsyslog() - vsyslog() implementation not using heap memory
* @pri: Facility and level map, same as priority for vsyslog()
* @format: Same as vsyslog() format
* @ap: Same as vsyslog() ap
*/
void passt_vsyslog(int pri, const char *format, va_list ap)
{
char buf[BUFSIZ];
int n;
if (!(LOG_MASK(LOG_PRI(pri)) & log_mask))
return;
/* Send without name and timestamp, the system logger should add them */
n = snprintf(buf, BUFSIZ, "<%i> ", pri);
n += vsnprintf(buf + n, BUFSIZ - n, format, ap);
if (format[strlen(format)] != '\n')
n += snprintf(buf + n, BUFSIZ - n, "\n");
if (log_opt & LOG_PERROR)
fprintf(stderr, "%s", buf + sizeof("<0>"));
if (send(log_sock, buf, n, 0) != n)
fprintf(stderr, "Failed to send %i bytes to syslog\n", n);
}

26
log.h Normal file
View file

@ -0,0 +1,26 @@
/* SPDX-License-Identifier: AGPL-3.0-or-later
* Copyright (c) 2022 Red Hat GmbH
* Author: Stefano Brivio <sbrivio@redhat.com>
*/
#ifndef LOG_H
#define LOG_H
void err(const char *format, ...);
void warn(const char *format, ...);
void info(const char *format, ...);
void debug(const char *format, ...);
extern int log_trace;
void trace_init(int enable);
#define trace(format, ...) \
do { \
if (log_trace) \
debug(format, ##__VA_ARGS__); \
} while (0)
void __openlog(const char *ident, int option, int facility);
void passt_vsyslog(int pri, const char *format, va_list ap);
void __setlogmask(int mask);
#endif /* LOG_H */

1
ndp.c
View file

@ -30,6 +30,7 @@
#include "util.h" #include "util.h"
#include "passt.h" #include "passt.h"
#include "tap.h" #include "tap.h"
#include "log.h"
#define RS 133 #define RS 133
#define RA 134 #define RA 134

View file

@ -30,6 +30,7 @@
#include "util.h" #include "util.h"
#include "passt.h" #include "passt.h"
#include "log.h"
#include "netlink.h" #include "netlink.h"
/* Socket in init, in target namespace, sequence (just needs to be monotonic) */ /* Socket in init, in target namespace, sequence (just needs to be monotonic) */

View file

@ -20,6 +20,7 @@
#include "packet.h" #include "packet.h"
#include "util.h" #include "util.h"
#include "log.h"
/** /**
* packet_add_do() - Add data as packet descriptor to given pool * packet_add_do() - Add data as packet descriptor to given pool

View file

@ -44,6 +44,7 @@
#include "conf.h" #include "conf.h"
#include "pasta.h" #include "pasta.h"
#include "arch.h" #include "arch.h"
#include "log.h"
#define EPOLL_EVENTS 8 #define EPOLL_EVENTS 8

View file

@ -44,6 +44,7 @@
#include "passt.h" #include "passt.h"
#include "isolation.h" #include "isolation.h"
#include "netlink.h" #include "netlink.h"
#include "log.h"
/* PID of child, in case we created a namespace */ /* PID of child, in case we created a namespace */
static int pasta_child_pid; static int pasta_child_pid;

1
pcap.c
View file

@ -30,6 +30,7 @@
#include "util.h" #include "util.h"
#include "passt.h" #include "passt.h"
#include "log.h"
#define PCAP_VERSION_MINOR 4 #define PCAP_VERSION_MINOR 4

1
tap.c
View file

@ -52,6 +52,7 @@
#include "netlink.h" #include "netlink.h"
#include "pasta.h" #include "pasta.h"
#include "packet.h" #include "packet.h"
#include "log.h"
/* IPv4 (plus ARP) and IPv6 message batches from tap/guest to IP handlers */ /* IPv4 (plus ARP) and IPv6 message batches from tap/guest to IP handlers */
static PACKET_POOL_NOINIT(pool_tap4, TAP_MSGS, pkt_buf); static PACKET_POOL_NOINIT(pool_tap4, TAP_MSGS, pkt_buf);

1
tcp.c
View file

@ -298,6 +298,7 @@
#include "pcap.h" #include "pcap.h"
#include "conf.h" #include "conf.h"
#include "tcp_splice.h" #include "tcp_splice.h"
#include "log.h"
#define TCP_FRAMES_MEM 128 #define TCP_FRAMES_MEM 128
#define TCP_FRAMES \ #define TCP_FRAMES \

View file

@ -47,6 +47,7 @@
#include "util.h" #include "util.h"
#include "passt.h" #include "passt.h"
#include "log.h"
#define MAX_PIPE_SIZE (8UL * 1024 * 1024) #define MAX_PIPE_SIZE (8UL * 1024 * 1024)
#define TCP_SPLICE_MAX_CONNS (128 * 1024) #define TCP_SPLICE_MAX_CONNS (128 * 1024)

1
udp.c
View file

@ -116,6 +116,7 @@
#include "passt.h" #include "passt.h"
#include "tap.h" #include "tap.h"
#include "pcap.h" #include "pcap.h"
#include "log.h"
#define UDP_CONN_TIMEOUT 180 /* s, timeout for ephemeral or local bind */ #define UDP_CONN_TIMEOUT 180 /* s, timeout for ephemeral or local bind */
#define UDP_SPLICE_FRAMES 32 #define UDP_SPLICE_FRAMES 32

121
util.c
View file

@ -19,8 +19,6 @@
#include <net/ethernet.h> #include <net/ethernet.h>
#include <sys/epoll.h> #include <sys/epoll.h>
#include <fcntl.h> #include <fcntl.h>
#include <syslog.h>
#include <stdarg.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
@ -29,124 +27,7 @@
#include "passt.h" #include "passt.h"
#include "packet.h" #include "packet.h"
#include "lineread.h" #include "lineread.h"
#include "log.h"
/* For __openlog() and __setlogmask() wrappers, and passt_vsyslog() */
static int log_mask;
static int log_sock = -1;
static char log_ident[BUFSIZ];
static int log_opt;
static time_t log_debug_start;
int log_trace;
#define logfn(name, level) \
void name(const char *format, ...) { \
struct timespec tp; \
va_list args; \
\
if (setlogmask(0) & LOG_MASK(LOG_DEBUG)) { \
clock_gettime(CLOCK_REALTIME, &tp); \
fprintf(stderr, "%li.%04li: ", \
tp.tv_sec - log_debug_start, \
tp.tv_nsec / (100L * 1000)); \
} else { \
va_start(args, format); \
passt_vsyslog(level, format, args); \
va_end(args); \
} \
\
if (setlogmask(0) & LOG_MASK(LOG_DEBUG) || \
setlogmask(0) == LOG_MASK(LOG_EMERG)) { \
va_start(args, format); \
(void)vfprintf(stderr, format, args); \
va_end(args); \
if (format[strlen(format)] != '\n') \
fprintf(stderr, "\n"); \
} \
}
logfn(err, LOG_ERR)
logfn(warn, LOG_WARNING)
logfn(info, LOG_INFO)
logfn(debug, LOG_DEBUG)
void trace_init(int enable)
{
log_trace = enable;
}
/**
* __openlog() - Non-optional openlog() wrapper, to allow custom vsyslog()
* @ident: openlog() identity (program name)
* @option: openlog() options
* @facility: openlog() facility (LOG_DAEMON)
*/
void __openlog(const char *ident, int option, int facility)
{
struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
log_debug_start = tp.tv_sec;
if (log_sock < 0) {
struct sockaddr_un a = { .sun_family = AF_UNIX, };
log_sock = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (log_sock < 0)
return;
strncpy(a.sun_path, _PATH_LOG, sizeof(a.sun_path));
if (connect(log_sock, (const struct sockaddr *)&a, sizeof(a))) {
close(log_sock);
log_sock = -1;
return;
}
}
log_mask |= facility;
strncpy(log_ident, ident, sizeof(log_ident) - 1);
log_opt = option;
openlog(ident, option, facility);
}
/**
* __setlogmask() - setlogmask() wrapper, to allow custom vsyslog()
* @mask: Same as setlogmask() mask
*/
void __setlogmask(int mask)
{
log_mask = mask;
setlogmask(mask);
}
/**
* passt_vsyslog() - vsyslog() implementation not using heap memory
* @pri: Facility and level map, same as priority for vsyslog()
* @format: Same as vsyslog() format
* @ap: Same as vsyslog() ap
*/
void passt_vsyslog(int pri, const char *format, va_list ap)
{
char buf[BUFSIZ];
int n;
if (!(LOG_MASK(LOG_PRI(pri)) & log_mask))
return;
/* Send without name and timestamp, the system logger should add them */
n = snprintf(buf, BUFSIZ, "<%i> ", pri);
n += vsnprintf(buf + n, BUFSIZ - n, format, ap);
if (format[strlen(format)] != '\n')
n += snprintf(buf + n, BUFSIZ - n, "\n");
if (log_opt & LOG_PERROR)
fprintf(stderr, "%s", buf + sizeof("<0>"));
if (send(log_sock, buf, n, 0) != n)
fprintf(stderr, "Failed to send %i bytes to syslog\n", n);
}
#define IPV6_NH_OPT(nh) \ #define IPV6_NH_OPT(nh) \
((nh) == 0 || (nh) == 43 || (nh) == 44 || (nh) == 50 || \ ((nh) == 0 || (nh) == 43 || (nh) == 44 || (nh) == 50 || \

16
util.h
View file

@ -6,19 +6,6 @@
#ifndef UTIL_H #ifndef UTIL_H
#define UTIL_H #define UTIL_H
void err(const char *format, ...);
void warn(const char *format, ...);
void info(const char *format, ...);
void debug(const char *format, ...);
extern int log_trace;
void trace_init(int enable);
#define trace(format, ...) \
do { \
if (log_trace) \
debug(format, ##__VA_ARGS__); \
} while (0)
#ifndef SECCOMP_RET_KILL_PROCESS #ifndef SECCOMP_RET_KILL_PROCESS
#define SECCOMP_RET_KILL_PROCESS SECCOMP_RET_KILL #define SECCOMP_RET_KILL_PROCESS SECCOMP_RET_KILL
#endif #endif
@ -196,9 +183,6 @@ struct ipv6_opt_hdr {
/* cppcheck-suppress funcArgNamesDifferent */ /* cppcheck-suppress funcArgNamesDifferent */
__attribute__ ((weak)) int ffsl(long int i) { return __builtin_ffsl(i); } __attribute__ ((weak)) int ffsl(long int i) { return __builtin_ffsl(i); }
void __openlog(const char *ident, int option, int facility);
void passt_vsyslog(int pri, const char *format, va_list ap);
void __setlogmask(int mask);
char *ipv6_l4hdr(const struct pool *p, int index, size_t offset, uint8_t *proto, char *ipv6_l4hdr(const struct pool *p, int index, size_t offset, uint8_t *proto,
size_t *dlen); size_t *dlen);
int sock_l4(const struct ctx *c, int af, uint8_t proto, int sock_l4(const struct ctx *c, int af, uint8_t proto,