From a137d9fd58b64603accdcedf874b58a412a1176f Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Tue, 24 Jun 2014 23:29:17 +0400 Subject: [PATCH] test: A simple test for criu_restore_sub call v2 Which is at the same time the demonstration of how to do the trick. v2: * remove stupid sleep 1 synchronization * run internal version of child, not the external script Signed-off-by: Pavel Emelyanov Acked-by: Andrew Vagin --- test/libcriu/Makefile | 10 ++- test/libcriu/run_sub.sh | 27 ++++++++ test/libcriu/test_sub.c | 140 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 test/libcriu/run_sub.sh create mode 100644 test/libcriu/test_sub.c diff --git a/test/libcriu/Makefile b/test/libcriu/Makefile index 88df427ff..850b8a304 100644 --- a/test/libcriu/Makefile +++ b/test/libcriu/Makefile @@ -1,9 +1,15 @@ -all: build/test +all: build/test test_sub .PHONY: all run: all ./run.sh +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 $@ @@ -11,5 +17,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 000000000..9e14a49eb --- /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 000000000..31361f566 --- /dev/null +++ b/test/libcriu/test_sub.c @@ -0,0 +1,140 @@ +#include "criu.h" +#include +#include +#include +#include +#include + +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; +}