On Tue, 2018-10-02 at 10:43 +0200, Pavel Hrdina wrote: > When creating cgroup hierarchy we need to enable controllers in the > parent cgroup in order to be usable. That means writing > "+{controller}" > into cgroup.subtree_control file. We can enable only controllers > that > are enabled for parent cgroup, that means we need to do that for the > whole cgroup tree. > > Cgroups for threads needs to be handled differently in cgroup > v2. There > are two types of controllers: > > - domain controllers: these cannot be enabled for threads > - threaded controllers: these can be enabled for threads > > In addition there are multiple types of cgroups: > > - domain: normal cgroup > - domain threaded: a domain cgroup that serves as root for > threaded > cgroups > - domain invalid: invalid cgroup, can be changed into threaded, > this > is the default state if you create subgroup > inside > domain threaded group or threaded group > - threaded: threaded cgroup which can have domain threaded or > threaded as parent group > > In order to create threaded cgroup it's sufficient to write > "threaded" > into cgroup.type file, it will automatically make parent cgroup > "domain threaded" if it was only "domain". In case the parent cgroup > is already "domain threaded" or "threaded" it will modify only the > type > of current cgroup. After that we can enable threaded controllers. > > Signed-off-by: Pavel Hrdina <phrdina@xxxxxxxxxx> > --- > src/util/vircgroup.c | 2 +- > src/util/vircgroupbackend.h | 1 + > src/util/vircgroupv2.c | 78 > +++++++++++++++++++++++++++++++++++++ > 3 files changed, 80 insertions(+), 1 deletion(-) > > diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c > index 1097b1f998..dc249bfe33 100644 > --- a/src/util/vircgroup.c > +++ b/src/util/vircgroup.c > @@ -938,7 +938,7 @@ virCgroupNewThread(virCgroupPtr domain, > if (virCgroupNew(-1, name, domain, controllers, group) < 0) > return -1; > > - if (virCgroupMakeGroup(domain, *group, create, VIR_CGROUP_NONE) > < 0) { > + if (virCgroupMakeGroup(domain, *group, create, > VIR_CGROUP_THREAD) < 0) { > virCgroupFree(group); > return -1; > } > diff --git a/src/util/vircgroupbackend.h > b/src/util/vircgroupbackend.h > index b1f19233e4..86d1539e07 100644 > --- a/src/util/vircgroupbackend.h > +++ b/src/util/vircgroupbackend.h > @@ -33,6 +33,7 @@ typedef enum { > * before creating subcgroups > and > * attaching tasks > */ > + VIR_CGROUP_THREAD = 1 << 1, /* cgroup v2 handles threads > differently */ > } virCgroupBackendFlags; > > typedef enum { > diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c > index 3ca463e4c2..8fb9ace474 100644 > --- a/src/util/vircgroupv2.c > +++ b/src/util/vircgroupv2.c > @@ -336,6 +336,83 @@ virCgroupV2PathOfController(virCgroupPtr group, > } > > > +static int > +virCgroupV2EnableController(virCgroupPtr parent, > + int controller) > +{ > + VIR_AUTOFREE(char *) val = NULL; > + > + if (virAsprintf(&val, "+%s", > + virCgroupV2ControllerTypeToString(controller)) < > 0) { > + return -1; > + } > + > + if (virCgroupSetValueStr(parent, controller, > + "cgroup.subtree_control", val) < 0) { > + return -1; > + } > + > + return 0; > +} > + > + > +static int > +virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNUSED, > + virCgroupPtr group, > + bool create, > + unsigned int flags) > +{ > + VIR_AUTOFREE(char *) path = NULL; > + int controller; > + > + VIR_DEBUG("Make group %s", group->path); > + > + controller = virCgroupV2GetAnyController(group); > + if (virCgroupV2PathOfController(group, controller, "", &path) < > 0) > + return -1; > + > + VIR_DEBUG("Make controller %s", path); > + > + if (!virFileExists(path)) { > + if (!create || mkdir(path, 0755 || errno == EEXIST) < 0) { The `mdkir(path, 0755 || errno == EEXIST) < 0` part of the check doesn't look right. -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list