[CRIU] [PATCH 4/4] test: A simple test for criu_restore_sub call
Andrew Vagin
avagin at parallels.com
Mon Jun 23 12:02:28 PDT 2014
On Mon, Jun 23, 2014 at 03:51:09PM +0400, Pavel Emelyanov wrote:
> >> + } 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?
It's good. Thanks.
Acked-by: Andrew Vagin <avagin at parallels.com>
>
> ---
>
> 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