Commit 925a2872 authored by Martin Pitt's avatar Martin Pitt
Browse files

scope: Make attachment of initial PIDs more robust

Fixes crash with processes that get started by an init.d script with a
different (aliased) name when the cgroup becomes empty.

Patch cherry-picked from upstream.

Closes: #781210
parent 6ef318a5
systemd (215-14) UNRELEASED; urgency=medium systemd (215-14) UNRELEASED; urgency=medium
[ Michael Biebl ]
* Map $x-display-manager LSB facility to display-manager.service instead of * Map $x-display-manager LSB facility to display-manager.service instead of
making it a target. Using a target had the downside that multiple display making it a target. Using a target had the downside that multiple display
managers could hook into it at the same time which could lead to several managers could hook into it at the same time which could lead to several
...@@ -9,6 +10,11 @@ systemd (215-14) UNRELEASED; urgency=medium ...@@ -9,6 +10,11 @@ systemd (215-14) UNRELEASED; urgency=medium
This avoids creating references to a no longer existing This avoids creating references to a no longer existing
x-display-manager.target unit. x-display-manager.target unit.
[ Martin Pitt ]
* scope: Make attachment of initial PIDs more robust. Fixes crash with
processes that get started by an init.d script with a different (aliased)
name when the cgroup becomes empty. (Closes: #781210)
-- Michael Biebl <biebl@debian.org> Sat, 28 Mar 2015 09:27:07 +0100 -- Michael Biebl <biebl@debian.org> Sat, 28 Mar 2015 09:27:07 +0100
systemd (215-13) unstable; urgency=medium systemd (215-13) unstable; urgency=medium
......
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 10 Dec 2014 22:06:44 +0100
Subject: scope: make attachment of initial PIDs a bit more robust
---
src/core/cgroup.c | 42 ++++++++++++++++++++++++++++++------------
src/core/cgroup.h | 1 +
src/core/execute.c | 2 +-
src/core/scope.c | 8 +-------
src/shared/cgroup-util.c | 18 ++++++++++++++----
src/shared/cgroup-util.h | 4 ++--
6 files changed, 49 insertions(+), 26 deletions(-)
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 77acd2e..a7ef88d 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -593,7 +593,6 @@ static const char *migrate_callback(CGroupControllerMask mask, void *userdata) {
}
static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) {
- _cleanup_free_ char *path = NULL;
CGroupContext *c;
int r;
@@ -603,18 +602,22 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) {
if (!c)
return 0;
- path = unit_default_cgroup_path(u);
- if (!path)
- return log_oom();
+ if (!u->cgroup_path) {
+ _cleanup_free_ char *path = NULL;
- r = hashmap_put(u->manager->cgroup_unit, path, u);
- if (r < 0) {
- log_error(r == -EEXIST ? "cgroup %s exists already: %s" : "hashmap_put failed for %s: %s", path, strerror(-r));
- return r;
- }
- if (r > 0) {
- u->cgroup_path = path;
- path = NULL;
+ path = unit_default_cgroup_path(u);
+ if (!path)
+ return log_oom();
+
+ r = hashmap_put(u->manager->cgroup_unit, path, u);
+ if (r < 0) {
+ log_error(r == -EEXIST ? "cgroup %s exists already: %s" : "hashmap_put failed for %s: %s", path, strerror(-r));
+ return r;
+ }
+ if (r > 0) {
+ u->cgroup_path = path;
+ path = NULL;
+ }
}
/* First, create our own group */
@@ -640,6 +643,21 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) {
return 0;
}
+int unit_attach_pids_to_cgroup(Unit *u) {
+ int r;
+ assert(u);
+
+ r = unit_realize_cgroup(u);
+ if (r < 0)
+ return r;
+
+ r = cg_attach_many_everywhere(u->manager->cgroup_supported, u->cgroup_path, u->pids, migrate_callback, u);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
static bool unit_has_mask_realized(Unit *u, CGroupControllerMask mask) {
assert(u);
diff --git a/src/core/cgroup.h b/src/core/cgroup.h
index d299872..8a22a26 100644
--- a/src/core/cgroup.h
+++ b/src/core/cgroup.h
@@ -108,6 +108,7 @@ CGroupControllerMask unit_get_target_mask(Unit *u);
void unit_update_cgroup_members_masks(Unit *u);
int unit_realize_cgroup(Unit *u);
void unit_destroy_cgroup(Unit *u);
+int unit_attach_pids_to_cgroup(Unit *u);
int manager_setup_cgroup(Manager *m);
void manager_shutdown_cgroup(Manager *m, bool delete);
diff --git a/src/core/execute.c b/src/core/execute.c
index 6b09402..4efafc9 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1406,7 +1406,7 @@ int exec_spawn(ExecCommand *command,
}
if (cgroup_path) {
- err = cg_attach_everywhere(cgroup_supported, cgroup_path, 0);
+ err = cg_attach_everywhere(cgroup_supported, cgroup_path, 0, NULL, NULL);
if (err < 0) {
r = EXIT_CGROUP;
goto fail_child;
diff --git a/src/core/scope.c b/src/core/scope.c
index e8f9e8d..273d7ba 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -288,13 +288,7 @@ static int scope_start(Unit *u) {
if (!u->transient && UNIT(s)->manager->n_reloading <= 0)
return -ENOENT;
- r = unit_realize_cgroup(u);
- if (r < 0) {
- log_error("Failed to realize cgroup: %s", strerror(-r));
- return r;
- }
-
- r = cg_attach_many_everywhere(u->manager->cgroup_supported, u->cgroup_path, UNIT(s)->pids);
+ r = unit_attach_pids_to_cgroup(u);
if (r < 0)
return r;
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index c1c4d40..af9471b 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -1628,7 +1628,7 @@ int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask ma
return 0;
}
-int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid) {
+int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid, cg_migrate_callback_t path_callback, void *userdata) {
CGroupControllerMask bit = 1;
const char *n;
int r;
@@ -1638,8 +1638,18 @@ int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t
return r;
NULSTR_FOREACH(n, mask_names) {
- if (supported & bit)
+
+ if (supported & bit) {
+ const char *p = NULL;
+
+ if (path_callback)
+ p = path_callback(bit, userdata);
+
+ if (!p)
+ p = path;
+
cg_attach_fallback(n, path, pid);
+ }
bit <<= 1;
}
@@ -1647,7 +1657,7 @@ int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t
return 0;
}
-int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids) {
+int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids, cg_migrate_callback_t path_callback, void *userdata) {
Iterator i;
void *pidp;
int r = 0;
@@ -1656,7 +1666,7 @@ int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path,
pid_t pid = PTR_TO_LONG(pidp);
int q;
- q = cg_attach_everywhere(supported, path, pid);
+ q = cg_attach_everywhere(supported, path, pid, path_callback, userdata);
if (q < 0)
r = q;
}
diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h
index aca4e44..b3425ca 100644
--- a/src/shared/cgroup-util.h
+++ b/src/shared/cgroup-util.h
@@ -125,8 +125,8 @@ 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_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_everywhere(CGroupControllerMask supported, const char *path, pid_t pid, cg_migrate_callback_t callback, void *userdata);
+int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids, cg_migrate_callback_t callback, void *userdata);
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);
...@@ -140,6 +140,7 @@ networkd-link-fix-stopping-v4-dhcpclient-when-the-ca.patch ...@@ -140,6 +140,7 @@ networkd-link-fix-stopping-v4-dhcpclient-when-the-ca.patch
core-do-not-add-dependencies-to-self.patch core-do-not-add-dependencies-to-self.patch
units-tmpfiles-setup-dev-allow-unsafe-file-creation-.patch units-tmpfiles-setup-dev-allow-unsafe-file-creation-.patch
core-don-t-migrate-PIDs-for-units-that-may-contain-s.patch core-don-t-migrate-PIDs-for-units-that-may-contain-s.patch
scope-make-attachment-of-initial-PIDs-a-bit-more-rob.patch
## Debian specific patches: ## Debian specific patches:
Add-back-support-for-Debian-specific-config-files.patch Add-back-support-for-Debian-specific-config-files.patch
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment