diff options
author | Adrian Reber <areber@redhat.com> | 2022-04-02 18:58:25 +0300 |
---|---|---|
committer | Andrei Vagin <avagin@gmail.com> | 2022-04-29 03:53:52 +0300 |
commit | 4adec8e8ef3682186fd21e1b04da3e309e1ddce7 (patch) | |
tree | 2111705439556c8232a7617b06b6b969ca36cb93 /test | |
parent | 2b6901707c883a0d1c1ae4a3b5f70a51e2bf77f3 (diff) |
cgroup: test for --manage-cgroups=ignore
Test to ensure that --manage-cgroups=ignore works correctly.
Signed-off-by: Adrian Reber <areber@redhat.com>
Diffstat (limited to 'test')
-rwxr-xr-x | test/jenkins/crit.sh | 2 | ||||
-rwxr-xr-x | test/jenkins/criu-dump.sh | 2 | ||||
-rw-r--r-- | test/zdtm/lib/zdtmtst.h | 26 | ||||
-rw-r--r-- | test/zdtm/static/Makefile | 1 | ||||
-rw-r--r-- | test/zdtm/static/cgroup_ignore.c | 161 | ||||
-rwxr-xr-x | test/zdtm/static/cgroup_ignore.checkskip | 13 | ||||
-rw-r--r-- | test/zdtm/static/cgroup_ignore.desc | 1 |
7 files changed, 204 insertions, 2 deletions
diff --git a/test/jenkins/crit.sh b/test/jenkins/crit.sh index fcf1c58d4..cec26c2b4 100755 --- a/test/jenkins/crit.sh +++ b/test/jenkins/crit.sh @@ -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 diff --git a/test/jenkins/criu-dump.sh b/test/jenkins/criu-dump.sh index 4c49532b2..761b3de0d 100755 --- a/test/jenkins/criu-dump.sh +++ b/test/jenkins/criu-dump.sh @@ -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 diff --git a/test/zdtm/lib/zdtmtst.h b/test/zdtm/lib/zdtmtst.h index 803d33e3d..ed7c23ee2 100644 --- a/test/zdtm/lib/zdtmtst.h +++ b/test/zdtm/lib/zdtmtst.h @@ -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_ */ diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile index 1e7925ca8..de64dd2ed 100644 --- a/test/zdtm/static/Makefile +++ b/test/zdtm/static/Makefile @@ -377,6 +377,7 @@ TST_DIR = \ cgroup03 \ cgroup04 \ cgroup_ifpriomap \ + cgroup_ignore \ cgroup_stray \ cgroup_yard \ unlink_fstat04 \ diff --git a/test/zdtm/static/cgroup_ignore.c b/test/zdtm/static/cgroup_ignore.c new file mode 100644 index 000000000..ca2b30316 --- /dev/null +++ b/test/zdtm/static/cgroup_ignore.c @@ -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; +} diff --git a/test/zdtm/static/cgroup_ignore.checkskip b/test/zdtm/static/cgroup_ignore.checkskip new file mode 100755 index 000000000..7b1d7ced1 --- /dev/null +++ b/test/zdtm/static/cgroup_ignore.checkskip @@ -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 diff --git a/test/zdtm/static/cgroup_ignore.desc b/test/zdtm/static/cgroup_ignore.desc new file mode 100644 index 000000000..3fa9ceb76 --- /dev/null +++ b/test/zdtm/static/cgroup_ignore.desc @@ -0,0 +1 @@ +{'flavor': 'h', 'flags': 'suid excl', 'ropts': '--manage-cgroups=ignore'} |