mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-25 02:58:54 +00:00
zdtm: add new test case for checking that SID is restored
2 2 session00
4 4 \_ session00 # {NEWSID, },
2 5 \_ session00 # {0, },
8 8 \_ session00
2 9 | \_ session00 # {CHANGESID, }
10 10 \_ session00
11 11 \_ session00
2 12 \_ session00 # {DOUBLE_CHANGESID | CHANGESID, }
2 3 session00 # {DETACH, },
6 7 session00 # {DETACH|NEWSID, },
Signed-off-by: Andrey Vagin <avagin@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
a4685cd30c
commit
24074a9dbb
3 changed files with 234 additions and 0 deletions
|
|
@ -53,6 +53,11 @@ transition/fork
|
|||
static/file_fown
|
||||
"
|
||||
|
||||
# These ones are in pidns
|
||||
TEST_LIST="$TEST_LIST
|
||||
pidns/static/session00
|
||||
"
|
||||
|
||||
UTS_TEST_LIST="
|
||||
static/utsname
|
||||
"
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ TST_NOFILE = \
|
|||
eventfs00 \
|
||||
inotify00 \
|
||||
uptime_grow \
|
||||
session00 \
|
||||
# jobctl00 \
|
||||
|
||||
TST_FILE = \
|
||||
|
|
|
|||
228
test/zdtm/live/static/session00.c
Normal file
228
test/zdtm/live/static/session00.c
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "zdtmtst.h"
|
||||
|
||||
const char *test_doc = "Test that sid, pgid are restored";
|
||||
const char *test_author = "Andrey Vagin <avagin@openvz.org>";
|
||||
|
||||
#define DETACH 1
|
||||
#define NEWSID 2
|
||||
#define CHANGESID 4
|
||||
#define DOUBLE_CHANGESID 8
|
||||
|
||||
struct testcase {
|
||||
int flags;
|
||||
pid_t pid;
|
||||
pid_t sid;
|
||||
};
|
||||
|
||||
static struct testcase testcases[] = {
|
||||
{DETACH, },
|
||||
{NEWSID, },
|
||||
{0, },
|
||||
{DETACH|NEWSID, },
|
||||
{CHANGESID, },
|
||||
{DOUBLE_CHANGESID | CHANGESID, }
|
||||
};
|
||||
/*
|
||||
2 2 session00
|
||||
4 4 \_ session00 # {NEWSID, },
|
||||
2 5 \_ session00 # {0, },
|
||||
8 8 \_ session00
|
||||
2 9 | \_ session00 # {CHANGESID, }
|
||||
10 10 \_ session00
|
||||
11 11 \_ session00
|
||||
2 12 \_ session00 # {DOUBLE_CHANGESID | CHANGESID, }
|
||||
2 3 session00 # {DETACH, },
|
||||
6 7 session00 # {DETACH|NEWSID, },
|
||||
*/
|
||||
|
||||
#define NUM_CASES (sizeof(testcases) / sizeof(struct testcase))
|
||||
|
||||
static int fork_child(int i)
|
||||
{
|
||||
int p[2];
|
||||
int status, ret;
|
||||
pid_t pid, sid;
|
||||
|
||||
ret = pipe(p);
|
||||
if (ret) {
|
||||
err("pipe() failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pid = test_fork();
|
||||
if (pid < 0) {
|
||||
err("Can't fork");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
if (testcases[i].flags & NEWSID) {
|
||||
sid = setsid();
|
||||
if (sid == -1) {
|
||||
err("setsid failed");
|
||||
write(p[1], &sid, sizeof(sid));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (testcases[i].flags & (DETACH | CHANGESID)) {
|
||||
pid = test_fork();
|
||||
if (pid < 0) {
|
||||
write(p[1], &pid, sizeof(pid));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (pid != 0) {
|
||||
if (!(testcases[i].flags & CHANGESID))
|
||||
exit(0);
|
||||
|
||||
sid = setsid();
|
||||
if (sid == -1) {
|
||||
err("setsid failed");
|
||||
write(p[1], &sid, sizeof(sid));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
wait(NULL);
|
||||
if (getsid(getpid()) != sid) {
|
||||
fail("The process %d (%x) has SID=%d (expected %d)",
|
||||
pid, testcases[i].flags, sid, testcases[i].sid);
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (testcases[i].flags & DOUBLE_CHANGESID) {
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
write(p[1], &pid, sizeof(pid));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (pid == 0)
|
||||
goto child;
|
||||
|
||||
sid = setsid();
|
||||
if (sid == -1) {
|
||||
err("setsid failed");
|
||||
write(p[1], &sid, sizeof(sid));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
wait(NULL);
|
||||
if (getsid(getpid()) != sid) {
|
||||
fail("The process %d (%x) has SID=%d (expected %d)",
|
||||
pid, testcases[i].flags, sid, testcases[i].sid);
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
child:
|
||||
pid = getpid();
|
||||
write(p[1], &pid, sizeof(pid));
|
||||
close(p[1]);
|
||||
|
||||
test_waitsig();
|
||||
pass();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
close(p[1]);
|
||||
|
||||
if (testcases[i].flags & DETACH) {
|
||||
pid_t ret;
|
||||
ret = wait(&status);
|
||||
if (ret != pid) {
|
||||
err("wait return %d instead of %d", ret, pid);
|
||||
kill(pid, SIGKILL);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = read(p[0], &testcases[i].pid, sizeof(pid));
|
||||
if (ret != sizeof(ret)) {
|
||||
err("read failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
close(p[0]);
|
||||
|
||||
if (testcases[i].pid < 0) {
|
||||
err("child failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
testcases[i].sid = getsid(testcases[i].pid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
int i, ret, err = 0, status;
|
||||
pid_t pid;
|
||||
|
||||
test_init(argc, argv);
|
||||
|
||||
for (i = 0; i < NUM_CASES; i++)
|
||||
if (fork_child(i))
|
||||
break;
|
||||
|
||||
if (i != NUM_CASES) {
|
||||
int j;
|
||||
for (j = 0; j < i; j++)
|
||||
kill(testcases[j].pid, SIGTERM);
|
||||
return 1;
|
||||
}
|
||||
|
||||
test_daemon();
|
||||
|
||||
test_waitsig();
|
||||
|
||||
for (i = 0; i < NUM_CASES; i++) {
|
||||
pid_t pid = testcases[i].pid;
|
||||
pid_t sid = getsid(pid);
|
||||
|
||||
if (sid != testcases[i].sid) {
|
||||
fail("The process %d (%x) has SID=%d (expected %d)",
|
||||
pid, testcases[i].flags, sid, testcases[i].sid);
|
||||
err++;
|
||||
}
|
||||
|
||||
ret = kill(pid, SIGKILL);
|
||||
if (ret == -1) {
|
||||
err("kill failed");
|
||||
err++;
|
||||
}
|
||||
waitpid(pid, NULL, 0);
|
||||
|
||||
if (testcases[i].flags & CHANGESID) {
|
||||
pid = wait(&status);
|
||||
if (pid == -1) {
|
||||
err("wait() failed");
|
||||
err++;
|
||||
}
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status)) {
|
||||
fail("The process with pid %d returns %d\n", pid, status);
|
||||
err++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pid = wait(&status);
|
||||
if (pid != -1 || errno != ECHILD) {
|
||||
err("%d isn't waited");
|
||||
err++;
|
||||
}
|
||||
|
||||
if (!err)
|
||||
pass();
|
||||
|
||||
return err > 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue