|
|
c480ed |
From 4a7aa0ff6839fd9ccefce19d63c48beed32ee7f1 Mon Sep 17 00:00:00 2001
|
|
|
c480ed |
Message-Id: <4a7aa0ff6839fd9ccefce19d63c48beed32ee7f1@dist-git>
|
|
|
c480ed |
From: Pavel Hrdina <phrdina@redhat.com>
|
|
|
c480ed |
Date: Mon, 1 Jul 2019 17:07:25 +0200
|
|
|
c480ed |
Subject: [PATCH] vircgroup: introduce virCgroupV2MakeGroup
|
|
|
c480ed |
MIME-Version: 1.0
|
|
|
c480ed |
Content-Type: text/plain; charset=UTF-8
|
|
|
c480ed |
Content-Transfer-Encoding: 8bit
|
|
|
c480ed |
|
|
|
c480ed |
When creating cgroup hierarchy we need to enable controllers in the
|
|
|
c480ed |
parent cgroup in order to be usable. That means writing "+{controller}"
|
|
|
c480ed |
into cgroup.subtree_control file. We can enable only controllers that
|
|
|
c480ed |
are enabled for parent cgroup, that means we need to do that for the
|
|
|
c480ed |
whole cgroup tree.
|
|
|
c480ed |
|
|
|
c480ed |
Cgroups for threads needs to be handled differently in cgroup v2. There
|
|
|
c480ed |
are two types of controllers:
|
|
|
c480ed |
|
|
|
c480ed |
- domain controllers: these cannot be enabled for threads
|
|
|
c480ed |
- threaded controllers: these can be enabled for threads
|
|
|
c480ed |
|
|
|
c480ed |
In addition there are multiple types of cgroups:
|
|
|
c480ed |
|
|
|
c480ed |
- domain: normal cgroup
|
|
|
c480ed |
- domain threaded: a domain cgroup that serves as root for threaded
|
|
|
c480ed |
cgroups
|
|
|
c480ed |
- domain invalid: invalid cgroup, can be changed into threaded, this
|
|
|
c480ed |
is the default state if you create subgroup inside
|
|
|
c480ed |
domain threaded group or threaded group
|
|
|
c480ed |
- threaded: threaded cgroup which can have domain threaded or
|
|
|
c480ed |
threaded as parent group
|
|
|
c480ed |
|
|
|
c480ed |
In order to create threaded cgroup it's sufficient to write "threaded"
|
|
|
c480ed |
into cgroup.type file, it will automatically make parent cgroup
|
|
|
c480ed |
"domain threaded" if it was only "domain". In case the parent cgroup
|
|
|
c480ed |
is already "domain threaded" or "threaded" it will modify only the type
|
|
|
c480ed |
of current cgroup. After that we can enable threaded controllers.
|
|
|
c480ed |
|
|
|
c480ed |
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
|
|
|
c480ed |
(cherry picked from commit 89f52abd07d3f991ddd22990e5d61338ff350a99)
|
|
|
c480ed |
|
|
|
c480ed |
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297
|
|
|
c480ed |
|
|
|
c480ed |
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
|
|
|
c480ed |
Message-Id: <165b3b0f0fd1e5a4b52e4b9e86e4137b3598f7ee.1561993100.git.phrdina@redhat.com>
|
|
|
c480ed |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
c480ed |
---
|
|
|
c480ed |
src/util/vircgroup.c | 2 +-
|
|
|
c480ed |
src/util/vircgroupbackend.h | 1 +
|
|
|
c480ed |
src/util/vircgroupv2.c | 76 +++++++++++++++++++++++++++++++++++++
|
|
|
c480ed |
3 files changed, 78 insertions(+), 1 deletion(-)
|
|
|
c480ed |
|
|
|
c480ed |
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
|
|
|
c480ed |
index 42930582db..a859628241 100644
|
|
|
c480ed |
--- a/src/util/vircgroup.c
|
|
|
c480ed |
+++ b/src/util/vircgroup.c
|
|
|
c480ed |
@@ -942,7 +942,7 @@ virCgroupNewThread(virCgroupPtr domain,
|
|
|
c480ed |
if (virCgroupNew(-1, name, domain, controllers, group) < 0)
|
|
|
c480ed |
return -1;
|
|
|
c480ed |
|
|
|
c480ed |
- if (virCgroupMakeGroup(domain, *group, create, VIR_CGROUP_NONE) < 0) {
|
|
|
c480ed |
+ if (virCgroupMakeGroup(domain, *group, create, VIR_CGROUP_THREAD) < 0) {
|
|
|
c480ed |
virCgroupFree(group);
|
|
|
c480ed |
return -1;
|
|
|
c480ed |
}
|
|
|
c480ed |
diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h
|
|
|
c480ed |
index b1f19233e4..86d1539e07 100644
|
|
|
c480ed |
--- a/src/util/vircgroupbackend.h
|
|
|
c480ed |
+++ b/src/util/vircgroupbackend.h
|
|
|
c480ed |
@@ -33,6 +33,7 @@ typedef enum {
|
|
|
c480ed |
* before creating subcgroups and
|
|
|
c480ed |
* attaching tasks
|
|
|
c480ed |
*/
|
|
|
c480ed |
+ VIR_CGROUP_THREAD = 1 << 1, /* cgroup v2 handles threads differently */
|
|
|
c480ed |
} virCgroupBackendFlags;
|
|
|
c480ed |
|
|
|
c480ed |
typedef enum {
|
|
|
c480ed |
diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
|
|
|
c480ed |
index 6695901766..cf8bd01317 100644
|
|
|
c480ed |
--- a/src/util/vircgroupv2.c
|
|
|
c480ed |
+++ b/src/util/vircgroupv2.c
|
|
|
c480ed |
@@ -338,6 +338,81 @@ virCgroupV2PathOfController(virCgroupPtr group,
|
|
|
c480ed |
}
|
|
|
c480ed |
|
|
|
c480ed |
|
|
|
c480ed |
+static int
|
|
|
c480ed |
+virCgroupV2EnableController(virCgroupPtr parent,
|
|
|
c480ed |
+ int controller)
|
|
|
c480ed |
+{
|
|
|
c480ed |
+ VIR_AUTOFREE(char *) val = NULL;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ if (virAsprintf(&val, "+%s",
|
|
|
c480ed |
+ virCgroupV2ControllerTypeToString(controller)) < 0) {
|
|
|
c480ed |
+ return -1;
|
|
|
c480ed |
+ }
|
|
|
c480ed |
+
|
|
|
c480ed |
+ if (virCgroupSetValueStr(parent, controller,
|
|
|
c480ed |
+ "cgroup.subtree_control", val) < 0) {
|
|
|
c480ed |
+ return -1;
|
|
|
c480ed |
+ }
|
|
|
c480ed |
+
|
|
|
c480ed |
+ return 0;
|
|
|
c480ed |
+}
|
|
|
c480ed |
+
|
|
|
c480ed |
+
|
|
|
c480ed |
+static int
|
|
|
c480ed |
+virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNUSED,
|
|
|
c480ed |
+ virCgroupPtr group,
|
|
|
c480ed |
+ bool create,
|
|
|
c480ed |
+ unsigned int flags)
|
|
|
c480ed |
+{
|
|
|
c480ed |
+ VIR_AUTOFREE(char *) path = NULL;
|
|
|
c480ed |
+ int controller;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ VIR_DEBUG("Make group %s", group->path);
|
|
|
c480ed |
+
|
|
|
c480ed |
+ controller = virCgroupV2GetAnyController(group);
|
|
|
c480ed |
+ if (virCgroupV2PathOfController(group, controller, "", &path) < 0)
|
|
|
c480ed |
+ return -1;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ VIR_DEBUG("Make controller %s", path);
|
|
|
c480ed |
+
|
|
|
c480ed |
+ if (!virFileExists(path) &&
|
|
|
c480ed |
+ (!create || (mkdir(path, 0755) < 0 && errno != EEXIST))) {
|
|
|
c480ed |
+ virReportSystemError(errno, _("Failed to create v2 cgroup '%s'"),
|
|
|
c480ed |
+ group->path);
|
|
|
c480ed |
+ return -1;
|
|
|
c480ed |
+ }
|
|
|
c480ed |
+
|
|
|
c480ed |
+ if (create) {
|
|
|
c480ed |
+ if (flags & VIR_CGROUP_THREAD) {
|
|
|
c480ed |
+ if (virCgroupSetValueStr(group, VIR_CGROUP_CONTROLLER_CPU,
|
|
|
c480ed |
+ "cgroup.type", "threaded") < 0) {
|
|
|
c480ed |
+ return -1;
|
|
|
c480ed |
+ }
|
|
|
c480ed |
+
|
|
|
c480ed |
+ if (virCgroupV2EnableController(parent,
|
|
|
c480ed |
+ VIR_CGROUP_CONTROLLER_CPU) < 0) {
|
|
|
c480ed |
+ return -1;
|
|
|
c480ed |
+ }
|
|
|
c480ed |
+ } else {
|
|
|
c480ed |
+ size_t i;
|
|
|
c480ed |
+ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
|
|
|
c480ed |
+ if (!virCgroupV2HasController(parent, i))
|
|
|
c480ed |
+ continue;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ /* Controllers that are implicitly enabled if available. */
|
|
|
c480ed |
+ if (i == VIR_CGROUP_CONTROLLER_CPUACCT)
|
|
|
c480ed |
+ continue;
|
|
|
c480ed |
+
|
|
|
c480ed |
+ if (virCgroupV2EnableController(parent, i) < 0)
|
|
|
c480ed |
+ return -1;
|
|
|
c480ed |
+ }
|
|
|
c480ed |
+ }
|
|
|
c480ed |
+ }
|
|
|
c480ed |
+
|
|
|
c480ed |
+ return 0;
|
|
|
c480ed |
+}
|
|
|
c480ed |
+
|
|
|
c480ed |
+
|
|
|
c480ed |
virCgroupBackend virCgroupV2Backend = {
|
|
|
c480ed |
.type = VIR_CGROUP_BACKEND_TYPE_V2,
|
|
|
c480ed |
|
|
|
c480ed |
@@ -353,6 +428,7 @@ virCgroupBackend virCgroupV2Backend = {
|
|
|
c480ed |
.hasController = virCgroupV2HasController,
|
|
|
c480ed |
.getAnyController = virCgroupV2GetAnyController,
|
|
|
c480ed |
.pathOfController = virCgroupV2PathOfController,
|
|
|
c480ed |
+ .makeGroup = virCgroupV2MakeGroup,
|
|
|
c480ed |
};
|
|
|
c480ed |
|
|
|
c480ed |
|
|
|
c480ed |
--
|
|
|
c480ed |
2.22.0
|
|
|
c480ed |
|