From 24074a9dbb0151676eb84cf11d3ca72d04cd07f9 Mon Sep 17 00:00:00 2001 From: Andrey Vagin Date: Fri, 22 Jun 2012 00:38:00 +0400 Subject: [PATCH] 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 Signed-off-by: Pavel Emelyanov --- test/zdtm.sh | 5 + test/zdtm/live/static/Makefile | 1 + test/zdtm/live/static/session00.c | 228 ++++++++++++++++++++++++++++++ 3 files changed, 234 insertions(+) create mode 100644 test/zdtm/live/static/session00.c diff --git a/test/zdtm.sh b/test/zdtm.sh index 3e535fe29..22ced1dfa 100644 --- a/test/zdtm.sh +++ b/test/zdtm.sh @@ -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 " diff --git a/test/zdtm/live/static/Makefile b/test/zdtm/live/static/Makefile index d6f710f73..f8e378157 100644 --- a/test/zdtm/live/static/Makefile +++ b/test/zdtm/live/static/Makefile @@ -47,6 +47,7 @@ TST_NOFILE = \ eventfs00 \ inotify00 \ uptime_grow \ + session00 \ # jobctl00 \ TST_FILE = \ diff --git a/test/zdtm/live/static/session00.c b/test/zdtm/live/static/session00.c new file mode 100644 index 000000000..ef064b987 --- /dev/null +++ b/test/zdtm/live/static/session00.c @@ -0,0 +1,228 @@ +#include +#include +#include + +#include "zdtmtst.h" + +const char *test_doc = "Test that sid, pgid are restored"; +const char *test_author = "Andrey Vagin "; + +#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; +}