chiark / gitweb /
cgroup: when getting cgroup empty notifications, always search up the tree
authorLennart Poettering <lennart@poettering.net>
Fri, 3 Feb 2012 04:25:31 +0000 (05:25 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 3 Feb 2012 04:25:31 +0000 (05:25 +0100)
TODO
src/cgroup.c
src/cgroup.h
src/login/logind.c

diff --git a/TODO b/TODO
index 74a36a1df3233956907d85693d2134ed1802962d..c2113f881eeb352b4e95c759cfb4015932d71fc2 100644 (file)
--- a/TODO
+++ b/TODO
@@ -31,7 +31,7 @@ Features:
 
 * write RPM spec macros for presets
 
-* write man pages for systemd-cgtop, systemd-cat
+* write man pages for systemd-cat
 
 * journal: write man pages for API
 
@@ -73,8 +73,6 @@ Features:
 
 * move to LGPL2+
 
-* logind: selinux is borked...
-
 * logind: allow showing logout dialog from system
 
 * document that %% can be used to write % in a string that is specifier extended
@@ -164,8 +162,6 @@ Features:
 
 * GC unreferenced jobs (such as .device jobs)
 
-* cgroup_notify_empty(): recursively check groups up the tree, too
-
 * when failing to start a service due to ratelimiting, try again later, if restart=always is set
 
 * write blog stories about:
@@ -175,6 +171,7 @@ Features:
   - remote access
   - how to pass throw-away units to systemd, or dynamically change properties of existing units
   - how to integrate cgconfig and suchlike with systemd
+  - resource control in systemd
 
 * allow port=0 in .socket units
 
index 9aff02e7bc1084f323a6267fe301887e82b92f2c..182dd59eec5aea5d09fcada8b32c63d5ca259955 100644 (file)
@@ -355,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;
index db4feb916e003f2e5599bc1c96084da75d0d756b..5faa7dc0f77287d781bb4041c660db04d71f0785 100644 (file)
@@ -86,6 +86,7 @@ pid_t cgroup_bonding_search_main_pid_list(CGroupBonding *b);
 int manager_setup_cgroup(Manager *m);
 void manager_shutdown_cgroup(Manager *m, bool delete);
 
+int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding);
 int cgroup_notify_empty(Manager *m, const char *group);
 
 Unit* cgroup_unit_by_pid(Manager *m, pid_t pid);
index 8997b4689ed1a0d1a332401d4e6c5d0f3699a98d..7fd6515ffd329e80a3163f89696f19a3b9b036a4 100644 (file)
@@ -782,12 +782,19 @@ finish:
 }
 
 int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session) {
+        Session *s;
         char *p;
 
         assert(m);
         assert(cgroup);
         assert(session);
 
+        s = hashmap_get(m->cgroups, cgroup);
+        if (s) {
+                *session = s;
+                return 1;
+        }
+
         p = strdup(cgroup);
         if (!p) {
                 log_error("Out of memory.");
@@ -795,24 +802,23 @@ int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **sess
         }
 
         for (;;) {
-                Session *s;
                 char *e;
 
-                if (isempty(p) || streq(p, "/")) {
+                e = strrchr(p, '/');
+                if (!e || e == p) {
                         free(p);
                         *session = NULL;
                         return 0;
                 }
 
+                *e = 0;
+
                 s = hashmap_get(m->cgroups, p);
                 if (s) {
                         free(p);
                         *session = s;
                         return 1;
                 }
-
-                assert_se(e = strrchr(p, '/'));
-                *e = 0;
         }
 }