mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-01-23 02:14:37 +00:00
kerndat: create separate netns for has_nftables_concat check
There was a race window in kerndat_has_nftables_concat(void) when two or more instances of CRIU are running in parallel. One instance would create the table normally, and another would fail when trying to create a table with the same name and wrongly set kdat.has_nftables_concat = false, and will save it to kerndat cache. A separate netns is created to avoid table collisions. v2: use call_in_child_process helper instead of fork Co-developed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> Signed-off-by: Zeyad Yasser <zeyady98@gmail.com>
This commit is contained in:
parent
aa772bf286
commit
d879220996
1 changed files with 35 additions and 10 deletions
|
|
@ -13,6 +13,7 @@
|
|||
#include <arpa/inet.h> /* for sockaddr_in and inet_ntoa() */
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sched.h>
|
||||
|
||||
#if defined(CONFIG_HAS_NFTABLES_LIB_API_0) || defined(CONFIG_HAS_NFTABLES_LIB_API_1)
|
||||
#include <nftables/libnftables.h>
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue