From: Pavel Hrdina Date: Tue, 25 Sep 2018 12:37:21 +0000 (+0200) Subject: vircgroup: introduce virCgroupV2DetectControllers X-Git-Tag: v4.9.0-rc1~92 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1bb7fffe2571e6a337bd87a9c5ed487ee6ee046;p=thirdparty%2Flibvirt.git vircgroup: introduce virCgroupV2DetectControllers Cgroup v2 has only single mount point for all controllers. The list of controllers is stored in cgroup.controllers file, name of controllers are separated by space. In cgroup v2 there is no cpuacct controller, the cpu.stat file always exists with usage stats. Signed-off-by: Pavel Hrdina --- diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index c1e7936457..77b6440078 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -32,6 +32,7 @@ #include "vircgroup.h" #include "vircgroupbackend.h" #include "vircgroupv2.h" +#include "virerror.h" #include "virfile.h" #include "virlog.h" #include "virstring.h" @@ -230,6 +231,73 @@ virCgroupV2StealPlacement(virCgroupPtr group) } +static int +virCgroupV2ParseControllersFile(virCgroupPtr group) +{ + int rc; + VIR_AUTOFREE(char *) contStr = NULL; + VIR_AUTOFREE(char *) contFile = NULL; + char **contList = NULL; + char **tmp; + + if (virAsprintf(&contFile, "%s/cgroup.controllers", + group->unified.mountPoint) < 0) + return -1; + + rc = virFileReadAll(contFile, 1024 * 1024, &contStr); + if (rc < 0) { + virReportSystemError(errno, _("Unable to read from '%s'"), contFile); + return -1; + } + + virTrimSpaces(contStr, NULL); + + contList = virStringSplit(contStr, " ", 20); + if (!contList) + return -1; + + tmp = contList; + + while (*tmp) { + int type = virCgroupV2ControllerTypeFromString(*tmp); + + if (type >= 0) + group->unified.controllers |= 1 << type; + + tmp++; + } + + virStringListFree(contList); + + return 0; +} + + +static int +virCgroupV2DetectControllers(virCgroupPtr group, + int controllers) +{ + size_t i; + + if (virCgroupV2ParseControllersFile(group) < 0) + return -1; + + /* In cgroup v2 there is no cpuacct controller, the cpu.stat file always + * exists with usage stats. */ + group->unified.controllers |= 1 << VIR_CGROUP_CONTROLLER_CPUACCT; + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) + VIR_DEBUG("Controller '%s' present=%s", + virCgroupV2ControllerTypeToString(i), + (group->unified.controllers & 1 << i) ? "yes" : "no"); + + if (controllers >= 0) + return controllers & group->unified.controllers; + else + return group->unified.controllers; +} + + virCgroupBackend virCgroupV2Backend = { .type = VIR_CGROUP_BACKEND_TYPE_V2, @@ -241,6 +309,7 @@ virCgroupBackend virCgroupV2Backend = { .detectPlacement = virCgroupV2DetectPlacement, .validatePlacement = virCgroupV2ValidatePlacement, .stealPlacement = virCgroupV2StealPlacement, + .detectControllers = virCgroupV2DetectControllers, };