chiark / gitweb /
util: flush inotify fd only when we have it
[elogind.git] / cgroup.c
index 24bbe1aa15637132813c8cf6f747787455ecb3ac..301fc949dada5c8fa590ee90723cc7b7716ba9a3 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);
         }
 
-        free(b->controller);
-        free(b->path);
-
         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);
         }
 
+        free(b->controller);
+        free(b->path);
         free(b);
 }
 
@@ -185,8 +183,6 @@ int cgroup_bonding_kill(CGroupBonding *b, int sig) {
         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;
@@ -416,6 +412,7 @@ int manager_setup_cgroup(Manager *m) {
         char *mp, *cp;
         int r;
         pid_t pid;
+        char suffix[32];
 
         assert(m);
 
@@ -438,36 +435,48 @@ int manager_setup_cgroup(Manager *m) {
                 return translate_error(r, errno);
         }
 
+        snprintf(suffix, sizeof(suffix), "/systemd-%u", (unsigned) pid);
+        char_array_0(suffix);
+
         free(m->cgroup_hierarchy);
-        m->cgroup_hierarchy = NULL;
-        if (asprintf(&m->cgroup_hierarchy, "%s/systemd-%llu", strcmp(cp, "/") == 0 ? "" : cp, (unsigned long long) pid) < 0) {
+
+        if (endswith(cp, suffix))
+                /* We probably got reexecuted and can continue to use our root cgroup */
+                m->cgroup_hierarchy = cp;
+        else {
+                /* We need a new root cgroup */
+
+                m->cgroup_hierarchy = NULL;
+                r = asprintf(&m->cgroup_hierarchy, "%s%s", streq(cp, "/") ? "" : cp, suffix);
                 free(cp);
-                free(mp);
-                return -ENOMEM;
+
+                if (r < 0) {
+                        free(mp);
+                        return -ENOMEM;
+                }
         }
 
-        log_info("Using cgroup controller <%s>, hierarchy mounted at <%s>, using root group <%s>.",
-                 m->cgroup_controller,
-                 mp,
-                 m->cgroup_hierarchy);
+        log_debug("Using cgroup controller <%s>, hierarchy mounted at <%s>, using root group <%s>.",
+                  m->cgroup_controller,
+                  mp,
+                  m->cgroup_hierarchy);
 
         if ((r = install_release_agent(m, mp)) < 0)
                 log_warning("Failed to install release agent, ignoring: %s", strerror(-r));
         else
-                log_info("Installed release agent, or already installed.");
+                log_debug("Installed release agent, or already installed.");
 
         free(mp);
-        free(cp);
 
         if ((r = create_hierarchy_cgroup(m)) < 0)
                 log_error("Failed to create root cgroup hierarchy: %s", strerror(-r));
         else
-                log_info("Created root group.");
+                log_debug("Created root group.");
 
         return r;
 }
 
-int manager_shutdown_cgroup(Manager *m) {
+int manager_shutdown_cgroup(Manager *m, bool delete) {
         struct cgroup *cg;
         int r;
 
@@ -484,11 +493,10 @@ int manager_shutdown_cgroup(Manager *m) {
                 goto finish;
         }
 
-        if ((r = cgroup_delete_cgroup_ext(cg, CGFLAG_DELETE_IGNORE_MIGRATION|CGFLAG_DELETE_RECURSIVE)) != 0) {
-                log_error("Failed to delete cgroup hierarchy group: %s", cgroup_strerror(r));
-                r = translate_error(r, errno);
-                goto finish;
-        }
+        /* Often enough we won't be able to delete the cgroup we
+         * ourselves are in, hence ignore all errors here */
+        if (delete)
+                cgroup_delete_cgroup_ext(cg, CGFLAG_DELETE_IGNORE_MIGRATION|CGFLAG_DELETE_RECURSIVE);
         r = 0;
 
 finish:
@@ -540,3 +548,14 @@ CGroupBonding *cgroup_bonding_find_list(CGroupBonding *first, const char *contro
 
         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;
+}