75 lines
2.7 KiB
Diff
75 lines
2.7 KiB
Diff
|
From ad929bcc27e2c6c1aa731053e45882686e9babab Mon Sep 17 00:00:00 2001
|
||
|
From: Kay Sievers <kay@vrfy.org>
|
||
|
Date: Thu, 4 Jul 2013 20:31:18 +0200
|
||
|
Subject: [PATCH 4/6] 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.
|
||
|
---
|
||
|
src/core/main.c | 4 ++++
|
||
|
src/shared/cgroup-util.c | 15 +++++++++++++++
|
||
|
src/shared/cgroup-util.h | 1 +
|
||
|
3 files changed, 20 insertions(+)
|
||
|
|
||
|
diff --git a/src/core/main.c b/src/core/main.c
|
||
|
index 8b8e110..ada0f9d 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 390259e..73013d1 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 c781aab..0fc93c1 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);
|
||
|
--
|
||
|
1.8.1.4
|
||
|
|