[CRIU] [PATCH] zdtm: add a small program to create a zdtm container (v2)

Ruslan Kuprieiev kupruser at gmail.com
Wed Aug 13 12:25:13 PDT 2014


13.08.2014 22:16, Andrey Vagin пишет:
> I didn't find a way how to do that with help "unshare".
> It's simpler to write this program. It looks better than tricks in
> zdtm.sh.
>
> v2: proxify exit status
>
> Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>
> Signed-off-by: Andrey Vagin <avagin at openvz.org>
> ---
>   test/.gitignore |  1 +
>   test/Makefile   |  8 +++++++-
>   test/zdtm.sh    | 11 ++--------
>   test/zdtm_ct.c  | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   4 files changed, 72 insertions(+), 10 deletions(-)
>   create mode 100644 test/zdtm_ct.c
>
> diff --git a/test/.gitignore b/test/.gitignore
> index 9f00af7..1a6f6d2 100644
> --- a/test/.gitignore
> +++ b/test/.gitignore
> @@ -4,3 +4,4 @@
>   /dev
>   /dump
>   /*.log
> +/zdtm_ct
> diff --git a/test/Makefile b/test/Makefile
> index 5d04805..9dcc523 100644
> --- a/test/Makefile
> +++ b/test/Makefile
> @@ -28,7 +28,13 @@ fault-injection: .FORCE
>   zdtm_ns: $(shell echo "$(TST)" | tr ' ' '\n' | grep -P $(EXP))
>   zdtm_nons: $(shell echo "$(TST)" | tr ' ' '\n' | grep -vP $(EXP))
>   
> -$(TST):
> +zdtm_ct: zdtm_ct.c
> +
> +clean:
> +	rm -rf zdtm_ct
> +	$(MAKE) -C zdtm $@
> +
> +$(TST): zdtm_ct
>   	./zdtm.sh --ct ${ZDTM_ARGS} $(@) &> $(subst /,_,$@).log || \
>   	{ flock Makefile cat $(subst /,_,$@).log; exit 1; }
>   .PHONY: zdtm_ns
> diff --git a/test/zdtm.sh b/test/zdtm.sh
> index 427ac22..da85c92 100755
> --- a/test/zdtm.sh
> +++ b/test/zdtm.sh
> @@ -881,18 +881,11 @@ while :; do
>   		[ -z "$ZDTM_SH_IN_CT" ] && {
>   			export ZDTM_SH_IN_CT=1
>   			shift
> -			args="$@"
>   			# pidns is used to avoid conflicts
>   			# mntns is used to mount /proc
>   			# net is used to avoid conflicts of parasite sockets
> -			unshare --pid --mount --ipc --net -- bash -c "
> -				(
> -					ip link set up dev lo &&
> -					mount --make-rprivate / &&
> -					umount -l /proc &&
> -					mount -t proc proc /proc/ &&
> -					./zdtm.sh $args
> -				)"
> +			make zdtm_ct &&
> +			./zdtm_ct ./zdtm.sh "$@"
>   			exit
>   		}
>   		shift
> diff --git a/test/zdtm_ct.c b/test/zdtm_ct.c
> new file mode 100644
> index 0000000..4524ab8
> --- /dev/null
> +++ b/test/zdtm_ct.c
> @@ -0,0 +1,62 @@
> +#define _GNU_SOURCE
> +#include <sched.h>
> +#include <sys/types.h>
> +#include <sys/wait.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <sys/mount.h>
> +
> +int main(int argc, char **argv)
> +{
> +	pid_t pid;
> +	int status;
> +
> +	/*
> +	 *pidns is used to avoid conflicts
> +	 * mntns is used to mount /proc
> +	 * net is used to avoid conflicts of parasite sockets
> +	*/
> +	if (unshare(CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWIPC))
> +		return 1;
> +	pid = fork();
> +	if (pid == 0) {
> +		if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL)) {
> +			fprintf(stderr, "mount(/, S_REC | MS_PRIVATE)): %m");
> +			return 1;
> +		}
> +		umount2("/proc", MNT_DETACH);
> +		umount2("/dev/pts", MNT_DETACH);
> +		if (mount("zdtm_proc", "/proc", "proc", 0, NULL)) {
> +			fprintf(stderr, "mount(/proc): %m");
> +			return 1;
> +		}
> +		if (mount("zdtm_devpts", "/dev/pts", "devpts", 0,
> +					"newinstance,ptmxmode=0666")) {
> +			fprintf(stderr, "mount(pts): %m");
> +			return 1;
> +		}
> +		if (mount("/dev/pts/ptmx", "/dev/ptmx", NULL, MS_BIND, NULL)) {
> +			fprintf(stderr, "mount(ptmx): %m");
> +			return 1;
> +		}
> +		if (system("ip link set up dev lo"))
> +			return 1;
> +		execv(argv[1], argv + 1);
> +		fprintf(stderr, "execve: %m");
> +		return 1;
> +	}
> +
> +	if (waitpid(pid, &status, 0) != pid) {
> +		fprintf(stderr, "waitpid: %m");
> +		return 1;
> +	}
> +
> +	if (WIFEXITED(status))
> +		return WEXITSTATUS(status);
> +	else if (WIFSIGNALED(status))
> +		kill(getpid(), WTERMSIG(status));
> +	else
> +		fprintf(stderr, "Unexpected exit status: %x\n", status);
> +
> +	return 1;
> +}
Acked-by: Ruslan Kuprieiev <kupruser at gmail.com>


More information about the CRIU mailing list