VIR_ENUM_IMPL(virCgroupController, VIR_CGROUP_CONTROLLER_LAST,
"cpu", "cpuacct", "cpuset", "memory", "devices",
- "freezer", "blkio", "net_cls", "perf_event");
+ "freezer", "blkio", "net_cls", "perf_event",
+ "name=systemd");
typedef enum {
VIR_CGROUP_NONE = 0, /* create subdir under each cgroup if possible. */
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
char *tmp;
+ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD)
+ continue;
+
if (!group->controllers[i].placement)
continue;
if (!group->controllers[i].mountPoint)
continue;
+ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD)
+ continue;
+
if (path[0] == '/') {
if (VIR_STRDUP(group->controllers[i].placement, path) < 0)
return -1;
int ret = -1;
char *procfile;
+ VIR_DEBUG("Detecting placement for pid %lld path %s",
+ (unsigned long long)pid, path);
if (pid == -1) {
if (VIR_STRDUP(procfile, "/proc/self/cgroup") < 0)
goto cleanup;
const char *typestr = virCgroupControllerTypeToString(i);
int typelen = strlen(typestr);
char *tmp = controllers;
+
while (tmp) {
char *next = strchr(tmp, ',');
int len;
* selfpath=="/libvirt.service" + path="foo" -> "/libvirt.service/foo"
*/
if (typelen == len && STREQLEN(typestr, tmp, len) &&
- group->controllers[i].mountPoint != NULL) {
- if (virAsprintf(&group->controllers[i].placement,
- "%s%s%s", selfpath,
- (STREQ(selfpath, "/") ||
- STREQ(path, "") ? "" : "/"),
- path) < 0)
- goto cleanup;
+ group->controllers[i].mountPoint != NULL &&
+ group->controllers[i].placement == NULL) {
+ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) {
+ if (VIR_STRDUP(group->controllers[i].placement,
+ selfpath) < 0)
+ goto cleanup;
+ } else {
+ if (virAsprintf(&group->controllers[i].placement,
+ "%s%s%s", selfpath,
+ (STREQ(selfpath, "/") ||
+ STREQ(path, "") ? "" : "/"),
+ path) < 0)
+ goto cleanup;
+ }
}
tmp = next;
return -1;
}
- if (parent || path[0] == '/') {
- if (virCgroupCopyPlacement(group, path, parent) < 0)
- return -1;
- } else {
- if (virCgroupDetectPlacement(group, pid, path) < 0)
- return -1;
- }
+ /* In some cases we can copy part of the placement info
+ * based on the parent cgroup...
+ */
+ if ((parent || path[0] == '/') &&
+ virCgroupCopyPlacement(group, path, parent) < 0)
+ return -1;
+
+ /* ... but use /proc/cgroups to fill in the rest */
+ if (virCgroupDetectPlacement(group, pid, path) < 0)
+ return -1;
/* Check that for every mounted controller, we found our placement */
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
char *path = NULL;
+ /* We must never mkdir() in systemd's hierarchy */
+ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) {
+ VIR_DEBUG("Not creating systemd controller group");
+ continue;
+ }
+
/* Skip over controllers that aren't mounted */
if (!group->controllers[i].mountPoint) {
VIR_DEBUG("Skipping unmounted controller %s",
if (!group->controllers[i].mountPoint)
continue;
+ /* We must never rmdir() in systemd's hierarchy */
+ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD)
+ continue;
+
/* Don't delete the root group, if we accidentally
ended up in it for some reason */
if (STREQ(group->controllers[i].placement, "/"))
if (!group->controllers[i].mountPoint)
continue;
+ /* We must never add tasks in systemd's hierarchy */
+ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD)
+ continue;
+
if (virCgroupSetValueU64(group, i, "tasks", (unsigned long long)pid) < 0)
goto cleanup;
}
!dest_group->controllers[i].mountPoint)
continue;
+ /* We must never move tasks in systemd's hierarchy */
+ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD)
+ continue;
+
/* New threads are created in the same group as their parent;
* but if a thread is created after we first read we aren't
* aware that it needs to move. Therefore, we must iterate
[VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
[VIR_CGROUP_CONTROLLER_FREEZER] = NULL,
[VIR_CGROUP_CONTROLLER_BLKIO] = NULL,
+ [VIR_CGROUP_CONTROLLER_SYSTEMD] = NULL,
};
const char *mountsFull[VIR_CGROUP_CONTROLLER_LAST] = {
[VIR_CGROUP_CONTROLLER_CPU] = "/not/really/sys/fs/cgroup/cpu,cpuacct",
[VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
[VIR_CGROUP_CONTROLLER_FREEZER] = "/not/really/sys/fs/cgroup/freezer",
[VIR_CGROUP_CONTROLLER_BLKIO] = "/not/really/sys/fs/cgroup/blkio",
+ [VIR_CGROUP_CONTROLLER_SYSTEMD] = "/not/really/sys/fs/cgroup/systemd",
};
const char *links[VIR_CGROUP_CONTROLLER_LAST] = {
[VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
[VIR_CGROUP_CONTROLLER_FREEZER] = "/",
[VIR_CGROUP_CONTROLLER_BLKIO] = "/",
+ [VIR_CGROUP_CONTROLLER_SYSTEMD] = "/user/berrange/123",
};
if (virCgroupNewSelf(&cgroup) < 0) {
[VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
[VIR_CGROUP_CONTROLLER_FREEZER] = NULL,
[VIR_CGROUP_CONTROLLER_BLKIO] = NULL,
+ [VIR_CGROUP_CONTROLLER_SYSTEMD] = NULL,
};
const char *placementFull[VIR_CGROUP_CONTROLLER_LAST] = {
[VIR_CGROUP_CONTROLLER_CPU] = "/virtualmachines.partition",
[VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
[VIR_CGROUP_CONTROLLER_FREEZER] = "/virtualmachines.partition",
[VIR_CGROUP_CONTROLLER_BLKIO] = "/virtualmachines.partition",
+ [VIR_CGROUP_CONTROLLER_SYSTEMD] = "/user/berrange/123",
};
if ((rv = virCgroupNewPartition("/virtualmachines", false, -1, &cgroup)) != -1) {
[VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
[VIR_CGROUP_CONTROLLER_FREEZER] = "/deployment.partition/production.partition",
[VIR_CGROUP_CONTROLLER_BLKIO] = "/deployment.partition/production.partition",
+ [VIR_CGROUP_CONTROLLER_SYSTEMD] = "/user/berrange/123",
};
if ((rv = virCgroupNewPartition("/deployment/production", false, -1, &cgroup)) != -1) {
[VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
[VIR_CGROUP_CONTROLLER_FREEZER] = "/user/berrange.user/production.partition",
[VIR_CGROUP_CONTROLLER_BLKIO] = "/user/berrange.user/production.partition",
+ [VIR_CGROUP_CONTROLLER_SYSTEMD] = "/user/berrange/123",
};
if ((rv = virCgroupNewPartition("/user/berrange.user/production", false, -1, &cgroup)) != -1) {
[VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
[VIR_CGROUP_CONTROLLER_FREEZER] = "/production.partition/foo.libvirt-lxc",
[VIR_CGROUP_CONTROLLER_BLKIO] = "/production.partition/foo.libvirt-lxc",
+ [VIR_CGROUP_CONTROLLER_SYSTEMD] = "/user/berrange/123",
};
if ((rv = virCgroupNewPartition("/production", true, -1, &partitioncgroup)) != 0) {
[VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
[VIR_CGROUP_CONTROLLER_FREEZER] = "/_cgroup.evil/net_cls.evil/__evil.evil/_cpu.foo.libvirt-lxc",
[VIR_CGROUP_CONTROLLER_BLKIO] = "/_cgroup.evil/net_cls.evil/__evil.evil/_cpu.foo.libvirt-lxc",
+ [VIR_CGROUP_CONTROLLER_SYSTEMD] = "/user/berrange/123",
};
if ((rv = virCgroupNewPartition("/cgroup.evil", true, -1, &partitioncgroup1)) != 0) {