Skip to content

Commit dc92915

Browse files
committed
Block cloning tests.
The test mostly focus on testing various corner cases. The tests take a long time to run, so for the common.run runfile we randomly select a hundred tests. To run all the bclone tests, bclone.run runfile should be used. Signed-off-by: Pawel Jakub Dawidek <[email protected]>
1 parent dbda451 commit dc92915

31 files changed

+1681
-44
lines changed

tests/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ dist_scripts_test_runner_include_DATA = \
1616

1717
scripts_runfilesdir = $(datadir)/$(PACKAGE)/runfiles
1818
dist_scripts_runfiles_DATA = \
19+
%D%/runfiles/bclone.run \
1920
%D%/runfiles/common.run \
2021
%D%/runfiles/freebsd.run \
2122
%D%/runfiles/linux.run \

tests/runfiles/bclone.run

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#
2+
# This file and its contents are supplied under the terms of the
3+
# Common Development and Distribution License ("CDDL"), version 1.0.
4+
# You may only use this file in accordance with the terms of version
5+
# 1.0 of the CDDL.
6+
#
7+
# A full copy of the text of the CDDL should have accompanied this
8+
# source. A copy of the CDDL is also available via the Internet at
9+
# http://www.illumos.org/license/CDDL.
10+
#
11+
# This run file contains all of the common functional tests. When
12+
# adding a new test consider also adding it to the sanity.run file
13+
# if the new test runs to completion in only a few seconds.
14+
#
15+
# Approximate run time: 5 hours
16+
#
17+
18+
[DEFAULT]
19+
pre = setup
20+
quiet = False
21+
pre_user = root
22+
user = root
23+
timeout = 28800
24+
post_user = root
25+
post = cleanup
26+
failsafe_user = root
27+
failsafe = callbacks/zfs_failsafe
28+
outputdir = /var/tmp/test_results
29+
tags = ['bclone']
30+
31+
[tests/functional/bclone]
32+
tests = ['bclone_crossfs_corner_cases',
33+
'bclone_crossfs_data',
34+
'bclone_crossfs_embedded',
35+
'bclone_crossfs_hole',
36+
'bclone_diffprops_all',
37+
'bclone_diffprops_checksum',
38+
'bclone_diffprops_compress',
39+
'bclone_diffprops_copies',
40+
'bclone_diffprops_recordsize',
41+
'bclone_prop_sync',
42+
'bclone_samefs_corner_cases',
43+
'bclone_samefs_data',
44+
'bclone_samefs_embedded',
45+
'bclone_samefs_hole']
46+
tags = ['bclone']

tests/runfiles/common.run

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,24 @@ tags = ['functional', 'arc']
5353
tests = ['atime_001_pos', 'atime_002_neg', 'root_atime_off', 'root_atime_on']
5454
tags = ['functional', 'atime']
5555

