summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2013-07-04 20:31:18 +0200
committerKay Sievers <kay@vrfy.org>2013-07-04 20:31:18 +0200
commitad929bcc27e2c6c1aa731053e45882686e9babab (patch)
tree6bee9093b59205b665751df7181347ab887841a0 /src
parentpo: add dbus-scope.c to POTFILES.skip (diff)
downloadsystemd-ad929bcc27e2c6c1aa731053e45882686e9babab.tar.xz
systemd-ad929bcc27e2c6c1aa731053e45882686e9babab.zip
disable the cgroups release agent when shutting down
During shutdown, when we try to clean up all remaining processes, the kernel will fork new agents every time a cgroup runs empty. These new processes cause delays in the final SIGTERM, SIGKILL logic. Apart from that, this should also avoid that the kernel-forked binaries cause unpredictably timed access to the filesystem which we might need to unmount.
Diffstat (limited to 'src')
-rw-r--r--src/core/main.c4
-rw-r--r--src/shared/cgroup-util.c15
-rw-r--r--src/shared/cgroup-util.h1
3 files changed, 20 insertions, 0 deletions
diff --git a/src/core/main.c b/src/core/main.c
index 8b8e110f24..ada0f9d94b 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1942,6 +1942,10 @@ finish:
watchdog_close(true);
}
+ /* avoid the creation of new processes forked by the kernel; at this
+ * point, we will not listen to the signals anyway */
+ cg_uninstall_release_agent(SYSTEMD_CGROUP_CONTROLLER);
+
execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
free(env_block);
log_error("Failed to execute shutdown binary, freezing: %m");
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index 390259e3e4..73013d1d97 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -790,6 +790,21 @@ int cg_install_release_agent(const char *controller, const char *agent) {
return 0;
}
+int cg_uninstall_release_agent(const char *controller) {
+ _cleanup_free_ char *fs = NULL;
+ int r;
+
+ r = cg_get_path(controller, NULL, "release_agent", &fs);
+ if (r < 0)
+ return r;
+
+ r = write_string_file(fs, "");
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
int cg_is_empty(const char *controller, const char *path, bool ignore_self) {
_cleanup_fclose_ FILE *f = NULL;
pid_t pid = 0, self_pid;
diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h
index c781aabb22..0fc93c12c8 100644
--- a/src/shared/cgroup-util.h
+++ b/src/shared/cgroup-util.h
@@ -89,6 +89,7 @@ int cg_set_group_access(const char *controller, const char *path, mode_t mode, u
int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid);
int cg_install_release_agent(const char *controller, const char *agent);
+int cg_uninstall_release_agent(const char *controller);
int cg_is_empty(const char *controller, const char *path, bool ignore_self);
int cg_is_empty_by_spec(const char *spec, bool ignore_self);