cgroup: test for --manage-cgroups=ignore

Test to ensure that --manage-cgroups=ignore works correctly.

Signed-off-by: Adrian Reber <areber@redhat.com>
This commit is contained in:
Adrian Reber 2022-04-02 15:58:25 +00:00 committed by Andrei Vagin
parent 2b6901707c
commit 4adec8e8ef
7 changed files with 204 additions and 2 deletions

View file

@ -2,6 +2,6 @@
set -e
source `dirname $0`/criu-lib.sh
prep
./test/zdtm.py run --all -f best -x maps04 -x cgroup02 --norst --keep-img always || fail
./test/zdtm.py run --all -f best -x maps04 -x cgroup02 -x cgroup_ignore --norst --keep-img always || fail
PYTHONPATH="$(pwd)/lib/" ./test/crit-recode.py || fail
exit 0

View file

@ -5,4 +5,4 @@ set -e
source `dirname $0`/criu-lib.sh
prep
mount_tmpfs_to_dump
./test/zdtm.py run --all --keep-going --report report --parallel 4 --norst -x 'maps04' -x 'cgroup02' || fail
./test/zdtm.py run --all --keep-going --report report --parallel 4 --norst -x 'maps04' -x 'cgroup02' -x 'cgroup_ignore' || fail

View file

@ -176,4 +176,30 @@ extern dev_t get_mapping_dev(void *addr);
___ret; \
})
#ifndef TEMP_FAILURE_RETRY
#define TEMP_FAILURE_RETRY(expression) \
(__extension__({ \
long int __result; \
do \
__result = (long int)(expression); \
while (__result < 0 && errno == EINTR); \
__result; \
}))
#endif
#define cleanup_close __attribute__((cleanup(cleanup_closep)))
#define cleanup_free __attribute__((cleanup(cleanup_freep)))
static inline void cleanup_freep(void *p)
{
void **pp = (void **)p;
free(*pp);
}
static inline void cleanup_closep(void *p)
{
int *pp = (int *)p;
if (*pp >= 0)
TEMP_FAILURE_RETRY(close(*pp));
}
#endif /* _VIMITESU_H_ */

View file

@ -377,6 +377,7 @@ TST_DIR = \
cgroup03 \
cgroup04 \
cgroup_ifpriomap \
cgroup_ignore \
cgroup_stray \
cgroup_yard \
unlink_fstat04 \

View file

@ -0,0 +1,161 @@
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include "zdtmtst.h"
const char *test_doc = "Check that cgroups are correctly ignored";
const char *test_author = "Adrian Reber <areber@redhat.com>";
char *dirname;
TEST_OPTION(dirname, string, "cgroup directory name", 1);
static const char *cgname = "zdtmtst";
static size_t read_all(int fd, char *buf, size_t size)
{
ssize_t r = 0, ret;
while (r < size) {
ret = read(fd, buf + r, size - r);
if (ret < 0) {
pr_perror("Read failed");
return -1;
} else if (ret == 0) {
return 0;
}
r += ret;
}
return 0;
}
int main(int argc, char **argv)
{
cleanup_free char *cgroup_procs = NULL;
cleanup_close int cgroup_procs_fd = -1;
cleanup_free char *destination = NULL;
cleanup_free char *buffer_old = NULL;
cleanup_free char *buffer_new = NULL;
cleanup_close int fd = -1;
int ret = 1;
test_init(argc, argv);
buffer_old = malloc(PAGE_SIZE);
if (!buffer_old) {
pr_err("Could not allocate memory\n");
return 1;
}
memset(buffer_old, 0, PAGE_SIZE);
buffer_new = malloc(PAGE_SIZE);
if (!buffer_new) {
pr_err("Could not allocate memory\n");
return 1;
}
memset(buffer_new, 0, PAGE_SIZE);
// Read /proc/self/cgroup to later compare against it
fd = open("/proc/self/cgroup", O_RDONLY);
if (fd < 0) {
pr_err("Could not open /proc/self/cgroup\n");
return 1;
}
if (read_all(fd, buffer_old, PAGE_SIZE)) {
pr_err("Could not read data from /proc/self/cgroup\n");
return 1;
}
// Create the cgroup root directory
if (mkdir(dirname, 0700) < 0 && errno != EEXIST) {
pr_err("Cannot make directory %s\n", dirname);
return 1;
}
// Mount cgroup2, skip if cgroup2 is not available
if (mount("none", dirname, "cgroup2", 0, 0)) {
if (errno == ENODEV) {
skip("Test relies on cgroup2 semantics which this system does not support. Skipping");
test_daemon();
test_waitsig();
pass();
return 0;
} else {
pr_err("Could not mount cgroup2 at %s\n", dirname);
}
return 1;
}
// Create the cgroup cgname (if it does not already exist)
if (asprintf(&destination, "%s/%s", dirname, cgname) == -1) {
pr_err("Could not allocate memory\n");
goto err;
}
if (mkdir(destination, 0700) < 0 && errno != EEXIST) {
pr_err("Failed to create temporary cgroup directory %s\n", destination);
goto err;
}
// Move this process to the newly created cgroup
if (asprintf(&cgroup_procs, "%s/cgroup.procs", destination) == -1) {
pr_err("Could not allocate memory\n");
goto err;
}
cgroup_procs_fd = open(cgroup_procs, O_RDWR);
if (cgroup_procs_fd < 0) {
pr_err("Could not open %s\n", cgroup_procs);
goto err;
}
if (write(cgroup_procs_fd, "0", 1) != 1) {
pr_err("Writing to %s failed\n", cgroup_procs);
goto err;
}
// Read /proc/self/cgroup (should have changed)
lseek(fd, 0, SEEK_SET);
if (read_all(fd, buffer_new, PAGE_SIZE)) {
pr_err("Could not read data from /proc/self/cgroup\n");
goto err;
}
// Test if /proc/self/cgroup has changed
if (!memcmp(buffer_new, buffer_old, PAGE_SIZE)) {
fail("/proc/self/cgroup should differ after move to another cgroup");
pr_err("original /proc/self/cgroup content %s\n", buffer_old);
pr_err("new /proc/self/cgroup content %s\n", buffer_new);
goto err;
}
test_daemon();
test_waitsig();
// Read /proc/self/cgroup. It should not be the same as after
// moving this process to another cgroup because of restore
// with '--manage-cgroups=ignore'. The process should be
// now in cgroup of the current session.
lseek(fd, 0, SEEK_SET);
memset(buffer_old, 0, PAGE_SIZE);
if (read_all(fd, buffer_old, PAGE_SIZE)) {
pr_err("Could not read data from /proc/self/cgroup\n");
goto err;
}
// Test if /proc/self/cgroup has changed again
if (!memcmp(buffer_new, buffer_old, PAGE_SIZE)) {
fail("/proc/self/cgroup should differ after restore");
pr_err("original /proc/self/cgroup content %s\n", buffer_new);
pr_err("new /proc/self/cgroup content %s\n", buffer_old);
goto err;
}
ret = 0;
pass();
err:
rmdir(destination);
umount(dirname);
return ret;
}

View file

@ -0,0 +1,13 @@
#!/bin/bash
dest=$(mktemp -d cg_ignore.XXXXXX)
trap 'rmdir "$dest"' EXIT
if ! mount -t cgroup2 none "$dest"; then
exit 1
fi
umount "$dest"
exit 0

View file

@ -0,0 +1 @@
{'flavor': 'h', 'flags': 'suid excl', 'ropts': '--manage-cgroups=ignore'}