git: 8b418c83d175 - main - cp: Adjust the sparse file tests.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 08 Feb 2023 16:50:06 UTC
The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=8b418c83d175fde3b1f65210509ddcf2ac248d9f commit 8b418c83d175fde3b1f65210509ddcf2ac248d9f Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2023-02-08 16:49:29 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2023-02-08 16:49:50 +0000 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 --- bin/cp/tests/Makefile | 2 ++ bin/cp/tests/cp_test.sh | 46 +++++++++++++++---------------- bin/cp/tests/sparse.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ 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); +}