56+
[tests/functional/bclone]
57+
tests = ['bclone_crossfs_corner_cases_limited',
58+
'bclone_crossfs_data',
59+
'bclone_crossfs_embedded',
60+
'bclone_crossfs_hole',
61+
'bclone_diffprops_all',
62+
'bclone_diffprops_checksum',
63+
'bclone_diffprops_compress',
64+
'bclone_diffprops_copies',
65+
'bclone_diffprops_recordsize',
66+
'bclone_prop_sync',
67+
'bclone_samefs_corner_cases_limited',
68+
'bclone_samefs_data',
69+
'bclone_samefs_embedded',
70+
'bclone_samefs_hole']
71+
tags = ['functional', 'bclone']
72+
timeout = 7200
73+
5674
[tests/functional/bootfs]
5775
tests = ['bootfs_001_pos', 'bootfs_002_neg', 'bootfs_003_pos',
5876
'bootfs_004_neg', 'bootfs_005_neg', 'bootfs_006_pos', 'bootfs_007_pos',

tests/zfs-tests/cmd/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ scripts_zfs_tests_bindir = $(datadir)/$(PACKAGE)/zfs-tests/bin
22

33

44
scripts_zfs_tests_bin_PROGRAMS = %D%/chg_usr_exec
5+
scripts_zfs_tests_bin_PROGRAMS += %D%/clonefile
56
scripts_zfs_tests_bin_PROGRAMS += %D%/cp_files
67
scripts_zfs_tests_bin_PROGRAMS += %D%/ctime
78
scripts_zfs_tests_bin_PROGRAMS += %D%/dir_rd_update
@@ -119,7 +120,6 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/renameat2
119120
scripts_zfs_tests_bin_PROGRAMS += %D%/xattrtest
120121
scripts_zfs_tests_bin_PROGRAMS += %D%/zed_fd_spill-zedlet
121122
scripts_zfs_tests_bin_PROGRAMS += %D%/idmap_util
122-
scripts_zfs_tests_bin_PROGRAMS += %D%/clonefile
123123

124124
%C%_idmap_util_LDADD = libspl.la
125125

tests/zfs-tests/cmd/clonefile.c

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@
5959
#endif
6060
#endif /* __NR_copy_file_range */
6161

62+
#ifdef __FreeBSD__
63+
#define loff_t off_t
64+
#endif
65+
6266
ssize_t
6367
copy_file_range(int, loff_t *, int, loff_t *, size_t, unsigned int)
6468
__attribute__((weak));
@@ -140,7 +144,7 @@ usage(void)
140144
" FICLONERANGE:\n"
141145
" clonefile -r <src> <dst> <soff> <doff> <len>\n"
142146
" copy_file_range:\n"
143-
" clonefile -f <src> <dst> <soff> <doff> <len>\n"
147+
" clonefile -f <src> <dst> [<soff> <doff> <len | \"all\">]\n"
144148
" FIDEDUPERANGE:\n"
145149
" clonefile -d <src> <dst> <soff> <doff> <len>\n");
146150
return (1);
@@ -179,13 +183,29 @@ main(int argc, char **argv)
179183
}
180184
}
181185

182-
if (mode == CF_MODE_NONE || (argc-optind) < 2 ||
183-
(mode != CF_MODE_CLONE && (argc-optind) < 5))
184-
return (usage());
186+
switch (mode) {
187+
case CF_MODE_NONE:
188+
return (usage());
189+
case CF_MODE_CLONE:
190+
if ((argc-optind) != 2)
191+
return (usage());
192+
break;
193+
case CF_MODE_CLONERANGE:
194+
case CF_MODE_DEDUPERANGE:
195+
if ((argc-optind) != 5)
196+
return (usage());
197+
break;
198+
case CF_MODE_COPYFILERANGE:
199+
if ((argc-optind) != 2 && (argc-optind) != 5)
200+
return (usage());
201+
break;
202+
default:
203+
abort();
204+
}
185205

