commit: c6b6d2ad7d5c2ad29d1958a22f6bd13c15757e39
parent 56a94bdfc264dfc1fe7bdd3f1913184fbfced974
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Wed, 18 Sep 2024 04:53:20 +0200
cmd/sync: add -f (syncfs) support
Diffstat:
4 files changed, 56 insertions(+), 27 deletions(-)
diff --git a/cmd/sync.1 b/cmd/sync.1
@@ -9,24 +9,29 @@
.Nd Schedule file system updates
.Sh SYNOPSIS
.Nm
-.Op Fl d
+.Op Fl df
.Op Ar file...
.Sh DESCRIPTION
Schedule cached writes to filesystems.
If any
.Ar file
-is specified, only those files are scheduled, otherwise all filesystems are synchronized.
+is specified, only those files are scheduled,
+otherwise all filesystems are synchronized.
.Sh OPTIONS
.Bl -tag -width _d
.It Fl d
Sync only file data, not metadata.
+.It Fl f
+Sync entire filesystem. (Only available on systems with
+.Xr syncfs 2 )
.El
.Sh EXIT STATUS
.Ex -std
.Sh SEE ALSO
.Xr fdatasync 2 ,
.Xr fsync 2 ,
-.Xr sync 2
+.Xr sync 2 ,
+.Xr syncfs 2
.Sh STANDARDS
No applicable one known.
.Sh AUTHORS
diff --git a/cmd/sync.c b/cmd/sync.c
@@ -3,6 +3,7 @@
// SPDX-License-Identifier: MPL-2.0
#define _POSIX_C_SOURCE 200809L
+#define _GNU_SOURCE // syncfs
#define _XOPEN_SOURCE 700 // sync
#include <errno.h>
@@ -11,23 +12,36 @@
#include <stdio.h> // fprintf
#include <stdlib.h> // abort
#include <string.h> // strerror
-#include <unistd.h> // fsync, sync, getopt
+#include <unistd.h> // fsync, sync, getopt, syncfs
int
main(int argc, char *argv[])
{
- bool optd = false;
+ int err = 0;
+ int (*sync_func)(int) = fsync;
int c = -1;
- while((c = getopt(argc, argv, ":d")) != -1)
+ while((c = getopt(argc, argv, ":df")) != -1)
{
switch(c)
{
case 'd':
- optd = true;
+ sync_func = fdatasync;
break;
+ case 'f':
+#ifdef HAS_SYNCFS
+ sync_func = syncfs;
+ break;
+#else
+ fprintf(stderr,
+ "sync: System doesn't supports syncfs(3), continuing with error status set\n");
+ err = 1;
+ break;
+#endif
case '?':
- fprintf(stderr, "sync: Unrecognized option '-%c'\n", optopt);
+ fprintf(
+ stderr, "sync: Unrecognized option '-%c', continuing with error status set\n", optopt);
+ err = 1;
break;
default:
abort();
@@ -39,8 +53,12 @@ main(int argc, char *argv[])
if(argc == 0)
{
+#ifdef HAS_SYNCFS
+ if(sync_func == syncfs) fprintf(stderr, "sync: Warning -f passed without arguments\n");
+#endif
+
sync();
- return 0;
+ return err;
}
for(int i = 0; i < argc; i++)
@@ -52,24 +70,13 @@ main(int argc, char *argv[])
return 1;
}
- if(optd)
- {
- if(fdatasync(fd) < 0)
- {
- fprintf(stderr,
- "sync: Failed synchronizing data changes of file '%s': %s\n",
- argv[i],
- strerror(errno));
- return 1;
- }
- }
- else
+ if(sync_func(fd) < 0)
{
- if(fsync(fd) < 0)
- {
- fprintf(stderr, "sync: Failed synchronizing file '%s': %s\n", argv[i], strerror(errno));
- return 1;
- }
+ fprintf(stderr,
+ "sync: Failed synchronizing changes related to file '%s': %s\n",
+ argv[i],
+ strerror(errno));
+ return 1;
}
if(close(fd) < 0)
@@ -82,5 +89,5 @@ main(int argc, char *argv[])
}
}
- return 0;
+ return err;
}
diff --git a/configure b/configure
@@ -233,6 +233,8 @@ fi
check_conftest configure.d/getopt_long.c && CFLAGS="${CFLAGS} -DHAS_GETOPT_LONG"
+check_conftest configure.d/syncfs.c && CFLAGS="${CFLAGS} -DHAS_SYNCFS"
+
echo
## Configuration write
diff --git a/configure.d/syncfs.c b/configure.d/syncfs.c
@@ -0,0 +1,15 @@
+// utils-std: Collection of commonly available Unix tools
+// SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
+// SPDX-License-Identifier: MPL-2.0
+
+// Because that's what our utilities will use :)
+#define _POSIX_C_SOURCE 200809L
+#define _GNU_SOURCE // for syncfs
+
+#include <unistd.h> // syncfs
+
+int
+test(int fd)
+{
+ return syncfs(fd);
+}