Repository: checkpoint-restore/criu (C)

Issue:
Alpine test/build fails
```
#10 7.842   CC       criu/pie/restorer.o
#10 7.926 criu/pie/restorer.c: In function 'restore_rlims':
#10 7.926 criu/pie/restorer.c:453:43: error: invalid use of undefined type 'struct rlimit64'
#10 7.926   453 |                 krlim.rlim_cur = ta->rlims[r].rlim_cur;
#10 7.926       |                                           ^
#10 7.926 criu/pie/restorer.c:453:46: error: invalid use of undefined type 'struct rlimit64'
#10 7.926   453 |                 krlim.rlim_cur = ta->rlims[r].rlim_cur;
#10 7.926       |                                              ^
#10 7.927 criu/pie/restorer.c:454:43: error: invalid use of undefined type 'struct rlimit64'
#10 7.927   454 |                 krlim.rlim_max = ta->rlims[r].rlim_max;
#10 7.927       |                                           ^
#10 7.927 criu/pie/restorer.c:454:46: error: invalid use of undefined type 'struct rlimit64'
#10 7.927   454 |                 krlim.rlim_max = ta->rlims[r].rlim_max;
#10 7.927       |                                              ^
#10 7.969 At top level:
#10 7.969 cc1: note: unrecognized command-line option '-Wno-unknown-warning-option' may have been intended to silence earlier diagnostics
#10 7.970 make[2]: *** [/criu/scripts/nmk/scripts/build.mk:118: criu/pie/restorer.o] Error 1
#10 7.970 make[2]: *** Waiting for unfinished jobs....
#10 8.040 make[1]: *** [criu/Makefile:59: pie] Error 2
#10 8.041 make: *** [Makefile:276: criu] Error 2
#10 ERROR: process "/bin/sh -c make mrproper && date && make -j $(nproc) CC=\"$CC\" && date" did not complete successfully: exit code: 2
```

https://github.com/checkpoint-restore/criu/actions/runs/7171767723/job/19527463844



Discussion: It was probably introduced by https://github.com/guidosarducci/musl/commit/25e6fee27f4a293728dd15b659170e7b9c7db9bc Cc: @richfelker

