From: Daan De Meyer Date: Sat, 20 Dec 2025 13:33:35 +0000 (+0100) Subject: tree-wide: Migrate to pidref_safe_fork() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=52ecf376fa48d8c1c4aa02311ea787f4f43deecc;p=thirdparty%2Fsystemd.git tree-wide: Migrate to pidref_safe_fork() Let's migrate all remaining callers of safe_fork() to pidref_safe_fork() and get rid of safe_fork(). --- diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 53845cc213b..d1c16971a89 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -1576,13 +1576,9 @@ int pidref_safe_fork_full( } if (ret) { - if (FLAGS_SET(flags, _FORK_PID_ONLY)) + r = pidref_set_pid(ret, pid); + if (r < 0) /* Let's not fail for this, no matter what, the process exists after all, and that's key */ *ret = PIDREF_MAKE_FROM_PID(pid); - else { - r = pidref_set_pid(ret, pid); - if (r < 0) /* Let's not fail for this, no matter what, the process exists after all, and that's key */ - *ret = PIDREF_MAKE_FROM_PID(pid); - } } return 1; @@ -1764,44 +1760,16 @@ int pidref_safe_fork_full( freeze(); if (ret) { - if (FLAGS_SET(flags, _FORK_PID_ONLY)) - *ret = PIDREF_MAKE_FROM_PID(getpid_cached()); - else { - r = pidref_set_self(ret); - if (r < 0) { - log_full_errno(prio, r, "Failed to acquire PID reference on ourselves: %m"); - _exit(EXIT_FAILURE); - } + r = pidref_set_self(ret); + if (r < 0) { + log_full_errno(prio, r, "Failed to acquire PID reference on ourselves: %m"); + _exit(EXIT_FAILURE); } } return 0; } -int safe_fork_full( - const char *name, - const int stdio_fds[3], - int except_fds[], - size_t n_except_fds, - ForkFlags flags, - pid_t *ret) { - - _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; - int r; - - /* Getting the detached child process pid without pidfd is racy, so don't allow it if not returning - * a pidref to the caller. */ - assert(!FLAGS_SET(flags, FORK_DETACH) || !ret); - - r = pidref_safe_fork_full(name, stdio_fds, except_fds, n_except_fds, flags|_FORK_PID_ONLY, ret ? &pidref : NULL); - if (r < 0 || !ret) - return r; - - *ret = pidref.pid; - - return r; -} - int namespace_fork_full( const char *outer_name, const char *inner_name, diff --git a/src/basic/process-util.h b/src/basic/process-util.h index 0b8587bed40..e92531798ac 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -176,8 +176,6 @@ typedef enum ForkFlags { FORK_NEW_PIDNS = 1 << 21, /* Run child in its own PID namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */ FORK_FREEZE = 1 << 22, /* Don't return in child, just call freeze() instead */ FORK_ALLOW_DLOPEN = 1 << 23, /* Do not block dlopen() in child */ - - _FORK_PID_ONLY = 1 << 24, /* Don't open a pidfd referencing the child process */ } ForkFlags; int pidref_safe_fork_full( @@ -192,18 +190,6 @@ static inline int pidref_safe_fork(const char *name, ForkFlags flags, PidRef *re return pidref_safe_fork_full(name, NULL, NULL, 0, flags, ret); } -int safe_fork_full( - const char *name, - const int stdio_fds[3], - int except_fds[], - size_t n_except_fds, - ForkFlags flags, - pid_t *ret); - -static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret) { - return safe_fork_full(name, NULL, NULL, 0, flags, ret); -} - int namespace_fork_full( const char *outer_name, const char *inner_name, diff --git a/src/core/automount.c b/src/core/automount.c index b70ef42abaf..79ccdd3fc70 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -655,12 +655,13 @@ static int asynchronous_expire(int dev_autofs_fd, int ioctl_fd) { * child's PID, we are PID1/autoreaper after all, hence when it dies we'll automatically clean it up * anyway. */ - r = safe_fork_full("(sd-expire)", - /* stdio_fds= */ NULL, - (int[]) { dev_autofs_fd, ioctl_fd }, - /* n_except_fds= */ 2, - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG, - /* ret= */ NULL); + r = pidref_safe_fork_full( + "(sd-expire)", + /* stdio_fds= */ NULL, + (int[]) { dev_autofs_fd, ioctl_fd }, + /* n_except_fds= */ 2, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG, + /* ret= */ NULL); if (r != 0) return r; diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 1fa20d67630..f02d305be50 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -1416,7 +1416,7 @@ static int setup_pam( parent_pid = getpid_cached(); - r = safe_fork("(sd-pam)", 0, NULL); + r = pidref_safe_fork("(sd-pam)", /* flags= */ 0, /* ret= */ NULL); if (r < 0) goto fail; if (r == 0) { diff --git a/src/core/manager.c b/src/core/manager.c index b627c04c128..490b209d998 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -4133,7 +4133,7 @@ static int manager_run_generators(Manager *m) { if (is_dir("/tmp", /* follow= */ false) > 0 && !MANAGER_IS_TEST_RUN(m)) flags |= FORK_PRIVATE_TMP; - r = safe_fork("(sd-gens)", flags, NULL); + r = pidref_safe_fork("(sd-gens)", flags, /* ret= */ NULL); if (r == 0) { r = manager_execute_generators(m, paths, /* remount_ro= */ true); _exit(r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE); diff --git a/src/core/namespace.c b/src/core/namespace.c index 2c87975baff..c4e2721b370 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -3502,7 +3502,6 @@ static int is_extension_overlay(const char *path, int fd) { static int unpeel_get_fd(const char *mount_path, int *ret_fd) { _cleanup_close_pair_ int pipe_fds[2] = EBADF_PAIR; _cleanup_close_ int fs_fd = -EBADF; - pid_t pid; int r; assert(mount_path); @@ -3513,7 +3512,7 @@ static int unpeel_get_fd(const char *mount_path, int *ret_fd) { return log_debug_errno(errno, "Failed to create socket pair: %m"); /* Clone mount namespace here to unpeel without affecting live process */ - r = safe_fork("(sd-ns-unpeel)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, &pid); + r = pidref_safe_fork("(sd-ns-unpeel)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, /* ret= */ NULL); if (r < 0) return r; if (r == 0) { @@ -3903,9 +3902,10 @@ int refresh_extensions_in_namespace( * overlays to obtain FDs the underlying directories, over which we will reapply the overlays * 3. In the child again, receive the FDs and reapply the overlays */ - r = safe_fork("(sd-ns-refresh-exts)", - FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, - NULL); + r = pidref_safe_fork( + "(sd-ns-refresh-exts)", + FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, + /* ret= */ NULL); if (r < 0) return r; if (r == 0) { diff --git a/src/core/unit.c b/src/core/unit.c index 4287179903e..7c51cc1b86b 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -5540,7 +5540,6 @@ int unit_set_exec_params(Unit *u, ExecParameters *p) { int unit_fork_helper_process_full(Unit *u, const char *name, bool into_cgroup, ForkFlags flags, PidRef *ret) { CGroupRuntime *crt = NULL; - pid_t pid; int r; assert(u); @@ -5548,8 +5547,8 @@ int unit_fork_helper_process_full(Unit *u, const char *name, bool into_cgroup, F assert(ret); /* Forks off a helper process and makes sure it is a member of the unit's cgroup, if configured to - * do so. Returns == 0 in the child, and > 0 in the parent. The pid parameter is always filled in - * with the child's PID. */ + * do so. Returns == 0 in the child, and > 0 in the parent. The pidref parameter is always filled in + * with the child's PID reference. */ if (into_cgroup) { r = unit_realize_cgroup(u); @@ -5559,19 +5558,11 @@ int unit_fork_helper_process_full(Unit *u, const char *name, bool into_cgroup, F crt = unit_get_cgroup_runtime(u); } - r = safe_fork(name, FORK_REOPEN_LOG|FORK_DEATHSIG_SIGTERM|flags, &pid); + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; + r = pidref_safe_fork(name, FORK_REOPEN_LOG|FORK_DEATHSIG_SIGTERM|flags, &pidref); if (r < 0) return r; if (r > 0) { - _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; - int q; - - /* Parent */ - - q = pidref_set_pid(&pidref, pid); - if (q < 0) - return q; - *ret = TAKE_PIDREF(pidref); return r; } @@ -5589,6 +5580,7 @@ int unit_fork_helper_process_full(Unit *u, const char *name, bool into_cgroup, F } } + *ret = TAKE_PIDREF(pidref); return 0; } diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index 4ae3fbc7337..8883dc6e263 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -1785,7 +1785,7 @@ static int action_with(DissectedImage *m, LoopDevice *d) { return log_error_errno(r, "Failed to unlock loopback block device: %m"); } - rcode = safe_fork("(with)", FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_WAIT, NULL); + rcode = pidref_safe_fork("(with)", FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_WAIT, /* ret= */ NULL); if (rcode == 0) { /* Child */ diff --git a/src/home/homed-home.c b/src/home/homed-home.c index 92fb1d9c2d1..985b18661cf 100644 --- a/src/home/homed-home.c +++ b/src/home/homed-home.c @@ -2233,9 +2233,10 @@ int home_killall(Home *h) { assert(h->uid > 0); /* We never should be UID 0 */ /* Let's kill everything matching the specified UID */ - r = safe_fork("(sd-killer)", - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_WAIT|FORK_LOG|FORK_REOPEN_LOG, - NULL); + r = pidref_safe_fork( + "(sd-killer)", + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_WAIT|FORK_LOG|FORK_REOPEN_LOG, + /* ret= */ NULL); if (r < 0) return r; if (r == 0) { diff --git a/src/home/homework-fscrypt.c b/src/home/homework-fscrypt.c index 2d75d5d3fb8..1c700999825 100644 --- a/src/home/homework-fscrypt.c +++ b/src/home/homework-fscrypt.c @@ -115,9 +115,10 @@ int home_flush_keyring_fscrypt(UserRecord *h) { if (!uid_is_valid(h->uid)) return 0; - r = safe_fork("(sd-delkey)", - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_REOPEN_LOG, - NULL); + r = pidref_safe_fork( + "(sd-delkey)", + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_REOPEN_LOG, + /* ret= */ NULL); if (r < 0) return r; if (r == 0) { @@ -409,9 +410,10 @@ int home_setup_fscrypt( /* Also install the access key in the user's own keyring */ if (uid_is_valid(h->uid)) { - r = safe_fork("(sd-addkey)", - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_REOPEN_LOG, - NULL); + r = pidref_safe_fork( + "(sd-addkey)", + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_REOPEN_LOG, + /* ret= */ NULL); if (r < 0) return log_error_errno(r, "Failed to install encryption key in user's keyring: %m"); if (r == 0) { diff --git a/src/import/import-common.c b/src/import/import-common.c index b0a54e8b43f..7be3ffeecce 100644 --- a/src/import/import-common.c +++ b/src/import/import-common.c @@ -301,7 +301,7 @@ int import_mangle_os_tree_fd_foreign( assert(tree_fd >= 0); assert(userns_fd >= 0); - r = safe_fork_full( + r = pidref_safe_fork_full( "mangle-tree", /* stdio_fds= */ NULL, (int[]) { userns_fd, tree_fd }, 2, @@ -401,7 +401,7 @@ int import_copy_foreign( if (r < 0) return r; - r = safe_fork_full( + r = pidref_safe_fork_full( "copy-tree", /* stdio_fds= */ NULL, (int[]) { *userns_fd, source_fd, target_fd }, 3, @@ -459,7 +459,7 @@ int import_remove_tree_foreign(const char *path, int *userns_fd) { if (r < 0) return r; - r = safe_fork_full( + r = pidref_safe_fork_full( "rm-tree", /* stdio_fds= */ NULL, (int[]) { *userns_fd, tree_fd }, 2, diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c index 19e25566d66..35ab12578b2 100644 --- a/src/journal-remote/journal-remote-main.c +++ b/src/journal-remote/journal-remote-main.c @@ -125,16 +125,17 @@ DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR( **********************************************************************/ static int spawn_child(const char *child, char **argv) { - pid_t child_pid; int fd[2], r; if (pipe(fd) < 0) return log_error_errno(errno, "Failed to create pager pipe: %m"); - r = safe_fork_full("(remote)", - (int[]) {STDIN_FILENO, fd[1], STDERR_FILENO }, - NULL, 0, - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &child_pid); + r = pidref_safe_fork_full( + "(remote)", + (int[]) {STDIN_FILENO, fd[1], STDERR_FILENO }, + NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, + /* ret= */ NULL); if (r < 0) { safe_close_pair(fd); return r; diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index 93550a668f7..6bb2ab4c871 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -1026,7 +1026,10 @@ static int connect_as(int fd, const struct sockaddr *sa, socklen_t salen, uid_t if (pipe2(pfd, O_CLOEXEC) < 0) return -errno; - r = safe_fork("(sd-setresuid)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_WAIT, /* ret= */ NULL); + r = pidref_safe_fork( + "(sd-setresuid)", + FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_WAIT, + /* ret= */ NULL); if (r < 0) return r; if (r == 0) { diff --git a/src/libsystemd/sd-bus/test-bus-cleanup.c b/src/libsystemd/sd-bus/test-bus-cleanup.c index 7c9899e129f..9468e9a412e 100644 --- a/src/libsystemd/sd-bus/test-bus-cleanup.c +++ b/src/libsystemd/sd-bus/test-bus-cleanup.c @@ -26,7 +26,7 @@ static void test_bus_fork(void) { assert_se(bus->n_ref == 1); /* Check that after a fork the cleanup functions return NULL */ - r = safe_fork("(bus-fork-test)", FORK_WAIT|FORK_LOG, NULL); + r = pidref_safe_fork("(bus-fork-test)", FORK_WAIT|FORK_LOG, NULL); if (r == 0) { assert_se(bus); ASSERT_RETURN_EXPECTED_SE(sd_bus_is_ready(bus) == -ECHILD); diff --git a/src/libsystemd/sd-device/test-sd-device.c b/src/libsystemd/sd-device/test-sd-device.c index 638598125a8..40a40a70bf0 100644 --- a/src/libsystemd/sd-device/test-sd-device.c +++ b/src/libsystemd/sd-device/test-sd-device.c @@ -39,7 +39,10 @@ TEST(mdio_bus) { if (running_in_chroot() > 0) return (void) log_tests_skipped("Running in chroot"); - ASSERT_OK(r = safe_fork("(mdio_bus)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL)); + r = ASSERT_OK(pidref_safe_fork( + "(mdio_bus)", + FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, + NULL)); if (r == 0) { const char *syspath = "/sys/bus/mdio_bus/drivers/Qualcomm Atheros AR8031!AR8033"; const char *id = "+drivers:mdio_bus:Qualcomm Atheros AR8031!AR8033"; diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c index 20c0ac73858..c1cfa3533a2 100644 --- a/src/libsystemd/sd-event/test-event.c +++ b/src/libsystemd/sd-event/test-event.c @@ -851,7 +851,7 @@ TEST(fork) { ASSERT_OK_ZERO(sd_event_prepare(e)); /* Check that after a fork the cleanup functions return NULL */ - r = safe_fork("(bus-fork-test)", FORK_WAIT|FORK_LOG, NULL); + r = pidref_safe_fork("(bus-fork-test)", FORK_WAIT|FORK_LOG, NULL); if (r == 0) { ASSERT_NOT_NULL(e); ASSERT_NULL(sd_event_ref(e)); diff --git a/src/libsystemd/sd-journal/test-journal-init.c b/src/libsystemd/sd-journal/test-journal-init.c index 7f7e12fbdd9..11f51064207 100644 --- a/src/libsystemd/sd-journal/test-journal-init.c +++ b/src/libsystemd/sd-journal/test-journal-init.c @@ -43,7 +43,7 @@ int main(int argc, char *argv[]) { assert_se(sd_journal_seek_head(j) == 0); assert_se(j->current_location.type == LOCATION_HEAD); - r = safe_fork("(journal-fork-test)", FORK_WAIT|FORK_LOG, NULL); + r = pidref_safe_fork("(journal-fork-test)", FORK_WAIT|FORK_LOG, NULL); if (r == 0) { assert_se(j); ASSERT_RETURN_EXPECTED_SE(sd_journal_get_realtime_usec(j, NULL) == -ECHILD); diff --git a/src/locale/localed-util.c b/src/locale/localed-util.c index 2842570ddac..0d7c1789910 100644 --- a/src/locale/localed-util.c +++ b/src/locale/localed-util.c @@ -573,10 +573,12 @@ int locale_gen_enable_locale(const char *locale) { int locale_gen_run(void) { #if HAVE_LOCALEGEN - pid_t pid; int r; - r = safe_fork("(sd-localegen)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_WAIT, &pid); + r = pidref_safe_fork( + "(locale-gen)", + FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_WAIT, + /* ret= */ NULL); if (r < 0) return r; if (r == 0) { diff --git a/src/login/logind-brightness.c b/src/login/logind-brightness.c index 47f6e2d18fa..3fede8fb2f0 100644 --- a/src/login/logind-brightness.c +++ b/src/login/logind-brightness.c @@ -9,6 +9,7 @@ #include "alloc-util.h" #include "bus-message-util.h" #include "device-util.h" +#include "event-util.h" #include "format-util.h" #include "hash-funcs.h" #include "logind.h" @@ -42,8 +43,6 @@ typedef struct BrightnessWriter { sd_device *device; char *path; - pid_t child; - uint32_t brightness; bool again; @@ -111,8 +110,6 @@ static int on_brightness_writer_exit(sd_event_source *s, const siginfo_t *si, vo assert(s); assert(si); - assert(si->si_pid == w->child); - w->child = 0; w->child_event_source = sd_event_source_unref(w->child_event_source); brightness_writer_reply(w, @@ -142,10 +139,13 @@ static int brightness_writer_fork(BrightnessWriter *w) { assert(w); assert(w->manager); - assert(w->child == 0); assert(!w->child_event_source); - r = safe_fork("(sd-bright)", FORK_DEATHSIG_SIGKILL|FORK_REARRANGE_STDIO|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &w->child); + _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL; + r = pidref_safe_fork( + "(sd-bright)", + FORK_DEATHSIG_SIGKILL|FORK_REARRANGE_STDIO|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, + &pidref); if (r < 0) return r; if (r == 0) { @@ -163,9 +163,15 @@ static int brightness_writer_fork(BrightnessWriter *w) { _exit(EXIT_SUCCESS); } - r = sd_event_add_child(w->manager->event, &w->child_event_source, w->child, WEXITED, on_brightness_writer_exit, w); + r = event_add_child_pidref(w->manager->event, &w->child_event_source, &pidref, WEXITED, on_brightness_writer_exit, w); + if (r < 0) + return log_error_errno(r, "Failed to watch brightness writer child " PID_FMT ": %m", pidref.pid); + + r = sd_event_source_set_child_process_own(w->child_event_source, true); if (r < 0) - return log_error_errno(r, "Failed to watch brightness writer child " PID_FMT ": %m", w->child); + return log_error_errno(r, "Failed to take ownership of child process: %m"); + + pidref_done(&pidref); return 0; } diff --git a/src/mountfsd/mountfsd-manager.c b/src/mountfsd/mountfsd-manager.c index 1cbe6c182ca..b4c5655c51d 100644 --- a/src/mountfsd/mountfsd-manager.c +++ b/src/mountfsd/mountfsd-manager.c @@ -15,6 +15,7 @@ #include "log.h" #include "mountfsd-manager.h" #include "pidfd-util.h" +#include "pidref.h" #include "process-util.h" #include "set.h" #include "signal-util.h" @@ -125,19 +126,19 @@ Manager* manager_free(Manager *m) { static int start_one_worker(Manager *m) { _cleanup_(sd_event_source_disable_unrefp) sd_event_source *source = NULL; bool fixed; - pid_t pid; int r; assert(m); fixed = set_size(m->workers_fixed) < MOUNTFS_WORKERS_MIN; - r = safe_fork_full( + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; + r = pidref_safe_fork_full( "(sd-worker)", /* stdio_fds= */ NULL, &m->listen_fd, 1, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_CLOSE_ALL_FDS, - &pid); + &pidref); if (r < 0) return log_error_errno(r, "Failed to fork new worker child: %m"); if (r == 0) { @@ -158,7 +159,7 @@ static int start_one_worker(Manager *m) { safe_close(m->listen_fd); } - r = setenvf("LISTEN_PID", /* overwrite= */ true, PID_FMT, pid); + r = setenvf("LISTEN_PID", /* overwrite= */ true, PID_FMT, pidref.pid); if (r < 0) { log_error_errno(r, "Failed to set $LISTEN_PID: %m"); _exit(EXIT_FAILURE); @@ -194,9 +195,9 @@ static int start_one_worker(Manager *m) { _exit(EXIT_FAILURE); } - r = sd_event_add_child(m->event, &source, pid, WEXITED, on_worker_exit, m); + r = event_add_child_pidref(m->event, &source, &pidref, WEXITED, on_worker_exit, m); if (r < 0) - return log_error_errno(r, "Failed to watch child " PID_FMT ": %m", pid); + return log_error_errno(r, "Failed to watch child " PID_FMT ": %m", pidref.pid); r = set_ensure_put( fixed ? &m->workers_fixed : &m->workers_dynamic, diff --git a/src/nspawn/nspawn-network.c b/src/nspawn/nspawn-network.c index f509e7d6728..c7e5c417cab 100644 --- a/src/nspawn/nspawn-network.c +++ b/src/nspawn/nspawn-network.c @@ -513,7 +513,10 @@ static int netns_fork_and_wait(int netns_fd, int *ret_original_netns_fd) { assert(netns_fd >= 0); - r = safe_fork("(sd-netns)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL); + r = pidref_safe_fork( + "(sd-netns)", + FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, + /* ret= */ NULL); if (r < 0) return log_error_errno(r, "Failed to fork process (sd-netns): %m"); if (r == 0) { diff --git a/src/nsresourced/nsresourced-manager.c b/src/nsresourced/nsresourced-manager.c index 59cdce6cb06..664cb2d1a2a 100644 --- a/src/nsresourced/nsresourced-manager.c +++ b/src/nsresourced/nsresourced-manager.c @@ -22,6 +22,7 @@ #include "nsresourced-manager.h" #include "parse-util.h" #include "pidfd-util.h" +#include "pidref.h" #include "process-util.h" #include "recurse-dir.h" #include "set.h" @@ -162,19 +163,19 @@ static size_t manager_current_workers(Manager *m) { static int start_one_worker(Manager *m) { _cleanup_(sd_event_source_disable_unrefp) sd_event_source *source = NULL; bool fixed; - pid_t pid; int r; assert(m); fixed = set_size(m->workers_fixed) < NSRESOURCE_WORKERS_MIN; - r = safe_fork_full( + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; + r = pidref_safe_fork_full( "(sd-worker)", /* stdio_fds= */ NULL, &m->listen_fd, 1, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_CLOSE_ALL_FDS, - &pid); + &pidref); if (r < 0) return log_error_errno(r, "Failed to fork new worker child: %m"); if (r == 0) { @@ -195,7 +196,7 @@ static int start_one_worker(Manager *m) { safe_close(m->listen_fd); } - r = setenvf("LISTEN_PID", /* overwrite= */ true, PID_FMT, pid); + r = setenvf("LISTEN_PID", /* overwrite= */ true, PID_FMT, pidref.pid); if (r < 0) { log_error_errno(r, "Failed to set $LISTEN_PID: %m"); _exit(EXIT_FAILURE); @@ -243,9 +244,9 @@ static int start_one_worker(Manager *m) { _exit(EXIT_FAILURE); } - r = sd_event_add_child(m->event, &source, pid, WEXITED, on_worker_exit, m); + r = event_add_child_pidref(m->event, &source, &pidref, WEXITED, on_worker_exit, m); if (r < 0) - return log_error_errno(r, "Failed to watch child " PID_FMT ": %m", pid); + return log_error_errno(r, "Failed to watch child " PID_FMT ": %m", pidref.pid); r = set_ensure_put( fixed ? &m->workers_fixed : &m->workers_dynamic, diff --git a/src/oom/test-oomd-util.c b/src/oom/test-oomd-util.c index 87a5b03f560..04db1e85ea0 100644 --- a/src/oom/test-oomd-util.c +++ b/src/oom/test-oomd-util.c @@ -12,6 +12,7 @@ #include "oomd-util.h" #include "parse-util.h" #include "path-util.h" +#include "pidref.h" #include "process-util.h" #include "set.h" #include "tests.h" @@ -39,11 +40,10 @@ static int enter_cgroup_root_cached(void) { return saved_result; } -static int fork_and_sleep(unsigned sleep_min) { - pid_t pid; +static int fork_and_sleep(unsigned sleep_min, PidRef *ret) { int r; - ASSERT_OK(r = safe_fork("(test-oom-child)", /* flags= */ 0, &pid)); + r = pidref_safe_fork("(test-oom-child)", FORK_LOG|FORK_DEATHSIG_SIGKILL, ret); if (r == 0) { usec_t timeout = usec_add(now(CLOCK_MONOTONIC), sleep_min * USEC_PER_MINUTE); for (;;) { @@ -56,7 +56,7 @@ static int fork_and_sleep(unsigned sleep_min) { } } - return pid; + return r; } TEST(oomd_cgroup_kill) { @@ -81,12 +81,12 @@ TEST(oomd_cgroup_kill) { /* Do this twice to also check the increment behavior on the xattrs */ for (size_t i = 0; i < 2; i++) { _cleanup_free_ char *v = NULL; - pid_t pid[2]; + _cleanup_(pidref_done) PidRef one = PIDREF_NULL, two = PIDREF_NULL; - for (size_t j = 0; j < 2; j++) { - pid[j] = fork_and_sleep(5); - ASSERT_OK(cg_attach(subcgroup, pid[j])); - } + ASSERT_OK(fork_and_sleep(5, &one)); + ASSERT_OK(cg_attach(subcgroup, one.pid)); + ASSERT_OK(fork_and_sleep(5, &two)); + ASSERT_OK(cg_attach(subcgroup, two.pid)); ASSERT_OK_POSITIVE(oomd_cgroup_kill(subcgroup, false /* recurse */, false /* dry run */)); diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c index cc7d9d788c8..52af13fa133 100644 --- a/src/quotacheck/quotacheck.c +++ b/src/quotacheck/quotacheck.c @@ -99,7 +99,10 @@ static int run(int argc, char *argv[]) { return log_oom(); } - r = safe_fork("(quotacheck)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_WAIT|FORK_LOG, NULL); + r = pidref_safe_fork( + "(quotacheck)", + FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_WAIT|FORK_LOG, + /* ret= */ NULL); if (r < 0) return r; if (r == 0) { diff --git a/src/remount-fs/remount-fs.c b/src/remount-fs/remount-fs.c index be74d553c5a..698bb80a4fc 100644 --- a/src/remount-fs/remount-fs.c +++ b/src/remount-fs/remount-fs.c @@ -15,6 +15,7 @@ #include "main-func.h" #include "mount-setup.h" #include "path-util.h" +#include "pidref.h" #include "process-util.h" #include "signal-util.h" @@ -42,15 +43,17 @@ static int track_pid(Hashmap **h, const char *path, pid_t pid) { } static int do_remount(const char *path, bool force_rw, Hashmap **pids) { - pid_t pid; int r; assert(path); log_debug("Remounting %s...", path); - r = safe_fork(force_rw ? "(remount-rw)" : "(remount)", - FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid); + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; + r = pidref_safe_fork( + force_rw ? "(remount-rw)" : "(remount)", + FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, + &pidref); if (r < 0) return r; if (r == 0) { @@ -65,7 +68,7 @@ static int do_remount(const char *path, bool force_rw, Hashmap **pids) { } /* Parent */ - return track_pid(pids, path, pid); + return track_pid(pids, path, pidref.pid); } static int remount_by_fstab(Hashmap **ret_pids) { diff --git a/src/repart/repart.c b/src/repart/repart.c index 706349a2cf4..ef80da0dce1 100644 --- a/src/repart/repart.c +++ b/src/repart/repart.c @@ -6719,7 +6719,10 @@ static int partition_populate_filesystem(Context *context, Partition *p, const c (void) dlopen_libmount(); - r = safe_fork("(sd-copy)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL); + r = pidref_safe_fork( + "(sd-copy)", + FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, + /* ret= */ NULL); if (r < 0) return r; if (r == 0) { diff --git a/src/resolve/test-resolved-stream.c b/src/resolve/test-resolved-stream.c index 36c3c1ac31e..9e6e7bc0508 100644 --- a/src/resolve/test-resolved-stream.c +++ b/src/resolve/test-resolved-stream.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include "sd-event.h" @@ -20,6 +19,7 @@ #include "fd-util.h" #include "log.h" #include "path-util.h" +#include "pidref.h" #include "process-util.h" #include "random-util.h" #include "resolved-dns-server.h" @@ -121,7 +121,6 @@ static void *tcp_dns_server(void *p) { * Spawns a DNS TLS server using the command line "openssl s_server" tool. */ static void *tls_dns_server(void *p) { - pid_t openssl_pid; int r; _cleanup_close_ int fd_server = -EBADF, fd_tls = -EBADF; _cleanup_free_ char *cert_path = NULL, *key_path = NULL; @@ -145,12 +144,13 @@ static void *tls_dns_server(void *p) { fd_tls = fd[1]; } - r = safe_fork_full("(test-resolved-stream-tls-openssl)", - (int[]) { fd_tls, fd_tls, STDOUT_FILENO }, - NULL, 0, - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_REOPEN_LOG, - &openssl_pid); - assert_se(r >= 0); + _cleanup_(pidref_done) PidRef openssl_pidref = PIDREF_NULL; + r = ASSERT_OK(pidref_safe_fork_full( + "(test-resolved-stream-tls-openssl)", + (int[]) { fd_tls, fd_tls, STDOUT_FILENO }, + NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_REOPEN_LOG, + &openssl_pidref)); if (r == 0) { /* Child */ execlp("openssl", "openssl", "s_server", "-accept", bind_str, @@ -165,8 +165,8 @@ static void *tls_dns_server(void *p) { /* Once the test is done kill the TLS server to release the port */ assert_se(pthread_mutex_lock(server_lock) == 0); - assert_se(kill(openssl_pid, SIGTERM) >= 0); - assert_se(waitpid(openssl_pid, NULL, 0) >= 0); + assert_se(pidref_kill(&openssl_pidref, SIGTERM) >= 0); + assert_se(pidref_wait_for_terminate(&openssl_pidref, NULL) >= 0); assert_se(pthread_mutex_unlock(server_lock) == 0); } @@ -333,7 +333,7 @@ static int try_isolate_network(void) { /* First test if CLONE_NEWUSER/CLONE_NEWNET can actually work for us, i.e. we can open the namespaces * and then still access the build dir we are run from. We do that in a child process since it's * nasty if we have to go back from the namespace once we entered it and realized it cannot work. */ - r = safe_fork("(usernstest)", FORK_DEATHSIG_SIGKILL|FORK_LOG|FORK_WAIT, NULL); + r = pidref_safe_fork("(usernstest)", FORK_DEATHSIG_SIGKILL|FORK_LOG|FORK_WAIT, NULL); if (r == 0) { /* child */ _cleanup_free_ char *rt = NULL, *d = NULL; diff --git a/src/shared/async.c b/src/shared/async.c index 0d5fbc13a7b..f4843deb78a 100644 --- a/src/shared/async.c +++ b/src/shared/async.c @@ -149,7 +149,7 @@ int asynchronous_rm_rf(const char *p, RemoveFlags flags) { /* Forks off a child that destroys the specified path. This will be best effort only, i.e. the child * will attempt to do its thing, but we won't wait for it or check its success. */ - r = safe_fork("(sd-rmrf)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DETACH, NULL); + r = pidref_safe_fork("(sd-rmrf)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DETACH, /* ret= */ NULL); if (r != 0) return r; diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c index bccd1590798..9904d5491bc 100644 --- a/src/shared/discover-image.c +++ b/src/shared/discover-image.c @@ -1155,7 +1155,7 @@ static int unprivileged_remove(Image *i) { if (r < 0) return r; /* Fork off child that moves into userns and does the copying */ - r = safe_fork_full( + r = pidref_safe_fork_full( "rm-tree", /* stdio_fds= */ NULL, (int[]) { userns_fd, tree_fd, }, 2, @@ -1508,7 +1508,7 @@ static int unpriviled_clone(Image *i, const char *new_path) { return r; /* Fork off child that moves into userns and does the copying */ - r = safe_fork_full( + r = pidref_safe_fork_full( "clone-tree", /* stdio_fds= */ NULL, (int[]) { userns_fd, tree_fd, target_fd }, 3, diff --git a/src/shared/edit-util.c b/src/shared/edit-util.c index 3ebf4a88cda..e5d976fb009 100644 --- a/src/shared/edit-util.c +++ b/src/shared/edit-util.c @@ -313,7 +313,10 @@ static int run_editor(const EditFileContext *context) { assert(context); - r = safe_fork("(editor)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_LOG|FORK_WAIT, NULL); + r = pidref_safe_fork( + "(editor)", + FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_LOG|FORK_WAIT, + /* ret= */ NULL); if (r < 0) return r; if (r == 0) { /* Child */ diff --git a/src/shared/elf-util.c b/src/shared/elf-util.c index 9a09352ca7f..6097b4cf9ea 100644 --- a/src/shared/elf-util.c +++ b/src/shared/elf-util.c @@ -857,12 +857,12 @@ int parse_elf_object( * bound since the core files have an upper size limit. It's also not doing any * system call or interacting with the system in any way, besides reading from * the file descriptor and writing into these four pipes. */ - r = safe_fork_full("(sd-parse-elf)", - NULL, + r = pidref_safe_fork_full("(sd-parse-elf)", + /* stdio_fds= */ NULL, (int[]){ fd, error_pipe[1], return_pipe[1], package_metadata_pipe[1], dlopen_metadata_pipe[1] }, 5, FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_NEW_USERNS|FORK_WAIT|FORK_REOPEN_LOG, - NULL); + /* ret= */ NULL); if (r < 0) { if (r == -EPROTO) { /* We should have the errno from the child, but don't clobber original error */ ssize_t k; diff --git a/src/shared/mkfs-util.c b/src/shared/mkfs-util.c index be9b30b47e0..3f00f803c45 100644 --- a/src/shared/mkfs-util.c +++ b/src/shared/mkfs-util.c @@ -152,7 +152,10 @@ static int do_mcopy(const char *node, const char *root) { if (strv_extend(&argv, "::") < 0) return log_oom(); - r = safe_fork("(mcopy)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS, NULL); + r = pidref_safe_fork( + "(mcopy)", + FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS, + /* ret= */ NULL); if (r < 0) return r; if (r == 0) { @@ -683,7 +686,7 @@ int make_filesystem( log_debug("Executing mkfs command: %s", strna(j)); } - r = safe_fork_full( + r = pidref_safe_fork_full( "(mkfs)", stdio_fds, /* except_fds= */ NULL, diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index d98a9616fcb..31b1ca2b363 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -1452,7 +1452,7 @@ int mount_fd_clone(int mount_fd, bool recursive, int *replacement_fd) { return log_debug_errno(errno, "Failed to open pipe: %m"); /* Fork a child. Note that we set FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE here, i.e. get a new mount namespace */ - r = safe_fork_full( + r = pidref_safe_fork_full( "(sd-clonemnt)", /* stdio_fds= */ NULL, (int[]) { mount_fd, transfer_fds[1], errno_pipe_fds[1] }, 3, diff --git a/src/shared/pager.c b/src/shared/pager.c index 203e6503889..d7d9f425965 100644 --- a/src/shared/pager.c +++ b/src/shared/pager.c @@ -21,7 +21,7 @@ #include "strv.h" #include "terminal-util.h" -static pid_t pager_pid = 0; +static PidRef pager_pidref = PIDREF_NULL; static int stored_stdout = -1; static int stored_stderr = -1; @@ -103,7 +103,7 @@ void pager_open(PagerFlags flags) { if (flags & PAGER_DISABLE) return; - if (pager_pid > 0) + if (pidref_is_set(&pager_pidref)) return; if (terminal_is_dumb()) @@ -150,7 +150,10 @@ void pager_open(PagerFlags flags) { } /* We set SIGINT as PR_DEATHSIG signal here, to match the "K" parameter we set in $LESS, which enables SIGINT behaviour. */ - r = safe_fork("(pager)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGINT|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pager_pid); + r = pidref_safe_fork( + "(pager)", + FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGINT|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, + &pager_pidref); if (r < 0) return; if (r == 0) { @@ -272,7 +275,7 @@ void pager_open(PagerFlags flags) { void pager_close(void) { - if (pager_pid <= 0) + if (!pidref_is_set(&pager_pidref)) return; /* Inform pager that we are done */ @@ -288,15 +291,13 @@ void pager_close(void) { stored_stderr = safe_close(stored_stderr); stdout_redirected = stderr_redirected = false; - (void) kill(pager_pid, SIGCONT); - _cleanup_(pidref_done) PidRef pidref = PIDREF_MAKE_FROM_PID(pager_pid); - (void) pidref_set_pid(&pidref, pager_pid); - (void) pidref_wait_for_terminate(&pidref, NULL); - TAKE_PID(pager_pid); + (void) pidref_kill(&pager_pidref, SIGCONT); + (void) pidref_wait_for_terminate(&pager_pidref, /* ret_si= */ NULL); + pidref_done(&pager_pidref); } bool pager_have(void) { - return pager_pid > 0; + return pidref_is_set(&pager_pidref); } int show_man_page(const char *desc, bool null_stdio) { diff --git a/src/shutdown/shutdown.c b/src/shutdown/shutdown.c index 3c80c8e4568..75872f2eda8 100644 --- a/src/shutdown/shutdown.c +++ b/src/shutdown/shutdown.c @@ -611,7 +611,10 @@ int main(int argc, char *argv[]) { /* We cheat and exec kexec to avoid doing all its work */ log_info("Rebooting with kexec."); - r = safe_fork("(sd-kexec)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_WAIT, NULL); + r = pidref_safe_fork( + "(sd-kexec)", + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_WAIT, + /* ret= */ NULL); if (r == 0) { /* Child */ diff --git a/src/socket-activate/socket-activate.c b/src/socket-activate/socket-activate.c index 29940ac354c..e7102b62a1a 100644 --- a/src/socket-activate/socket-activate.c +++ b/src/socket-activate/socket-activate.c @@ -18,6 +18,7 @@ #include "log.h" #include "main-func.h" #include "pidfd-util.h" +#include "pidref.h" #include "pretty-print.h" #include "process-util.h" #include "socket-netlink.h" @@ -238,7 +239,6 @@ static int exec_process(char * const *argv, int start_fd, size_t n_fds) { static int fork_and_exec_process(char * const *argv, int fd) { _cleanup_free_ char *joined = NULL; - pid_t child_pid; int r; assert(!strv_isempty(argv)); @@ -248,9 +248,11 @@ static int fork_and_exec_process(char * const *argv, int fd) { if (!joined) return log_oom(); - r = safe_fork("(activate)", - FORK_RESET_SIGNALS | FORK_DEATHSIG_SIGTERM | FORK_RLIMIT_NOFILE_SAFE | FORK_LOG, - &child_pid); + _cleanup_(pidref_done) PidRef child_pidref = PIDREF_NULL; + r = pidref_safe_fork( + "(activate)", + FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, + &child_pidref); if (r < 0) return r; if (r == 0) { @@ -259,7 +261,7 @@ static int fork_and_exec_process(char * const *argv, int fd) { _exit(EXIT_FAILURE); } - log_info("Spawned '%s' as PID " PID_FMT ".", joined, child_pid); + log_info("Spawned '%s' as PID " PID_FMT ".", joined, child_pidref.pid); return 0; } diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c index 931aadea4c0..221f4f9f876 100644 --- a/src/sysext/sysext.c +++ b/src/sysext/sysext.c @@ -557,7 +557,10 @@ static int unmerge( return r; need_to_reload = r > 0; - r = safe_fork("(sd-unmerge)", FORK_WAIT|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_NEW_MOUNTNS, /* ret= */ NULL); + r = pidref_safe_fork( + "(sd-unmerge)", + FORK_WAIT|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_NEW_MOUNTNS, + /* ret= */ NULL); if (r < 0) return r; if (r == 0) { diff --git a/src/systemctl/systemctl-start-special.c b/src/systemctl/systemctl-start-special.c index 78cbceed7e1..71927846dee 100644 --- a/src/systemctl/systemctl-start-special.c +++ b/src/systemctl/systemctl-start-special.c @@ -26,7 +26,6 @@ static int load_kexec_kernel(void) { _cleanup_(boot_config_free) BootConfig config = BOOT_CONFIG_NULL; _cleanup_free_ char *kernel = NULL, *initrd = NULL, *options = NULL; const BootEntry *e; - pid_t pid; int r; if (kexec_loaded()) { @@ -89,7 +88,10 @@ static int load_kexec_kernel(void) { if (arg_dry_run) return 0; - r = safe_fork("(kexec)", FORK_WAIT|FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid); + r = pidref_safe_fork( + "(kexec)", + FORK_WAIT|FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, + /* ret= */ NULL); if (r < 0) return r; if (r == 0) { diff --git a/src/test/test-argv-util.c b/src/test/test-argv-util.c index 153278efb3f..df844db30a3 100644 --- a/src/test/test-argv-util.c +++ b/src/test/test-argv-util.c @@ -63,7 +63,7 @@ static void test_rename_process_one(const char *p, int ret) { log_info("/* %s(%s) */", __func__, p); - r = ASSERT_OK(safe_fork("(rename)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret= */ NULL)); + r = ASSERT_OK(pidref_safe_fork("(rename)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret= */ NULL)); if (r == 0) { /* child */ @@ -80,7 +80,7 @@ TEST(rename_process_invalid) { TEST(rename_process_multi) { int r; - r = ASSERT_OK(safe_fork("(rename)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret= */ NULL)); + r = ASSERT_OK(pidref_safe_fork("(rename)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret= */ NULL)); if (r == 0) { /* child */ diff --git a/src/test/test-async.c b/src/test/test-async.c index 46156d724dc..f36190436fb 100644 --- a/src/test/test-async.c +++ b/src/test/test-async.c @@ -42,8 +42,10 @@ TEST(asynchronous_close) { asynchronous_close(fd); wait_fd_closed(fd); - r = safe_fork("(subreaper)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_LOG|FORK_WAIT, NULL); - ASSERT_OK(r); + r = ASSERT_OK(pidref_safe_fork( + "(subreaper)", + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_LOG|FORK_WAIT, + NULL)); if (r == 0) { /* child */ @@ -84,8 +86,10 @@ TEST(asynchronous_rm_rf) { /* Do this once more, from a subreaper. Which is nice, because we can watch the async child even * though detached */ - r = safe_fork("(subreaper)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_WAIT, NULL); - ASSERT_OK(r); + r = ASSERT_OK(pidref_safe_fork( + "(subreaper)", + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_WAIT, + NULL)); if (r == 0) { _cleanup_free_ char *tt = NULL, *kk = NULL; diff --git a/src/test/test-capability-util.c b/src/test/test-capability-util.c index 944c96da784..6313d088ab4 100644 --- a/src/test/test-capability-util.c +++ b/src/test/test-capability-util.c @@ -224,8 +224,10 @@ static void test_capability_get_ambient(void) { if (r <= 0) return (void) log_tests_skipped("Lacking CAP_LINUX_IMMUTABLE, skipping getambient test."); - r = safe_fork("(getambient)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG, NULL); - ASSERT_OK(r); + r = ASSERT_OK(pidref_safe_fork( + "(getambient)", + FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG, + NULL)); if (r == 0) { int x, y; diff --git a/src/test/test-env-util.c b/src/test/test-env-util.c index d45f210689a..281ea7951cb 100644 --- a/src/test/test-env-util.c +++ b/src/test/test-env-util.c @@ -494,7 +494,7 @@ TEST(setenv_systemd_exec_pid) { TEST(getenv_steal_erase) { int r; - r = safe_fork("(sd-getenvstealerase)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL); + r = pidref_safe_fork("(sd-getenvstealerase)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL); if (r == 0) { _cleanup_strv_free_ char **l = NULL; diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 1c787757424..55b7c08924d 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -17,6 +17,7 @@ #include "cpu-set-util.h" #include "dropin.h" #include "errno-list.h" +#include "event-util.h" #include "extract-word.h" #include "fd-util.h" #include "fileio.h" @@ -671,11 +672,9 @@ reenable: } static int on_spawn_timeout(sd_event_source *s, uint64_t usec, void *userdata) { - pid_t *pid = userdata; + PidRef *pidref = ASSERT_PTR(userdata); - ASSERT_NOT_NULL(pid); - - (void) kill(*pid, SIGKILL); + (void) pidref_kill(pidref, SIGKILL); return 1; } @@ -700,7 +699,6 @@ static int find_libraries(const char *exec, char ***ret) { _cleanup_close_pair_ int outpipe[2] = EBADF_PAIR, errpipe[2] = EBADF_PAIR; _cleanup_strv_free_ char **libraries = NULL; _cleanup_free_ char *result = NULL; - pid_t pid; int r; ASSERT_NOT_NULL(exec); @@ -709,10 +707,13 @@ static int find_libraries(const char *exec, char ***ret) { ASSERT_OK_ERRNO(pipe2(outpipe, O_NONBLOCK|O_CLOEXEC)); ASSERT_OK_ERRNO(pipe2(errpipe, O_NONBLOCK|O_CLOEXEC)); - r = safe_fork_full("(spawn-ldd)", - (int[]) { -EBADF, outpipe[1], errpipe[1] }, - NULL, 0, - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG, &pid); + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; + r = pidref_safe_fork_full( + "(spawn-ldd)", + (int[]) { -EBADF, outpipe[1], errpipe[1] }, + NULL, 0, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG, + &pidref); ASSERT_OK(r); if (r == 0) { execlp("ldd", "ldd", exec, NULL); @@ -725,12 +726,12 @@ static int find_libraries(const char *exec, char ***ret) { ASSERT_OK(sd_event_new(&e)); ASSERT_OK(sd_event_add_time_relative(e, NULL, CLOCK_MONOTONIC, - 10 * USEC_PER_SEC, USEC_PER_SEC, on_spawn_timeout, &pid)); + 10 * USEC_PER_SEC, USEC_PER_SEC, on_spawn_timeout, &pidref)); ASSERT_OK(sd_event_add_io(e, &stdout_source, outpipe[0], EPOLLIN, on_spawn_io, &result)); ASSERT_OK(sd_event_source_set_enabled(stdout_source, SD_EVENT_ONESHOT)); ASSERT_OK(sd_event_add_io(e, &stderr_source, errpipe[0], EPOLLIN, on_spawn_io, NULL)); ASSERT_OK(sd_event_source_set_enabled(stderr_source, SD_EVENT_ONESHOT)); - ASSERT_OK(sd_event_add_child(e, &sigchld_source, pid, WEXITED, on_spawn_exit, NULL)); + ASSERT_OK(event_add_child_pidref(e, &sigchld_source, &pidref, WEXITED, on_spawn_exit, NULL)); /* Child exit should be processed after IO is complete */ ASSERT_OK(sd_event_source_set_priority(sigchld_source, SD_EVENT_PRIORITY_NORMAL + 1)); @@ -1464,16 +1465,17 @@ static void run_tests(RuntimeScope scope, char **patterns) { static int prepare_ns(const char *process_name) { int r; - r = safe_fork(process_name, - FORK_RESET_SIGNALS | - FORK_CLOSE_ALL_FDS | - FORK_DEATHSIG_SIGTERM | - FORK_WAIT | - FORK_REOPEN_LOG | - FORK_LOG | - FORK_NEW_MOUNTNS | - FORK_MOUNTNS_SLAVE, - NULL); + r = pidref_safe_fork( + process_name, + FORK_RESET_SIGNALS| + FORK_CLOSE_ALL_FDS| + FORK_DEATHSIG_SIGTERM| + FORK_WAIT| + FORK_REOPEN_LOG| + FORK_LOG| + FORK_NEW_MOUNTNS| + FORK_MOUNTNS_SLAVE, + NULL); ASSERT_OK(r); if (r == 0) { _cleanup_free_ char *unit_dir = NULL, *build_dir = NULL, *build_dir_mount = NULL; diff --git a/src/test/test-fd-util.c b/src/test/test-fd-util.c index db869b5d11c..5a8b58440b8 100644 --- a/src/test/test-fd-util.c +++ b/src/test/test-fd-util.c @@ -157,10 +157,9 @@ TEST(fd_move_above_stdio) { } TEST(rearrange_stdio) { - pid_t pid; int r; - r = safe_fork("rearrange", FORK_WAIT|FORK_LOG, &pid); + r = pidref_safe_fork("rearrange", FORK_WAIT|FORK_LOG, NULL); assert_se(r >= 0); if (r == 0) { @@ -335,27 +334,28 @@ static void test_close_all_fds_inner(int (*func)(const int except[], size_t n_ex } TEST(close_all_fds) { + ForkFlags flags = FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT; int r; - ASSERT_OK(r = safe_fork("(caf-plain)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(caf-plain)", flags, NULL)); if (r == 0) { test_close_all_fds_inner(close_all_fds); _exit(EXIT_SUCCESS); } - ASSERT_OK(r = safe_fork("(caf-nomalloc)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL)); + ASSERT_OK(r = pidref_safe_fork("(caf-nomalloc)", flags, NULL)); if (r == 0) { test_close_all_fds_inner(close_all_fds_without_malloc); _exit(EXIT_SUCCESS); } - ASSERT_OK(r = safe_fork("(caf-proc)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL)); + ASSERT_OK(r = pidref_safe_fork("(caf-proc)", flags, NULL)); if (r == 0) { test_close_all_fds_inner(close_all_fds_by_proc); _exit(EXIT_SUCCESS); } - ASSERT_OK(r = safe_fork("(caf-frugal)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL)); + ASSERT_OK(r = pidref_safe_fork("(caf-frugal)", flags, NULL)); if (r == 0) { test_close_all_fds_inner(close_all_fds_frugal); _exit(EXIT_SUCCESS); diff --git a/src/test/test-mempress.c b/src/test/test-mempress.c index 55cbc6e432c..817eaa421f1 100644 --- a/src/test/test-mempress.c +++ b/src/test/test-mempress.c @@ -12,10 +12,12 @@ #include "bus-locator.h" #include "bus-wait-for-jobs.h" +#include "event-util.h" #include "fd-util.h" #include "format-util.h" #include "hashmap.h" #include "path-util.h" +#include "pidref.h" #include "process-util.h" #include "random-util.h" #include "rm-rf.h" @@ -198,7 +200,6 @@ TEST(real_pressure) { _cleanup_free_ char *scope = NULL; const char *object; int r; - pid_t pid; r = sd_bus_open_system(&bus); if (r < 0) @@ -227,14 +228,15 @@ TEST(real_pressure) { assert_se(pipe2(pipe_fd, O_CLOEXEC) >= 0); - r = safe_fork("(eat-memory)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM, &pid); + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; + r = pidref_safe_fork("(eat-memory)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM, &pidref); assert_se(r >= 0); if (r == 0) { real_pressure_eat_memory(pipe_fd[0]); _exit(EXIT_SUCCESS); } - assert_se(sd_event_add_child(e, &cs, pid, WEXITED, real_pressure_child_callback, NULL) >= 0); + assert_se(event_add_child_pidref(e, &cs, &pidref, WEXITED, real_pressure_child_callback, NULL) >= 0); assert_se(sd_event_source_set_child_process_own(cs, true) >= 0); assert_se(unsetenv("MEMORY_PRESSURE_WATCH") >= 0); diff --git a/src/test/test-mkdir.c b/src/test/test-mkdir.c index 0a9183de2f3..65e19d46a38 100644 --- a/src/test/test-mkdir.c +++ b/src/test/test-mkdir.c @@ -80,7 +80,7 @@ TEST(mkdir_p_safe) { p = mfree(p); ASSERT_NOT_NULL(p = path_join(tmp, "zero-mode/should-fail-to-create-child")); ASSERT_OK(mkdir_parents_safe(tmp, p, 0000, UID_INVALID, GID_INVALID, 0)); - ASSERT_OK(r = safe_fork("(test-mkdir-no-cap)", FORK_DEATHSIG_SIGTERM | FORK_WAIT | FORK_LOG, NULL)); + r = ASSERT_OK(pidref_safe_fork("(test-mkdir-no-cap)", FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG, NULL)); if (r == 0) { (void) capability_bounding_set_drop(0, /* right_now= */ true); ASSERT_ERROR(mkdir_p_safe(tmp, p, 0000, UID_INVALID, GID_INVALID, 0), EACCES); diff --git a/src/test/test-mount-util.c b/src/test/test-mount-util.c index 137b58b4d4c..4b232ac598f 100644 --- a/src/test/test-mount-util.c +++ b/src/test/test-mount-util.c @@ -160,7 +160,7 @@ TEST(bind_remount_recursive) { assert_se(mkdir(subdir, 0755) >= 0); FOREACH_STRING(p, "/usr", "/sys", "/", tmp) { - ASSERT_OK(r = safe_fork("(bind-remount-recursive)", FORK_COMMON_FLAGS, NULL)); + r = ASSERT_OK(pidref_safe_fork("(bind-remount-recursive)", FORK_COMMON_FLAGS, NULL)); if (r == 0) { /* child */ struct statvfs svfs; @@ -196,7 +196,7 @@ TEST(bind_remount_one) { CHECK_PRIV; - ASSERT_OK(r = safe_fork("(remount-one-with-mountinfo)", FORK_COMMON_FLAGS, NULL)); + r = ASSERT_OK(pidref_safe_fork("(remount-one-with-mountinfo)", FORK_COMMON_FLAGS, NULL)); if (r == 0) { /* child */ _cleanup_fclose_ FILE *proc_self_mountinfo = NULL; @@ -211,7 +211,7 @@ TEST(bind_remount_one) { _exit(EXIT_SUCCESS); } - ASSERT_OK(r = safe_fork("(remount-one)", FORK_COMMON_FLAGS, NULL)); + r = ASSERT_OK(pidref_safe_fork("(remount-one)", FORK_COMMON_FLAGS, NULL)); if (r == 0) { /* child */ assert_se(bind_remount_one("/run", MS_RDONLY, MS_RDONLY) >= 0); assert_se(bind_remount_one("/run", MS_NOEXEC, MS_RDONLY|MS_NOEXEC) >= 0); @@ -291,7 +291,7 @@ TEST(make_mount_switch_root) { }; FOREACH_ELEMENT(i, table) { - ASSERT_OK(r = safe_fork("(switch-root)", FORK_COMMON_FLAGS, NULL)); + r = ASSERT_OK(pidref_safe_fork("(switch-root)", FORK_COMMON_FLAGS, NULL)); if (r == 0) { assert_se(make_mount_point(i->path) >= 0); assert_se(mount_switch_root_full(i->path, /* mount_propagation_flag= */ 0, i->force_ms_move) >= 0); @@ -335,7 +335,7 @@ TEST(umount_recursive) { CHECK_PRIV; FOREACH_ELEMENT(t, test_table) { - ASSERT_OK(r = safe_fork("(umount-rec)", FORK_COMMON_FLAGS, NULL)); + r = ASSERT_OK(pidref_safe_fork("(umount-rec)", FORK_COMMON_FLAGS, NULL)); if (r == 0) { /* child */ _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; @@ -392,7 +392,7 @@ TEST(fd_make_mount_point) { assert_se(s); assert_se(mkdir(s, 0700) >= 0); - ASSERT_OK(r = safe_fork("(make-mount-point)", FORK_COMMON_FLAGS, NULL)); + r = ASSERT_OK(pidref_safe_fork("(make-mount-point)", FORK_COMMON_FLAGS, NULL)); if (r == 0) { _cleanup_close_ int fd = -EBADF, fd2 = -EBADF; @@ -423,7 +423,7 @@ TEST(bind_mount_submounts) { assert_se(mkdtemp_malloc(NULL, &a) >= 0); assert_se(mkdtemp_malloc(NULL, &b) >= 0); - ASSERT_OK(r = safe_fork("(bind-mount-submounts)", FORK_COMMON_FLAGS, NULL)); + r = ASSERT_OK(pidref_safe_fork("(bind-mount-submounts)", FORK_COMMON_FLAGS, NULL)); if (r == 0) { char *x; @@ -512,7 +512,7 @@ TEST(path_is_network_fs_harder) { _cleanup_(rm_rf_physical_and_freep) char *t = NULL; assert_se(mkdtemp_malloc("/tmp/test-mount-util.path_is_network_fs_harder.XXXXXXX", &t) >= 0); - ASSERT_OK(r = safe_fork("(path-is-network-fs-harder)", FORK_COMMON_FLAGS, NULL)); + r = ASSERT_OK(pidref_safe_fork("(path-is-network-fs-harder)", FORK_COMMON_FLAGS, NULL)); if (r == 0) { ASSERT_OK(mount_nofollow_verbose(LOG_INFO, "tmpfs", t, "tmpfs", 0, NULL)); ASSERT_OK_ZERO(path_is_network_fs_harder(t)); @@ -554,7 +554,7 @@ TEST(mount_fd_clone) { /* Set up a socket pair to transfer the mount fd from the child (in a different mountns) to us. */ ASSERT_OK_ERRNO(socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, fds)); - r = ASSERT_OK(safe_fork_full( + r = ASSERT_OK(pidref_safe_fork_full( "(mount-fd-clone-setup)", /* stdio_fds= */ NULL, &fds[1], 1, @@ -588,7 +588,7 @@ TEST(mount_fd_clone) { _cleanup_free_ char *target = ASSERT_NOT_NULL(path_join(t, "target")); ASSERT_OK_ERRNO(mkdir(target, 0755)); - r = ASSERT_OK(safe_fork_full( + r = ASSERT_OK(pidref_safe_fork_full( "(mount-fd-clone-verify)", /* stdio_fds= */ NULL, &first_clone, 1, diff --git a/src/test/test-namespace.c b/src/test/test-namespace.c index b3ac293be3f..c487fc54ec5 100644 --- a/src/test/test-namespace.c +++ b/src/test/test-namespace.c @@ -220,7 +220,7 @@ TEST(protect_kernel_logs) { } ASSERT_OK(r); - r = ASSERT_OK(safe_fork("(protect)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret= */ NULL)); + r = ASSERT_OK(pidref_safe_fork("(protect)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret= */ NULL)); if (r == 0) { _cleanup_close_ int fd = -EBADF; diff --git a/src/test/test-nss-hosts.c b/src/test/test-nss-hosts.c index 4b82b96d1a7..20d151a4254 100644 --- a/src/test/test-nss-hosts.c +++ b/src/test/test-nss-hosts.c @@ -490,7 +490,7 @@ static int run(int argc, char **argv) { /* Testing with several syscalls filtered, and check if the nss modules gracefully handle failures in * masked syscalls. See issue #38582. */ - r = ASSERT_OK(safe_fork("(with-seccomp)", FORK_LOG|FORK_WAIT, /* ret= */ NULL)); + r = ASSERT_OK(pidref_safe_fork("(with-seccomp)", FORK_LOG|FORK_WAIT, /* ret= */ NULL)); if (r == 0) { _cleanup_hashmap_free_ Hashmap *filter = NULL; ASSERT_NOT_NULL(filter = hashmap_new(NULL)); diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index 2a909e95ddf..41a652648a3 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -475,7 +475,10 @@ static void test_find_executable_exec_one(const char *path) { if (path_is_absolute(path)) ASSERT_STREQ(t, path); - r = ASSERT_OK(safe_fork("(find-exec)", FORK_LOG|FORK_DEATHSIG_SIGKILL|FORK_WAIT, /* ret= */ NULL)); + r = ASSERT_OK(pidref_safe_fork( + "(find-exec)", + FORK_LOG|FORK_DEATHSIG_SIGKILL|FORK_WAIT, + /* ret= */ NULL)); if (r == 0) { r = fexecve_or_execve(fd, t, STRV_MAKE(t, "--version"), STRV_MAKE(NULL)); diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c index 31e79370b52..4c803fbbd9c 100644 --- a/src/test/test-process-util.c +++ b/src/test/test-process-util.c @@ -285,7 +285,7 @@ TEST(pid_get_cmdline_harder) { } #endif - r = ASSERT_OK(safe_fork("(cmdline)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret= */ NULL)); + r = ASSERT_OK(pidref_safe_fork("(cmdline)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret= */ NULL)); if (r == 0) { r = detach_mount_namespace(); if (r < 0) { @@ -573,7 +573,7 @@ TEST(getpid_cached) { ASSERT_EQ(a, b); ASSERT_EQ(a, c); - r = ASSERT_OK(safe_fork("(getpid)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret= */ NULL)); + r = ASSERT_OK(pidref_safe_fork("(getpid)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret= */ NULL)); if (r == 0) { /* In child */ @@ -619,12 +619,13 @@ TEST(getpid_measure) { log_info("getpid_cached(): %lf μs each", (double) q / iterations); } -TEST(safe_fork) { +TEST(pidref_safe_fork) { + _cleanup_(pidref_done) PidRef child = PIDREF_NULL; siginfo_t status; pid_t pid; int r; - r = safe_fork("(test-child)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_REOPEN_LOG, &pid); + r = pidref_safe_fork("(test-child)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_REOPEN_LOG, &child); ASSERT_OK(r); if (r == 0) { @@ -634,9 +635,6 @@ TEST(safe_fork) { _exit(88); } - _cleanup_(pidref_done) PidRef child = PIDREF_NULL; - ASSERT_OK(pidref_set_pid(&child, pid)); - ASSERT_OK(pidref_wait_for_terminate(&child, &status)); ASSERT_EQ(status.si_code, CLD_EXITED); ASSERT_EQ(status.si_status, 88); @@ -710,8 +708,10 @@ TEST(ioprio_class_from_to_string) { TEST(setpriority_closest) { int r; - r = safe_fork("(test-setprio)", - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG|FORK_REOPEN_LOG, NULL); + r = pidref_safe_fork( + "(test-setprio)", + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG|FORK_REOPEN_LOG, + NULL); ASSERT_OK(r); if (r == 0) { @@ -909,7 +909,10 @@ TEST(get_process_threads) { int r; /* Run this test in a child, so that we can guarantee there's exactly one thread around in the child */ - r = safe_fork("(nthreads)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG, NULL); + r = pidref_safe_fork( + "(nthreads)", + FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG, + NULL); ASSERT_OK(r); if (r == 0) { @@ -953,8 +956,10 @@ TEST(get_process_threads) { TEST(is_reaper_process) { int r; - r = safe_fork("(regular)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_WAIT, NULL); - ASSERT_OK(r); + r = ASSERT_OK(pidref_safe_fork( + "(regular)", + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_WAIT, + NULL)); if (r == 0) { /* child */ @@ -962,8 +967,10 @@ TEST(is_reaper_process) { _exit(EXIT_SUCCESS); } - r = safe_fork("(newpid)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_WAIT, NULL); - ASSERT_OK(r); + r = ASSERT_OK(pidref_safe_fork( + "(newpid)", + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_WAIT, + NULL)); if (r == 0) { /* child */ @@ -974,8 +981,10 @@ TEST(is_reaper_process) { } } - r = safe_fork("(newpid1)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_WAIT, NULL); - ASSERT_OK(r); + r = ASSERT_OK(pidref_safe_fork( + "(newpid1)", + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_WAIT, + NULL)); if (r == 0) { /* grandchild, which is PID1 in a pidns */ ASSERT_OK_EQ(getpid_cached(), 1); @@ -986,8 +995,10 @@ TEST(is_reaper_process) { _exit(EXIT_SUCCESS); } - r = safe_fork("(subreaper)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_WAIT, NULL); - ASSERT_OK(r); + r = ASSERT_OK(pidref_safe_fork( + "(subreaper)", + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_WAIT, + NULL)); if (r == 0) { /* child */ ASSERT_OK(make_reaper_process(true)); diff --git a/src/test/test-reread-partition-table.c b/src/test/test-reread-partition-table.c index 3897a306530..61487cb9d1c 100644 --- a/src/test/test-reread-partition-table.c +++ b/src/test/test-reread-partition-table.c @@ -26,7 +26,7 @@ static void sfdisk(const char *sfdisk_path, LoopDevice *loop, const char *defini _cleanup_close_ int memfd = memfd_new_and_seal("sfdisk", definition, SIZE_MAX); ASSERT_OK(memfd); - r = safe_fork_full( + r = pidref_safe_fork_full( "(sfdisk)", (int[]) { memfd, STDOUT_FILENO, STDERR_FILENO }, /* except_fds= */ NULL, diff --git a/src/test/test-rlimit-util.c b/src/test/test-rlimit-util.c index 962c776bd32..f1d2ea19246 100644 --- a/src/test/test-rlimit-util.c +++ b/src/test/test-rlimit-util.c @@ -155,9 +155,10 @@ TEST(pid_getrlimit) { assert_se(getrlimit(resource, &direct) >= 0); /* We fork off a child so that getrlimit() doesn't work anymore */ - r = safe_fork("(getrlimit)", - FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_LOG|FORK_WAIT, - /* ret= */ NULL); + r = pidref_safe_fork( + "(getrlimit)", + FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_LOG|FORK_WAIT, + /* ret= */ NULL); assert_se(r >= 0); if (r == 0) { diff --git a/src/test/test-rm-rf.c b/src/test/test-rm-rf.c index 870a8b9a4ef..d029f608e2a 100644 --- a/src/test/test-rm-rf.c +++ b/src/test/test-rm-rf.c @@ -102,7 +102,7 @@ TEST(rm_rf_chmod) { /* This test only works unpriv (as only then the access mask for the owning user matters), * hence drop privs here */ - ASSERT_OK(r = safe_fork("(setresuid)", FORK_DEATHSIG_SIGTERM|FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(setresuid)", FORK_DEATHSIG_SIGTERM|FORK_WAIT, NULL)); if (r == 0) { /* child */ diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c index fa05eecb95a..d40abf24e4d 100644 --- a/src/test/test-seccomp.c +++ b/src/test/test-seccomp.c @@ -197,7 +197,7 @@ TEST(filter_sets) { log_info("Testing %s", syscall_filter_sets[i].name); - ASSERT_OK(r = safe_fork("(filter_sets)", FORK_LOG | FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(filter_sets)", FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { int fd; @@ -295,7 +295,7 @@ TEST(restrict_namespace) { CHECK_SECCOMP(/* skip_container= */ false); - ASSERT_OK(r = safe_fork("(restrict-namespace)", FORK_LOG | FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(restrict-namespace)", FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { assert_se(seccomp_restrict_namespaces(CLONE_NEWNS|CLONE_NEWNET) >= 0); @@ -357,7 +357,7 @@ TEST(protect_sysctl) { if (!streq(seccomp, "0")) log_warning("Warning: seccomp filter detected, results may be unreliable for %s", __func__); - ASSERT_OK(r = safe_fork("(protect-sysctl)", FORK_LOG | FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(protect-sysctl)", FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { #if defined __NR__sysctl && __NR__sysctl >= 0 assert_se(syscall(__NR__sysctl, NULL) < 0); @@ -388,7 +388,7 @@ TEST(protect_syslog) { /* in containers syslog() is likely missing anyway */ CHECK_SECCOMP(/* skip_container= */ true); - ASSERT_OK(r = safe_fork("(protect-syslog)", FORK_LOG | FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(protect-syslog)", FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { #if defined __NR_syslog && __NR_syslog >= 0 assert_se(syscall(__NR_syslog, -1, NULL, 0) < 0); @@ -411,7 +411,7 @@ TEST(restrict_address_families) { CHECK_SECCOMP(/* skip_container= */ false); - ASSERT_OK(r = safe_fork("(restrict-address-families)", FORK_LOG | FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(restrict-address-families)", FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { int fd; Set *s; @@ -488,7 +488,7 @@ TEST(restrict_realtime) { /* in containers RT privs are likely missing anyway */ CHECK_SECCOMP(/* skip_container= */ true); - ASSERT_OK(r = safe_fork("(restrict-realtime)", FORK_LOG | FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(restrict-realtime)", FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { /* On some CI environments, the restriction may be already enabled. */ if (sched_setscheduler(0, SCHED_FIFO, &(struct sched_param) { .sched_priority = 1 }) < 0) { @@ -542,7 +542,7 @@ TEST(memory_deny_write_execute_mmap) { return; #endif - ASSERT_OK(r = safe_fork("(memory_deny_write_execute_mmap)", FORK_LOG | FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(memory_deny_write_execute_mmap)", FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { void *p; @@ -606,7 +606,7 @@ TEST(memory_deny_write_execute_shmat) { shmid = shmget(IPC_PRIVATE, page_size(), 0); assert_se(shmid >= 0); - ASSERT_OK(r = safe_fork("(memory-deny-write-execute)", FORK_LOG | FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(memory-deny-write-execute)", FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { void *p; @@ -648,7 +648,7 @@ TEST(restrict_archs) { CHECK_SECCOMP(/* skip_container= */ false); - ASSERT_OK(r = safe_fork("(restrict-archs)", FORK_LOG | FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(restrict-archs)", FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { _cleanup_set_free_ Set *s = NULL; @@ -675,7 +675,7 @@ TEST(load_syscall_filter_set_raw) { CHECK_SECCOMP(/* skip_container= */ false); - ASSERT_OK(r = safe_fork("(load-filter)", FORK_LOG | FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(load-filter)", FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { _cleanup_hashmap_free_ Hashmap *s = NULL; @@ -777,7 +777,7 @@ TEST(native_syscalls_filtered) { CHECK_SECCOMP(/* skip_container= */ false); - ASSERT_OK(r = safe_fork("(native-syscalls)", FORK_LOG | FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(native-syscalls)", FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { _cleanup_set_free_ Set *arch_s = NULL; _cleanup_hashmap_free_ Hashmap *s = NULL; @@ -830,7 +830,7 @@ TEST(lock_personality) { log_info("current personality=0x%lX", (unsigned long) safe_personality(PERSONALITY_INVALID)); log_info("current opinionated personality=0x%lX", current_opinionated); - ASSERT_OK(r = safe_fork("(lock-personality)", FORK_LOG | FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(lock-personality)", FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { unsigned long current; @@ -900,7 +900,7 @@ TEST(restrict_suid_sgid) { CHECK_SECCOMP(/* skip_container= */ false); - ASSERT_OK(r = safe_fork("(suid-sgid)", FORK_LOG | FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(suid-sgid)", FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { char path[] = "/tmp/suidsgidXXXXXX", dir[] = "/tmp/suidsgiddirXXXXXX"; int fd = -EBADF, k = -EBADF; @@ -1124,7 +1124,7 @@ TEST(seccomp_suppress_sync) { CHECK_SECCOMP(/* skip_container= */ false); - ASSERT_OK(r = safe_fork("(suppress-sync)", FORK_LOG | FORK_WAIT, NULL)); + r = ASSERT_OK(pidref_safe_fork("(suppress-sync)", FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { test_seccomp_suppress_sync_child(); _exit(EXIT_SUCCESS); diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c index 0313350000a..4549dcb0dda 100644 --- a/src/test/test-socket-util.c +++ b/src/test/test-socket-util.c @@ -153,8 +153,7 @@ TEST(in_addr_is_multicast) { TEST(getpeercred_getpeergroups) { int r; - r = safe_fork("(getpeercred)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL); - assert_se(r >= 0); + r = ASSERT_OK(pidref_safe_fork("(getpeercred)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { static const gid_t gids[] = { 3, 4, 5, 6, 7 }; @@ -220,8 +219,7 @@ TEST(passfd_read) { assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0); - r = safe_fork("(passfd_read)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL); - assert_se(r >= 0); + r = ASSERT_OK(pidref_safe_fork("(passfd_read)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { /* Child */ @@ -262,8 +260,7 @@ TEST(passfd_contents_read) { assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0); - r = safe_fork("(passfd_contents_read)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL); - assert_se(r >= 0); + r = ASSERT_OK(pidref_safe_fork("(passfd_contents_read)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { /* Child */ @@ -314,8 +311,7 @@ TEST(pass_many_fds_contents_read) { assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0); - r = safe_fork("(passfd_contents_read)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL); - assert_se(r >= 0); + r = ASSERT_OK(pidref_safe_fork("(passfd_contents_read)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { /* Child */ @@ -374,7 +370,7 @@ TEST(receive_nopassfd) { assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0); - r = safe_fork("(receive_nopassfd)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL); + r = ASSERT_OK(pidref_safe_fork("(receive_nopassfd)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL)); assert_se(r >= 0); if (r == 0) { @@ -410,8 +406,7 @@ TEST(send_nodata_nofd) { assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0); - r = safe_fork("(send_nodata_nofd)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL); - assert_se(r >= 0); + r = ASSERT_OK(pidref_safe_fork("(send_nodata_nofd)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { /* Child */ @@ -443,8 +438,7 @@ TEST(send_emptydata) { assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0); - r = safe_fork("(send_emptydata)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL); - assert_se(r >= 0); + r = ASSERT_OK(pidref_safe_fork("(send_emptydata)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL)); if (r == 0) { /* Child */ diff --git a/src/test/test-terminal-util.c b/src/test/test-terminal-util.c index 5ce4e355336..ae33a9aeea3 100644 --- a/src/test/test-terminal-util.c +++ b/src/test/test-terminal-util.c @@ -385,11 +385,12 @@ TEST(terminal_new_session) { ASSERT_OK(pty_fd = openpt_allocate(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK, NULL)); ASSERT_OK(peer_fd = pty_open_peer(pty_fd, O_RDWR|O_NOCTTY|O_CLOEXEC)); - r = safe_fork_full("test-term-session", - (int[]) { peer_fd, peer_fd, peer_fd }, - NULL, 0, - FORK_DEATHSIG_SIGKILL|FORK_LOG|FORK_WAIT|FORK_REARRANGE_STDIO, - NULL); + r = pidref_safe_fork_full( + "test-term-session", + (int[]) { peer_fd, peer_fd, peer_fd }, + NULL, 0, + FORK_DEATHSIG_SIGKILL|FORK_LOG|FORK_WAIT|FORK_REARRANGE_STDIO, + NULL); ASSERT_OK(r); if (r == 0) { ASSERT_OK(terminal_new_session()); diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c index 4a2b47ca19e..1ee2239aa4a 100644 --- a/src/tty-ask-password-agent/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent/tty-ask-password-agent.c @@ -30,6 +30,7 @@ #include "main-func.h" #include "mkdir-label.h" #include "path-util.h" +#include "pidref.h" #include "pretty-print.h" #include "process-util.h" #include "set.h" @@ -570,18 +571,18 @@ static int parse_argv(int argc, char *argv[]) { * and its own controlling terminal. If one of the tasks does handle a password, the remaining tasks will be * terminated. */ -static int ask_on_this_console(const char *tty, char **arguments, pid_t *ret_pid) { +static int ask_on_this_console(const char *tty, char **arguments, PidRef *ret) { int r; assert(tty); assert(arguments); - assert(ret_pid); + assert(ret); assert_se(sigaction(SIGCHLD, &sigaction_nop_nocldstop, NULL) >= 0); assert_se(sigaction(SIGHUP, &sigaction_default, NULL) >= 0); assert_se(sigprocmask_many(SIG_UNBLOCK, NULL, SIGHUP, SIGCHLD) >= 0); - r = safe_fork("(sd-passwd)", FORK_RESET_SIGNALS|FORK_KEEP_NOTIFY_SOCKET|FORK_LOG, ret_pid); + r = pidref_safe_fork("(sd-passwd)", FORK_RESET_SIGNALS|FORK_KEEP_NOTIFY_SOCKET|FORK_LOG, ret); if (r < 0) return r; if (r == 0) { @@ -691,13 +692,13 @@ static int ask_on_consoles(char *argv[]) { /* Start an agent on each console. */ STRV_FOREACH(tty, consoles) { - pid_t pid; + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; - r = ask_on_this_console(*tty, arguments, &pid); + r = ask_on_this_console(*tty, arguments, &pidref); if (r < 0) return r; - if (set_put(pids, PID_TO_PTR(pid)) < 0) + if (set_put(pids, PID_TO_PTR(pidref.pid)) < 0) return log_oom(); } diff --git a/src/userdb/userdbd-manager.c b/src/userdb/userdbd-manager.c index 76962225104..8803f3090f9 100644 --- a/src/userdb/userdbd-manager.c +++ b/src/userdb/userdbd-manager.c @@ -16,6 +16,7 @@ #include "log.h" #include "mkdir.h" #include "pidfd-util.h" +#include "pidref.h" #include "process-util.h" #include "set.h" #include "signal-util.h" @@ -143,19 +144,19 @@ static size_t manager_current_workers(Manager *m) { static int start_one_worker(Manager *m) { _cleanup_(sd_event_source_disable_unrefp) sd_event_source *source = NULL; bool fixed; - pid_t pid; int r; assert(m); fixed = set_size(m->workers_fixed) < USERDB_WORKERS_MIN; - r = safe_fork_full( + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; + r = pidref_safe_fork_full( "(sd-worker)", /* stdio_fds= */ NULL, &m->listen_fd, 1, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_CLOSE_ALL_FDS, - &pid); + &pidref); if (r < 0) return log_error_errno(r, "Failed to fork new worker child: %m"); if (r == 0) { @@ -176,7 +177,7 @@ static int start_one_worker(Manager *m) { safe_close(m->listen_fd); } - r = setenvf("LISTEN_PID", /* overwrite= */ true, PID_FMT, pid); + r = setenvf("LISTEN_PID", /* overwrite= */ true, PID_FMT, pidref.pid); if (r < 0) { log_error_errno(r, "Failed to set $LISTEN_PID: %m"); _exit(EXIT_FAILURE); @@ -212,9 +213,9 @@ static int start_one_worker(Manager *m) { _exit(EXIT_FAILURE); } - r = sd_event_add_child(m->event, &source, pid, WEXITED, on_worker_exit, m); + r = event_add_child_pidref(m->event, &source, &pidref, WEXITED, on_worker_exit, m); if (r < 0) - return log_error_errno(r, "Failed to watch child " PID_FMT ": %m", pid); + return log_error_errno(r, "Failed to watch child " PID_FMT ": %m", pidref.pid); r = set_ensure_put( fixed ? &m->workers_fixed : &m->workers_dynamic, diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c index 8951e19704a..43817954a3d 100644 --- a/src/vmspawn/vmspawn.c +++ b/src/vmspawn/vmspawn.c @@ -1274,7 +1274,7 @@ static int start_tpm( if (!argv) return log_oom(); - r = safe_fork("(swtpm-setup)", FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_WAIT, NULL); + r = pidref_safe_fork("(swtpm-setup)", FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_WAIT, /* ret= */ NULL); if (r == 0) { /* Child */ execvp(argv[0], argv); @@ -1287,7 +1287,7 @@ static int start_tpm( strv_remove(argv, "--profile-name"); strv_remove(argv, "default-v2"); - r = safe_fork("(swtpm-setup)", FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_WAIT, NULL); + r = pidref_safe_fork("(swtpm-setup)", FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_WAIT, /* ret= */ NULL); if (r == 0) { /* Child */ execvp(argv[0], argv); @@ -1739,10 +1739,10 @@ static int generate_ssh_keypair(const char *key_path, const char *key_type) { log_debug("Executing: %s", joined); } - r = safe_fork( + r = pidref_safe_fork( ssh_keygen, FORK_WAIT|FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REARRANGE_STDIO, - NULL); + /* ret= */ NULL); if (r < 0) return r; if (r == 0) {