Index: systemd-215/src/shared/cgroup-util.c
===
--- systemd-215.orig/src/shared/cgroup-util.c
+++ systemd-215/src/shared/cgroup-util.c
@@ -1620,7 +1620,14 @@ static const char mask_names[] =
"cpuacct\0"
"blkio\0"
"memory\0"
-"devices\0";
+"devices\0"
+"hugetlb\0"
+"cpuset\0"
+"net_cls\0"
+"net_prio\0"
+"freezer\0"
+"perf_event\0"
+"pids\0";
int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask mask, const char *path) {
CGroupControllerMask bit = 1;
Index: systemd-215/src/shared/cgroup-util.h
===
--- systemd-215.orig/src/shared/cgroup-util.h
+++ systemd-215/src/shared/cgroup-util.h
@@ -30,11 +30,19 @@
/* A bit mask of well known cgroup controllers */
typedef enum CGroupControllerMask {
-CGROUP_CPU = 1,
-CGROUP_CPUACCT = 2,
-CGROUP_BLKIO = 4,
-CGROUP_MEMORY = 8,
-CGROUP_DEVICE = 16
+CGROUP_CPU = (1 << 0),
+CGROUP_CPUACCT = (1 << 1),
+CGROUP_BLKIO = (1 << 2),
+CGROUP_MEMORY = (1 << 3),
+CGROUP_DEVICE = (1 << 4),
+CGROUP_HUGETLB = (1 << 5),
+CGROUP_CPUSET = (1 << 6),
+CGROUP_NET_CLS = (1 << 7),
+CGROUP_NET_PRIO = (1 << 8),
+CGROUP_FREEZER = (1 << 9),
+CGROUP_PERF_EVENT = (1 << 10),
+CGROUP_PIDS = (1 << 11),
+_CGROUP_CONTROLLER_MASK_ALL = (1 << 12) - 1
} CGroupControllerMask;
/*
Index: systemd-215/src/core/cgroup.c
===
--- systemd-215.orig/src/core/cgroup.c
+++ systemd-215/src/core/cgroup.c
@@ -947,6 +947,10 @@ int manager_setup_cgroup(Manager *m) {
/* 7. Always enable hierarchial support if it exists... */
cg_set_attribute("memory", "/", "memory.use_hierarchy", "1");
+/* 8. Enable conf copying of cpuset attributes to children, so
+ * that we can actually attach processes to cpuset */
+cg_set_attribute("cpuset", "/", "cgroup.clone_children", "1");
+
return 0;
}
Index: systemd-215/src/core/cgroup.c
===
--- systemd-215.orig/src/core/cgroup.c
+++ systemd-215/src/core/cgroup.c
@@ -609,6 +609,13 @@ static int unit_create_cgroups(Unit *u,
if (!path)
return log_oom();
+log_debug("unit_create_cgroups %s: path=%s realized %i hashmap %p", u->id, path, u->cgroup_realized, hashmap_get(u->manager->cgroup_unit, path));
+
+if (hashmap_get(u->manager->cgroup_unit, path)) {
+log_warning("unit_create_cgroups %s: cgroup %s exists already", u->id, u->cgroup_path);
+return 0;
+}
+
r = hashmap_put(u->manager->cgroup_unit, path, u);
if (r < 0) {
log_error(r == -EEXIST ? "cgroup %s exists already: %s" : "hashmap_put failed for %s: %s", path, strerror(-r));
Index: systemd-215/src/core/cgroup.c
===
--- systemd-215.orig/src/core/cgroup.c
+++ systemd-215/src/core/cgroup.c
@@ -651,6 +651,20 @@ int unit_attach_pids_to_cgroup(Unit *u)
if (r < 0)
return r;
+/* put logind sessions into all controllers, for LXC user containers */
+if (UNIT_ISSET(u->slice) && startswith(UNIT_DEREF(u->slice)->id, "user-")) {
+long uid = atol(UNIT_DEREF(u->slice)->id + 5); /* FIXME: Eww! Is there a better way to get the UID? */
+if (uid > 0) {
+r = cg_create_everywhere_uid(u->manager->cgroup_supported,
+ u->manager->cgroup_supported,
+ u->cgroup_path, (uid_t) uid);
+if (r < 0)
+log_warning_unit(u->id, "Cannot create cgroup controllers for %s: %s", u->id, strerror(-r));
+} else {
+log_warning_unit(u->id, "Cannot determine UID from slice %s", UNIT_DEREF(u->slice)->id);
+}
+}
+
r = cg_attach_many_everywhere(u->manager->cgroup_supported, u->cgroup_path, u->pids, migrate_callback, u);
if (r < 0)
return r;
Index: systemd-215/src/shared/cgroup-util.c
===
--- systemd-215.orig/src/shared/cgroup-util.c
+++ systemd-215/src/shared/cgroup-util.c
@@ -609,6 +609,27 @@ int cg_create(const char *controller, co
return 1;
}
+int cg_create_uid(const char *controller, const char *path, uid_t uid) {
+_cleanup_free_ char *fs = NULL;
+int r;
+
+r = cg_get_path_and_check(controller, path,