mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-08-04 15:53:44 +00:00
Acked-by: Mike Rapoport <rppt@linux.ibm.com> Signed-off-by: Adrian Reber <areber@redhat.com>
170 lines
3.2 KiB
C
170 lines
3.2 KiB
C
#include <unistd.h>
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/mount.h>
|
|
#include <limits.h>
|
|
#include "zdtmtst.h"
|
|
|
|
const char *test_doc = "Check that global cgroup settings (+perms) are restored";
|
|
const char *test_author = "Tycho Andersen <tycho.andersen@canonical.com>";
|
|
|
|
char *dirname;
|
|
TEST_OPTION(dirname, string, "cgroup directory name", 1);
|
|
static const char *cgname = "zdtmtst";
|
|
|
|
int mount_and_add(const char *controller, const char *path)
|
|
{
|
|
char aux[1024], paux[1024], subdir[1024];
|
|
int cgfd, l;
|
|
|
|
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;
|
|
}
|
|
|
|
ssprintf(paux, "%s/%s", subdir, path);
|
|
mkdir(paux, 0600);
|
|
|
|
l = sprintf(aux, "%d", getpid());
|
|
ssprintf(paux, "%s/%s/tasks", subdir, path);
|
|
|
|
cgfd = open(paux, O_WRONLY);
|
|
if (cgfd < 0) {
|
|
pr_perror("Can't open tasks");
|
|
goto err_rs;
|
|
}
|
|
|
|
l = write(cgfd, aux, l);
|
|
close(cgfd);
|
|
|
|
if (l < 0) {
|
|
pr_perror("Can't move self to subcg");
|
|
goto err_rs;
|
|
}
|
|
|
|
return 0;
|
|
err_rs:
|
|
umount(dirname);
|
|
err_rd:
|
|
rmdir(dirname);
|
|
return -1;
|
|
}
|
|
|
|
int chownmod(char *path, int flags)
|
|
{
|
|
int fd, ret = -1;
|
|
|
|
fd = open(path, flags);
|
|
if (fd < 0) {
|
|
pr_perror("can't open %s", path);
|
|
return -1;
|
|
}
|
|
|
|
if (fchown(fd, 1000, 1000) < 0) {
|
|
pr_perror("can't chown %s", path);
|
|
goto out;
|
|
}
|
|
|
|
if (fchmod(fd, 0777) < 0) {
|
|
pr_perror("can't chmod %s", path);
|
|
goto out;
|
|
}
|
|
|
|
ret = 0;
|
|
out:
|
|
close(fd);
|
|
return ret;
|
|
}
|
|
|
|
int checkperms(char *path)
|
|
{
|
|
struct stat sb;
|
|
|
|
if (stat(path, &sb) < 0) {
|
|
pr_perror("can't stat %s", path);
|
|
return -1;
|
|
}
|
|
|
|
if ((sb.st_mode & 0777) != 0777) {
|
|
fail("mode for %s doesn't match (%o)", path, sb.st_mode);
|
|
return -1;
|
|
}
|
|
|
|
if (sb.st_uid != 1000) {
|
|
fail("uid for %s doesn't match (%d)", path, sb.st_uid);
|
|
return -1;
|
|
}
|
|
|
|
if (sb.st_gid != 1000) {
|
|
fail("gid for %s doesn't match (%d)", path, sb.st_gid);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int ret = -1;
|
|
char path[PATH_MAX];
|
|
|
|
test_init(argc, argv);
|
|
|
|
if (mount_and_add(cgname, "test") < 0)
|
|
return -1;
|
|
|
|
sprintf(path, "%s/%s/test", dirname, cgname);
|
|
if (chownmod(path, O_DIRECTORY) < 0)
|
|
goto out_umount;
|
|
|
|
sprintf(path, "%s/%s/test/notify_on_release", dirname, cgname);
|
|
if (chownmod(path, O_RDWR) < 0)
|
|
goto out_umount;
|
|
|
|
sprintf(path, "%s/%s/test/cgroup.procs", dirname, cgname);
|
|
if (chownmod(path, O_RDWR) < 0)
|
|
goto out_umount;
|
|
|
|
test_daemon();
|
|
test_waitsig();
|
|
|
|
sprintf(path, "%s/%s/test", dirname, cgname);
|
|
if (checkperms(path) < 0)
|
|
goto out_umount;
|
|
|
|
sprintf(path, "%s/%s/test/notify_on_release", dirname, cgname);
|
|
if (checkperms(path) < 0)
|
|
goto out_umount;
|
|
|
|
sprintf(path, "%s/%s/test/cgroup.procs", dirname, cgname);
|
|
if (checkperms(path) < 0)
|
|
goto out_umount;
|
|
|
|
pass();
|
|
ret = 0;
|
|
|
|
out_umount:
|
|
sprintf(path, "%s/%s/test", dirname, cgname);
|
|
rmdir(path);
|
|
sprintf(path, "%s/%s", dirname, cgname);
|
|
umount(path);
|
|
rmdir(path);
|
|
rmdir(dirname);
|
|
return ret;
|
|
}
|