[CRIU] [PATCH v2 08/57] zdtm: Add pidns00 test

Kirill Tkhai ktkhai at virtuozzo.com
Thu Apr 6 03:05:49 PDT 2017


On 06.04.2017 01:32, Andrei Vagin wrote:
> @@ -55,6 +54,12 @@ futex_t *futex;
>  
>  int child(void)
>  {
> +       int fd;
> +       fd = open("/proc/self/ns/pid", O_RDONLY);
> +       unshare(CLONE_NEWPID);
> +       fork();
> +       setns(fd, CLONE_NEWPID);
> +       close(fd);
>         futex_wait_while_lt(futex, 1);
>         return 0;
>  }
> 
> [root at fc24 criu]# python test/zdtm.py run -t zdtm/static/pidns00 --iter 1 --sbs
> === Run 1/1 ================ zdtm/static/pidns00
> 
> ======================== Run zdtm/static/pidns00 in ns =========================
> make[1]: Nothing to be done for 'default'.
> Start test
> Test is SUID
> make[1]: Nothing to be done for 'default'.
> ./pidns00 --pidfile=pidns00.pid --outfile=pidns00.out
> Pause at pre-dump. Press any key to continue.
> Run criu dump
> Pause at pre-restore. Press any key to continue.
> Run criu restore
> =[log]=> dump/zdtm/static/pidns00/30/1/restore.log
> ------------------------ grep Error ------------------------
> (00.021200) Add cgroup ns 7 pid 1
> (00.021467) pstree pid_max=12
> (00.021487) Will restore in 6c020000 namespaces
> (00.021499) NS mask to use 6c020000
> (00.021537) Error (criu/pstree.c:522): pid is already linked

Hm, can't reproduce so far.. Trying to find a reason

