From 91e8a6fcd8fc82c96ad7f117585eb4f9b366745c Mon Sep 17 00:00:00 2001 From: Adrian Reber Date: Tue, 17 Dec 2024 08:52:46 +0100 Subject: [PATCH] net: redirect nftables stdout and stderr to CRIU's log file When using the nftables network locking backend and restoring a process a second time the network locking has already been deleted by the first restore. The second restore will print out to the console text like: Error: Could not process rule: No such file or directory delete table inet CRIU-202621 With this change CRIU's log FD is used by libnftables stdout and stderr. Signed-off-by: Adrian Reber --- criu/net.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/criu/net.c b/criu/net.c index eee3311087..efd52db327 100644 --- a/criu/net.c +++ b/criu/net.c @@ -3066,9 +3066,43 @@ static int iptables_restore(bool ipv6, char *buf, int size) return ret; } +#if defined(CONFIG_HAS_NFTABLES_LIB_API_0) || defined(CONFIG_HAS_NFTABLES_LIB_API_1) +static inline FILE *redirect_nftables_output(struct nft_ctx *nft) +{ + FILE *fp; + int fd; + + fd = dup(log_get_fd()); + if (fd < 0) { + pr_perror("dup() to redirect nftables output failed"); + return NULL; + } + + fp = fdopen(fd, "w"); + if (!fp) { + pr_perror("fdopen() to redirect nftables output failed"); + return NULL; + } + + /** + * Without setvbuf() the output from libnftables will be + * somewhere in the log file, probably at the end. + * With setvbuf() potential output will be at the correct + * position. + */ + setvbuf(fp, NULL, _IONBF, 0); + + nft_ctx_set_output(nft, fp); + nft_ctx_set_error(nft, fp); + + return fp; +} +#endif + static inline int nftables_lock_network_internal(void) { #if defined(CONFIG_HAS_NFTABLES_LIB_API_0) || defined(CONFIG_HAS_NFTABLES_LIB_API_1) + cleanup_file FILE *fp = NULL; struct nft_ctx *nft; int ret = 0; char table[32]; @@ -3081,6 +3115,10 @@ static inline int nftables_lock_network_internal(void) if (!nft) return -1; + fp = redirect_nftables_output(nft); + if (!fp) + goto out; + snprintf(buf, sizeof(buf), "create table %s", table); if (NFT_RUN_CMD(nft, buf)) goto err2; @@ -3168,6 +3206,7 @@ static inline int nftables_network_unlock(void) { #if defined(CONFIG_HAS_NFTABLES_LIB_API_0) || defined(CONFIG_HAS_NFTABLES_LIB_API_1) int ret = 0; + cleanup_file FILE *fp = NULL; struct nft_ctx *nft; char table[32]; char buf[128]; @@ -3179,6 +3218,10 @@ static inline int nftables_network_unlock(void) if (!nft) return -1; + fp = redirect_nftables_output(nft); + if (!fp) + return -1; + snprintf(buf, sizeof(buf), "delete table %s", table); if (NFT_RUN_CMD(nft, buf)) ret = -1;