[CRIU] [PATCH 10/10] tests: fix cgroupns test to not use nested namespaces

Tycho Andersen tycho.andersen at canonical.com
Wed Mar 2 15:17:08 PST 2016


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: Tycho Andersen <tycho.andersen at canonical.com>
---
 test/zdtm/static/Makefile      |   2 +-
 test/zdtm/static/cgroupns.c    | 116 ++++++++++++++++-------------------------
 test/zdtm/static/cgroupns.desc |   2 +-
 3 files changed, 47 insertions(+), 73 deletions(-)

diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile
index f5b9e67..08cf642 100644
--- a/test/zdtm/static/Makefile
+++ b/test/zdtm/static/Makefile
@@ -147,6 +147,7 @@ TST_NOFILE	=				\
 		vfork00				\
 		oom_score_adj			\
 		loginuid			\
+		cgroupns			\
 #		jobctl00			\
 
 TST_FILE	=				\
@@ -216,7 +217,6 @@ TST_DIR		=				\
 		cgroup01			\
 		cgroup02			\
 		cgroup03			\
-		cgroupns			\
 		cgroup_stray		\
 		mntns_open			\
 		mntns_link_remap		\
diff --git a/test/zdtm/static/cgroupns.c b/test/zdtm/static/cgroupns.c
index b66757e..955ab72 100644
--- a/test/zdtm/static/cgroupns.c
+++ b/test/zdtm/static/cgroupns.c
@@ -21,8 +21,8 @@
 const char *test_doc	= "Check that cgroup NS is correctly handled.";
 const char *test_author	= "Tycho Andersen <tycho.andersen at canonical.com>";
 
-char *dirname;
-TEST_OPTION(dirname, string, "cgroup directory name", 1);
+/* we need dirname before test_init() here */
+char *dirname = "cgroupns.test";
 static const char *cgname = "zdtmtst";
 
 int mount_and_add(const char *controller, const char *path)
@@ -128,107 +128,81 @@ out:
 	return ret;
 }
 
-static int unshare_cgns_and_wait(void *arg)
+int main(int argc, char **argv)
 {
-	int sk = *((int*)arg), ret = -1;
-	char c;
-	char buf[20];
-
-	if (unshare(CLONE_NEWCGROUP) < 0) {
-		pr_perror("unshare");
-		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;
-	}
+	int ret = -1, fd, status;
+	char path[PATH_MAX];
+	pid_t pid;
 
-	sprintf(buf, "name=%s", cgname);
+	if (!getenv("ZDTM_NEWNS")) {
+		if (mount_and_add(cgname, "test") < 0)
+			return -1;
 
-	if (!pid_in_cgroup(getpid(), buf, "/")) {
-		pr_err("subtask not in right cg!\n");
-		goto out;
+		if (unshare(CLONE_NEWCGROUP) < 0) {
+			pr_perror("unshare");
+			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);
 
-	if (mount_and_add(cgname, "test") < 0)
-		return -1;
+	test_daemon();
+	test_waitsig();
+
+	sprintf(path, "name=%s", cgname);
 
-	if (socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sk_pair)) {
-		pr_perror("socketpair");
+	/* first check that the task is in zdtmtst:/ */
+	if (!pid_in_cgroup(getpid(), path, "/")) {
+		fail("pid not in cgroup /");
 		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();
 	if (pid < 0) {
-		pr_perror("fork failed");
+		pr_perror("fork");
 		goto out;
 	}
 
 	if (pid == 0) {
-		close(sk_pair[0]);
-		if (unshare_cgns_and_wait(sk_pair+1))
+		sprintf(path, "/proc/%d/ns/cgroup", 1);
+		fd = open(path, O_RDONLY);
+		if (fd < 0) {
+			pr_perror("open");
 			exit(1);
-		exit(0);
-	}
-
-	close(sk_pair[1]);
-	sk = sk_pair[0];
-
-	if ((ret = read(sk, &c, 1)) != 1) {
-		pr_perror("read %d", ret);
-		goto out;
-	}
-
-	test_daemon();
-	test_waitsig();
+		}
 
-	sprintf(path, "name=%s", cgname);
+		ret = setns(fd, CLONE_NEWCGROUP);
+		close(fd);
+		if (ret < 0) {
+			pr_perror("setns");
+			exit(1);
+		}
 
-	/* first check that the task is in zdtmtst:/test */
-	if (!pid_in_cgroup(pid, path, "/test")) {
-		fail("pid not in cgroup /test");
-		goto out;
-	}
+		sprintf(path, "name=%s", cgname);
+		if (!pid_in_cgroup(getppid(), path, "/test")) {
+			fail("pid not in cgroup %s", path);
+			exit(1);
+		}
 
-	/* now have the task check that it is in / */
-	if (write(sk, &c, 1) != 1) {
-		pr_perror("write");
-		goto out;
+		exit(0);
 	}
 
 	if (pid != waitpid(pid, &status, 0)) {
-		pr_perror("waitpid");
+		pr_err("wrong pid");
 		goto out;
 	}
 
 	if (!WIFEXITED(status) || WEXITSTATUS(status)) {
-		fail("exit status %s\n", status);
+		pr_err("got bad exit status %d\n", status);
 		goto out;
 	}
 
-	pass();
 	ret = 0;
+	pass();
+
 out:
 	sprintf(path, "%s/%s/test", dirname, cgname);
 	rmdir(path);
diff --git a/test/zdtm/static/cgroupns.desc b/test/zdtm/static/cgroupns.desc
index 65748f5..88a9100 100644
--- a/test/zdtm/static/cgroupns.desc
+++ b/test/zdtm/static/cgroupns.desc
@@ -1 +1 @@
-{'flavor': 'h ns', 'flags': 'suid', 'feature': 'cgroupns', 'opts': '--manage-cgroups'}
+{'flavor': 'h', 'flags': 'suid', 'feature': 'cgroupns', 'opts': '--manage-cgroups'}
-- 
2.7.0



More information about the CRIU mailing list