> ------------------------ ERROR OVER ------------------------
> ################ Test zdtm/static/pidns00 FAIL at CRIU restore #################
> ##################################### FAIL #####################################
> 
> On Tue, Mar 28, 2017 at 06:35:24PM +0300, Kirill Tkhai wrote:
>> Create parent (P) and its three children (C1, C2 and C3)
>> with different pid namespaces:
>>
>> 	     P (pid_ns1)
>> 	    /|\
>> 	   / | \
>> 	  /  |  \
>> 	 /   |   \
>> 	/    |    \
>> (pid_ns1) C1     C2    C3 (pid_ns1)
>> 	 (pid_ns2)
>>
>> where pid_ns1 is a parent of pid_ns2:
>>
>> 	   pid_ns1
>> 	      |
>> 	   pid_ns2
>>
>> Children C1, C2 and C3 created in the written order,
>> i.e. C1 has the smallest pid and C2 has the biggest.
>>
>> After receiving signal check, that pid namespaces
>> restored right.
>>
>> Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
>> ---
>>  test/zdtm/static/Makefile     |    1 
>>  test/zdtm/static/pidns00.c    |  206 +++++++++++++++++++++++++++++++++++++++++
>>  test/zdtm/static/pidns00.desc |    1 
>>  3 files changed, 208 insertions(+)
>>  create mode 100644 test/zdtm/static/pidns00.c
>>  create mode 100644 test/zdtm/static/pidns00.desc
>>
>> diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile
>> index 8d5641bb..1c921d35 100644
>> --- a/test/zdtm/static/Makefile
>> +++ b/test/zdtm/static/Makefile
>> @@ -182,6 +182,7 @@ TST_NOFILE	:=				\
>>  		userns01			\
>>  		userns02			\
>>  		netns_sub_veth			\
>> +		pidns00				\
>>  #		jobctl00			\
>>  
>>  ifneq ($(SRCARCH),arm)
>> diff --git a/test/zdtm/static/pidns00.c b/test/zdtm/static/pidns00.c
>> new file mode 100644
>> index 00000000..cdfdbd3d
>> --- /dev/null
>> +++ b/test/zdtm/static/pidns00.c
>> @@ -0,0 +1,206 @@
>> +#define _GNU_SOURCE
>> +#include <stdbool.h>
>> +#include <string.h>
>> +#include <fcntl.h>
>> +#include <unistd.h>
>> +#include <signal.h>
>> +#include <stdio.h>
>> +#include <sys/mount.h>
>> +#include <sys/stat.h>
>> +#include <sys/mman.h>
>> +#include <sys/types.h>
>> +#include <sched.h>
>> +#include <sys/wait.h>
>> +#include <stdlib.h>
>> +#include <limits.h>
>> +#include <dirent.h>
>> +
>> +#include "zdtmtst.h"
>> +#include "lock.h"
>> +
>> +/*
>> + * Create parent (P) and its three children (C1, C2 and C3)
>> + * with different pid namespaces:
>> + *
>> + *                  P (pid_ns1)
>> + *                 /|\
>> + *                / | \
>> + *               /  |  \
>> + *              /   |   \
>> + *             /    |    \
>> + * (pid_ns1) C1     C2    C3 (pid_ns1)
>> + *              (pid_ns2)
>> + *
>> + * where pid_ns1 is a parent of pid_ns2:
>> + *
>> + *               pid_ns1
>> + *                  |
>> + *               pid_ns2
>> + * Children C1, C2 and C3 created in the written order,
>> + * i.e. C1 has the smallest pid and C2 has the biggest
>> + * (so, current restorer should restore them in the same order).
>> + * After receiving signal check, that pid namespaces
>> + * restored right.
>> + */
>> +
>> +#ifndef NSIO
>> +#define NSIO    0xb7
>> +#define NS_GET_PARENT   _IO(NSIO, 0x2)
>> +#endif
>> +
>> +const char *test_doc	= "Check pid namespace hierarhy restores right";
>> +const char *test_author	= "Kirill Tkhai <ktkhai at virtuozzo.com>";
>> +
>> +futex_t *futex;
>> +
>> +int child(void)
>> +{
>> +	futex_wait_while_lt(futex, 1);
>> +	return 0;
>> +}
>> +
>> +int __get_ns_id(int fd, unsigned int *id)
>> +{
>> +	struct stat st;
>> +	if (fstat(fd, &st) < 0) {
>> +		pr_perror("fstat() kaput");
>> +		return 1;
>> +	}
>> +	*id = st.st_ino;
>> +	return 0;
>> +}
>> +
>> +int get_ns_id(pid_t pid, unsigned int *id)
>> +{
>> +	char buf[PATH_MAX];
>> +	int fd, ret;
>> +	sprintf(buf, "/proc/%d/ns/pid", pid);
>> +	fd = open(buf, O_RDONLY);
>> +	if (fd < 0) {
>> +		pr_perror("Can't open %s", buf);
>> +		return -1;
>> +	}
>> +	ret = __get_ns_id(fd, id);
>> +	close(fd);
>> +	return ret;
>> +}
>> +int main(int argc, char **argv)
>> +{
>> +	int status, fd, p_fd, i, nr = 0;
>> +	unsigned int id, c_id;
>> +	char path[PATH_MAX];
>> +	pid_t pid[3];
>> +
>> +	test_init(argc, argv);
>> +	futex = mmap(NULL, sizeof(*futex), PROT_WRITE | PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
>> +	if (futex == MAP_FAILED) {
>> +		fail("mmap futex\n");
>> +		return 1;
>> +	}
>> +	futex_init(futex);
>> +
>> +	/* Child 1 */
>> +	pid[0] = fork();
>> +	if (pid[0] == -1) {
>> +		fail("fork");
>> +		return 1;
>> +	} else if (pid[0] == 0)
>> +		exit(child());
>> +	nr++;
>> +
>> +	/* Child 2 */
>> +	fd = open("/proc/self/ns/pid", O_RDONLY);
>> +	if (fd < 0) {
>> +		pr_perror("Can't get my own pid ns");
>> +		goto err;
>> +	}
>> +
>> +	if (unshare(CLONE_NEWPID) < 0) {
>> +		pr_perror("Can't unshare");
>> +		goto err;
>> +	}
>> +
>> +	pid[1] = fork();
>> +	if (pid[1] == -1) {
>> +		fail("fork");
>> +		return 1;
>> +	} else if (pid[1] == 0)
>> +		exit(child());
>> +	nr++;
>> +
>> +	/* Restore pid namespace for children */
>> +	if (setns(fd, CLONE_NEWPID) < 0) {
>> +		pr_perror("Can't setns");
>> +		goto err;
>> +	}
>> +	close(fd);
>> +
>> +	/* Child 3 */
>> +	pid[2] = fork();
>> +	if (pid[2] == -1) {
>> +		fail("fork");
>> +		goto err;
>> +	} else if (pid[2] == 0)
>> +		exit(child());
>> +	nr++;
>> +
>> +	test_daemon();
>> +	test_waitsig();
>> +
>> +	if (get_ns_id(getpid(), &id))
>> +		goto err;
>> +
>> +	for (i = 0; i < nr; i++) {
>> +		if (get_ns_id(pid[i], &c_id))
>> +			goto err;
>> +		if (i % 2 == 0) {
>> +			if (c_id != id) {
>> +				pr_err("Child %d has wrong pid ns\n", i);
>> +				goto err;
>> +			}
>> +			continue;
>> +		}
>> +
>> +		if (id == c_id) {
>> +			pr_err("Child %d has wrong pid ns\n", i);
>> +			goto err;
>> +		}
>> +		/* This parent namespace of this Child's should be same to ours */
>> +		sprintf(path, "/proc/%d/ns/pid", pid[i]);
>> +		fd = open(path, O_RDONLY);
>> +		if (fd < 0) {
>> +			pr_perror("Can't open");
>> +			goto err;
>> +		}
>> +		p_fd = ioctl(fd, NS_GET_PARENT);
>> +		if (p_fd < 0)
>> +			pr_perror("Can't get parent");
>> +		close(fd);
>> +		if (p_fd < 0)
>> +			goto err;
>> +		if (__get_ns_id(p_fd, &c_id))
>> +			goto err;
>> +		close(p_fd);
>> +		if (id != c_id) {
>> +			pr_err("Child %d has wrong pid ns hierarhy\n", i);
>> +			goto err;
>> +		}
>> +	}
>> +
>> +	futex_set_and_wake(futex, 1);
>> +
>> +	while (nr-- > 0) {
>> +		if (wait(&status) < 0 || WEXITSTATUS(status)) {
>> +			fail("pid: status=%d\n", WEXITSTATUS(status));
>> +			goto err;
>> +		}
>> +	}
>> +
>> +	pass();
>> +	return 0;
>> +err:
>> +	futex_set_and_wake(futex, 1);
>> +	while (nr-- > 0)
>> +		wait(&status);
>> +	return 1;
>> +}
>> diff --git a/test/zdtm/static/pidns00.desc b/test/zdtm/static/pidns00.desc
>> new file mode 100644
>> index 00000000..41c1adcc
>> --- /dev/null
>> +++ b/test/zdtm/static/pidns00.desc
>> @@ -0,0 +1 @@
>> +{'flavor': 'ns uns', 'flags': 'suid noauto'}
>>


More information about the CRIU mailing list