core: find the closest parent slice that has a specfic cgroup controller enabled when enabling/disabling cgroup controllers for units
This commit is contained in:
parent
6d2357247b
commit
03b90d4bad
|
@ -448,9 +448,26 @@ void unit_update_cgroup_members_masks(Unit *u) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *migrate_callback(CGroupControllerMask mask, void *userdata) {
|
||||||
|
Unit *u = userdata;
|
||||||
|
|
||||||
|
assert(mask != 0);
|
||||||
|
assert(u);
|
||||||
|
|
||||||
|
while (u) {
|
||||||
|
if (u->cgroup_path &&
|
||||||
|
u->cgroup_realized &&
|
||||||
|
(u->cgroup_realized_mask & mask) == mask)
|
||||||
|
return u->cgroup_path;
|
||||||
|
|
||||||
|
u = UNIT_DEREF(u->slice);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) {
|
static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) {
|
||||||
_cleanup_free_ char *path;
|
_cleanup_free_ char *path = NULL;
|
||||||
bool was_in_hash = false;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
|
@ -460,38 +477,31 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) {
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
r = hashmap_put(u->manager->cgroup_unit, path, u);
|
r = hashmap_put(u->manager->cgroup_unit, path, u);
|
||||||
if (r == 0)
|
if (r < 0) {
|
||||||
was_in_hash = true;
|
log_error(r == -EEXIST ? "cgroup %s exists already: %s" : "hashmap_put failed for %s: %s", path, strerror(-r));
|
||||||
else if (r < 0) {
|
|
||||||
log_error(r == -EEXIST ?
|
|
||||||
"cgroup %s exists already: %s" : "hashmap_put failed for %s: %s",
|
|
||||||
path, strerror(-r));
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
if (r > 0) {
|
||||||
/* First, create our own group */
|
|
||||||
r = cg_create_everywhere(u->manager->cgroup_supported, mask, path);
|
|
||||||
if (r < 0)
|
|
||||||
log_error("Failed to create cgroup %s: %s", path, strerror(-r));
|
|
||||||
|
|
||||||
/* Then, possibly move things over */
|
|
||||||
if (u->cgroup_path) {
|
|
||||||
r = cg_migrate_everywhere(u->manager->cgroup_supported, u->cgroup_path, path);
|
|
||||||
if (r < 0)
|
|
||||||
log_error("Failed to migrate cgroup from %s to %s: %s",
|
|
||||||
u->cgroup_path, path, strerror(-r));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!was_in_hash) {
|
|
||||||
/* Remember the new data */
|
|
||||||
free(u->cgroup_path);
|
|
||||||
u->cgroup_path = path;
|
u->cgroup_path = path;
|
||||||
path = NULL;
|
path = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* First, create our own group */
|
||||||
|
r = cg_create_everywhere(u->manager->cgroup_supported, mask, u->cgroup_path);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to create cgroup %s: %s", u->cgroup_path, strerror(-r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep track that this is now realized */
|
||||||
u->cgroup_realized = true;
|
u->cgroup_realized = true;
|
||||||
u->cgroup_realized_mask = mask;
|
u->cgroup_realized_mask = mask;
|
||||||
|
|
||||||
|
/* Then, possibly move things over */
|
||||||
|
r = cg_migrate_everywhere(u->manager->cgroup_supported, u->cgroup_path, u->cgroup_path, migrate_callback, u);
|
||||||
|
if (r < 0)
|
||||||
|
log_warning("Failed to migrate cgroup from to %s: %s", u->cgroup_path, strerror(-r));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1668,7 +1668,7 @@ int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path,
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to) {
|
int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to, cg_migrate_callback_t to_callback, void *userdata) {
|
||||||
CGroupControllerMask bit = 1;
|
CGroupControllerMask bit = 1;
|
||||||
const char *n;
|
const char *n;
|
||||||
int r;
|
int r;
|
||||||
|
@ -1680,8 +1680,17 @@ int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
NULSTR_FOREACH(n, mask_names) {
|
NULSTR_FOREACH(n, mask_names) {
|
||||||
if (supported & bit)
|
if (supported & bit) {
|
||||||
cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, n, to, false, false);
|
const char *p = NULL;
|
||||||
|
|
||||||
|
if (to_callback)
|
||||||
|
p = to_callback(bit, userdata);
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
p = to;
|
||||||
|
|
||||||
|
cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, n, p, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
bit <<= 1;
|
bit <<= 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,10 +122,12 @@ bool cg_controller_is_valid(const char *p, bool allow_named);
|
||||||
|
|
||||||
int cg_slice_to_path(const char *unit, char **ret);
|
int cg_slice_to_path(const char *unit, char **ret);
|
||||||
|
|
||||||
|
typedef const char* (*cg_migrate_callback_t)(CGroupControllerMask mask, void *userdata);
|
||||||
|
|
||||||
int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask mask, const char *path);
|
int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask mask, const char *path);
|
||||||
int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid);
|
int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid);
|
||||||
int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids);
|
int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids);
|
||||||
int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to);
|
int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to, cg_migrate_callback_t callback, void *userdata);
|
||||||
int cg_trim_everywhere(CGroupControllerMask supported, const char *path, bool delete_root);
|
int cg_trim_everywhere(CGroupControllerMask supported, const char *path, bool delete_root);
|
||||||
|
|
||||||
CGroupControllerMask cg_mask_supported(void);
|
CGroupControllerMask cg_mask_supported(void);
|
||||||
|
|
Loading…
Reference in a new issue