chiark / gitweb /
binfmt: fix apply loop
[elogind.git] / src / cgroup.c
index e141b4153ddb86292b603814ed9fdc71e951df47..1f6139e25f752176b2d19781c1253c8e608f8dc9 100644 (file)
@@ -60,7 +60,7 @@ int cgroup_bonding_realize_list(CGroupBonding *first) {
         return 0;
 }
 
-void cgroup_bonding_free(CGroupBonding *b, bool remove_or_trim) {
+void cgroup_bonding_free(CGroupBonding *b, bool trim) {
         assert(b);
 
         if (b->unit) {
@@ -79,13 +79,8 @@ void cgroup_bonding_free(CGroupBonding *b, bool remove_or_trim) {
                 }
         }
 
-        if (b->realized && b->ours && remove_or_trim) {
-
-                if (cgroup_bonding_is_empty(b) > 0)
-                        cg_delete(b->controller, b->path);
-                else
-                        cg_trim(b->controller, b->path, false);
-        }
+        if (b->realized && b->ours && trim)
+                cg_trim(b->controller, b->path, false);
 
         free(b->controller);
         free(b->path);
@@ -159,21 +154,21 @@ int cgroup_bonding_set_group_access_list(CGroupBonding *first, mode_t mode, uid_
         return 0;
 }
 
-int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid) {
+int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky) {
         assert(b);
 
         if (!b->realized)
                 return -EINVAL;
 
-        return cg_set_task_access(b->controller, b->path, mode, uid, gid);
+        return cg_set_task_access(b->controller, b->path, mode, uid, gid, sticky);
 }
 
-int cgroup_bonding_set_task_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid) {
+int cgroup_bonding_set_task_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid, int sticky) {
         CGroupBonding *b;
         int r;
 
         LIST_FOREACH(by_unit, b, first) {
-                r = cgroup_bonding_set_task_access(b, mode, uid, gid);
+                r = cgroup_bonding_set_task_access(b, mode, uid, gid, sticky);
                 if (r < 0)
                         return r;
         }
@@ -360,15 +355,55 @@ void manager_shutdown_cgroup(Manager *m, bool delete) {
         m->cgroup_hierarchy = NULL;
 }
 
+int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding) {
+        CGroupBonding *b;
+        char *p;
+
+        assert(m);
+        assert(cgroup);
+        assert(bonding);
+
+        b = hashmap_get(m->cgroup_bondings, cgroup);
+        if (b) {
+                *bonding = b;
+                return 1;
+        }
+
+        p = strdup(cgroup);
+        if (!p)
+                return -ENOMEM;
+
+        for (;;) {
+                char *e;
+
+                e = strrchr(p, '/');
+                if (!e || e == p) {
+                        free(p);
+                        *bonding = NULL;
+                        return 0;
+                }
+
+                *e = 0;
+
+                b = hashmap_get(m->cgroup_bondings, p);
+                if (b) {
+                        free(p);
+                        *bonding = b;
+                        return 1;
+                }
+        }
+}
+
 int cgroup_notify_empty(Manager *m, const char *group) {
         CGroupBonding *l, *b;
+        int r;
 
         assert(m);
         assert(group);
 
-        l = hashmap_get(m->cgroup_bondings, group);
-        if (!l)
-                return 0;
+        r = cgroup_bonding_get(m, group, &l);
+        if (r <= 0)
+                return r;
 
         LIST_FOREACH(by_path, b, l) {
                 int t;