diff options
author | Lennart Poettering <lennart@poettering.net> | 2023-06-22 22:24:04 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2023-06-23 10:05:16 +0200 |
commit | 8c3fe1b5b59ebfd6e462245f2ab82097b4f7494d (patch) | |
tree | 4f9dab8ca39791f570f38df3a242b6e03b45f6d6 /src | |
parent | docs: document threading situation in coding style (diff) | |
download | systemd-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.c | 18 | ||||
-rw-r--r-- | src/basic/process-util.h | 1 | ||||
-rw-r--r-- | src/core/main.c | 7 | ||||
-rw-r--r-- | src/nspawn/nspawn.c | 5 | ||||
-rw-r--r-- | src/test/test-async.c | 4 | ||||
-rw-r--r-- | src/test/test-process-util.c | 2 |
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); |