From b2ada85ed3c92ccb58f20a49d877e18832f77271 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 16 Jun 2026 10:43:37 -0700 Subject: [PATCH 1/5] tests: fix dummy0 flakes Once we add a new network device, systemd-udev may execute some rules. In particular, we see that on Fedora it sets the MAC address (presumably based on the host name and device name). This setting races with ours 'ip link set address', as a result, "checkpoint and restore with netdevice" test sometimes fails telling the MAC address is not as expected. In the future there may be some other udev rules etc., so the overall solution is to wait until systemd-udev is finished applying the rules, thus eliminating the race. Signed-off-by: Kir Kolyshkin --- tests/integration/checkpoint.bats | 1 + tests/integration/netdev.bats | 1 + tests/integration/userns.bats | 2 ++ 3 files changed, 4 insertions(+) diff --git a/tests/integration/checkpoint.bats b/tests/integration/checkpoint.bats index 0d6dce4c9..539b83dbd 100644 --- a/tests/integration/checkpoint.bats +++ b/tests/integration/checkpoint.bats @@ -25,6 +25,7 @@ function setup() { # Create a dummy interface to move to the container. ip link add dummy0 type dummy + udevadm settle } function teardown() { diff --git a/tests/integration/netdev.bats b/tests/integration/netdev.bats index b14ad834a..6dddbab07 100644 --- a/tests/integration/netdev.bats +++ b/tests/integration/netdev.bats @@ -28,6 +28,7 @@ function setup() { # Create a dummy interface to move to the container. ip link add dummy0 type dummy + udevadm settle } function teardown() { diff --git a/tests/integration/userns.bats b/tests/integration/userns.bats index 1f2e83400..b4ae16249 100644 --- a/tests/integration/userns.bats +++ b/tests/integration/userns.bats @@ -252,6 +252,7 @@ function teardown() { # Create a dummy interface to move to the container. ip link add dummy0 type dummy + udevadm settle update_config ' .linux.netDevices |= {"dummy0": {} } | .process.args |= ["ip", "address", "show", "dev", "dummy0"]' @@ -269,6 +270,7 @@ function teardown() { # Create a dummy interface to move to the container. ip link add dummy0 type dummy + udevadm settle update_config ' .linux.netDevices |= { "dummy0": { "name" : "ctr_dummy0" } } | .process.args |= ["ip", "address", "show", "dev", "ctr_dummy0"]' From b16ed9a0b88cc02b72521f6ca1f9d016414c52f8 Mon Sep 17 00:00:00 2001 From: Rodrigo Campos Date: Wed, 17 Jun 2026 12:53:47 +0200 Subject: [PATCH 2/5] tests/checkpoint.bats: Move netdev code outside of setup() We are creating the interface for every test, but there is only one using it. Let's just call the function to create the netdev on the test that uses it. I guess that was the reason we had the "ip link del ..." in teardown. Because in a lot of tests we were just creating and deleting the interface on the host. While we are there, as suggested by lifubang, let's make the "ip link add" line specify the mtu and mac addr. This way, the interface is not created without that info and we race with host daemons (like udev) that _might_ want to change it. Signed-off-by: Rodrigo Campos --- tests/integration/checkpoint.bats | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/tests/integration/checkpoint.bats b/tests/integration/checkpoint.bats index 539b83dbd..bb3f9617c 100644 --- a/tests/integration/checkpoint.bats +++ b/tests/integration/checkpoint.bats @@ -3,6 +3,17 @@ load helpers function create_netns() { + mtu_value=1789 + mac_address="00:11:22:33:44:55" + global_ip="169.254.169.77/32" + + # Create a dummy interface to move to the container. + # Specify all link-level parameters at creation time, this way it is not created without + # those values unassigned and we might race with host's daemons to set them. + ip link add dummy0 address "$mac_address" mtu $mtu_value type dummy + udevadm settle + ip address add "$global_ip" dev dummy0 + # Create a temporary name for the test network namespace. tmp=$(mktemp -u) ns_name=$(basename "$tmp") @@ -13,6 +24,10 @@ function create_netns() { } function delete_netns() { + # The interface shouldn't be on the host, but if we failed to move it to the container, it + # might. Let's delete it if we created one (i.e. if ns_name is defined). + [ -v ns_name ] && ip link del dev dummy0 2>/dev/null + # Delete the namespace only if the ns_name variable is set. [ -v ns_name ] && ip netns del "$ns_name" } @@ -22,14 +37,9 @@ function setup() { requires criu root setup_busybox - - # Create a dummy interface to move to the container. - ip link add dummy0 type dummy - udevadm settle } function teardown() { - ip link del dev dummy0 delete_netns teardown_bundle } @@ -142,15 +152,6 @@ function simple_cr() { } @test "checkpoint and restore with netdevice" { - # Set custom parameters to the netdevice to validate those are respected - mtu_value=1789 - mac_address="00:11:22:33:44:55" - global_ip="169.254.169.77/32" - - ip link set mtu "$mtu_value" dev dummy0 - ip link set address "$mac_address" dev dummy0 - ip address add "$global_ip" dev dummy0 - # Tell runc which network namespace to use. create_netns update_config '(.. | select(.type? == "network")) .path |= "'"$ns_path"'"' From e79bff701ad04fc107933464a1be3eb768272887 Mon Sep 17 00:00:00 2001 From: Rodrigo Campos Date: Wed, 17 Jun 2026 13:24:14 +0200 Subject: [PATCH 3/5] tests: Unset ns_path when deleting the netns The cleaning is condition on this variable being set. So let's unset it after we clean the resources. Signed-off-by: Rodrigo Campos --- tests/integration/checkpoint.bats | 3 +++ tests/integration/netdev.bats | 3 +++ 2 files changed, 6 insertions(+) diff --git a/tests/integration/checkpoint.bats b/tests/integration/checkpoint.bats index bb3f9617c..e7b5a06d8 100644 --- a/tests/integration/checkpoint.bats +++ b/tests/integration/checkpoint.bats @@ -30,6 +30,9 @@ function delete_netns() { # Delete the namespace only if the ns_name variable is set. [ -v ns_name ] && ip netns del "$ns_name" + + unset ns_name + unset ns_path } function setup() { diff --git a/tests/integration/netdev.bats b/tests/integration/netdev.bats index 6dddbab07..25b36e5d5 100644 --- a/tests/integration/netdev.bats +++ b/tests/integration/netdev.bats @@ -20,6 +20,9 @@ function setup_netns() { function delete_netns() { # Delete the namespace only if the ns_name variable is set. [ -v ns_name ] && ip netns del "$ns_name" + + unset ns_name + unset ns_path } function setup() { From bb9d1ccaba4189791017d97b5964be0f97051e5e Mon Sep 17 00:00:00 2001 From: Rodrigo Campos Date: Wed, 17 Jun 2026 13:20:31 +0200 Subject: [PATCH 4/5] tests: Clarify the interface might not be on the host We try to delete the interface, but it lot of tests it won't be there unless we failed to move it to the container. Let's just clarify that in a comment and redirect the error output to /dev/null, as it seems an error otherwise while it is completely normal. Signed-off-by: Rodrigo Campos --- tests/integration/netdev.bats | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/integration/netdev.bats b/tests/integration/netdev.bats index 25b36e5d5..daf8c22df 100644 --- a/tests/integration/netdev.bats +++ b/tests/integration/netdev.bats @@ -35,7 +35,10 @@ function setup() { } function teardown() { - ip link del dev dummy0 + # The interface might be on the host or not, depending the test. If it's on the host, let's + # delete it. + ip link del dev dummy0 2>/dev/null + delete_netns teardown_bundle } From e6aea33b47dd410aab18123b1437f1fbb2013f01 Mon Sep 17 00:00:00 2001 From: Rodrigo Campos Date: Thu, 18 Jun 2026 18:57:21 +0200 Subject: [PATCH 5/5] tests/integration: Simplify delete_netns() Signed-off-by: Rodrigo Campos --- tests/integration/checkpoint.bats | 6 ++++-- tests/integration/netdev.bats | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/integration/checkpoint.bats b/tests/integration/checkpoint.bats index e7b5a06d8..98b458edb 100644 --- a/tests/integration/checkpoint.bats +++ b/tests/integration/checkpoint.bats @@ -24,12 +24,14 @@ function create_netns() { } function delete_netns() { + [ -v ns_name ] || return + # The interface shouldn't be on the host, but if we failed to move it to the container, it # might. Let's delete it if we created one (i.e. if ns_name is defined). - [ -v ns_name ] && ip link del dev dummy0 2>/dev/null + ip link del dev dummy0 2>/dev/null # Delete the namespace only if the ns_name variable is set. - [ -v ns_name ] && ip netns del "$ns_name" + ip netns del "$ns_name" unset ns_name unset ns_path diff --git a/tests/integration/netdev.bats b/tests/integration/netdev.bats index daf8c22df..a87dad8eb 100644 --- a/tests/integration/netdev.bats +++ b/tests/integration/netdev.bats @@ -18,8 +18,10 @@ function setup_netns() { } function delete_netns() { + [ -v ns_name ] || return + # Delete the namespace only if the ns_name variable is set. - [ -v ns_name ] && ip netns del "$ns_name" + ip netns del "$ns_name" unset ns_name unset ns_path