[CRIU] [PATCH 1/2] test: add a test for dumping non-root-subset cg sets

Tycho Andersen tycho.andersen at canonical.com
Fri Feb 26 09:25:33 PST 2016


Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 test/zdtm/.gitignore               |   1 +
 test/zdtm/static/Makefile          |   1 +
 test/zdtm/static/cgroup_stray.c    | 231 +++++++++++++++++++++++++++++++++++++
 test/zdtm/static/cgroup_stray.desc |   1 +
 4 files changed, 234 insertions(+)
 create mode 100644 test/zdtm/static/cgroup_stray.c
 create mode 100644 test/zdtm/static/cgroup_stray.desc

diff --git a/test/zdtm/.gitignore b/test/zdtm/.gitignore
index e8686f1..408d5c0 100644
--- a/test/zdtm/.gitignore
+++ b/test/zdtm/.gitignore
@@ -11,6 +11,7 @@
 /static/cgroup02
 /static/cgroup03
 /static/cgroupns
+/static/cgroup_stray
 /static/child_opened_proc
 /static/chroot
 /static/chroot-file
diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile
index 2b00663..f5b9e67 100644
--- a/test/zdtm/static/Makefile
+++ b/test/zdtm/static/Makefile
@@ -217,6 +217,7 @@ TST_DIR		=				\
 		cgroup02			\
 		cgroup03			\
 		cgroupns			\
+		cgroup_stray		\
 		mntns_open			\
 		mntns_link_remap		\
 		mntns_link_ghost		\
