aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2023-02-08 16:49:29 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2023-02-08 16:49:50 +0000
commit8b418c83d175fde3b1f65210509ddcf2ac248d9f (patch)
treedcdd2ce74e28e43b8814a57f5296e025684320a5 /bin
parent9df6eeabb379b0816d58b05a4de24fc0478e1dba (diff)
downloadsrc-8b418c83d175fde3b1f65210509ddcf2ac248d9f.tar.gz
src-8b418c83d175fde3b1f65210509ddcf2ac248d9f.zip
cp: Adjust the sparse file tests.
* The sparsity check was ineffective: it compared the apparent size in bytes to the actual size in blocks. Instead, write a tool that reliably detects sparseness. * Some of the seq commands were missing an argument. * Based on empirical evidence, 1 MB holes are not necessarily large enough to be preserved by the underlying filesystem. Increase the hole size to 16 MB. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: cracauer Differential Revision: https://reviews.freebsd.org/D38414
Diffstat (limited to 'bin')
-rw-r--r--bin/cp/tests/Makefile2
-rwxr-xr-xbin/cp/tests/cp_test.sh46
-rw-r--r--bin/cp/tests/sparse.c73
3 files changed, 98 insertions, 23 deletions
diff --git a/bin/cp/tests/Makefile b/bin/cp/tests/Makefile
index faad22df713a..1e480ad706d1 100644
--- a/bin/cp/tests/Makefile
+++ b/bin/cp/tests/Makefile
@@ -3,5 +3,7 @@
PACKAGE= tests
ATF_TESTS_SH= cp_test
+PROGS+= sparse
+BINDIR= ${TESTSDIR}
.include <bsd.test.mk>
diff --git a/bin/cp/tests/cp_test.sh b/bin/cp/tests/cp_test.sh
index 932bd2221ba3..559a5ecc3c00 100755
--- a/bin/cp/tests/cp_test.sh
+++ b/bin/cp/tests/cp_test.sh
@@ -201,7 +201,7 @@ recursive_link_Lflag_body()
file_is_sparse()
{
- atf_check test "$(stat -f "%b" "$1")" != "$(stat -f "%z" "$1")"
+ atf_check ${0%/*}/sparse "$1"
}
files_are_equal()
@@ -213,8 +213,8 @@ files_are_equal()
atf_test_case sparse_leading_hole
sparse_leading_hole_body()
{
- # A one-megabyte hole followed by one megabyte of data
- truncate -s 1M foo
+ # A 16-megabyte hole followed by one megabyte of data
+ truncate -s 16M foo
seq -f%015g 65536 >>foo
file_is_sparse foo
@@ -227,14 +227,14 @@ atf_test_case sparse_multiple_holes
sparse_multiple_holes_body()
{
# Three one-megabyte blocks of data preceded, separated, and
- # followed by one-megabyte holes
- truncate -s 1M foo
- seq -f%015g >>foo
- truncate -s 3M foo
- seq -f%015g >>foo
- truncate -s 5M foo
- seq -f%015g >>foo
- truncate -s 7M foo
+ # followed by 16-megabyte holes
+ truncate -s 16M foo
+ seq -f%015g 65536 >>foo
+ truncate -s 33M foo
+ seq -f%015g 65536 >>foo
+ truncate -s 50M foo
+ seq -f%015g 65536 >>foo
+ truncate -s 67M foo
file_is_sparse foo
atf_check cp foo bar
@@ -245,8 +245,8 @@ sparse_multiple_holes_body()
atf_test_case sparse_only_hole
sparse_only_hole_body()
{
- # A one-megabyte hole
- truncate -s 1M foo
+ # A 16-megabyte hole
+ truncate -s 16M foo
file_is_sparse foo
atf_check cp foo bar
@@ -258,14 +258,14 @@ atf_test_case sparse_to_dev
sparse_to_dev_body()
{
# Three one-megabyte blocks of data preceded, separated, and
- # followed by one-megabyte holes
- truncate -s 1M foo
- seq -f%015g >>foo
- truncate -s 3M foo
- seq -f%015g >>foo
- truncate -s 5M foo
- seq -f%015g >>foo
- truncate -s 7M foo
+ # followed by 16-megabyte holes
+ truncate -s 16M foo
+ seq -f%015g 65536 >>foo
+ truncate -s 33M foo
+ seq -f%015g 65536 >>foo
+ truncate -s 50M foo
+ seq -f%015g 65536 >>foo
+ truncate -s 67M foo
file_is_sparse foo
atf_check -o file:foo cp foo /dev/stdout
@@ -274,9 +274,9 @@ sparse_to_dev_body()
atf_test_case sparse_trailing_hole
sparse_trailing_hole_body()
{
- # One megabyte of data followed by a one-megabyte hole
+ # One megabyte of data followed by a 16-megabyte hole
seq -f%015g 65536 >foo
- truncate -s 2M foo
+ truncate -s 17M foo
file_is_sparse foo
atf_check cp foo bar
diff --git a/bin/cp/tests/sparse.c b/bin/cp/tests/sparse.c
new file mode 100644
index 000000000000..78957581a56c
--- /dev/null
+++ b/bin/cp/tests/sparse.c
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 2023 Klara, Inc.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+static bool verbose;
+
+/*
+ * Returns true if the file named by its argument is sparse, i.e. if
+ * seeking to SEEK_HOLE returns a different value than seeking to
+ * SEEK_END.
+ */
+static bool
+sparse(const char *filename)
+{
+ off_t hole, end;
+ int fd;
+
+ if ((fd = open(filename, O_RDONLY)) < 0 ||
+ (hole = lseek(fd, 0, SEEK_HOLE)) < 0 ||
+ (end = lseek(fd, 0, SEEK_END)) < 0)
+ err(1, "%s", filename);
+ close(fd);
+ if (end > hole) {
+ if (verbose)
+ printf("%s: hole at %zu\n", filename, (size_t)hole);
+ return (true);
+ }
+ return (false);
+}
+
+static void
+usage(void)
+{
+
+ fprintf(stderr, "usage: sparse [-v] file [...]\n");
+ exit(EX_USAGE);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int opt, rv;
+
+ while ((opt = getopt(argc, argv, "v")) != -1) {
+ switch (opt) {
+ case 'v':
+ verbose = true;
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 0)
+ usage();
+ rv = EXIT_SUCCESS;
+ while (argc-- > 0)
+ if (!sparse(*argv++))
+ rv = EXIT_FAILURE;
+ exit(rv);
+}