[CRIU] [PATCH 4/4] test: A simple test for criu_restore_sub call

Pavel Emelyanov xemul at parallels.com
Mon Jun 23 04:51:09 PDT 2014


>> +	} else if (ret == 0)
>> +		printf("   `- Success\n");
>> +
>> +	sleep(1); /* Ugly -- wait for pid from dump to free */
> 
> I don't understand why do we need this sleep. I afraid it will be failed
> in jenkins and it's a bad demonstration of how to do the trick ;)
> 
>> +
>> +	printf("--- Restore loop ---\n");
>> +	criu_init_opts();
>> +	criu_set_log_level(4);
>> +	criu_set_log_file("restore.log");
>> +	criu_set_images_dir_fd(fd);
>> +
>> +	printf("   Restore returned pid %d\n", ret);
>> +	kill(ret, 9);
> 
> You need to check return code here, otherwise you can't be sure that a
> process don't die w/o your help.

Fair enough. How about this?

---

diff --git a/test/libcriu/Makefile b/test/libcriu/Makefile
index a1af1f5..474f3d1 100644
--- a/test/libcriu/Makefile
+++ b/test/libcriu/Makefile
@@ -1,6 +1,12 @@
-all: build/test
+all: build/test test_sub
 .PHONY: all
 
+test_sub: test_sub.o
+	gcc $^ -L ../../lib -lcriu -o $@
+
+test_sub.o: test_sub.c
+	gcc -c $^ -I ../../lib -o $@
+
 build/test: build/test.o
 	gcc $^ -L ../../lib -lcriu -o $@
 
@@ -8,5 +14,5 @@ build/test.o: test.c
 	gcc -c $^ -I ../../lib -o $@
 
 clean:
-	rm -rf build
+	rm -rf build test_sub test_sub.o
 .PHONY: clean
diff --git a/test/libcriu/run_sub.sh b/test/libcriu/run_sub.sh
new file mode 100644
index 0000000..9e14a49
--- /dev/null
+++ b/test/libcriu/run_sub.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+source ../env.sh || exit 1
+
+LOOP_PID=0
+
+echo "== Clean"
+make clean
+rm -rf wdir
+rm -f ./libcriu.so.1
+
+echo "== Prepare"
+make test_sub || { echo "FAIL"; exit 1; }
+
+mkdir -p wdir/s/
+mkdir -p wdir/i/
+echo "== Start service"
+${CRIU} service -v4 -o service.log --address cs.sk -d --pidfile pidfile -W wdir/s/ || { echo "FAIL"; exit 1; }
+
+echo "== Run test_sub"
+ln -s ../../lib/libcriu.so libcriu.so.1
+export LD_LIBRARY_PATH=.
+export PATH="`dirname ${BASH_SOURCE[0]}`/../../:$PATH"
+./test_sub wdir/s/cs.sk wdir/i/
+
+echo "== Stopping service"
+kill -TERM $(cat wdir/s/pidfile)
diff --git a/test/libcriu/test_sub.c b/test/libcriu/test_sub.c
new file mode 100644
index 0000000..31361f5
--- /dev/null
+++ b/test/libcriu/test_sub.c
@@ -0,0 +1,140 @@
+#include "criu.h"
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <signal.h>
+
+static void what_err_ret_mean(ret)
+{
+	/* NOTE: errno is set by libcriu */
+	switch (ret) {
+	case -EBADE:
+		perror("RPC has returned fail");
+		break;
+	case -ECONNREFUSED:
+		perror("Unable to connect to CRIU");
+		break;
+	case -ECOMM:
+		perror("Unable to send/recv msg to/from CRIU");
+		break;
+	case -EINVAL:
+		perror("CRIU doesn't support this type of request."
+		       "You should probably update CRIU");
+		break;
+	case -EBADMSG:
+		perror("Unexpected response from CRIU."
+		       "You should probably update CRIU");
+		break;
+	default:
+		perror("Unknown error type code."
+		       "You should probably update CRIU");
+	}
+}
+
+static int stop = 0;
+static void sh(int sig)
+{
+	stop = 1;
+}
+
+#define SUCC_ECODE	42
+
+int main(int argc, char **argv)
+{
+	int pid, ret, fd, p[2];
+
+	printf("--- Start loop ---\n");
+	pipe(p);
+	pid = fork();
+	if (pid < 0) {
+		perror("Can't");
+		return -1;
+	}
+
+	if (!pid) {
+		printf("   `- loop: initializing\n");
+		if (setsid() < 0)
+			exit(1);
+		if (signal(SIGUSR1, sh) == SIG_ERR)
+			exit(1);
+
+		close(0);
+		close(1);
+		close(2);
+		close(p[0]);
+
+		ret = SUCC_ECODE;
+		write(p[1], &ret, sizeof(ret));
+		close(p[1]);
+
+		while (!stop)
+			sleep(1);
+		exit(SUCC_ECODE);
+	}
+
+	close(p[1]);
+
+	/* Wait for kid to start */
+	ret = -1;
+	read(p[0], &ret, sizeof(ret));
+	if (ret != SUCC_ECODE) {
+		printf("Error starting loop\n");
+		goto err;
+	}
+
+	/* Wait for pipe to get closed, then dump */
+	read(p[0], &ret, 1);
+	close(p[0]);
+
+	printf("--- Dump loop ---\n");
+	criu_init_opts();
+	criu_set_service_address(argv[1]);
+	criu_set_pid(pid);
+	criu_set_log_file("dump.log");
+	criu_set_log_level(4);
+	fd = open(argv[2], O_DIRECTORY);
+	criu_set_images_dir_fd(fd);
+
+	ret = criu_dump();
+	if (ret < 0) {
+		what_err_ret_mean(ret);
+		kill(pid, SIGKILL);
+		goto err;
+	}
+
+	printf("   `- Dump succeeded\n");
+	wait(pid, NULL, 0);
+
+	printf("--- Restore loop ---\n");
+	criu_init_opts();
+	criu_set_log_level(4);
+	criu_set_log_file("restore.log");
+	criu_set_images_dir_fd(fd);
+
+	pid = criu_restore_child();
+	if (pid <= 0) {
+		what_err_ret_mean(pid);
+		return -1;
+	}
+
+	printf("   `- Restore returned pid %d\n", pid);
+	kill(pid, SIGUSR1);
+err:
+	if (waitpid(pid, &ret, 0) < 0) {
+		perror("   Can't wait kid");
+		return -1;
+	}
+
+	if (WIFEXITED(ret)) {
+		if (WEXITSTATUS(ret) == SUCC_ECODE)
+			printf("   `- Success\n");
+		else
+			printf("   `- FAIL ec is %d\n", WEXITSTATUS(ret));
+	} else if (WIFSIGNALED(ret))
+		printf("   `- FAIL killed %d\n", WTERMSIG(ret));
+	else
+		printf("   `- FAIL bs %#x\n", ret);
+
+	return 0;
+}




More information about the CRIU mailing list