summaryrefslogtreecommitdiffstats
path: root/src/shared/async.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2024-09-09 17:49:33 +0200
committerLennart Poettering <lennart@poettering.net>2024-09-09 19:12:31 +0200
commit13b5225d6278af15e84ebd1889f04cfe81b47787 (patch)
treea3744f9123f530eb239fabb07ad266863be1d1ac /src/shared/async.c
parentmachinectl: suppress redirection notice if --quiet is specified (diff)
downloadsystemd-13b5225d6278af15e84ebd1889f04cfe81b47787.tar.xz
systemd-13b5225d6278af15e84ebd1889f04cfe81b47787.zip
shutdown: teach sync_with_progress() to optionally sync a specific fd only
This is preparation for reusing the logic for syncing DM and other devices with a timeout applied.
Diffstat (limited to 'src/shared/async.c')
-rw-r--r--src/shared/async.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/shared/async.c b/src/shared/async.c
index bbb8b81011..bd043c8484 100644
--- a/src/shared/async.c
+++ b/src/shared/async.c
@@ -34,6 +34,28 @@ int asynchronous_sync(pid_t *ret_pid) {
return 0;
}
+int asynchronous_fsync(int fd, pid_t *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);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ /* Child process */
+ fsync(fd);
+ _exit(EXIT_SUCCESS);
+ }
+
+ return 0;
+}
+
/* We encode the fd to close in the userdata pointer as an unsigned value. The highest bit indicates whether
* we need to fork again */
#define NEED_DOUBLE_FORK (1U << (sizeof(unsigned) * 8 - 1))