diff --git a/test/zdtm/static/cgroup_stray.c b/test/zdtm/static/cgroup_stray.c
new file mode 100644
index 0000000..204ffb7
--- /dev/null
+++ b/test/zdtm/static/cgroup_stray.c
@@ -0,0 +1,231 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sched.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <limits.h>
+#include "zdtmtst.h"
+
+const char *test_doc	= "Check that stray cgroups are c/r'd correctly";
+const char *test_author	= "Tycho Andersen <tycho.andersen at canonical.com>";
+
+char *dirname;
+TEST_OPTION(dirname, string, "cgroup directory name", 1);
+static const char *cgname = "zdtmtst";
+
+static int mount_ctrl(const char *controller)
+{
+	char aux[1024], subdir[1024];
+
+	if (mkdir(dirname, 0700) < 0 && errno != EEXIST) {
+		pr_perror("Can't make dir");
+		return -1;
+	}
+
+	sprintf(subdir, "%s/%s", dirname, controller);
+	if (mkdir(subdir, 0700) < 0) {
+		pr_perror("Can't make dir");
+		return -1;
+	}
+
+	sprintf(aux, "none,name=%s", controller);
+	if (mount("none", subdir, "cgroup", 0, aux)) {
+		pr_perror("Can't mount cgroups");
+		goto err_rd;
+	}
+
+	return 0;
+err_rd:
+	rmdir(dirname);
+	return -1;
+}
+
+static int add_to_cg(const char *controller, const char *path)
+{
+	char aux[1024], paux[1024], subdir[1024];
+	int cgfd, l;
+
+	sprintf(subdir, "%s/%s", dirname, controller);
+	sprintf(paux, "%s/%s", subdir, path);
+	mkdir(paux, 0600);
+
+	l = sprintf(aux, "%d", getpid());
+	sprintf(paux, "%s/%s/tasks", subdir, path);
+
+	cgfd = open(paux, O_WRONLY);
+	if (cgfd < 0) {
+		pr_perror("Can't open tasks %s", paux);
+		return -1;
+	}
+
+	l = write(cgfd, aux, l);
+	close(cgfd);
+
+	if (l < 0) {
+		pr_perror("Can't move self to subcg %s", path);
+		return -1;
+	}
+
+	return 0;
+}
+
+static bool pid_in_cgroup(pid_t pid, const char *controller, const char *path) {
+	char buf[2048];
+	FILE *f;
+	bool ret = false;
+
+	sprintf(buf, "/proc/%d/cgroup", pid);
+	f = fopen(buf, "r");
+	if (!f) {
+		pr_perror("fopen");
+		return false;
+	}
+
+	while (NULL != fgets(buf, sizeof(buf), f)) {
+		char *pos, *pid_controller, *pid_path;
+
+		/* chop off trailing \n */
+		buf[strlen(buf)-1] = '\0';
+
+		/* skip heirarchy no. */
+		pos = strstr(buf, ":");
+		if (!pos) {
+			pr_err("invalid /proc/pid/cgroups file");
+			goto out;
+		}
+		pos++;
+		pid_controller = pos;
+
+		pos = strstr(pos, ":");
+		if (!pos) {
+			pr_err("invalid /proc/pid/cgroups file");
+			goto out;
+		}
+
+		*pos = '\0';
+		pos++;
+		pid_path = pos;
+
+test_msg("comparing %s and %s\n", controller, pid_controller);
+		if (strcmp(controller, pid_controller))
+			continue;
+
+		if (strcmp(path, pid_path))
+			pr_err("task not in right cg for controller %s expected %s, got %s\n", controller, path, pid_path);
+		else
+			ret = true;
+
+		goto out;
+	}
+
+out:
+	fclose(f);
+	return ret;
+}
+
+int main(int argc, char **argv)
+{
+	int ret = -1, sk_pair[2], sk, status;
+	char path[PATH_MAX], c;
+	pid_t pid = 0;
+
+	test_init(argc, argv);
+
+	if (socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sk_pair)) {
+		pr_perror("socketpair");
+		return -1;
+	}
+
+	if (mount_ctrl(cgname) < 0)
+		return -1;
+
+	pid = fork();
+	if (pid < 0) {
+		pr_perror("fork");
+		goto out_umount;
+	}
+
+	if (pid == 0) {
+		close(sk_pair[0]);
+		sk = sk_pair[1];
+
+		if (add_to_cg(cgname, "foo"))
+			exit(1);
+
+		if (write(sk, &c, 1) != 1) {
+			pr_perror("write");
+			exit(1);
+		}
+
+		if (read(sk, &c, 1) != 1) {
+			pr_perror("read %d", ret);
+			exit(1);
+		}
+
+		sprintf(path, "name=%s", cgname);
+		if (!pid_in_cgroup(getpid(), path, "/foo"))
+			exit(1);
+		exit(0);
+	}
+
+	close(sk_pair[1]);
+	sk = sk_pair[0];
+
+	if (add_to_cg(cgname, "bar"))
+		goto out_kill;
+
+	if ((ret = read(sk, &c, 1)) != 1) {
+		pr_perror("read %d", ret);
+		goto out_kill;
+	}
+
+	test_daemon();
+	test_waitsig();
+
+	if (write(sk, &c, 1) != 1) {
+		pr_perror("write");
+		goto out_kill;
+	}
+
+	sprintf(path, "name=%s", cgname);
+	if (!pid_in_cgroup(getpid(), path, "/bar")) {
+		fail("parent not in cgroup /bar");
+		goto out_kill;
+	}
+
+	if (pid != waitpid(pid, &status, 0)) {
+		pr_perror("waitpid");
+		goto out_umount;
+	}
+
+	if (!WIFEXITED(status) || WEXITSTATUS(status)) {
+		fail("exit status %s\n", status);
+		goto out_umount;
+	}
+
+	pass();
+	ret = 0;
+
+out_kill:
+	if (pid > 0)
+		kill(pid, SIGKILL);
+
+out_umount:
+	sprintf(path, "%s/%s/foo", dirname, cgname);
+	rmdir(path);
+	sprintf(path, "%s/%s/test", dirname, cgname);
+	rmdir(path);
+	sprintf(path, "%s/%s", dirname, cgname);
+	umount(path);
+	rmdir(path);
+	rmdir(dirname);
+	return ret;
+}
diff --git a/test/zdtm/static/cgroup_stray.desc b/test/zdtm/static/cgroup_stray.desc
new file mode 100644
index 0000000..65748f5
--- /dev/null
+++ b/test/zdtm/static/cgroup_stray.desc
@@ -0,0 +1 @@
+{'flavor': 'h ns', 'flags': 'suid', 'feature': 'cgroupns', 'opts': '--manage-cgroups'}
-- 
2.7.0



More information about the CRIU mailing list