summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-06-22 22:24:04 +0200
committerLennart Poettering <lennart@poettering.net>2023-06-23 10:05:16 +0200
commit8c3fe1b5b59ebfd6e462245f2ab82097b4f7494d (patch)
tree4f9dab8ca39791f570f38df3a242b6e03b45f6d6 /src
parentdocs: document threading situation in coding style (diff)
downloadsystemd-8c3fe1b5b59ebfd6e462245f2ab82097b4f7494d.tar.xz
systemd-8c3fe1b5b59ebfd6e462245f2ab82097b4f7494d.zip
process-util: add simple wrapper around PR_SET_CHILD_SUBREAPER
Let's a simple helper that knows how to deal with PID == 1.
Diffstat (limited to 'src')
-rw-r--r--src/basic/process-util.c18
-rw-r--r--src/basic/process-util.h1
-rw-r--r--src/core/main.c7
-rw-r--r--src/nspawn/nspawn.c5
-rw-r--r--src/test/test-async.c4
-rw-r--r--src/test/test-process-util.c2
6 files changed, 28 insertions, 9 deletions
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 437e83bc6d..001002a55e 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -1705,6 +1705,24 @@ int is_reaper_process(void) {
return b != 0;
}
+int make_reaper_process(bool b) {
+
+ if (getpid_cached() == 1) {
+
+ if (!b)
+ return -EINVAL;
+
+ return 0;
+ }
+
+ /* Some prctl()s insist that all 5 arguments are specified, others do not. Let's always specify all,
+ * to avoid any ambiguities */
+ if (prctl(PR_SET_CHILD_SUBREAPER, (unsigned long) b, 0UL, 0UL, 0UL) < 0)
+ return -errno;
+
+ return 0;
+}
+
static const char *const sigchld_code_table[] = {
[CLD_EXITED] = "exited",
[CLD_KILLED] = "killed",
diff --git a/src/basic/process-util.h b/src/basic/process-util.h
index 1b77478cf5..8f87fdc2ae 100644
--- a/src/basic/process-util.h
+++ b/src/basic/process-util.h
@@ -209,3 +209,4 @@ _noreturn_ void freeze(void);
int get_process_threads(pid_t pid);
int is_reaper_process(void);
+int make_reaper_process(bool b);
diff --git a/src/core/main.c b/src/core/main.c
index f067b13fff..208d22f4f3 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -2294,10 +2294,9 @@ static int initialize_runtime(
}
}
- if (arg_runtime_scope == RUNTIME_SCOPE_USER)
- /* Become reaper of our children */
- if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0)
- log_warning_errno(errno, "Failed to make us a subreaper, ignoring: %m");
+ r = make_reaper_process(true);
+ if (r < 0)
+ log_warning_errno(r, "Failed to make us a subreaper, ignoring: %m");
/* Bump up RLIMIT_NOFILE for systemd itself */
(void) bump_rlimit_nofile(saved_rlimit_nofile);
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 97a2c386e6..4fdb5e9fd7 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -5826,8 +5826,9 @@ static int run(int argc, char *argv[]) {
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, SIGWINCH, SIGTERM, SIGINT, SIGRTMIN+18, -1) >= 0);
- if (prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) < 0) {
- r = log_error_errno(errno, "Failed to become subreaper: %m");
+ r = make_reaper_process(true);
+ if (r < 0) {
+ log_error_errno(r, "Failed to become subreaper: %m");
goto finish;
}
diff --git a/src/test/test-async.c b/src/test/test-async.c
index 64b94886ff..dc0e34b48f 100644
--- a/src/test/test-async.c
+++ b/src/test/test-async.c
@@ -36,7 +36,7 @@ TEST(asynchronous_close) {
if (r == 0) {
/* child */
- assert(prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) >= 0);
+ assert(make_reaper_process(true) >= 0);
fd = open("/dev/null", O_RDONLY|O_CLOEXEC);
assert_se(fd >= 0);
@@ -72,7 +72,7 @@ TEST(asynchronous_rm_rf) {
/* child */
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0);
- assert_se(prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) >= 0);
+ assert_se(make_reaper_process(true) >= 0);
assert_se(mkdtemp_malloc(NULL, &tt) >= 0);
assert_se(kk = path_join(tt, "somefile"));
diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c
index 6de09c3c11..ebf73c54ec 100644
--- a/src/test/test-process-util.c
+++ b/src/test/test-process-util.c
@@ -931,7 +931,7 @@ TEST(is_reaper_process) {
assert_se(r >= 0);
if (r == 0) {
/* child */
- assert_se(prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) >= 0);
+ assert_se(make_reaper_process(true) >= 0);
assert_se(is_reaper_process() > 0);
_exit(EXIT_SUCCESS);