vircgroup: fix cgroups v2 controllers detection

When creating new group for cgroups v2 the we cannot check
cgroups.controllers for that cgroup because the directory is created
later.  In that case we should check cgroups.subtree_control of parent
group to get list of controllers enabled for child cgroups.

In order to achieve that we will prefer the parent group if it exists,
the current group will be used only for root group.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Acked-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
Pavel Hrdina 2019-07-22 14:37:36 +02:00
parent bd53501f07
commit 7b77f3a11e
4 changed files with 21 additions and 10 deletions

View File

@ -407,7 +407,7 @@ virCgroupDetect(virCgroupPtr group,
for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
if (group->backends[i]) {
int rc = group->backends[i]->detectControllers(group, controllers);
int rc = group->backends[i]->detectControllers(group, controllers, parent);
if (rc < 0)
return -1;
controllersAvailable |= rc;

View File

@ -98,7 +98,8 @@ typedef char *
typedef int
(*virCgroupDetectControllersCB)(virCgroupPtr group,
int controllers);
int controllers,
virCgroupPtr parent);
typedef bool
(*virCgroupHasControllerCB)(virCgroupPtr cgroup,

View File

@ -420,7 +420,8 @@ virCgroupV1StealPlacement(virCgroupPtr group)
static int
virCgroupV1DetectControllers(virCgroupPtr group,
int controllers)
int controllers,
virCgroupPtr parent ATTRIBUTE_UNUSED)
{
size_t i;
size_t j;

View File

@ -242,7 +242,8 @@ virCgroupV2StealPlacement(virCgroupPtr group)
static int
virCgroupV2ParseControllersFile(virCgroupPtr group)
virCgroupV2ParseControllersFile(virCgroupPtr group,
virCgroupPtr parent)
{
int rc;
VIR_AUTOFREE(char *) contStr = NULL;
@ -250,10 +251,17 @@ virCgroupV2ParseControllersFile(virCgroupPtr group)
char **contList = NULL;
char **tmp;
if (virAsprintf(&contFile, "%s%s/cgroup.controllers",
group->unified.mountPoint,
NULLSTR_EMPTY(group->unified.placement)) < 0)
return -1;
if (parent) {
if (virAsprintf(&contFile, "%s%s/cgroup.subtree_control",
parent->unified.mountPoint,
NULLSTR_EMPTY(parent->unified.placement)) < 0)
return -1;
} else {
if (virAsprintf(&contFile, "%s%s/cgroup.controllers",
group->unified.mountPoint,
NULLSTR_EMPTY(group->unified.placement)) < 0)
return -1;
}
rc = virFileReadAll(contFile, 1024 * 1024, &contStr);
if (rc < 0) {
@ -286,11 +294,12 @@ virCgroupV2ParseControllersFile(virCgroupPtr group)
static int
virCgroupV2DetectControllers(virCgroupPtr group,
int controllers)
int controllers,
virCgroupPtr parent)
{
size_t i;
if (virCgroupV2ParseControllersFile(group) < 0)
if (virCgroupV2ParseControllersFile(group, parent) < 0)
return -1;
/* In cgroup v2 there is no cpuacct controller, the cpu.stat file always