186206
loff_t soff = 0, doff = 0;
187-
size_t len = 0;
188-
if (mode != CF_MODE_CLONE) {
207+
size_t len = SSIZE_MAX;
208+
if ((argc-optind) == 5) {
189209
soff = strtoull(argv[optind+2], NULL, 10);
190210
if (soff == ULLONG_MAX) {
191211
fprintf(stderr, "invalid source offset");
@@ -196,10 +216,15 @@ main(int argc, char **argv)
196216
fprintf(stderr, "invalid dest offset");
197217
return (1);
198218
}
199-
len = strtoull(argv[optind+4], NULL, 10);
200-
if (len == ULLONG_MAX) {
201-
fprintf(stderr, "invalid length");
202-
return (1);
219+
if (mode == CF_MODE_COPYFILERANGE &&
220+
strcmp(argv[optind+4], "all") == 0) {
221+
len = SSIZE_MAX;
222+
} else {
223+
len = strtoull(argv[optind+4], NULL, 10);
224+
if (len == ULLONG_MAX) {
225+
fprintf(stderr, "invalid length");
226+
return (1);
227+
}
203228
}
204229
}
205230

@@ -237,13 +262,15 @@ main(int argc, char **argv)
237262
abort();
238263
}
239264

240-
off_t spos = lseek(sfd, 0, SEEK_CUR);
241-
off_t slen = lseek(sfd, 0, SEEK_END);
242-
off_t dpos = lseek(dfd, 0, SEEK_CUR);
243-
off_t dlen = lseek(dfd, 0, SEEK_END);
265+
if (!quiet) {
266+
off_t spos = lseek(sfd, 0, SEEK_CUR);
267+
off_t slen = lseek(sfd, 0, SEEK_END);
268+
off_t dpos = lseek(dfd, 0, SEEK_CUR);
269+
off_t dlen = lseek(dfd, 0, SEEK_END);
244270

245-
fprintf(stderr, "file offsets: src=%lu/%lu; dst=%lu/%lu\n", spos, slen,
246-
dpos, dlen);
271+
fprintf(stderr, "file offsets: src=%lu/%lu; dst=%lu/%lu\n",
272+
spos, slen, dpos, dlen);
273+
}
247274

248275
close(dfd);
249276
close(sfd);
@@ -254,7 +281,8 @@ main(int argc, char **argv)
254281
int
255282
do_clone(int sfd, int dfd)
256283
{
257-
fprintf(stderr, "using FICLONE\n");
284+
if (!quiet)
285+
fprintf(stderr, "using FICLONE\n");
258286
int err = ioctl(dfd, CF_FICLONE, sfd);
259287
if (err < 0) {
260288
fprintf(stderr, "ioctl(FICLONE): %s\n", strerror(errno));
@@ -266,7 +294,8 @@ do_clone(int sfd, int dfd)
266294
int
267295
do_clonerange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
268296
{
269-
fprintf(stderr, "using FICLONERANGE\n");
297+
if (!quiet)
298+
fprintf(stderr, "using FICLONERANGE\n");
270299
cf_file_clone_range_t fcr = {
271300
.src_fd = sfd,
272301
.src_offset = soff,
@@ -284,12 +313,22 @@ do_clonerange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
284313
int
285314
do_copyfilerange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
286315
{
287-
fprintf(stderr, "using copy_file_range\n");
316+
if (!quiet)
317+
fprintf(stderr, "using copy_file_range\n");
288318
ssize_t copied = cf_copy_file_range(sfd, &soff, dfd, &doff, len, 0);
289319
if (copied < 0) {
290320
fprintf(stderr, "copy_file_range: %s\n", strerror(errno));
291321
return (1);
292322
}
323+
if (len == SSIZE_MAX) {
324+
struct stat sb;
325+
326+
if (fstat(sfd, &sb) < 0) {
327+
fprintf(stderr, "fstat(sfd): %s\n", strerror(errno));
328+
return (1);
329+
}
330+
len = sb.st_size;
331+
}
293332
if (copied != len) {
294333
fprintf(stderr, "copy_file_range: copied less than requested: "
295334
"requested=%lu; copied=%lu\n", len, copied);
@@ -301,7 +340,8 @@ do_copyfilerange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
301340
int
302341
do_deduperange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
303342
{
304-
fprintf(stderr, "using FIDEDUPERANGE\n");
343+
if (!quiet)
344+
fprintf(stderr, "using FIDEDUPERANGE\n");
305345

306346
char buf[sizeof (cf_file_dedupe_range_t)+
307347
sizeof (cf_file_dedupe_range_info_t)] = {0};

tests/zfs-tests/include/commands.cfg

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ export SYSTEM_FILES_COMMON='awk
9898
uname
9999
uniq
100100
vmstat
101-
wc'
101+
wc
102+
xargs'
102103

103104
export SYSTEM_FILES_FREEBSD='chflags
104105
compress

tests/zfs-tests/include/libtest.shlib

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2629,6 +2629,38 @@ function get_config
26292629
fi | awk -F: -v cfg="$config:" '$0 ~ cfg {sub(/^'\''/, $2); sub(/'\''$/, $2); print $2}'
26302630
}
26312631

2632+
#
2633+
# Get random number between min and max number.
2634+
#
2635+
# $1 Minimal value
2636+
# $2 Maximal value
2637+
# [$3 How many]
2638+
#
2639+
function random
2640+
{
2641+
typeset -ri min=$1
2642+
typeset -ri max=$2
2643+
typeset -i value
2644+
typeset -i count
2645+
typeset -i i
2646+
2647+
if [[ -z "$3" ]]; then
2648+
count=1
2649+
else
2650+
count=$3
2651+
fi
2652+
2653+
for (( i = 0; i < $count; i++ )); do
2654+
while true; do
2655+
((value = RANDOM % (max + 1)))
2656+
if ((value >= min)); then
2657+
break
2658+
fi
2659+
done
2660+
echo $value
2661+
done
2662+
}
2663+
26322664
#
26332665
# Privated function. Random select one of items from arguments.
26342666
#

tests/zfs-tests/tests/Makefile.am

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ nobase_dist_datadir_zfs_tests_tests_DATA += \
9090
functional/alloc_class/alloc_class.kshlib \
9191
functional/atime/atime.cfg \
9292
functional/atime/atime_common.kshlib \
93+
functional/bclone/bclone.cfg \
94+
functional/bclone/bclone_common.kshlib \
95+
functional/bclone/bclone_corner_cases.kshlib \
9396
functional/block_cloning/block_cloning.kshlib \
9497
functional/cache/cache.cfg \
9598
functional/cache/cache.kshlib \
@@ -438,6 +441,24 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
438441
functional/atime/root_atime_on.ksh \
439442
functional/atime/root_relatime_on.ksh \
440443
functional/atime/setup.ksh \
444+
functional/bclone/bclone_crossfs_corner_cases.ksh \
445+
functional/bclone/bclone_crossfs_corner_cases_limited.ksh \
446+
functional/bclone/bclone_crossfs_data.ksh \
447+
functional/bclone/bclone_crossfs_embedded.ksh \
448+
functional/bclone/bclone_crossfs_hole.ksh \
449+
functional/bclone/bclone_diffprops_all.ksh \
450+
functional/bclone/bclone_diffprops_checksum.ksh \
451+
functional/bclone/bclone_diffprops_compress.ksh \
452+
functional/bclone/bclone_diffprops_copies.ksh \
453+
functional/bclone/bclone_diffprops_recordsize.ksh \
454+
functional/bclone/bclone_prop_sync.ksh \
455+
functional/bclone/bclone_samefs_corner_cases.ksh \
456+
functional/bclone/bclone_samefs_corner_cases_limited.ksh \
457+
functional/bclone/bclone_samefs_data.ksh \
458+
functional/bclone/bclone_samefs_embedded.ksh \
459+
functional/bclone/bclone_samefs_hole.ksh \
460+
functional/bclone/cleanup.ksh \
461+
functional/bclone/setup.ksh \
441462
functional/block_cloning/cleanup.ksh \
442463
functional/block_cloning/setup.ksh \
443464
functional/block_cloning/block_cloning_copyfilerange_cross_dataset.ksh \
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
- If dedup enabled, block_cloning uses dedup.
2+
- block_cloning works only with the same encryption key
3+
- check when block cloning doesn't suppose to work
4+
- check block cloning between two different pools
5+
- block cloning from a snapshot
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#
2+
# CDDL HEADER START
3+
#
4+
# The contents of this file are subject to the terms of the
5+
# Common Development and Distribution License (the "License").
6+
# You may not use this file except in compliance with the License.
7+
#
8+
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9+
# or https://opensource.org/licenses/CDDL-1.0.
10+
# See the License for the specific language governing permissions
11+
# and limitations under the License.
12+
#
13+
# When distributing Covered Code, include this CDDL HEADER in each
14+
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15+
# If applicable, add the following below this CDDL HEADER, with the
16+
# fields enclosed by brackets "[]" replaced with your own identifying
17+
# information: Portions Copyright [yyyy] [name of copyright owner]
18+
#
19+
# CDDL HEADER END
20+
#
21+
22+
#
23+
# Copyright (c) 2023 by Pawel Jakub Dawidek
24+
#
25+
26+
# TODO: We should calculate that based on ashift.
27+
export MINBLOCKSIZE=512
28+
29+
export TESTSRCFS="$TESTPOOL/$TESTFS/src"
30+
export TESTDSTFS="$TESTPOOL/$TESTFS/dst"
31+
export TESTSRCDIR="$TESTDIR/src"
32+
export TESTDSTDIR="$TESTDIR/dst"

0 commit comments

Comments
 (0)