diff --git a/src/shared/async.c b/src/shared/async.c index 8d65062285..c8f755cb2e 100644 --- a/src/shared/async.c +++ b/src/shared/async.c @@ -14,7 +14,7 @@ #include "process-util.h" #include "signal-util.h" -int asynchronous_sync(pid_t *ret_pid) { +int asynchronous_sync(PidRef *ret_pid) { int r; /* This forks off an invocation of fork() as a child process, in order to initiate synchronization to @@ -22,7 +22,7 @@ int asynchronous_sync(pid_t *ret_pid) { * original process ever, and a thread would do that as the process can't exit with threads hanging in blocking * syscalls. */ - r = safe_fork("(sd-sync)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|(ret_pid ? 0 : FORK_DETACH), ret_pid); + r = pidref_safe_fork("(sd-sync)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|(ret_pid ? 0 : FORK_DETACH), ret_pid); if (r < 0) return r; if (r == 0) { @@ -34,17 +34,19 @@ int asynchronous_sync(pid_t *ret_pid) { return 0; } -int asynchronous_fsync(int fd, pid_t *ret_pid) { +int asynchronous_fsync(int fd, PidRef *ret_pid) { int r; assert(fd >= 0); /* Same as asynchronous_sync() above, but calls fsync() on a specific fd */ - r = safe_fork_full("(sd-fsync)", - /* stdio_fds= */ NULL, - /* except_fds= */ &fd, - /* n_except_fds= */ 1, - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|(ret_pid ? 0 : FORK_DETACH), ret_pid); + r = pidref_safe_fork_full( + "(sd-fsync)", + /* stdio_fds= */ NULL, + /* except_fds= */ &fd, + /* n_except_fds= */ 1, + FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|(ret_pid ? 0 : FORK_DETACH), + ret_pid); if (r < 0) return r; if (r == 0) { diff --git a/src/shared/async.h b/src/shared/async.h index d8604f8746..c49b385308 100644 --- a/src/shared/async.h +++ b/src/shared/async.h @@ -4,6 +4,7 @@ #include #include "macro.h" +#include "pidref.h" #include "rm-rf.h" /* These functions implement various potentially slow operations that are executed asynchronously. They are @@ -19,8 +20,8 @@ * child, or never use clone()/clone3() and stick to fork() only. Because we need clone()/clone3() we opted * for avoiding threads. */ -int asynchronous_sync(pid_t *ret_pid); -int asynchronous_fsync(int fd, pid_t *ret_pid); +int asynchronous_sync(PidRef *ret_pid); +int asynchronous_fsync(int fd, PidRef *ret_pid); int asynchronous_close(int fd); void asynchronous_close_many(const int fds[], size_t n_fds); diff --git a/src/shutdown/shutdown.c b/src/shutdown/shutdown.c index e26a8579c5..cb7d4eb408 100644 --- a/src/shutdown/shutdown.c +++ b/src/shutdown/shutdown.c @@ -226,7 +226,7 @@ int sync_with_progress(int fd) { unsigned long long dirty = ULLONG_MAX; _cleanup_free_ char *path = NULL; const char *what; - pid_t pid; + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; int r; BLOCK_SIGNALS(SIGCHLD); @@ -235,13 +235,13 @@ int sync_with_progress(int fd) { * the progress. If the timeout lapses, the assumption is that the particular sync stalled. */ if (fd >= 0) { - r = asynchronous_fsync(fd, &pid); + r = asynchronous_fsync(fd, &pidref); if (r < 0) return log_error_errno(r, "Failed to fork fsync(): %m"); (void) fd_get_path(fd, &path); } else { - r = asynchronous_sync(&pid); + r = asynchronous_sync(&pidref); if (r < 0) return log_error_errno(r, "Failed to fork sync(): %m"); } @@ -253,7 +253,7 @@ int sync_with_progress(int fd) { * SYNC_PROGRESS_ATTEMPTS lapse without progress being made, * we assume that the sync is stalled */ for (unsigned checks = 0; checks < SYNC_PROGRESS_ATTEMPTS; checks++) { - r = wait_for_terminate_with_timeout(pid, SYNC_TIMEOUT_USEC); + r = wait_for_terminate_with_timeout(pidref.pid, SYNC_TIMEOUT_USEC); if (r == 0) /* Sync finished without error (sync() call itself does not return an error code) */ return 0; @@ -267,8 +267,8 @@ int sync_with_progress(int fd) { /* Only reached in the event of a timeout. We should issue a kill to the stray process. */ r = log_error_errno(SYNTHETIC_ERRNO(ETIMEDOUT), - "Syncing %s - timed out, issuing SIGKILL to PID "PID_FMT".", what, pid); - (void) kill(pid, SIGKILL); + "Syncing %s - timed out, issuing SIGKILL to PID "PID_FMT".", what, pidref.pid); + (void) pidref_kill(&pidref, SIGKILL); return r; } diff --git a/src/test/test-async.c b/src/test/test-async.c index 443505c3eb..2b87faba7d 100644 --- a/src/test/test-async.c +++ b/src/test/test-async.c @@ -15,7 +15,9 @@ #include "tmpfile-util.h" TEST(asynchronous_sync) { - ASSERT_OK(asynchronous_sync(NULL)); + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; + ASSERT_OK(asynchronous_sync(&pidref)); + ASSERT_OK(pidref_wait_for_terminate(&pidref, /* ret= */ NULL)); } static void wait_fd_closed(int fd) {