diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a092714fed..c302bacf6d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1188,6 +1188,7 @@ virCgroupNewIOThread; virCgroupNewMachine; virCgroupNewPartition; virCgroupNewSelf; +virCgroupNewThread; virCgroupNewVcpu; virCgroupPathOfController; virCgroupRemove; diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index 00c0bab490..f53319db6d 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -1421,6 +1421,67 @@ virCgroupNewDomainPartition(virCgroupPtr partition, } +/** + * virCgroupNewThread: + * + * @domain: group for the domain + * @name: enum to generate the name for the new thread + * @id: id of the vcpu or iothread + * @create: true to create if not already existing + * @group: Pointer to returned virCgroupPtr + * + * Returns 0 on success, or -1 on error + */ +int +virCgroupNewThread(virCgroupPtr domain, + virCgroupThreadName nameval, + int id, + bool create, + virCgroupPtr *group) +{ + int ret = -1; + char *name = NULL; + int controllers; + + switch (nameval) { + case VIR_CGROUP_THREAD_VCPU: + if (virAsprintf(&name, "vcpu%d", id) < 0) + goto cleanup; + break; + case VIR_CGROUP_THREAD_EMULATOR: + if (VIR_STRDUP(name, "emulator") < 0) + goto cleanup; + break; + case VIR_CGROUP_THREAD_IOTHREAD: + if (virAsprintf(&name, "iothread%d", id) < 0) + goto cleanup; + break; + case VIR_CGROUP_THREAD_LAST: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected name value %d"), nameval); + goto cleanup; + } + + controllers = ((1 << VIR_CGROUP_CONTROLLER_CPU) | + (1 << VIR_CGROUP_CONTROLLER_CPUACCT) | + (1 << VIR_CGROUP_CONTROLLER_CPUSET)); + + if (virCgroupNew(-1, name, domain, controllers, group) < 0) + goto cleanup; + + if (virCgroupMakeGroup(domain, *group, create, VIR_CGROUP_NONE) < 0) { + virCgroupRemove(*group); + virCgroupFree(group); + goto cleanup; + } + + ret = 0; + cleanup: + VIR_FREE(name); + return ret; +} + + /** * virCgroupNewVcpu: * @@ -4079,6 +4140,19 @@ virCgroupNewDomainPartition(virCgroupPtr partition ATTRIBUTE_UNUSED, } +int +virCgroupNewThread(virCgroupPtr domain ATTRIBUTE_UNUSED, + virCgroupThreadName nameval ATTRIBUTE_UNUSED, + int id ATTRIBUTE_UNUSED, + bool create ATTRIBUTE_UNUSED, + virCgroupPtr *group ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENXIO, "%s", + _("Control groups not supported on this platform")); + return -1; +} + + int virCgroupNewVcpu(virCgroupPtr domain ATTRIBUTE_UNUSED, int vcpuid ATTRIBUTE_UNUSED, diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h index 5d6356d7b9..7b57afc740 100644 --- a/src/util/vircgroup.h +++ b/src/util/vircgroup.h @@ -52,6 +52,14 @@ VIR_ENUM_DECL(virCgroupController); * Make sure we will not overflow */ verify(VIR_CGROUP_CONTROLLER_LAST < 8 * sizeof(int)); +typedef enum { + VIR_CGROUP_THREAD_VCPU = 0, + VIR_CGROUP_THREAD_EMULATOR, + VIR_CGROUP_THREAD_IOTHREAD, + + VIR_CGROUP_THREAD_LAST +} virCgroupThreadName; + bool virCgroupAvailable(void); int virCgroupNewPartition(const char *path, @@ -70,6 +78,13 @@ int virCgroupNewDomainPartition(virCgroupPtr partition, virCgroupPtr *group) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5); +int virCgroupNewThread(virCgroupPtr domain, + virCgroupThreadName nameval, + int id, + bool create, + virCgroupPtr *group) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(5); + int virCgroupNewVcpu(virCgroupPtr domain, int vcpuid, bool create,