From 5b4d8244ee6361111903a956843b03739f006b4a Mon Sep 17 00:00:00 2001 Message-Id: <5b4d8244ee6361111903a956843b03739f006b4a@dist-git> From: Pavel Hrdina Date: Mon, 1 Jul 2019 17:07:55 +0200 Subject: [PATCH] vircgroupmock: add support to test cgroup v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to create the cgroup v2 sysfs the same way as we do for cgroup v1. This introduces new VIR_CGROUP_MOCK_MODE env variable which will configure which cgroup mode each test requires. There are three different modes: - legacy: only cgroup v1 is available and it's the default mode - hybrid: both cgroup v1 and cgroup v2 are available and have some controllers - unified: only cgroup v2 is available Signed-off-by: Pavel Hrdina (cherry picked from commit 61ff6021d842a3baf2f6cbc3f37dd272f6c86563) Conflicts: src/util/vircgroupv2.c: missing commit c0abcca417 Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 Signed-off-by: Pavel Hrdina Message-Id: <26937fa61f83f373ff46d4a7d6cc8cb2dfd3c66d.1561993100.git.phrdina@redhat.com> Reviewed-by: Ján Tomko --- tests/vircgroupmock.c | 162 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 147 insertions(+), 15 deletions(-) diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c index fcc00a7a7b..2041b1e970 100644 --- a/tests/vircgroupmock.c +++ b/tests/vircgroupmock.c @@ -36,6 +36,7 @@ # include # include "testutilslxc.h" +# include "viralloc.h" # include "virstring.h" # include "virfile.h" @@ -107,7 +108,8 @@ static int make_file(const char *path, return ret; } -static int make_controller(const char *path, mode_t mode) + +static int make_controller_v1(const char *path, mode_t mode) { int ret = -1; const char *controller; @@ -233,11 +235,86 @@ static int make_controller(const char *path, mode_t mode) goto cleanup; } +# undef MAKE_FILE + ret = 0; cleanup: return ret; } + +static int make_controller_v2(const char *path, mode_t mode) +{ + if (!STRPREFIX(path, fakesysfscgroupdir)) { + errno = EINVAL; + return -1; + } + + if (real_mkdir(path, mode) < 0 && errno != EEXIST) + return -1; + +# define MAKE_FILE(name, value) \ + do { \ + if (make_file(path, name, value) < 0) \ + return -1; \ + } while (0) + + MAKE_FILE("cgroup.controllers", "cpu io memory\n"); + MAKE_FILE("cgroup.subtree_control", ""); + MAKE_FILE("cgroup.type", "domain\n"); + MAKE_FILE("cpu.max", "max 100000\n"); + MAKE_FILE("cpu.stat", + "usage_usec 0\n" + "user_usec 0\n" + "system_usec 0\n" + "nr_periods 0\n" + "nr_throttled 0\n" + "throttled_usec 0\n"); + MAKE_FILE("cpu.weight", "100\n"); + MAKE_FILE("memory.current", "1455321088\n"); + MAKE_FILE("memory.high", "max\n"); + MAKE_FILE("memory.max", "max\n"); + MAKE_FILE("memory.stat", + "anon 0\n" + "file 0\n" + "kernel_stack 0\n" + "slab 0\n" + "sock 0\n" + "shmem 0\n" + "file_mapped 0\n" + "file_dirty 0\n" + "file_writeback 0\n" + "inactive_anon 0\n" + "active_anon 0\n" + "inactive_file 0\n" + "active_file 0\n" + "unevictable 0\n" + "slab_reclaimable 0\n" + "slab_unreclaimable 0\n" + "pgfault 0\n" + "pgmajfault 0\n" + "pgrefill 0\n" + "pgscan 0\n" + "pgsteal 0\n" + "pgactivate 0\n" + "pgdeactivate 0\n" + "pglazyfree 0\n" + "pglazyfreed 0\n" + "workingset_refault 0\n" + "workingset_activate 0\n" + "workingset_nodereclaim 0\n"); + MAKE_FILE("memory.swap.current", "0\n"); + MAKE_FILE("memory.swap.max", "max\n"); + MAKE_FILE("io.stat", "8:0 rbytes=26828800 wbytes=77062144 rios=2256 wios=7849 dbytes=0 dios=0\n"); + MAKE_FILE("io.max", ""); + MAKE_FILE("io.weight", "default 100\n"); + +# undef MAKE_FILE + + return 0; +} + + static void init_syms(void) { if (real_fopen) @@ -251,16 +328,64 @@ static void init_syms(void) VIR_MOCK_REAL_INIT(open); } + +static int make_controller(const char *path, mode_t mode) +{ + const char *mock; + bool unified = false; + bool hybrid = false; + + mock = getenv("VIR_CGROUP_MOCK_MODE"); + if (mock) { + if (STREQ(mock, "unified")) { + unified = true; + } else if (STREQ(mock, "hybrid")) { + hybrid = true; + } else { + fprintf(stderr, "invalid mode '%s'\n", mock); + abort(); + } + } + + if (unified || (hybrid && strstr(path, "unified"))) { + return make_controller_v2(path, mode); + } else { + return make_controller_v1(path, mode); + } +} + + static void init_sysfs(void) { - if (fakerootdir && fakesysfscgroupdir) - return; + const char *mock; + char *newfakerootdir; + bool unified = false; + bool hybrid = false; - if (!(fakerootdir = getenv("LIBVIRT_FAKE_ROOT_DIR"))) { + if (!(newfakerootdir = getenv("LIBVIRT_FAKE_ROOT_DIR"))) { fprintf(stderr, "Missing LIBVIRT_FAKE_ROOT_DIR env variable\n"); abort(); } + if (fakerootdir && STREQ(fakerootdir, newfakerootdir)) + return; + + fakerootdir = newfakerootdir; + + mock = getenv("VIR_CGROUP_MOCK_MODE"); + if (mock) { + if (STREQ(mock, "unified")) { + unified = true; + } else if (STREQ(mock, "hybrid")) { + hybrid = true; + } else { + fprintf(stderr, "invalid mode '%s'\n", mock); + abort(); + } + } + + VIR_FREE(fakesysfscgroupdir); + if (virAsprintfQuiet(&fakesysfscgroupdir, "%s%s", fakerootdir, SYSFS_CGROUP_PREFIX) < 0) abort(); @@ -283,18 +408,25 @@ static void init_sysfs(void) free(path); \ } while (0) - MAKE_CONTROLLER("cpu"); - MAKE_CONTROLLER("cpuacct"); - MAKE_CONTROLLER("cpu,cpuacct"); - MAKE_CONTROLLER("cpu,cpuacct/system"); - MAKE_CONTROLLER("cpuset"); - MAKE_CONTROLLER("blkio"); - MAKE_CONTROLLER("memory"); - MAKE_CONTROLLER("freezer"); + if (unified) { + MAKE_CONTROLLER(""); + } else if (hybrid) { + MAKE_CONTROLLER("unified"); + MAKE_CONTROLLER("cpuset"); + MAKE_CONTROLLER("freezer"); + } else { + MAKE_CONTROLLER("cpu"); + MAKE_CONTROLLER("cpuacct"); + MAKE_CONTROLLER("cpu,cpuacct"); + MAKE_CONTROLLER("cpuset"); + MAKE_CONTROLLER("blkio"); + MAKE_CONTROLLER("memory"); + MAKE_CONTROLLER("freezer"); - if (make_file(fakesysfscgroupdir, - SYSFS_CPU_PRESENT_MOCKED, "8-23,48-159\n") < 0) - abort(); + if (make_file(fakesysfscgroupdir, + SYSFS_CPU_PRESENT_MOCKED, "8-23,48-159\n") < 0) + abort(); + } } -- 2.22.0