mirror of
https://github.com/systemd/systemd.git
synced 2025-02-27 01:57:35 +03:00
process-util: add helper that detects if we are a reaper process
This commit is contained in:
parent
da3cd87ab4
commit
09f9530baf
@ -1623,6 +1623,21 @@ int get_process_threads(pid_t pid) {
|
||||
return n;
|
||||
}
|
||||
|
||||
int is_reaper_process(void) {
|
||||
int b = 0;
|
||||
|
||||
/* Checks if we are running in a reaper process, i.e. if we are expected to deal with processes
|
||||
* reparented to us. This simply checks if we are PID 1 or if PR_SET_CHILD_SUBREAPER was called. */
|
||||
|
||||
if (getpid_cached() == 1)
|
||||
return true;
|
||||
|
||||
if (prctl(PR_GET_CHILD_SUBREAPER, (unsigned long) &b, 0UL, 0UL, 0UL) < 0)
|
||||
return -errno;
|
||||
|
||||
return b != 0;
|
||||
}
|
||||
|
||||
static const char *const sigchld_code_table[] = {
|
||||
[CLD_EXITED] = "exited",
|
||||
[CLD_KILLED] = "killed",
|
||||
|
@ -199,3 +199,5 @@ int setpriority_closest(int priority);
|
||||
_noreturn_ void freeze(void);
|
||||
|
||||
int get_process_threads(pid_t pid);
|
||||
|
||||
int is_reaper_process(void);
|
||||
|
@ -891,6 +891,53 @@ TEST(get_process_threads) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(is_reaper_process) {
|
||||
int r;
|
||||
|
||||
r = safe_fork("(regular)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_WAIT, NULL);
|
||||
assert_se(r >= 0);
|
||||
if (r == 0) {
|
||||
/* child */
|
||||
|
||||
assert_se(is_reaper_process() == 0);
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
r = safe_fork("(newpid)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_WAIT, NULL);
|
||||
assert_se(r >= 0);
|
||||
if (r == 0) {
|
||||
/* child */
|
||||
|
||||
if (unshare(CLONE_NEWPID) < 0) {
|
||||
if (ERRNO_IS_PRIVILEGE(errno) || ERRNO_IS_NOT_SUPPORTED(errno)) {
|
||||
log_notice("Skipping CLONE_NEWPID reaper check, lacking privileges/support");
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
r = safe_fork("(newpid1)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_WAIT, NULL);
|
||||
assert_se(r >= 0);
|
||||
if (r == 0) {
|
||||
/* grandchild, which is PID1 in a pidns */
|
||||
assert_se(getpid_cached() == 1);
|
||||
assert_se(is_reaper_process() > 0);
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
r = safe_fork("(subreaper)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_WAIT, NULL);
|
||||
assert_se(r >= 0);
|
||||
if (r == 0) {
|
||||
/* child */
|
||||
assert_se(prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) >= 0);
|
||||
|
||||
assert_se(is_reaper_process() > 0);
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
static int intro(void) {
|
||||
log_show_color(true);
|
||||
return EXIT_SUCCESS;
|
||||
|
Loading…
x
Reference in New Issue
Block a user