mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-22 17:49:13 +00:00
zdtm: test for new init reparent handling with tricky setns
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@virtuozzo.com>
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
parent
55cd96cfd6
commit
0020399593
1 changed files with 119 additions and 1 deletions
|
|
@ -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()
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue