pid1: do not reset subtree_control on already-existing units with delegation
Fixes #8364. Reproducer: $ sudo systemd-run -t -p Delegate=yes bash # mkdir /sys/fs/cgroup/system.slice/run-u6958.service/supervisor # echo $$ > /sys/fs/cgroup/system.slice/run-u6958.service/supervisor/cgroup.procs # echo +memory > /sys/fs/cgroup/system.slice/run-u6958.service/cgroup.subtree_control # cat /sys/fs/cgroup/system.slice/run-u6958.service/cgroup.subtree_control memory # systemctl daemon-reload # cat /sys/fs/cgroup/system.slice/run-u6958.service/cgroup.subtree_control (empty) With patch, the last command shows 'memory'.
This commit is contained in:
committed by
Lennart Poettering
parent
d28b67d46a
commit
65be7e0652
+12
-3
@@ -754,6 +754,9 @@ int cg_trim(const char *controller, const char *path, bool delete_root) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create a cgroup in the hierarchy of controller.
|
||||||
|
* Returns 0 if the group already existed, 1 on success, negative otherwise.
|
||||||
|
*/
|
||||||
int cg_create(const char *controller, const char *path) {
|
int cg_create(const char *controller, const char *path) {
|
||||||
_cleanup_free_ char *fs = NULL;
|
_cleanup_free_ char *fs = NULL;
|
||||||
int r;
|
int r;
|
||||||
@@ -2104,23 +2107,29 @@ done:
|
|||||||
|
|
||||||
int cg_create_everywhere(CGroupMask supported, CGroupMask mask, const char *path) {
|
int cg_create_everywhere(CGroupMask supported, CGroupMask mask, const char *path) {
|
||||||
CGroupController c;
|
CGroupController c;
|
||||||
|
bool created;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* This one will create a cgroup in our private tree, but also
|
/* This one will create a cgroup in our private tree, but also
|
||||||
* duplicate it in the trees specified in mask, and remove it
|
* duplicate it in the trees specified in mask, and remove it
|
||||||
* in all others */
|
* in all others.
|
||||||
|
*
|
||||||
|
* Returns 0 if the group already existed in the systemd hierarchy,
|
||||||
|
* 1 on success, negative otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
/* First create the cgroup in our own hierarchy. */
|
/* First create the cgroup in our own hierarchy. */
|
||||||
r = cg_create(SYSTEMD_CGROUP_CONTROLLER, path);
|
r = cg_create(SYSTEMD_CGROUP_CONTROLLER, path);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
created = !!r;
|
||||||
|
|
||||||
/* If we are in the unified hierarchy, we are done now */
|
/* If we are in the unified hierarchy, we are done now */
|
||||||
r = cg_all_unified();
|
r = cg_all_unified();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
return 0;
|
return created;
|
||||||
|
|
||||||
/* Otherwise, do the same in the other hierarchies */
|
/* Otherwise, do the same in the other hierarchies */
|
||||||
for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
|
for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
|
||||||
@@ -2135,7 +2144,7 @@ int cg_create_everywhere(CGroupMask supported, CGroupMask mask, const char *path
|
|||||||
(void) cg_trim(n, path, true);
|
(void) cg_trim(n, path, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return created;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cg_attach_everywhere(CGroupMask supported, const char *path, pid_t pid, cg_migrate_callback_t path_callback, void *userdata) {
|
int cg_attach_everywhere(CGroupMask supported, const char *path, pid_t pid, cg_migrate_callback_t path_callback, void *userdata) {
|
||||||
|
|||||||
+11
-4
@@ -1453,6 +1453,7 @@ static int unit_create_cgroup(
|
|||||||
|
|
||||||
CGroupContext *c;
|
CGroupContext *c;
|
||||||
int r;
|
int r;
|
||||||
|
bool created;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
|
|
||||||
@@ -1469,14 +1470,20 @@ static int unit_create_cgroup(
|
|||||||
r = cg_create_everywhere(u->manager->cgroup_supported, target_mask, u->cgroup_path);
|
r = cg_create_everywhere(u->manager->cgroup_supported, target_mask, u->cgroup_path);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_unit_error_errno(u, r, "Failed to create cgroup %s: %m", u->cgroup_path);
|
return log_unit_error_errno(u, r, "Failed to create cgroup %s: %m", u->cgroup_path);
|
||||||
|
created = !!r;
|
||||||
|
|
||||||
/* Start watching it */
|
/* Start watching it */
|
||||||
(void) unit_watch_cgroup(u);
|
(void) unit_watch_cgroup(u);
|
||||||
|
|
||||||
/* Enable all controllers we need */
|
/* Preserve enabled controllers in delegated units, adjust others. */
|
||||||
r = cg_enable_everywhere(u->manager->cgroup_supported, enable_mask, u->cgroup_path);
|
if (created || !unit_cgroup_delegate(u)) {
|
||||||
if (r < 0)
|
|
||||||
log_unit_warning_errno(u, r, "Failed to enable controllers on cgroup %s, ignoring: %m", u->cgroup_path);
|
/* Enable all controllers we need */
|
||||||
|
r = cg_enable_everywhere(u->manager->cgroup_supported, enable_mask, u->cgroup_path);
|
||||||
|
if (r < 0)
|
||||||
|
log_unit_warning_errno(u, r, "Failed to enable controllers on cgroup %s, ignoring: %m",
|
||||||
|
u->cgroup_path);
|
||||||
|
}
|
||||||
|
|
||||||
/* Keep track that this is now realized */
|
/* Keep track that this is now realized */
|
||||||
u->cgroup_realized = true;
|
u->cgroup_realized = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user