diff --git a/criu/kerndat.c b/criu/kerndat.c index b2e5650cf..0e88ba43e 100644 --- a/criu/kerndat.c +++ b/criu/kerndat.c @@ -13,6 +13,7 @@ #include /* for sockaddr_in and inet_ntoa() */ #include #include +#include #if defined(CONFIG_HAS_NFTABLES_LIB_API_0) || defined(CONFIG_HAS_NFTABLES_LIB_API_1) #include @@ -1150,32 +1151,56 @@ close: return ret; } -static int kerndat_has_nftables_concat(void) -{ #if defined(CONFIG_HAS_NFTABLES_LIB_API_0) || defined(CONFIG_HAS_NFTABLES_LIB_API_1) +static int __has_nftables_concat(void *arg) +{ + bool *has = (bool *)arg; struct nft_ctx *nft; - int ret = 0; + int ret = 1; + + /* + * Create a separate network namespace to avoid + * collisions between two CRIU instances. + */ + if (unshare(CLONE_NEWNET)) { + pr_perror("Unable create a network namespace"); + return 1; + } nft = nft_ctx_new(NFT_CTX_DEFAULT); if (!nft) - return -1; + return 1; - if (NFT_RUN_CMD(nft, "create table inet CRIU-kerndat-test")) { - ret = -1; + if (NFT_RUN_CMD(nft, "create table inet CRIU")) { + pr_err("Can't create nftables table\n"); goto nft_ctx_free_out; } - if (NFT_RUN_CMD(nft, "add set inet CRIU-kerndat-test conn { type ipv4_addr . inet_service ;}")) - kdat.has_nftables_concat = false; + if (NFT_RUN_CMD(nft, "add set inet CRIU conn { type ipv4_addr . inet_service ;}")) + *has = false; /* kdat.has_nftables_concat = false */ else - kdat.has_nftables_concat = true; + *has = true; /* kdat.has_nftables_concat = true */ /* Clean up */ - NFT_RUN_CMD(nft, "delete table inet CRIU-kerndat-test"); + NFT_RUN_CMD(nft, "delete table inet CRIU"); + ret = 0; nft_ctx_free_out: nft_ctx_free(nft); return ret; +} +#endif + +static int kerndat_has_nftables_concat(void) +{ +#if defined(CONFIG_HAS_NFTABLES_LIB_API_0) || defined(CONFIG_HAS_NFTABLES_LIB_API_1) + bool has; + + if (call_in_child_process(__has_nftables_concat, (void *)&has)) + return -1; + + kdat.has_nftables_concat = has; + return 0; #else pr_warn("CRIU was built without libnftables support\n"); kdat.has_nftables_concat = false;