diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2025-08-13 18:45:05 +0200 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2025-08-19 16:29:52 +0200 |
commit | b4fc6cd31a8729b92a305008e443b56310fd30d4 (patch) | |
tree | a099fcab216f8489758791041a59de541d4673f7 | |
parent | 309eefd6af5ba20f760b92b6131a9ea7f2e161d4 (diff) | |
download | passt-b4fc6cd31a8729b92a305008e443b56310fd30d4.tar passt-b4fc6cd31a8729b92a305008e443b56310fd30d4.tar.gz passt-b4fc6cd31a8729b92a305008e443b56310fd30d4.tar.bz2 passt-b4fc6cd31a8729b92a305008e443b56310fd30d4.tar.lz passt-b4fc6cd31a8729b92a305008e443b56310fd30d4.tar.xz passt-b4fc6cd31a8729b92a305008e443b56310fd30d4.tar.zst passt-b4fc6cd31a8729b92a305008e443b56310fd30d4.zip |
I didn't imagine that occasionally truncated pcap and log files, as a
result of commit d0006fa784a7 ("treewide: use _exit() over exit()"),
would be such a big deal, until I tried to debug TCP issues with this
beauty:
while true; do ./pasta --trace -l /tmp/pasta.log -p /tmp/pasta.pcap --config-net -t 5555 -- socat TCP-LISTEN:5555 OPEN:/tmp/large.rcv,trunc & (sleep 0.3; socat -T2 OPEN:large.bin TCP:88.198.0.164:5555; ); wait; diff large.bin /tmp/large.rcv || break; done
...flush files and pcap if we're using them. Ignore fsync() errors for
the log file as we obviously can't reliably log them.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | log.c | 2 | ||||
-rw-r--r-- | log.h | 1 | ||||
-rw-r--r-- | passt.c | 1 | ||||
-rw-r--r-- | pasta.c | 2 | ||||
-rw-r--r-- | pcap.c | 2 | ||||
-rw-r--r-- | pcap.h | 2 | ||||
-rw-r--r-- | tap.c | 4 | ||||
-rw-r--r-- | util.c | 15 | ||||
-rw-r--r-- | util.h | 1 |
10 files changed, 28 insertions, 4 deletions
@@ -291,7 +291,7 @@ speeding up local connections, and usually requiring NAT. _pasta_: * ✅ all capabilities dropped, other than `CAP_NET_BIND_SERVICE` (if granted) * ✅ with default options, user, mount, IPC, UTS, PID namespaces are detached * ✅ no external dependencies (other than a standard C library) -* ✅ restrictive seccomp profiles (30 syscalls allowed for _passt_, 41 for +* ✅ restrictive seccomp profiles (33 syscalls allowed for _passt_, 43 for _pasta_ on x86_64) * ✅ examples of [AppArmor](/passt/tree/contrib/apparmor) and [SELinux](/passt/tree/contrib/selinux) profiles available @@ -35,7 +35,7 @@ static int log_sock = -1; /* Optional socket to system logger */ static char log_ident[BUFSIZ]; /* Identifier string for openlog() */ static int log_mask; /* Current log priority mask */ -static int log_file = -1; /* Optional log file descriptor */ +int log_file = -1; /* Optional log file descriptor */ static size_t log_size; /* Maximum log file size in bytes */ static size_t log_written; /* Currently used bytes in log file */ static size_t log_cut_size; /* Bytes to cut at start on rotation */ @@ -41,6 +41,7 @@ void logmsg_perror(int pri, const char *format, ...) _exit(EXIT_FAILURE); \ } while (0) +extern int log_file; extern int log_trace; extern bool log_conf_parsed; extern bool log_stderr; @@ -170,6 +170,7 @@ static void exit_handler(int signal) { (void)signal; + fsync_pcap_and_log(); _exit(EXIT_SUCCESS); } @@ -70,6 +70,8 @@ void pasta_child_handler(int signal) if (pasta_child_pid && !waitid(P_PID, pasta_child_pid, &infop, WEXITED | WNOHANG)) { if (infop.si_pid == pasta_child_pid) { + fsync_pcap_and_log(); + if (infop.si_code == CLD_EXITED) _exit(infop.si_status); @@ -37,7 +37,7 @@ #define PCAP_VERSION_MINOR 4 -static int pcap_fd = -1; +int pcap_fd = -1; struct pcap_pkthdr { uint32_t tv_sec; @@ -6,6 +6,8 @@ #ifndef PCAP_H #define PCAP_H +extern int pcap_fd; + void pcap(const char *pkt, size_t l2len); void pcap_multiple(const struct iovec *iov, size_t frame_parts, unsigned int n, size_t offset); @@ -1117,8 +1117,10 @@ void tap_sock_reset(struct ctx *c) { info("Client connection closed%s", c->one_off ? ", exiting" : ""); - if (c->one_off) + if (c->one_off) { + fsync_pcap_and_log(); _exit(EXIT_SUCCESS); + } /* Close the connected socket, wait for a new connection */ epoll_del(c, c->fd_tap); @@ -34,6 +34,7 @@ #include "passt.h" #include "packet.h" #include "log.h" +#include "pcap.h" #ifdef HAS_GETRANDOM #include <sys/random.h> #endif @@ -1045,3 +1046,17 @@ void abort_with_msg(const char *fmt, ...) */ abort(); } + +/** + * fsync_pcap_and_log() - Flush pcap and log files as needed + * + * #syscalls fsync + */ +void fsync_pcap_and_log(void) +{ + if (pcap_fd != -1 && fsync(pcap_fd)) + warn_perror("Failed to flush pcap file, it might be truncated"); + + if (log_file != -1) + (void)fsync(log_file); +} @@ -226,6 +226,7 @@ int read_all_buf(int fd, void *buf, size_t len); int read_remainder(int fd, const struct iovec *iov, size_t cnt, size_t skip); void close_open_files(int argc, char **argv); bool snprintf_check(char *str, size_t size, const char *format, ...); +void fsync_pcap_and_log(void); /** * af_name() - Return name of an address family |