chiark / gitweb /
cgroup: when getting cgroup empty notifications, always search up the tree
[elogind.git] / src / login / logind.c
index 4aeac0cc2e28a7b6e88acdd828f4acb40e925a67..7fd6515ffd329e80a3163f89696f19a3b9b036a4 100644 (file)
@@ -781,34 +781,74 @@ finish:
         return r;
 }
 
-void manager_cgroup_notify_empty(Manager *m, const char *cgroup) {
+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.");
-                return;
+                return -ENOMEM;
         }
 
         for (;;) {
                 char *e;
 
-                if (isempty(p) || streq(p, "/"))
-                        break;
-
-                s = hashmap_get(m->cgroups, p);
-                if (s)
-                        session_add_to_gc_queue(s);
+                e = strrchr(p, '/');
+                if (!e || e == p) {
+                        free(p);
+                        *session = NULL;
+                        return 0;
+                }
 
-                assert_se(e = strrchr(p, '/'));
                 *e = 0;
+
+                s = hashmap_get(m->cgroups, p);
+                if (s) {
+                        free(p);
+                        *session = s;
+                        return 1;
+                }
         }
+}
 
+int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
+        char *p;
+        int r;
+
+        assert(m);
+        assert(pid >= 1);
+        assert(session);
+
+        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &p);
+        if (r < 0)
+                return r;
+
+        r = manager_get_session_by_cgroup(m, p, session);
         free(p);
+
+        return r;
+}
+
+void manager_cgroup_notify_empty(Manager *m, const char *cgroup) {
+        Session *s;
+        int r;
+
+        r = manager_get_session_by_cgroup(m, cgroup, &s);
+        if (r <= 0)
+                return;
+
+        session_add_to_gc_queue(s);
 }
 
 static void manager_pipe_notify_eof(Manager *m, int fd) {