When we create a new child cgroup and the parent cgroup has any process
attached to it enabling controllers for the child cgroup fails with
error. We need to move the process into the child cgroup first before
enabling any controllers.
Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
src/util/vircgroup.c | 11 ++++++-----
src/util/vircgroupbackend.h | 1 +
src/util/vircgroupv1.c | 1 +
src/util/vircgroupv2.c | 13 +++++++++++++
4 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 7a0e14eb73..44a3064876 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -694,13 +694,14 @@ static int
virCgroupMakeGroup(virCgroupPtr parent,
virCgroupPtr group,
bool create,
+ pid_t pid,
unsigned int flags)
{
size_t i;
for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
if (group->backends[i] &&
- group->backends[i]->makeGroup(parent, group, create, flags) < 0) {
+ group->backends[i]->makeGroup(parent, group, create, pid, flags) <
0) {
virCgroupRemove(group);
return -1;
}
@@ -970,7 +971,7 @@ virCgroupNewPartition(const char *path,
return -1;
if (parent) {
- if (virCgroupMakeGroup(parent, newGroup, create, VIR_CGROUP_NONE) < 0)
+ if (virCgroupMakeGroup(parent, newGroup, create, -1, VIR_CGROUP_NONE) < 0)
return -1;
}
@@ -1033,7 +1034,7 @@ virCgroupNewDomainPartition(virCgroupPtr partition,
* a group for driver, is to avoid overhead to track
* cumulative usage that we don't need.
*/
- if (virCgroupMakeGroup(partition, newGroup, true,
+ if (virCgroupMakeGroup(partition, newGroup, true, -1,
VIR_CGROUP_MEM_HIERACHY) < 0) {
return -1;
}
@@ -1090,7 +1091,7 @@ virCgroupNewThread(virCgroupPtr domain,
if (virCgroupNewFromParent(domain, name, controllers, &newGroup) < 0)
return -1;
- if (virCgroupMakeGroup(domain, newGroup, create, VIR_CGROUP_THREAD) < 0)
+ if (virCgroupMakeGroup(domain, newGroup, create, -1, VIR_CGROUP_THREAD) < 0)
return -1;
*group = g_steal_pointer(&newGroup);
@@ -1192,7 +1193,7 @@ virCgroupEnableMissingControllers(char *path,
&tmp) < 0)
return -1;
- if (virCgroupMakeGroup(parent, tmp, true, VIR_CGROUP_SYSTEMD) < 0)
+ if (virCgroupMakeGroup(parent, tmp, true, -1, VIR_CGROUP_SYSTEMD) < 0)
return -1;
virCgroupFree(parent);
diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h
index 4ca2e38af2..497dde5625 100644
--- a/src/util/vircgroupbackend.h
+++ b/src/util/vircgroupbackend.h
@@ -122,6 +122,7 @@ typedef int
(*virCgroupMakeGroupCB)(virCgroupPtr parent,
virCgroupPtr group,
bool create,
+ pid_t pid,
unsigned int flags);
typedef int
diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c
index f4dd20fd73..51ada12f6e 100644
--- a/src/util/vircgroupv1.c
+++ b/src/util/vircgroupv1.c
@@ -622,6 +622,7 @@ static int
virCgroupV1MakeGroup(virCgroupPtr parent,
virCgroupPtr group,
bool create,
+ pid_t pid G_GNUC_UNUSED,
unsigned int flags)
{
size_t i;
diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
index 3f3e5ac83d..d590f83187 100644
--- a/src/util/vircgroupv2.c
+++ b/src/util/vircgroupv2.c
@@ -406,10 +406,17 @@ virCgroupV2EnableController(virCgroupPtr group,
}
+static int
+virCgroupV2AddTask(virCgroupPtr group,
+ pid_t pid,
+ unsigned int flags);
+
+
static int
virCgroupV2MakeGroup(virCgroupPtr parent,
virCgroupPtr group,
bool create,
+ pid_t pid,
unsigned int flags)
{
g_autofree char *path = NULL;
@@ -455,6 +462,12 @@ virCgroupV2MakeGroup(virCgroupPtr parent,
}
} else {
size_t i;
+
+ if (pid > 0) {
+ if (virCgroupV2AddTask(group, pid, VIR_CGROUP_TASK_PROCESS) < 0)
+ return -1;
+ }
+
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
int rc;
--
2.29.2