static int unshare_cgns_and_wait(void *arg) { 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; } 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 = 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 %d\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; }
int main(int argc, char **argv) { int ret = -1, fd, status; char path[PATH_MAX]; pid_t pid; if (!getenv("ZDTM_NEWNS")) { if (mount_and_add(cgname, "test") < 0) return -1; if (unshare(CLONE_NEWCGROUP) < 0) { pr_perror("unshare"); goto out; } } test_init(argc, argv); test_daemon(); test_waitsig(); sprintf(path, "name=%s", cgname); /* 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"); goto out; } if (pid == 0) { sprintf(path, "/proc/%d/ns/cgroup", 1); fd = open(path, O_RDONLY); if (fd < 0) { pr_perror("open"); exit(1); } ret = setns(fd, CLONE_NEWCGROUP); close(fd); if (ret < 0) { pr_perror("setns"); exit(1); } sprintf(path, "name=%s", cgname); if (!pid_in_cgroup(getppid(), path, "/test")) { fail("pid not in cgroup %s", path); exit(1); } exit(0); } if (pid != waitpid(pid, &status, 0)) { pr_err("wrong pid"); goto out; } if (!WIFEXITED(status) || WEXITSTATUS(status)) { pr_err("got bad exit status %d\n", status); goto out; } ret = 0; pass(); out: sprintf(path, "%s/%s/test", dirname, cgname); rmdir(path); sprintf(path, "%s/%s", dirname, cgname); umount(path); rmdir(path); rmdir(dirname); 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; if (socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sk_pair)) { pr_perror("socketpair"); goto out; } pid = fork(); if (pid < 0) { pr_perror("fork failed"); goto out; } if (pid == 0) { close(sk_pair[0]); if (unshare_cgns_and_wait(sk_pair+1)) 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); /* first check that the task is in zdtmtst:/test */ if (!pid_in_cgroup(pid, path, "/test")) { fail("pid not in cgroup /test"); goto out; } /* now have the task check that it is in / */ if (write(sk, &c, 1) != 1) { pr_perror("write"); goto out; } if (pid != waitpid(pid, &status, 0)) { pr_perror("waitpid"); goto out; } if (!WIFEXITED(status) || WEXITSTATUS(status)) { fail("exit status %s\n", status); goto out; } pass(); ret = 0; out: sprintf(path, "%s/%s/test", dirname, cgname); rmdir(path); sprintf(path, "%s/%s", dirname, cgname); umount(path); rmdir(path); rmdir(dirname); return ret; }