```
2023-12-28T07:09:22.4352258Z =================== Run zdtm/static/netns_lock_iptables in h ===================
2023-12-28T07:09:22.4353045Z Start test
2023-12-28T07:09:22.4353418Z Test is SUID
2023-12-28T07:09:22.4354358Z ./netns_lock_iptables --pidfile=netns_lock_iptables.pid --outfile=netns_lock_iptables.out
2023-12-28T07:09:22.4355385Z Timeout when trying to connect to server
2023-12-28T07:09:22.4356261Z Running zdtm/static/netns_lock_iptables.hook(--post-start)
2023-12-28T07:09:22.4357249Z Running zdtm/static/netns_lock_iptables.hook(--pre-dump)
2023-12-28T07:09:22.4357950Z Run criu dump
2023-12-28T07:09:22.4358513Z =[log]=> dump/zdtm/static/netns_lock_iptables/56/1/dump.log
2023-12-28T07:09:22.4359682Z ------------------------ grep Error ------------------------
2023-12-28T07:09:22.4360513Z b'(00.008185) net: \tRunning ip -6 route save'
2023-12-28T07:09:22.4361278Z b'(00.008796) net: \tRunning ip rule save'
2023-12-28T07:09:22.4362305Z b'(00.009924) iptables has nft backend: iptables-save v1.8.10 (nf_tables)'
2023-12-28T07:09:22.4363163Z b''
2023-12-28T07:09:22.4364163Z b'Error (criu/util.c:627): execvp("iptables-legacy-save", ...) failed: No such file or directory'
2023-12-28T07:09:22.4365506Z b'(00.010220) Error (criu/util.c:1653): iptables-legacy-save -V failed'
2023-12-28T07:09:22.4366876Z b'(00.010797) iptables has nft backend: ip6tables-save v1.8.10 (nf_tables)'
2023-12-28T07:09:22.4367766Z b''
2023-12-28T07:09:22.4368764Z b'Error (criu/util.c:627): execvp("ip6tables-legacy-save", ...) failed: No such file or directory'
2023-12-28T07:09:22.4370207Z b'(00.011104) Error (criu/util.c:1653): ip6tables-legacy-save -V failed'
2023-12-28T07:09:22.4371250Z ------------------------ ERROR OVER ------------------------
2023-12-28T07:09:22.4372191Z Running zdtm/static/netns_lock_iptables.hook(--pre-restore)
2023-12-28T07:09:22.4372910Z Run criu restore
2023-12-28T07:09:22.4373574Z =[log]=> dump/zdtm/static/netns_lock_iptables/56/1/restore.log
2023-12-28T07:09:22.4374526Z ------------------------ grep Error ------------------------
2023-12-28T07:09:22.4375470Z b'(00.005490)     56: net: \tRunning ip rule delete table local'
2023-12-28T07:09:22.4376470Z b'(00.006112)     56: net: \tRunning ip rule restore'
2023-12-28T07:09:22.4377609Z b'(00.007341)     56: iptables has nft backend: iptables-restore v1.8.10 (nf_tables)'
2023-12-28T07:09:22.4378506Z b''
2023-12-28T07:09:22.4379494Z b'Error (criu/util.c:627): execvp("iptables-legacy-restore", ...) failed: No such file or directory'
2023-12-28T07:09:22.4381039Z b'(00.007639)     56: Error (criu/util.c:1653): iptables-legacy-restore -V failed'
2023-12-28T07:09:22.4382588Z b'(00.008148)     56: iptables has nft backend: ip6tables-restore v1.8.10 (nf_tables)'
2023-12-28T07:09:22.4383543Z b''
2023-12-28T07:09:22.4384560Z b'Error (criu/util.c:627): execvp("ip6tables-legacy-restore", ...) failed: No such file or directory'
2023-12-28T07:09:22.4386074Z b'(00.008435)     56: Error (criu/util.c:1653): ip6tables-legacy-restore -V failed'
2023-12-28T07:09:22.4387062Z b'(00.011015) net: Unlock network'
2023-12-28T07:09:22.4387808Z b'(00.011017) Running network-unlock scripts'
2023-12-28T07:09:22.4388615Z b'iptables-restore v1.8.10 (nf_tables):'
2023-12-28T07:09:22.4389472Z b'line 5: CHAIN_DEL failed (Resource busy): chain CRIU'
2023-12-28T07:09:22.4390437Z b'(00.031422) Error (criu/util.c:642): exited, status=4'
2023-12-28T07:09:22.4391284Z b'ip6tables-restore v1.8.10 (nf_tables):'
2023-12-28T07:09:22.4392124Z b'line 5: CHAIN_DEL failed (Resource busy): chain CRIU'
2023-12-28T07:09:22.4393047Z b'(00.051362) Error (criu/util.c:642): exited, status=4'
2023-12-28T07:09:22.4393931Z ------------------------ ERROR OVER ------------------------
2023-12-28T07:09:22.4394866Z Running zdtm/static/netns_lock_iptables.hook(--post-restore)
2023-12-28T07:09:22.4396041Z ####### Test zdtm/static/netns_lock_iptables FAIL at hook --post-restore #######
```
https://github.com/checkpoint-restore/criu/actions/runs/7345320063/job/19998316100
The following error causes this test to fail in [`iptables_network_unlock_internal()`](https://github.com/checkpoint-restore/criu/blob/50aa6da65adbeea50152753b86fb02f22bb88a22/criu/net.c#L3181) during restore:
```
2023-12-28T07:09:22.4387062Z b'(00.011015) net: Unlock network'
2023-12-28T07:09:22.4387808Z b'(00.011017) Running network-unlock scripts'
2023-12-28T07:09:22.4388615Z b'iptables-restore v1.8.10 (nf_tables):'
2023-12-28T07:09:22.4389472Z b'line 5: CHAIN_DEL failed (Resource busy): chain CRIU'
```
[`iptables_restore()`](https://github.com/checkpoint-restore/criu/blob/50aa6da65adbeea50152753b86fb02f22bb88a22/criu/net.c#L3031) is using `iptables-restore` instead of `iptables-legacy-restore`.
@avagin This error appears with Alpine [v3.19](https://alpinelinux.org/posts/Alpine-3.19.0-released.html) because `iptables-nft` is now the default iptables backend.
I've opened the following pull request with a fix: https://github.com/checkpoint-restore/criu/pull/2323



Fix (patch):
diff --git a/criu/net.c b/criu/net.c
index 7109e6876a..0f7280bb50 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -2438,27 +2438,39 @@ static inline int do_restore_nftables(struct cr_img *img)
 	off_t img_data_size;
 	char *buf;
 
-	if ((img_data_size = img_raw_size(img)) < 0)
+	if ((img_data_size = img_raw_size(img)) < 0) {
+		pr_err("image size mismatch\n");
 		goto out;
+	}
 
-	if (read_img_str(img, &buf, img_data_size) < 0)
+	if (read_img_str(img, &buf, img_data_size) < 0) {
+		pr_err("Failed to read nftables data\n");
 		goto out;
+	}
 
 	nft = nft_ctx_new(NFT_CTX_DEFAULT);
-	if (!nft)
+	if (!nft) {
+		pr_err("Failed to create nft context object\n");
 		goto buf_free_out;
+	}
+
+	if (nft_ctx_buffer_output(nft) || nft_ctx_buffer_error(nft)) {
+		pr_err("Failed to enable std/err output buffering\n");
+		goto nft_ctx_free_out;
+	}
 
-	if (nft_ctx_buffer_output(nft) || nft_ctx_buffer_error(nft) ||
 #if defined(CONFIG_HAS_NFTABLES_LIB_API_0)
-	    nft_run_cmd_from_buffer(nft, buf, strlen(buf)))
+	if (nft_run_cmd_from_buffer(nft, buf, strlen(buf)))
 #elif defined(CONFIG_HAS_NFTABLES_LIB_API_1)
-	    nft_run_cmd_from_buffer(nft, buf))
+	if (nft_run_cmd_from_buffer(nft, buf))
 #else
-	{
-		BUILD_BUG_ON(1);
-	}
+	BUILD_BUG_ON(1);
 #endif
+	{
+		pr_err("nft command error:\n%s\n%s\n",
+		       nft_ctx_get_error_buffer(nft), buf);
 		goto nft_ctx_free_out;
+	}
 
 	exit_code = 0;
 
@@ -3178,19 +3190,53 @@ static inline int nftables_network_unlock(void)
 #endif
 }
 
+static int iptables_has_criu_jump_target(void)
+{
+	int fd, ret;
+	char *argv[4] = { "sh", "-c", "iptables -C INPUT -j CRIU", NULL };
+
+	fd = open("/dev/null", O_RDWR);
+	if (fd < 0) {
+		fd = -1;
+		pr_perror("failed to open /dev/null, using log fd");
+	}
+
+	ret = cr_system(fd, fd, fd, "sh", argv, CRS_CAN_FAIL);
+	close_safe(&fd);
+	return ret;
+}
+
 static int iptables_network_unlock_internal(void)
 {
-	char conf[] = "*filter\n"
-		      ":CRIU - [0:0]\n"
-		      "-D INPUT -j CRIU\n"
-		      "-D OUTPUT -j CRIU\n"
-		      "-X CRIU\n"
-		      "COMMIT\n";
+	char delete_jump_targets[] = "*filter\n"
+				     ":CRIU - [0:0]\n"
+				     "-D INPUT -j CRIU\n"
+				     "-D OUTPUT -j CRIU\n"
+				     "COMMIT\n";
+
+	char delete_criu_chain[] = "*filter\n"
+				   ":CRIU - [0:0]\n"
+				   "-X CRIU\n"
+				   "COMMIT\n";
+
 	int ret = 0;
 
-	ret |= iptables_restore(false, conf, sizeof(conf) - 1);
+	ret |= iptables_restore(false, delete_jump_targets, sizeof(delete_jump_targets) - 1);
 	if (kdat.ipv6)
-		ret |= iptables_restore(true, conf, sizeof(conf) - 1);
+		ret |= iptables_restore(true, delete_jump_targets, sizeof(delete_jump_targets) - 1);
+
+	/* For compatibility with iptables-nft backend, we need to make sure that all jump
+	 * targets have been removed before deleting the CRIU chain.
+	 */
+	if (!iptables_has_criu_jump_target()) {
+		ret |= iptables_restore(false, delete_jump_targets, sizeof(delete_jump_targets) - 1);
+		if (kdat.ipv6)
+			ret |= iptables_restore(true, delete_jump_targets, sizeof(delete_jump_targets) - 1);
+	}
+
+	ret |= iptables_restore(false, delete_criu_chain, sizeof(delete_criu_chain) - 1);
+	if (kdat.ipv6)
+		ret |= iptables_restore(true, delete_criu_chain, sizeof(delete_criu_chain) - 1);
 
 	return ret;
 }
diff --git a/scripts/build/Dockerfile.alpine b/scripts/build/Dockerfile.alpine
index 593e190315..2c58c910e7 100644
--- a/scripts/build/Dockerfile.alpine
+++ b/scripts/build/Dockerfile.alpine
@@ -33,6 +33,7 @@ RUN make mrproper && date && make -j $(nproc) CC="$CC" && date
 RUN apk add \
 	ip6tables \
 	iptables \
+	iptables-legacy \
 	nftables \
 	iproute2 \
 	tar \