[CRIU] [PATCH v2 08/57] zdtm: Add pidns00 test
Andrei Vagin
avagin at virtuozzo.com
Wed Apr 5 15:32:50 PDT 2017
@@ -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
------------------------ 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