#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
* 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) {
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) {
#include <sys/types.h>
#include "macro.h"
+#include "pidref.h"
#include "rm-rf.h"
/* These functions implement various potentially slow operations that are executed asynchronously. They are
* 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);
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);
* 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");
}
* 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;
/* 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;
}