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, NULL, &fs);
+        if (r < 0)
+                return r;
+
+        r = mkdir_parents(fs, 0755);
+        if (r < 0)
+                return r;
+
+        if (mkdir(fs, 0755) < 0 && errno != EEXIST)
+                return -errno;
+
+        if (chown(fs, uid, (gid_t) -1) < 0)
+                return -errno;
+
+        return 1;
+}
+
 int cg_create_and_attach(const char *controller, const char *path, pid_t pid) {
         int r, q;
 
@@ -1622,6 +1643,33 @@ int cg_create_everywhere(CGroupControlle
 
                 bit <<= 1;
         }
+
+        return 0;
+}
+
+int cg_create_everywhere_uid(CGroupControllerMask supported, CGroupControllerMask mask, const char *path, uid_t uid) {
+        CGroupControllerMask bit = 1;
+        const char *n;
+        int r;
+
+        /* This one will create a cgroup in our private tree, but also
+         * duplicate it in the trees specified in mask, and remove it
+         * in all others */
+
+        /* First create the cgroup in our own hierarchy. */
+        r = cg_create(SYSTEMD_CGROUP_CONTROLLER, path);
+        if (r < 0)
+                return r;
+
+        /* Then, do the same in the other hierarchies */
+        NULSTR_FOREACH(n, mask_names) {
+                if (mask & bit)
+                        cg_create_uid(n, path, uid);
+                else if (supported & bit)
+                        cg_trim(n, path, true);
+
+                bit <<= 1;
+        }
 
         return 0;
 }
Index: systemd-215/src/shared/cgroup-util.h
===================================================================
--- systemd-215.orig/src/shared/cgroup-util.h
+++ systemd-215/src/shared/cgroup-util.h
@@ -79,6 +79,7 @@ int cg_rmdir(const char *controller, con
 int cg_delete(const char *controller, const char *path);
 
 int cg_create(const char *controller, const char *path);
+int cg_create_uid(const char *controller, const char *path, uid_t uid);
 int cg_attach(const char *controller, const char *path, pid_t pid);
 int cg_attach_fallback(const char *controller, const char *path, pid_t pid);
 int cg_create_and_attach(const char *controller, const char *path, pid_t pid);
@@ -125,6 +126,7 @@ int cg_slice_to_path(const char *unit, c
 typedef const char* (*cg_migrate_callback_t)(CGroupControllerMask mask, void *userdata);
 
 int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask mask, const char *path);
+int cg_create_everywhere_uid(CGroupControllerMask supported, CGroupControllerMask mask, const char *path, uid_t uid);
 int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid, cg_migrate_callback_t callback, void *userdata);
 int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids, cg_migrate_callback_t callback, void *userdata);
 int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to, cg_migrate_callback_t callback, void *userdata);

Reply via email to