[CRIU] [PATCH 11/11] zdtm: test for new init reparent handling with tricky setns
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Fri May 26 10:02:54 PDT 2017
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 <ptikhomirov at virtuozzo.com>
---
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 859a18a..c5acba4 100644
--- a/test/zdtm/static/session04.c
+++ b/test/zdtm/static/session04.c
@@ -2,11 +2,16 @@
#include <sched.h>
#include <unistd.h>
#include <stdlib.h>
+#include <fcntl.h>
+#include <limits.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/prctl.h>
#include <sys/user.h>
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#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()
@@ -42,6 +47,7 @@ enum commands
TEST_SETSID,
TEST_DIE,
TEST_GETSID,
+ TEST_SETNS,
};
struct command
@@ -96,6 +102,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;
@@ -152,6 +231,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;
@@ -266,6 +351,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;
--
2.9.3
More information about the CRIU
mailing list