Commit fd972a73 authored by Tycho Andersen's avatar Tycho Andersen Committed by Pavel Emelyanov

tests: fix cgroupns test to not use nested namespaces

Before we were unshare(CLONE_NEWCGROUP)ing in a child task, which meant
that we couldn't c/r this test once we forbid nested cgroup namespaces.

Instead, use a new strategy for testing cgroup namespaces: set up the
namespace before forking the test task so there is no nesting, and then do
a setns back to init's ns to check the cgroup namespace of the test. This
doesn't work in the 'ns' flavor because init in the test's pid ns is the
test itself. There is a bit of a chicken and egg problem here, though,
because if we set it up after test_init(), we can't unshare because that
would be a nested cgroup ns.
Signed-off-by: 's avatarTycho Andersen <tycho.andersen@canonical.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 0a1b2463
...@@ -147,6 +147,7 @@ TST_NOFILE = \ ...@@ -147,6 +147,7 @@ TST_NOFILE = \
vfork00 \ vfork00 \
oom_score_adj \ oom_score_adj \
loginuid \ loginuid \
cgroupns \
# jobctl00 \ # jobctl00 \
TST_FILE = \ TST_FILE = \
...@@ -216,7 +217,6 @@ TST_DIR = \ ...@@ -216,7 +217,6 @@ TST_DIR = \
cgroup01 \ cgroup01 \
cgroup02 \ cgroup02 \
cgroup03 \ cgroup03 \
cgroupns \
cgroup_stray \ cgroup_stray \
mntns_open \ mntns_open \
mntns_link_remap \ mntns_link_remap \
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
const char *test_doc = "Check that cgroup NS is correctly handled."; const char *test_doc = "Check that cgroup NS is correctly handled.";
const char *test_author = "Tycho Andersen <tycho.andersen@canonical.com>"; const char *test_author = "Tycho Andersen <tycho.andersen@canonical.com>";
char *dirname; /* we need dirname before test_init() here */
TEST_OPTION(dirname, string, "cgroup directory name", 1); char *dirname = "cgroupns.test";
static const char *cgname = "zdtmtst"; static const char *cgname = "zdtmtst";
int mount_and_add(const char *controller, const char *path) int mount_and_add(const char *controller, const char *path)
...@@ -128,107 +128,81 @@ out: ...@@ -128,107 +128,81 @@ out:
return ret; return ret;
} }
static int unshare_cgns_and_wait(void *arg) int main(int argc, char **argv)
{ {
int sk = *((int*)arg), ret = -1; int ret = -1, fd, status;
char c; char path[PATH_MAX];
char buf[20]; pid_t pid;
if (!getenv("ZDTM_NEWNS")) {
if (mount_and_add(cgname, "test") < 0)
return -1;
if (unshare(CLONE_NEWCGROUP) < 0) { if (unshare(CLONE_NEWCGROUP) < 0) {
pr_perror("unshare"); pr_perror("unshare");
goto out; goto out;
} }
if (write(sk, &c, 1) != 1) {
pr_perror("write");
goto out;
}
if (read(sk, &c, 1) != 1) {
pr_perror("read %d", ret);
goto out;
} }
sprintf(buf, "name=%s", cgname);
if (!pid_in_cgroup(getpid(), buf, "/")) {
pr_err("subtask not in right cg!\n");
goto out;
}
ret = 0;
out:
close(sk);
return ret;
}
int main(int argc, char **argv)
{
int ret = -1, sk_pair[2], sk, status;
char path[PATH_MAX], c;
pid_t pid;
test_init(argc, argv); test_init(argc, argv);
if (mount_and_add(cgname, "test") < 0) test_daemon();
return -1; test_waitsig();
if (socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sk_pair)) { sprintf(path, "name=%s", cgname);
pr_perror("socketpair");
/* first check that the task is in zdtmtst:/ */
if (!pid_in_cgroup(getpid(), path, "/")) {
fail("pid not in cgroup /");
goto out; goto out;
} }
/* now check that the task is in the right place in a ns by setnsing to
* someone else's ns and looking there.
*/
pid = fork(); pid = fork();
if (pid < 0) { if (pid < 0) {
pr_perror("fork failed"); pr_perror("fork");
goto out; goto out;
} }
if (pid == 0) { if (pid == 0) {
close(sk_pair[0]); sprintf(path, "/proc/%d/ns/cgroup", 1);
if (unshare_cgns_and_wait(sk_pair+1)) fd = open(path, O_RDONLY);
if (fd < 0) {
pr_perror("open");
exit(1); exit(1);
exit(0);
} }
close(sk_pair[1]); ret = setns(fd, CLONE_NEWCGROUP);
sk = sk_pair[0]; close(fd);
if (ret < 0) {
if ((ret = read(sk, &c, 1)) != 1) { pr_perror("setns");
pr_perror("read %d", ret); exit(1);
goto out;
} }
test_daemon();
test_waitsig();
sprintf(path, "name=%s", cgname); sprintf(path, "name=%s", cgname);
if (!pid_in_cgroup(getppid(), path, "/test")) {
/* first check that the task is in zdtmtst:/test */ fail("pid not in cgroup %s", path);
if (!pid_in_cgroup(pid, path, "/test")) { exit(1);
fail("pid not in cgroup /test");
goto out;
} }
/* now have the task check that it is in / */ exit(0);
if (write(sk, &c, 1) != 1) {
pr_perror("write");
goto out;
} }
if (pid != waitpid(pid, &status, 0)) { if (pid != waitpid(pid, &status, 0)) {
pr_perror("waitpid"); pr_err("wrong pid");
goto out; goto out;
} }
if (!WIFEXITED(status) || WEXITSTATUS(status)) { if (!WIFEXITED(status) || WEXITSTATUS(status)) {
fail("exit status %s\n", status); pr_err("got bad exit status %d\n", status);
goto out; goto out;
} }
pass();
ret = 0; ret = 0;
pass();
out: out:
sprintf(path, "%s/%s/test", dirname, cgname); sprintf(path, "%s/%s/test", dirname, cgname);
rmdir(path); rmdir(path);
......
{'flavor': 'h ns', 'flags': 'suid', 'feature': 'cgroupns', 'opts': '--manage-cgroups'} {'flavor': 'h', 'flags': 'suid', 'feature': 'cgroupns', 'opts': '--manage-cgroups'}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment