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);