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);
}
int r;
Set *s;
bool done;
+ bool killed = false;
assert(b);
assert(sig > 0);
+ if (!b->only_us)
+ return -EAGAIN;
+
if (!(s = set_new(trivial_hash_func, trivial_compare_func)))
return -ENOMEM;
break;
}
+ killed = true;
done = false;
if ((r = set_put(s, INT_TO_PTR(pid))) < 0)
} 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 r = -EAGAIN;
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 0;
}
- return 0;
+ return r;
}
/* Returns 1 if the group is empty, 0 if it is not, -EAGAIN if we
char *mp, *cp;
int r;
pid_t pid;
+ char suffix[32];
assert(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;
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:
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;
+}