From 0a17c4160580d9bc7092ba9eb7db86952921d221 Mon Sep 17 00:00:00 2001 From: Adrian Reber Date: Thu, 16 Jan 2025 07:52:42 +0000 Subject: [PATCH 1/2] util: added cleanup_file attribute. Signed-off-by: Adrian Reber --- criu/include/util.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/criu/include/util.h b/criu/include/util.h index ae293a68c8..4793f7f20e 100644 --- a/criu/include/util.h +++ b/criu/include/util.h @@ -406,6 +406,14 @@ static inline void cleanup_freep(void *p) free(*pp); } +#define cleanup_file __attribute__((cleanup(cleanup_filep))) +static inline void cleanup_filep(FILE **f) +{ + FILE *file = *f; + if (file) + (void)fclose(file); +} + extern int run_command(char *buf, size_t buf_size, int (*child_fn)(void *), void *args); /* From 1ed4109958644fbe1cbadf7c72472c82a12834b0 Mon Sep 17 00:00:00 2001 From: Adrian Reber Date: Tue, 17 Dec 2024 08:52:46 +0100 Subject: [PATCH 2/2] 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;