chiark / gitweb /
cgroup: only delete empty cgroups
[elogind.git] / cgroup.c
index 9e1b0de379a2f4d29de4aeef5753461eba0ed2e8..565ce24ce18725159b9763d2e15f558cdbfb6f49 100644 (file)
--- a/cgroup.c
+++ b/cgroup.c
@@ -118,17 +118,15 @@ void cgroup_bonding_free(CGroupBonding *b) {
                         hashmap_remove(b->unit->meta.manager->cgroup_bondings, b->path);
         }
 
                         hashmap_remove(b->unit->meta.manager->cgroup_bondings, b->path);
         }
 
-        free(b->controller);
-        free(b->path);
-
         if (b->cgroup) {
         if (b->cgroup) {
-
-                if (b->only_us && b->clean_up)
-                        cgroup_delete_cgroup(b->cgroup, true);
+                if (b->only_us && b->clean_up && cgroup_bonding_is_empty(b) > 0)
+                        cgroup_delete_cgroup_ext(b->cgroup, true);
 
                 cgroup_free(&b->cgroup);
         }
 
 
                 cgroup_free(&b->cgroup);
         }
 
+        free(b->controller);
+        free(b->path);
         free(b);
 }
 
         free(b);
 }
 
@@ -174,13 +172,19 @@ int cgroup_bonding_kill(CGroupBonding *b, int sig) {
         int r;
         Set *s;
         bool done;
         int r;
         Set *s;
         bool done;
+        bool killed = false;
 
         assert(b);
         assert(sig > 0);
 
 
         assert(b);
         assert(sig > 0);
 
+        if (!b->only_us)
+                return -EAGAIN;
+
         if (!(s = set_new(trivial_hash_func, trivial_compare_func)))
                 return -ENOMEM;
 
         if (!(s = set_new(trivial_hash_func, trivial_compare_func)))
                 return -ENOMEM;
 
+        log_debug("Killing processes from process group %s:%s", b->controller, b->path);
+
         do {
                 void *iterator;
                 pid_t pid;
         do {
                 void *iterator;
                 pid_t pid;
@@ -208,6 +212,7 @@ int cgroup_bonding_kill(CGroupBonding *b, int sig) {
                                         break;
                                 }
 
                                         break;
                                 }
 
+                                killed = true;
                                 done = false;
 
                                 if ((r = set_put(s, INT_TO_PTR(pid))) < 0)
                                 done = false;
 
                                 if ((r = set_put(s, INT_TO_PTR(pid))) < 0)
@@ -235,20 +240,29 @@ int cgroup_bonding_kill(CGroupBonding *b, int sig) {
         } while (!done && r >= 0);
 
         set_free(s);
         } while (!done && r >= 0);
 
         set_free(s);
-        return r;
+
+        if (r < 0)
+                return r;
+
+        return killed ? 0 : -ESRCH;
 }
 
 int cgroup_bonding_kill_list(CGroupBonding *first, int sig) {
         CGroupBonding *b;
 }
 
 int cgroup_bonding_kill_list(CGroupBonding *first, int sig) {
         CGroupBonding *b;
+        int r = -EAGAIN;
 
         LIST_FOREACH(by_unit, b, first) {
 
         LIST_FOREACH(by_unit, b, first) {
-                int r;
+                if ((r = cgroup_bonding_kill(b, sig)) < 0) {
+                        if (r == -EAGAIN || -ESRCH)
+                                continue;
 
 
-                if ((r = cgroup_bonding_kill(b, sig)) < 0)
                         return r;
                         return r;
+                }
+
+                return 0;
         }
 
         }
 
-        return 0;
+        return r;
 }
 
 /* Returns 1 if the group is empty, 0 if it is not, -EAGAIN if we
 }
 
 /* Returns 1 if the group is empty, 0 if it is not, -EAGAIN if we
@@ -524,3 +538,14 @@ CGroupBonding *cgroup_bonding_find_list(CGroupBonding *first, const char *contro
 
         return NULL;
 }
 
         return NULL;
 }
+
+char *cgroup_bonding_to_string(CGroupBonding *b) {
+        char *r;
+
+        assert(b);
+
+        if (asprintf(&r, "%s:%s", b->controller, b->path) < 0)
+                return NULL;
+
+        return r;
+}