From 00203995937543997c66c052d981272e689cf3b3 Mon Sep 17 00:00:00 2001 From: Pavel Tikhomirov Date: Fri, 26 May 2017 20:02:54 +0300 Subject: [PATCH] zdtm: test for new init reparent handling with tricky setns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Session 15's(20) leader is in first pidns, one it's process is in second pidns and one is in the third. So we create two helpers here for each aditional pidns. (It is critical that Full test now looks like (mind pids here are different(real) from their id's in source code e.g. 15 is 20 here): (pid,ppid,sid) session04(1, 0, 1)───session04(4, 1, 4)───session04(5, 4, 4)───session04(6, 5, 6,pid1)─┬─session04(8, 6, 8)───session04(9, 8, 7) ├─session04(10, 6, 6)───session04(11, 10, 11) ├─session04(13, 6, 13)───session04(14, 13, 11) ├─session04(15, 6, 15) ├─session04(17, 6, 17)─┬─session04(18, 17, 15) │ └─session04(19, 17, 17,pid2)───session04(22, 19, 20) ├─session04(20, 6, 20) └─session04(23, 6, 6,pid3)───session04(25, 23, 20) Signed-off-by: Pavel Tikhomirov Signed-off-by: Andrei Vagin --- test/zdtm/static/session04.c | 120 ++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) diff --git a/test/zdtm/static/session04.c b/test/zdtm/static/session04.c index 007ebe403..155480ff3 100644 --- a/test/zdtm/static/session04.c +++ b/test/zdtm/static/session04.c @@ -2,11 +2,16 @@ #include #include #include +#include +#include #include #include #include #include #include +#include +#include +#include #include "zdtmtst.h" @@ -22,7 +27,7 @@ struct process }; struct process *processes; -int nr_processes = 20; +int nr_processes = 21; int current = 0; static void cleanup() @@ -40,6 +45,7 @@ enum commands TEST_SETSID, TEST_DIE, TEST_GETSID, + TEST_SETNS, }; struct command @@ -94,6 +100,79 @@ static int make_child(int id, int flags) return cid; } +static int open_proc(void) +{ + int fd; + char proc_mountpoint[] = "session04_proc.XXXXXX"; + + if (mkdtemp(proc_mountpoint) == NULL) { + pr_perror("mkdtemp failed %s", proc_mountpoint); + return -1; + } + + if (mount("proc", proc_mountpoint, "proc", MS_MGC_VAL | MS_NOSUID | MS_NOEXEC | MS_NODEV, NULL)) { + pr_perror("mount proc failed"); + rmdir(proc_mountpoint); + return -1; + } + + fd = open(proc_mountpoint, O_RDONLY | O_DIRECTORY, 0); + if (fd < 0) + pr_perror("can't open proc"); + + if (umount2(proc_mountpoint, MNT_DETACH)) { + pr_perror("can't umount proc"); + goto err_close; + } + + if (rmdir(proc_mountpoint)) { + pr_perror("can't remove tmp dir"); + goto err_close; + } + + return fd; +err_close: + if (fd >= 0) + close(fd); + return -1; +} + +static int open_pidns(int pid) +{ + int proc, fd; + char pidns_path[PATH_MAX]; + + proc = open_proc(); + if (proc < 0) { + pr_err("open proc"); + return -1; + } + + sprintf(pidns_path, "%d/ns/pid", pid); + fd = openat(proc, pidns_path, O_RDONLY); + if (fd == -1) + pr_err("open pidns fd"); + + close(proc); + return fd; +} + +static int setns_pid(int pid, int nstype) +{ + int pidns, ret; + + pidns = open_pidns(pid); + if (pidns < 0) + return -1; + + ret = setns(pidns, nstype); + if (ret == -1) + pr_perror("setns"); + + close(pidns); + return ret; +} + static void handle_command() { int sk = processes[current].sks[0], ret, status = 0; @@ -150,6 +229,12 @@ static void handle_command() if(status == -1) pr_perror("getsid"); break; + case TEST_SETNS: + test_msg("%3d: setns(%d, %d) = %d\n", current, + cmd.arg1, cmd.arg2, processes[cmd.arg1].pid); + setns_pid(processes[cmd.arg1].pid, cmd.arg2); + + break; case TEST_DIE: test_msg("%3d: die()\n", current); processes[current].dead = 1; @@ -264,6 +349,39 @@ int main(int argc, char ** argv) send_command(7, TEST_DIE, 0, 0); send_command(6, TEST_WAIT, 7, 0); + /* + * Branch of (11,10) - [(12,12)->(13,10)] reparents to init (1,1), + * have session leader but it is not reachable, and branch of + * (16,15) - [(17,15)] reparents to init of second pidns (14,14), + * so have session leader in other pidns. + */ + send_command(1, TEST_FORK, 10, 0); + send_command(10, TEST_SETSID, 0, 0); + send_command(10, TEST_FORK, 11, 0); + send_command(11, TEST_FORK, 12, 0); + send_command(12, TEST_FORK, 13, 0); + send_command(12, TEST_SETSID, 0, 0); + send_command(12, TEST_FORK, 14, CLONE_NEWPID); + send_command(1, TEST_FORK, 15, 0); + send_command(15, TEST_SETSID, 0, 0); + send_command(15, TEST_SETNS, 14, CLONE_NEWPID); + send_command(15, TEST_FORK, 16, 0); + send_command(16, TEST_FORK, 17, 0); + send_command(11, TEST_DIE, 0, 0); + send_command(10, TEST_WAIT, 11, 0); + send_command(16, TEST_DIE, 0, 0); + send_command(15, TEST_WAIT, 16, 0); + + /* + * Add session 15's adopted representative to third pidns + */ + send_command(1, TEST_FORK, 18, CLONE_NEWPID); + send_command(15, TEST_SETNS, 18, CLONE_NEWPID); + send_command(15, TEST_FORK, 19, 0); + send_command(19, TEST_FORK, 20, 0); + send_command(19, TEST_DIE, 0, 0); + send_command(15, TEST_WAIT, 19, 0); + for (i = 0; i < nr_processes; i++) { if (processes[i].dead) continue;