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. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Pawel Jakub Dawidek <pawel@dawidek.net> Closes #15631
This commit is contained in:
parent
f94a77951d
commit
c16d103422
|
@ -16,6 +16,7 @@ dist_scripts_test_runner_include_DATA = \
|
||||||
|
|
||||||
scripts_runfilesdir = $(datadir)/$(PACKAGE)/runfiles
|
scripts_runfilesdir = $(datadir)/$(PACKAGE)/runfiles
|
||||||
dist_scripts_runfiles_DATA = \
|
dist_scripts_runfiles_DATA = \
|
||||||
|
%D%/runfiles/bclone.run \
|
||||||
%D%/runfiles/common.run \
|
%D%/runfiles/common.run \
|
||||||
%D%/runfiles/freebsd.run \
|
%D%/runfiles/freebsd.run \
|
||||||
%D%/runfiles/linux.run \
|
%D%/runfiles/linux.run \
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
#
|
||||||
|
# This file and its contents are supplied under the terms of the
|
||||||
|
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||||
|
# You may only use this file in accordance with the terms of version
|
||||||
|
# 1.0 of the CDDL.
|
||||||
|
#
|
||||||
|
# A full copy of the text of the CDDL should have accompanied this
|
||||||
|
# source. A copy of the CDDL is also available via the Internet at
|
||||||
|
# http://www.illumos.org/license/CDDL.
|
||||||
|
#
|
||||||
|
# This run file contains all of the common functional tests. When
|
||||||
|
# adding a new test consider also adding it to the sanity.run file
|
||||||
|
# if the new test runs to completion in only a few seconds.
|
||||||
|
#
|
||||||
|
# Approximate run time: 5 hours
|
||||||
|
#
|
||||||
|
|
||||||
|
[DEFAULT]
|
||||||
|
pre = setup
|
||||||
|
quiet = False
|
||||||
|
pre_user = root
|
||||||
|
user = root
|
||||||
|
timeout = 28800
|
||||||
|
post_user = root
|
||||||
|
post = cleanup
|
||||||
|
failsafe_user = root
|
||||||
|
failsafe = callbacks/zfs_failsafe
|
||||||
|
outputdir = /var/tmp/test_results
|
||||||
|
tags = ['bclone']
|
||||||
|
|
||||||
|
[tests/functional/bclone]
|
||||||
|
tests = ['bclone_crossfs_corner_cases',
|
||||||
|
'bclone_crossfs_data',
|
||||||
|
'bclone_crossfs_embedded',
|
||||||
|
'bclone_crossfs_hole',
|
||||||
|
'bclone_diffprops_all',
|
||||||
|
'bclone_diffprops_checksum',
|
||||||
|
'bclone_diffprops_compress',
|
||||||
|
'bclone_diffprops_copies',
|
||||||
|
'bclone_diffprops_recordsize',
|
||||||
|
'bclone_prop_sync',
|
||||||
|
'bclone_samefs_corner_cases',
|
||||||
|
'bclone_samefs_data',
|
||||||
|
'bclone_samefs_embedded',
|
||||||
|
'bclone_samefs_hole']
|
||||||
|
tags = ['bclone']
|
|
@ -53,6 +53,24 @@ tags = ['functional', 'arc']
|
||||||
tests = ['atime_001_pos', 'atime_002_neg', 'root_atime_off', 'root_atime_on']
|
tests = ['atime_001_pos', 'atime_002_neg', 'root_atime_off', 'root_atime_on']
|
||||||
tags = ['functional', 'atime']
|
tags = ['functional', 'atime']
|
||||||
|
|
||||||
|
[tests/functional/bclone]
|
||||||
|
tests = ['bclone_crossfs_corner_cases_limited',
|
||||||
|
'bclone_crossfs_data',
|
||||||
|
'bclone_crossfs_embedded',
|
||||||
|
'bclone_crossfs_hole',
|
||||||
|
'bclone_diffprops_all',
|
||||||
|
'bclone_diffprops_checksum',
|
||||||
|
'bclone_diffprops_compress',
|
||||||
|
'bclone_diffprops_copies',
|
||||||
|
'bclone_diffprops_recordsize',
|
||||||
|
'bclone_prop_sync',
|
||||||
|
'bclone_samefs_corner_cases_limited',
|
||||||
|
'bclone_samefs_data',
|
||||||
|
'bclone_samefs_embedded',
|
||||||
|
'bclone_samefs_hole']
|
||||||
|
tags = ['functional', 'bclone']
|
||||||
|
timeout = 7200
|
||||||
|
|
||||||
[tests/functional/bootfs]
|
[tests/functional/bootfs]
|
||||||
tests = ['bootfs_001_pos', 'bootfs_002_neg', 'bootfs_003_pos',
|
tests = ['bootfs_001_pos', 'bootfs_002_neg', 'bootfs_003_pos',
|
||||||
'bootfs_004_neg', 'bootfs_005_neg', 'bootfs_006_pos', 'bootfs_007_pos',
|
'bootfs_004_neg', 'bootfs_005_neg', 'bootfs_006_pos', 'bootfs_007_pos',
|
||||||
|
|
|
@ -263,13 +263,50 @@ if sys.platform.startswith('freebsd'):
|
||||||
'cli_root/zpool_import/zpool_import_012_pos': ['FAIL', known_reason],
|
'cli_root/zpool_import/zpool_import_012_pos': ['FAIL', known_reason],
|
||||||
'delegate/zfs_allow_003_pos': ['FAIL', known_reason],
|
'delegate/zfs_allow_003_pos': ['FAIL', known_reason],
|
||||||
'inheritance/inherit_001_pos': ['FAIL', 11829],
|
'inheritance/inherit_001_pos': ['FAIL', 11829],
|
||||||
'resilver/resilver_restart_001': ['FAIL', known_reason],
|
|
||||||
'pool_checkpoint/checkpoint_big_rewind': ['FAIL', 12622],
|
'pool_checkpoint/checkpoint_big_rewind': ['FAIL', 12622],
|
||||||
'pool_checkpoint/checkpoint_indirect': ['FAIL', 12623],
|
'pool_checkpoint/checkpoint_indirect': ['FAIL', 12623],
|
||||||
|
'resilver/resilver_restart_001': ['FAIL', known_reason],
|
||||||
'snapshot/snapshot_002_pos': ['FAIL', '14831'],
|
'snapshot/snapshot_002_pos': ['FAIL', '14831'],
|
||||||
})
|
})
|
||||||
elif sys.platform.startswith('linux'):
|
elif sys.platform.startswith('linux'):
|
||||||
maybe.update({
|
maybe.update({
|
||||||
|
'bclone/bclone_crossfs_corner_cases': ['SKIP', cfr_cross_reason],
|
||||||
|
'bclone/bclone_crossfs_corner_cases_limited':
|
||||||
|
['SKIP', cfr_cross_reason],
|
||||||
|
'bclone/bclone_crossfs_data': ['SKIP', cfr_cross_reason],
|
||||||
|
'bclone/bclone_crossfs_embedded': ['SKIP', cfr_cross_reason],
|
||||||
|
'bclone/bclone_crossfs_hole': ['SKIP', cfr_cross_reason],
|
||||||
|
'bclone/bclone_diffprops_all': ['SKIP', cfr_cross_reason],
|
||||||
|
'bclone/bclone_diffprops_checksum': ['SKIP', cfr_cross_reason],
|
||||||
|
'bclone/bclone_diffprops_compress': ['SKIP', cfr_cross_reason],
|
||||||
|
'bclone/bclone_diffprops_copies': ['SKIP', cfr_cross_reason],
|
||||||
|
'bclone/bclone_diffprops_recordsize': ['SKIP', cfr_cross_reason],
|
||||||
|
'bclone/bclone_prop_sync': ['SKIP', cfr_cross_reason],
|
||||||
|
'bclone/bclone_samefs_corner_cases': ['SKIP', cfr_reason],
|
||||||
|
'bclone/bclone_samefs_corner_cases_limited': ['SKIP', cfr_reason],
|
||||||
|
'bclone/bclone_samefs_data': ['SKIP', cfr_reason],
|
||||||
|
'bclone/bclone_samefs_embedded': ['SKIP', cfr_reason],
|
||||||
|
'bclone/bclone_samefs_hole': ['SKIP', cfr_reason],
|
||||||
|
'block_cloning/block_cloning_copyfilerange':
|
||||||
|
['SKIP', cfr_reason],
|
||||||
|
'block_cloning/block_cloning_copyfilerange_cross_dataset':
|
||||||
|
['SKIP', cfr_cross_reason],
|
||||||
|
'block_cloning/block_cloning_copyfilerange_fallback':
|
||||||
|
['SKIP', cfr_reason],
|
||||||
|
'block_cloning/block_cloning_copyfilerange_fallback_same_txg':
|
||||||
|
['SKIP', cfr_cross_reason],
|
||||||
|
'block_cloning/block_cloning_copyfilerange_partial':
|
||||||
|
['SKIP', cfr_reason],
|
||||||
|
'block_cloning/block_cloning_cross_enc_dataset':
|
||||||
|
['SKIP', cfr_cross_reason],
|
||||||
|
'block_cloning/block_cloning_disabled_copyfilerange':
|
||||||
|
['SKIP', cfr_reason],
|
||||||
|
'block_cloning/block_cloning_lwb_buffer_overflow':
|
||||||
|
['SKIP', cfr_reason],
|
||||||
|
'block_cloning/block_cloning_replay':
|
||||||
|
['SKIP', cfr_reason],
|
||||||
|
'block_cloning/block_cloning_replay_encrypted':
|
||||||
|
['SKIP', cfr_reason],
|
||||||
'cli_root/zfs_rename/zfs_rename_002_pos': ['FAIL', known_reason],
|
'cli_root/zfs_rename/zfs_rename_002_pos': ['FAIL', known_reason],
|
||||||
'cli_root/zpool_reopen/zpool_reopen_003_pos': ['FAIL', known_reason],
|
'cli_root/zpool_reopen/zpool_reopen_003_pos': ['FAIL', known_reason],
|
||||||
'fault/auto_online_002_pos': ['FAIL', 11889],
|
'fault/auto_online_002_pos': ['FAIL', 11889],
|
||||||
|
@ -278,41 +315,21 @@ elif sys.platform.startswith('linux'):
|
||||||
'fault/auto_spare_multiple': ['FAIL', 11889],
|
'fault/auto_spare_multiple': ['FAIL', 11889],
|
||||||
'fault/auto_spare_shared': ['FAIL', 11889],
|
'fault/auto_spare_shared': ['FAIL', 11889],
|
||||||
'fault/decompress_fault': ['FAIL', 11889],
|
'fault/decompress_fault': ['FAIL', 11889],
|
||||||
|
'idmap_mount/idmap_mount_001': ['SKIP', idmap_reason],
|
||||||
|
'idmap_mount/idmap_mount_002': ['SKIP', idmap_reason],
|
||||||
|
'idmap_mount/idmap_mount_003': ['SKIP', idmap_reason],
|
||||||
|
'idmap_mount/idmap_mount_004': ['SKIP', idmap_reason],
|
||||||
|
'idmap_mount/idmap_mount_005': ['SKIP', idmap_reason],
|
||||||
'io/io_uring': ['SKIP', 'io_uring support required'],
|
'io/io_uring': ['SKIP', 'io_uring support required'],
|
||||||
'limits/filesystem_limit': ['SKIP', known_reason],
|
'limits/filesystem_limit': ['SKIP', known_reason],
|
||||||
'limits/snapshot_limit': ['SKIP', known_reason],
|
'limits/snapshot_limit': ['SKIP', known_reason],
|
||||||
'mmp/mmp_active_import': ['FAIL', known_reason],
|
'mmp/mmp_active_import': ['FAIL', known_reason],
|
||||||
'mmp/mmp_exported_import': ['FAIL', known_reason],
|
'mmp/mmp_exported_import': ['FAIL', known_reason],
|
||||||
'mmp/mmp_inactive_import': ['FAIL', known_reason],
|
'mmp/mmp_inactive_import': ['FAIL', known_reason],
|
||||||
'zvol/zvol_misc/zvol_misc_snapdev': ['FAIL', 12621],
|
|
||||||
'zvol/zvol_misc/zvol_misc_volmode': ['FAIL', known_reason],
|
|
||||||
'zvol/zvol_misc/zvol_misc_fua': ['SKIP', 14872],
|
'zvol/zvol_misc/zvol_misc_fua': ['SKIP', 14872],
|
||||||
|
'zvol/zvol_misc/zvol_misc_snapdev': ['FAIL', 12621],
|
||||||
'zvol/zvol_misc/zvol_misc_trim': ['SKIP', 14872],
|
'zvol/zvol_misc/zvol_misc_trim': ['SKIP', 14872],
|
||||||
'idmap_mount/idmap_mount_001': ['SKIP', idmap_reason],
|
'zvol/zvol_misc/zvol_misc_volmode': ['FAIL', known_reason],
|
||||||
'idmap_mount/idmap_mount_002': ['SKIP', idmap_reason],
|
|
||||||
'idmap_mount/idmap_mount_003': ['SKIP', idmap_reason],
|
|
||||||
'idmap_mount/idmap_mount_004': ['SKIP', idmap_reason],
|
|
||||||
'idmap_mount/idmap_mount_005': ['SKIP', idmap_reason],
|
|
||||||
'block_cloning/block_cloning_disabled_copyfilerange':
|
|
||||||
['SKIP', cfr_reason],
|
|
||||||
'block_cloning/block_cloning_copyfilerange':
|
|
||||||
['SKIP', cfr_reason],
|
|
||||||
'block_cloning/block_cloning_copyfilerange_partial':
|
|
||||||
['SKIP', cfr_reason],
|
|
||||||
'block_cloning/block_cloning_copyfilerange_fallback':
|
|
||||||
['SKIP', cfr_reason],
|
|
||||||
'block_cloning/block_cloning_replay':
|
|
||||||
['SKIP', cfr_reason],
|
|
||||||
'block_cloning/block_cloning_replay_encrypted':
|
|
||||||
['SKIP', cfr_reason],
|
|
||||||
'block_cloning/block_cloning_lwb_buffer_overflow':
|
|
||||||
['SKIP', cfr_reason],
|
|
||||||
'block_cloning/block_cloning_copyfilerange_cross_dataset':
|
|
||||||
['SKIP', cfr_cross_reason],
|
|
||||||
'block_cloning/block_cloning_copyfilerange_fallback_same_txg':
|
|
||||||
['SKIP', cfr_cross_reason],
|
|
||||||
'block_cloning/block_cloning_cross_enc_dataset':
|
|
||||||
['SKIP', cfr_cross_reason],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
# Not all Github actions runners have scsi_debug module, so we may skip
|
# Not all Github actions runners have scsi_debug module, so we may skip
|
||||||
|
|
|
@ -2,6 +2,7 @@ scripts_zfs_tests_bindir = $(datadir)/$(PACKAGE)/zfs-tests/bin
|
||||||
|
|
||||||
|
|
||||||
scripts_zfs_tests_bin_PROGRAMS = %D%/chg_usr_exec
|
scripts_zfs_tests_bin_PROGRAMS = %D%/chg_usr_exec
|
||||||
|
scripts_zfs_tests_bin_PROGRAMS += %D%/clonefile
|
||||||
scripts_zfs_tests_bin_PROGRAMS += %D%/cp_files
|
scripts_zfs_tests_bin_PROGRAMS += %D%/cp_files
|
||||||
scripts_zfs_tests_bin_PROGRAMS += %D%/ctime
|
scripts_zfs_tests_bin_PROGRAMS += %D%/ctime
|
||||||
scripts_zfs_tests_bin_PROGRAMS += %D%/dir_rd_update
|
scripts_zfs_tests_bin_PROGRAMS += %D%/dir_rd_update
|
||||||
|
@ -119,7 +120,6 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/renameat2
|
||||||
scripts_zfs_tests_bin_PROGRAMS += %D%/xattrtest
|
scripts_zfs_tests_bin_PROGRAMS += %D%/xattrtest
|
||||||
scripts_zfs_tests_bin_PROGRAMS += %D%/zed_fd_spill-zedlet
|
scripts_zfs_tests_bin_PROGRAMS += %D%/zed_fd_spill-zedlet
|
||||||
scripts_zfs_tests_bin_PROGRAMS += %D%/idmap_util
|
scripts_zfs_tests_bin_PROGRAMS += %D%/idmap_util
|
||||||
scripts_zfs_tests_bin_PROGRAMS += %D%/clonefile
|
|
||||||
|
|
||||||
%C%_idmap_util_LDADD = libspl.la
|
%C%_idmap_util_LDADD = libspl.la
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,10 @@
|
||||||
#endif
|
#endif
|
||||||
#endif /* __NR_copy_file_range */
|
#endif /* __NR_copy_file_range */
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#define loff_t off_t
|
||||||
|
#endif
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
copy_file_range(int, loff_t *, int, loff_t *, size_t, unsigned int)
|
copy_file_range(int, loff_t *, int, loff_t *, size_t, unsigned int)
|
||||||
__attribute__((weak));
|
__attribute__((weak));
|
||||||
|
@ -140,7 +144,7 @@ usage(void)
|
||||||
" FICLONERANGE:\n"
|
" FICLONERANGE:\n"
|
||||||
" clonefile -r <src> <dst> <soff> <doff> <len>\n"
|
" clonefile -r <src> <dst> <soff> <doff> <len>\n"
|
||||||
" copy_file_range:\n"
|
" copy_file_range:\n"
|
||||||
" clonefile -f <src> <dst> <soff> <doff> <len>\n"
|
" clonefile -f <src> <dst> [<soff> <doff> <len | \"all\">]\n"
|
||||||
" FIDEDUPERANGE:\n"
|
" FIDEDUPERANGE:\n"
|
||||||
" clonefile -d <src> <dst> <soff> <doff> <len>\n");
|
" clonefile -d <src> <dst> <soff> <doff> <len>\n");
|
||||||
return (1);
|
return (1);
|
||||||
|
@ -179,13 +183,29 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == CF_MODE_NONE || (argc-optind) < 2 ||
|
switch (mode) {
|
||||||
(mode != CF_MODE_CLONE && (argc-optind) < 5))
|
case CF_MODE_NONE:
|
||||||
return (usage());
|
return (usage());
|
||||||
|
case CF_MODE_CLONE:
|
||||||
|
if ((argc-optind) != 2)
|
||||||
|
return (usage());
|
||||||
|
break;
|
||||||
|
case CF_MODE_CLONERANGE:
|
||||||
|
case CF_MODE_DEDUPERANGE:
|
||||||
|
if ((argc-optind) != 5)
|
||||||
|
return (usage());
|
||||||
|
break;
|
||||||
|
case CF_MODE_COPYFILERANGE:
|
||||||
|
if ((argc-optind) != 2 && (argc-optind) != 5)
|
||||||
|
return (usage());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
loff_t soff = 0, doff = 0;
|
loff_t soff = 0, doff = 0;
|
||||||
size_t len = 0;
|
size_t len = SSIZE_MAX;
|
||||||
if (mode != CF_MODE_CLONE) {
|
if ((argc-optind) == 5) {
|
||||||
soff = strtoull(argv[optind+2], NULL, 10);
|
soff = strtoull(argv[optind+2], NULL, 10);
|
||||||
if (soff == ULLONG_MAX) {
|
if (soff == ULLONG_MAX) {
|
||||||
fprintf(stderr, "invalid source offset");
|
fprintf(stderr, "invalid source offset");
|
||||||
|
@ -196,12 +216,17 @@ main(int argc, char **argv)
|
||||||
fprintf(stderr, "invalid dest offset");
|
fprintf(stderr, "invalid dest offset");
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
if (mode == CF_MODE_COPYFILERANGE &&
|
||||||
|
strcmp(argv[optind+4], "all") == 0) {
|
||||||
|
len = SSIZE_MAX;
|
||||||
|
} else {
|
||||||
len = strtoull(argv[optind+4], NULL, 10);
|
len = strtoull(argv[optind+4], NULL, 10);
|
||||||
if (len == ULLONG_MAX) {
|
if (len == ULLONG_MAX) {
|
||||||
fprintf(stderr, "invalid length");
|
fprintf(stderr, "invalid length");
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int sfd = open(argv[optind], O_RDONLY);
|
int sfd = open(argv[optind], O_RDONLY);
|
||||||
if (sfd < 0) {
|
if (sfd < 0) {
|
||||||
|
@ -237,13 +262,15 @@ main(int argc, char **argv)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!quiet) {
|
||||||
off_t spos = lseek(sfd, 0, SEEK_CUR);
|
off_t spos = lseek(sfd, 0, SEEK_CUR);
|
||||||
off_t slen = lseek(sfd, 0, SEEK_END);
|
off_t slen = lseek(sfd, 0, SEEK_END);
|
||||||
off_t dpos = lseek(dfd, 0, SEEK_CUR);
|
off_t dpos = lseek(dfd, 0, SEEK_CUR);
|
||||||
off_t dlen = lseek(dfd, 0, SEEK_END);
|
off_t dlen = lseek(dfd, 0, SEEK_END);
|
||||||
|
|
||||||
fprintf(stderr, "file offsets: src=%lu/%lu; dst=%lu/%lu\n", spos, slen,
|
fprintf(stderr, "file offsets: src=%lu/%lu; dst=%lu/%lu\n",
|
||||||
dpos, dlen);
|
spos, slen, dpos, dlen);
|
||||||
|
}
|
||||||
|
|
||||||
close(dfd);
|
close(dfd);
|
||||||
close(sfd);
|
close(sfd);
|
||||||
|
@ -254,6 +281,7 @@ main(int argc, char **argv)
|
||||||
int
|
int
|
||||||
do_clone(int sfd, int dfd)
|
do_clone(int sfd, int dfd)
|
||||||
{
|
{
|
||||||
|
if (!quiet)
|
||||||
fprintf(stderr, "using FICLONE\n");
|
fprintf(stderr, "using FICLONE\n");
|
||||||
int err = ioctl(dfd, CF_FICLONE, sfd);
|
int err = ioctl(dfd, CF_FICLONE, sfd);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
@ -266,6 +294,7 @@ do_clone(int sfd, int dfd)
|
||||||
int
|
int
|
||||||
do_clonerange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
|
do_clonerange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
|
||||||
{
|
{
|
||||||
|
if (!quiet)
|
||||||
fprintf(stderr, "using FICLONERANGE\n");
|
fprintf(stderr, "using FICLONERANGE\n");
|
||||||
cf_file_clone_range_t fcr = {
|
cf_file_clone_range_t fcr = {
|
||||||
.src_fd = sfd,
|
.src_fd = sfd,
|
||||||
|
@ -284,12 +313,22 @@ do_clonerange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
|
||||||
int
|
int
|
||||||
do_copyfilerange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
|
do_copyfilerange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
|
||||||
{
|
{
|
||||||
|
if (!quiet)
|
||||||
fprintf(stderr, "using copy_file_range\n");
|
fprintf(stderr, "using copy_file_range\n");
|
||||||
ssize_t copied = cf_copy_file_range(sfd, &soff, dfd, &doff, len, 0);
|
ssize_t copied = cf_copy_file_range(sfd, &soff, dfd, &doff, len, 0);
|
||||||
if (copied < 0) {
|
if (copied < 0) {
|
||||||
fprintf(stderr, "copy_file_range: %s\n", strerror(errno));
|
fprintf(stderr, "copy_file_range: %s\n", strerror(errno));
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
if (len == SSIZE_MAX) {
|
||||||
|
struct stat sb;
|
||||||
|
|
||||||
|
if (fstat(sfd, &sb) < 0) {
|
||||||
|
fprintf(stderr, "fstat(sfd): %s\n", strerror(errno));
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
len = sb.st_size;
|
||||||
|
}
|
||||||
if (copied != len) {
|
if (copied != len) {
|
||||||
fprintf(stderr, "copy_file_range: copied less than requested: "
|
fprintf(stderr, "copy_file_range: copied less than requested: "
|
||||||
"requested=%lu; copied=%lu\n", len, copied);
|
"requested=%lu; copied=%lu\n", len, copied);
|
||||||
|
@ -301,6 +340,7 @@ do_copyfilerange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
|
||||||
int
|
int
|
||||||
do_deduperange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
|
do_deduperange(int sfd, int dfd, loff_t soff, loff_t doff, size_t len)
|
||||||
{
|
{
|
||||||
|
if (!quiet)
|
||||||
fprintf(stderr, "using FIDEDUPERANGE\n");
|
fprintf(stderr, "using FIDEDUPERANGE\n");
|
||||||
|
|
||||||
char buf[sizeof (cf_file_dedupe_range_t)+
|
char buf[sizeof (cf_file_dedupe_range_t)+
|
||||||
|
|
|
@ -98,7 +98,8 @@ export SYSTEM_FILES_COMMON='awk
|
||||||
uname
|
uname
|
||||||
uniq
|
uniq
|
||||||
vmstat
|
vmstat
|
||||||
wc'
|
wc
|
||||||
|
xargs'
|
||||||
|
|
||||||
export SYSTEM_FILES_FREEBSD='chflags
|
export SYSTEM_FILES_FREEBSD='chflags
|
||||||
compress
|
compress
|
||||||
|
|
|
@ -123,10 +123,21 @@ function verify_ne # <a> <b> <type>
|
||||||
#
|
#
|
||||||
# $1 lower bound
|
# $1 lower bound
|
||||||
# $2 upper bound
|
# $2 upper bound
|
||||||
|
# [$3 how many]
|
||||||
function random_int_between
|
function random_int_between
|
||||||
{
|
{
|
||||||
typeset -i min=$1
|
typeset -i min=$1
|
||||||
typeset -i max=$2
|
typeset -i max=$2
|
||||||
|
typeset -i count
|
||||||
|
typeset -i i
|
||||||
|
|
||||||
|
if [[ -z "$3" ]]; then
|
||||||
|
count=1
|
||||||
|
else
|
||||||
|
count=$3
|
||||||
|
fi
|
||||||
|
|
||||||
|
for (( i = 0; i < $count; i++ )); do
|
||||||
echo $(( (RANDOM % (max - min + 1)) + min ))
|
echo $(( (RANDOM % (max - min + 1)) + min ))
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,9 @@ nobase_dist_datadir_zfs_tests_tests_DATA += \
|
||||||
functional/alloc_class/alloc_class.kshlib \
|
functional/alloc_class/alloc_class.kshlib \
|
||||||
functional/atime/atime.cfg \
|
functional/atime/atime.cfg \
|
||||||
functional/atime/atime_common.kshlib \
|
functional/atime/atime_common.kshlib \
|
||||||
|
functional/bclone/bclone.cfg \
|
||||||
|
functional/bclone/bclone_common.kshlib \
|
||||||
|
functional/bclone/bclone_corner_cases.kshlib \
|
||||||
functional/block_cloning/block_cloning.kshlib \
|
functional/block_cloning/block_cloning.kshlib \
|
||||||
functional/cache/cache.cfg \
|
functional/cache/cache.cfg \
|
||||||
functional/cache/cache.kshlib \
|
functional/cache/cache.kshlib \
|
||||||
|
@ -438,6 +441,24 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
||||||
functional/atime/root_atime_on.ksh \
|
functional/atime/root_atime_on.ksh \
|
||||||
functional/atime/root_relatime_on.ksh \
|
functional/atime/root_relatime_on.ksh \
|
||||||
functional/atime/setup.ksh \
|
functional/atime/setup.ksh \
|
||||||
|
functional/bclone/bclone_crossfs_corner_cases.ksh \
|
||||||
|
functional/bclone/bclone_crossfs_corner_cases_limited.ksh \
|
||||||
|
functional/bclone/bclone_crossfs_data.ksh \
|
||||||
|
functional/bclone/bclone_crossfs_embedded.ksh \
|
||||||
|
functional/bclone/bclone_crossfs_hole.ksh \
|
||||||
|
functional/bclone/bclone_diffprops_all.ksh \
|
||||||
|
functional/bclone/bclone_diffprops_checksum.ksh \
|
||||||
|
functional/bclone/bclone_diffprops_compress.ksh \
|
||||||
|
functional/bclone/bclone_diffprops_copies.ksh \
|
||||||
|
functional/bclone/bclone_diffprops_recordsize.ksh \
|
||||||
|
functional/bclone/bclone_prop_sync.ksh \
|
||||||
|
functional/bclone/bclone_samefs_corner_cases.ksh \
|
||||||
|
functional/bclone/bclone_samefs_corner_cases_limited.ksh \
|
||||||
|
functional/bclone/bclone_samefs_data.ksh \
|
||||||
|
functional/bclone/bclone_samefs_embedded.ksh \
|
||||||
|
functional/bclone/bclone_samefs_hole.ksh \
|
||||||
|
functional/bclone/cleanup.ksh \
|
||||||
|
functional/bclone/setup.ksh \
|
||||||
functional/block_cloning/cleanup.ksh \
|
functional/block_cloning/cleanup.ksh \
|
||||||
functional/block_cloning/setup.ksh \
|
functional/block_cloning/setup.ksh \
|
||||||
functional/block_cloning/block_cloning_copyfilerange_cross_dataset.ksh \
|
functional/block_cloning/block_cloning_copyfilerange_cross_dataset.ksh \
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
- If dedup enabled, block_cloning uses dedup.
|
||||||
|
- check when block cloning doesn't suppose to work
|
||||||
|
- check block cloning between two different pools
|
||||||
|
- block cloning from a snapshot
|
|
@ -0,0 +1,32 @@
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
# TODO: We should calculate that based on ashift.
|
||||||
|
export MINBLOCKSIZE=512
|
||||||
|
|
||||||
|
export TESTSRCFS="$TESTPOOL/$TESTFS/src"
|
||||||
|
export TESTDSTFS="$TESTPOOL/$TESTFS/dst"
|
||||||
|
export TESTSRCDIR="$TESTDIR/src"
|
||||||
|
export TESTDSTDIR="$TESTDIR/dst"
|
|
@ -0,0 +1,280 @@
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone.cfg
|
||||||
|
|
||||||
|
export RECORDSIZE=$(zfs get -Hp -o value recordsize $TESTPOOL/$TESTFS)
|
||||||
|
|
||||||
|
MINBLKSIZE1=512
|
||||||
|
MINBLKSIZE2=1024
|
||||||
|
|
||||||
|
function verify_block_cloning
|
||||||
|
{
|
||||||
|
if is_linux && [[ $(linux_version) -lt $(linux_version "4.5") ]]; then
|
||||||
|
log_unsupported "copy_file_range not available before Linux 4.5"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function verify_crossfs_block_cloning
|
||||||
|
{
|
||||||
|
if is_linux && [[ $(linux_version) -lt $(linux_version "5.3") ]]; then
|
||||||
|
log_unsupported "copy_file_range can't copy cross-filesystem before Linux 5.3"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Unused.
|
||||||
|
function size_to_dsize
|
||||||
|
{
|
||||||
|
typeset -r size=$1
|
||||||
|
typeset -r dir=$2
|
||||||
|
|
||||||
|
typeset -r dataset=$(df $dir | tail -1 | awk '{print $1}')
|
||||||
|
typeset -r recordsize=$(get_prop recordsize $dataset)
|
||||||
|
typeset -r copies=$(get_prop copies $dataset)
|
||||||
|
typeset dsize
|
||||||
|
|
||||||
|
if [[ $size -le $recordsize ]]; then
|
||||||
|
dsize=$(( ((size - 1) / MINBLOCKSIZE + 1) * MINBLOCKSIZE ))
|
||||||
|
else
|
||||||
|
dsize=$(( ((size - 1) / recordsize + 1) * recordsize ))
|
||||||
|
fi
|
||||||
|
dsize=$((dsize*copies))
|
||||||
|
|
||||||
|
echo $dsize
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_file_integrity
|
||||||
|
{
|
||||||
|
typeset -r original_checksum=$1
|
||||||
|
typeset -r clone=$2
|
||||||
|
typeset -r filesize=$3
|
||||||
|
|
||||||
|
typeset -r clone_checksum=$(sha256digest $clone)
|
||||||
|
|
||||||
|
if [[ $original_checksum != $clone_checksum ]]; then
|
||||||
|
log_fail "Clone $clone is corrupted with file size $filesize"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function verify_pool_prop_eq
|
||||||
|
{
|
||||||
|
typeset -r prop=$1
|
||||||
|
typeset -r expected=$2
|
||||||
|
|
||||||
|
typeset -r value=$(get_pool_prop $prop $TESTPOOL)
|
||||||
|
if [[ $value != $expected ]]; then
|
||||||
|
log_fail "Pool property $prop is incorrect: expected $expected, got $value"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function verify_pool_props
|
||||||
|
{
|
||||||
|
typeset -r dsize=$1
|
||||||
|
typeset -r ratio=$2
|
||||||
|
|
||||||
|
if [[ $dsize -eq 0 ]]; then
|
||||||
|
verify_pool_prop_eq bcloneused 0
|
||||||
|
verify_pool_prop_eq bclonesaved 0
|
||||||
|
verify_pool_prop_eq bcloneratio 1.00
|
||||||
|
else
|
||||||
|
if [[ $ratio -eq 1 ]]; then
|
||||||
|
verify_pool_prop_eq bcloneused 0
|
||||||
|
else
|
||||||
|
verify_pool_prop_eq bcloneused $dsize
|
||||||
|
fi
|
||||||
|
verify_pool_prop_eq bclonesaved $((dsize*(ratio-1)))
|
||||||
|
verify_pool_prop_eq bcloneratio "${ratio}.00"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to test file copying and integrity check.
|
||||||
|
function bclone_test
|
||||||
|
{
|
||||||
|
typeset -r datatype=$1
|
||||||
|
typeset filesize=$2
|
||||||
|
typeset -r embedded=$3
|
||||||
|
typeset -r srcdir=$4
|
||||||
|
typeset -r dstdir=$5
|
||||||
|
typeset dsize
|
||||||
|
|
||||||
|
typeset -r original="${srcdir}/original"
|
||||||
|
typeset -r clone="${dstdir}/clone"
|
||||||
|
|
||||||
|
log_note "Testing file copy with datatype $datatype, file size $filesize, embedded $embedded"
|
||||||
|
|
||||||
|
# Create a test file with known content.
|
||||||
|
case $datatype in
|
||||||
|
random|text)
|
||||||
|
sync_pool $TESTPOOL
|
||||||
|
if [[ $datatype = "random" ]]; then
|
||||||
|
dd if=/dev/urandom of=$original bs=$filesize count=1 2>/dev/null
|
||||||
|
else
|
||||||
|
filesize=$(((filesize/4)*4))
|
||||||
|
dd if=/dev/urandom bs=$(((filesize/4)*3)) count=1 | \
|
||||||
|
openssl base64 -A > $original
|
||||||
|
fi
|
||||||
|
sync_pool $TESTPOOL
|
||||||
|
clonefile -f $original "${clone}-tmp"
|
||||||
|
sync_pool $TESTPOOL
|
||||||
|
# It is hard to predict block sizes that will be used,
|
||||||
|
# so just do one clone and take it from bcloneused.
|
||||||
|
filesize=$(zpool get -Hp -o value bcloneused $TESTPOOL)
|
||||||
|
if [[ $embedded = "false" ]]; then
|
||||||
|
log_must test $filesize -gt 0
|
||||||
|
fi
|
||||||
|
rm -f "${clone}-tmp"
|
||||||
|
sync_pool $TESTPOOL
|
||||||
|
dsize=$filesize
|
||||||
|
;;
|
||||||
|
hole)
|
||||||
|
log_must truncate_test -s $filesize -f $original
|
||||||
|
dsize=0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_fail "Unknown datatype $datatype"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
if [[ $embedded = "true" ]]; then
|
||||||
|
dsize=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
typeset -r original_checksum=$(sha256digest $original)
|
||||||
|
|
||||||
|
sync_pool $TESTPOOL
|
||||||
|
|
||||||
|
# Create a first clone of the entire file.
|
||||||
|
clonefile -f $original "${clone}0"
|
||||||
|
# Try to clone the clone in the same transaction group.
|
||||||
|
clonefile -f "${clone}0" "${clone}2"
|
||||||
|
|
||||||
|
# Clone the original again...
|
||||||
|
clonefile -f $original "${clone}1"
|
||||||
|
# ...and overwrite it in the same transaction group.
|
||||||
|
clonefile -f $original "${clone}1"
|
||||||
|
|
||||||
|
# Clone the clone...
|
||||||
|
clonefile -f "${clone}1" "${clone}3"
|
||||||
|
sync_pool $TESTPOOL
|
||||||
|
# ...and overwrite in the new transaction group.
|
||||||
|
clonefile -f "${clone}1" "${clone}3"
|
||||||
|
|
||||||
|
sync_pool $TESTPOOL
|
||||||
|
|
||||||
|
# Test removal of the pending clones (before they are committed to disk).
|
||||||
|
clonefile -f $original "${clone}4"
|
||||||
|
clonefile -f "${clone}4" "${clone}5"
|
||||||
|
rm -f "${clone}4" "${clone}5"
|
||||||
|
|
||||||
|
# Clone into one file, but remove another file, but with the same data in
|
||||||
|
# the same transaction group.
|
||||||
|
clonefile -f $original "${clone}5"
|
||||||
|
sync_pool $TESTPOOL
|
||||||
|
clonefile -f $original "${clone}4"
|
||||||
|
rm -f "${clone}5"
|
||||||
|
test_file_integrity $original_checksum "${clone}4" $filesize
|
||||||
|
sync_pool $TESTPOOL
|
||||||
|
test_file_integrity $original_checksum "${clone}4" $filesize
|
||||||
|
|
||||||
|
clonefile -f "${clone}4" "${clone}5"
|
||||||
|
# Verify integrity of the cloned file before it is committed to disk.
|
||||||
|
test_file_integrity $original_checksum "${clone}5" $filesize
|
||||||
|
|
||||||
|
sync_pool $TESTPOOL
|
||||||
|
|
||||||
|
# Verify integrity in the new transaction group.
|
||||||
|
test_file_integrity $original_checksum "${clone}0" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}1" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}2" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}3" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}4" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}5" $filesize
|
||||||
|
|
||||||
|
verify_pool_props $dsize 7
|
||||||
|
|
||||||
|
# Clear cache and test after fresh import.
|
||||||
|
log_must zpool export $TESTPOOL
|
||||||
|
log_must zpool import $TESTPOOL
|
||||||
|
|
||||||
|
# Cloned uncached file.
|
||||||
|
clonefile -f $original "${clone}6"
|
||||||
|
# Cloned uncached clone.
|
||||||
|
clonefile -f "${clone}6" "${clone}7"
|
||||||
|
|
||||||
|
# Cache the file.
|
||||||
|
cat $original >/dev/null
|
||||||
|
clonefile -f $original "${clone}8"
|
||||||
|
clonefile -f "${clone}8" "${clone}9"
|
||||||
|
|
||||||
|
test_file_integrity $original_checksum "${clone}6" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}7" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}8" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}9" $filesize
|
||||||
|
|
||||||
|
sync_pool $TESTPOOL
|
||||||
|
|
||||||
|
verify_pool_props $dsize 11
|
||||||
|
|
||||||
|
log_must zpool export $TESTPOOL
|
||||||
|
log_must zpool import $TESTPOOL
|
||||||
|
|
||||||
|
test_file_integrity $original_checksum "${clone}0" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}1" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}2" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}3" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}4" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}5" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}6" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}7" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}8" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}9" $filesize
|
||||||
|
|
||||||
|
rm -f $original
|
||||||
|
rm -f "${clone}1" "${clone}3" "${clone}5" "${clone}7"
|
||||||
|
|
||||||
|
sync_pool $TESTPOOL
|
||||||
|
|
||||||
|
test_file_integrity $original_checksum "${clone}0" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}2" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}4" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}6" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}8" $filesize
|
||||||
|
test_file_integrity $original_checksum "${clone}9" $filesize
|
||||||
|
|
||||||
|
verify_pool_props $dsize 6
|
||||||
|
|
||||||
|
rm -f "${clone}0" "${clone}2" "${clone}4" "${clone}8" "${clone}9"
|
||||||
|
|
||||||
|
sync_pool $TESTPOOL
|
||||||
|
|
||||||
|
test_file_integrity $original_checksum "${clone}6" $filesize
|
||||||
|
|
||||||
|
verify_pool_props $dsize 1
|
||||||
|
|
||||||
|
rm -f "${clone}6"
|
||||||
|
|
||||||
|
sync_pool $TESTPOOL
|
||||||
|
|
||||||
|
verify_pool_props $dsize 1
|
||||||
|
}
|
|
@ -0,0 +1,315 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/include/math.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_common.kshlib
|
||||||
|
|
||||||
|
function first_half_checksum
|
||||||
|
{
|
||||||
|
typeset -r file=$1
|
||||||
|
|
||||||
|
dd if=$file bs=$HALFRECORDSIZE count=1 2>/dev/null | sha256digest
|
||||||
|
}
|
||||||
|
|
||||||
|
function second_half_checksum
|
||||||
|
{
|
||||||
|
typeset -r file=$1
|
||||||
|
|
||||||
|
dd if=$file bs=$HALFRECORDSIZE count=1 skip=1 2>/dev/null | sha256digest
|
||||||
|
}
|
||||||
|
|
||||||
|
function bclone_corner_cases_init
|
||||||
|
{
|
||||||
|
typeset -r srcdir=$1
|
||||||
|
typeset -r dstdir=$2
|
||||||
|
|
||||||
|
export RECORDSIZE=4096
|
||||||
|
export HALFRECORDSIZE=$((RECORDSIZE / 2))
|
||||||
|
|
||||||
|
export CLONE="$dstdir/clone0"
|
||||||
|
export ORIG0="$srcdir/orig0"
|
||||||
|
export ORIG1="$srcdir/orig1"
|
||||||
|
export ORIG2="$srcdir/orig2"
|
||||||
|
|
||||||
|
# Create source files.
|
||||||
|
log_must dd if=/dev/urandom of="$ORIG0" bs=$RECORDSIZE count=1
|
||||||
|
log_must dd if=/dev/urandom of="$ORIG1" bs=$RECORDSIZE count=1
|
||||||
|
log_must dd if=/dev/urandom of="$ORIG2" bs=$RECORDSIZE count=1
|
||||||
|
|
||||||
|
export FIRST_HALF_ORIG0_CHECKSUM=$(first_half_checksum $ORIG0)
|
||||||
|
export FIRST_HALF_ORIG1_CHECKSUM=$(first_half_checksum $ORIG1)
|
||||||
|
export FIRST_HALF_ORIG2_CHECKSUM=$(first_half_checksum $ORIG2)
|
||||||
|
export SECOND_HALF_ORIG0_CHECKSUM=$(second_half_checksum $ORIG0)
|
||||||
|
export SECOND_HALF_ORIG1_CHECKSUM=$(second_half_checksum $ORIG1)
|
||||||
|
export SECOND_HALF_ORIG2_CHECKSUM=$(second_half_checksum $ORIG2)
|
||||||
|
export ZEROS_CHECKSUM=$(dd if=/dev/zero bs=$HALFRECORDSIZE count=1 | sha256digest)
|
||||||
|
export FIRST_HALF_CHECKSUM=""
|
||||||
|
export SECOND_HALF_CHECKSUM=""
|
||||||
|
}
|
||||||
|
|
||||||
|
function cache_clone
|
||||||
|
{
|
||||||
|
typeset -r cached=$1
|
||||||
|
|
||||||
|
case "$cached" in
|
||||||
|
"cached")
|
||||||
|
dd if=$CLONE of=/dev/null bs=$RECORDSIZE 2>/dev/null
|
||||||
|
;;
|
||||||
|
"uncached")
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_fail "invalid cached: $cached"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_existing
|
||||||
|
{
|
||||||
|
typeset -r existing=$1
|
||||||
|
|
||||||
|
case "$existing" in
|
||||||
|
"no")
|
||||||
|
;;
|
||||||
|
"small empty")
|
||||||
|
log_must truncate_test -s $HALFRECORDSIZE -f $CLONE
|
||||||
|
;;
|
||||||
|
"full empty")
|
||||||
|
log_must truncate_test -s $RECORDSIZE -f $CLONE
|
||||||
|
;;
|
||||||
|
"small data")
|
||||||
|
log_must dd if=/dev/urandom of=$CLONE bs=$HALFRECORDSIZE count=1 \
|
||||||
|
2>/dev/null
|
||||||
|
;;
|
||||||
|
"full data")
|
||||||
|
log_must dd if=/dev/urandom of=$CLONE bs=$RECORDSIZE count=1 2>/dev/null
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_fail "invalid existing: $existing"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_clone
|
||||||
|
{
|
||||||
|
typeset -r clone=$1
|
||||||
|
typeset -r file=$2
|
||||||
|
|
||||||
|
case "$clone" in
|
||||||
|
"no")
|
||||||
|
;;
|
||||||
|
"yes")
|
||||||
|
clonefile -f $file $CLONE
|
||||||
|
case "$file" in
|
||||||
|
$ORIG0)
|
||||||
|
FIRST_HALF_CHECKSUM=$FIRST_HALF_ORIG0_CHECKSUM
|
||||||
|
SECOND_HALF_CHECKSUM=$SECOND_HALF_ORIG0_CHECKSUM
|
||||||
|
;;
|
||||||
|
$ORIG2)
|
||||||
|
FIRST_HALF_CHECKSUM=$FIRST_HALF_ORIG2_CHECKSUM
|
||||||
|
SECOND_HALF_CHECKSUM=$SECOND_HALF_ORIG2_CHECKSUM
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_fail "invalid file: $file"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_fail "invalid clone: $clone"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
function overwrite_clone
|
||||||
|
{
|
||||||
|
typeset -r overwrite=$1
|
||||||
|
|
||||||
|
case "$overwrite" in
|
||||||
|
"no")
|
||||||
|
;;
|
||||||
|
"free")
|
||||||
|
log_must truncate_test -s 0 -f $CLONE
|
||||||
|
log_must truncate_test -s $RECORDSIZE -f $CLONE
|
||||||
|
FIRST_HALF_CHECKSUM=$ZEROS_CHECKSUM
|
||||||
|
SECOND_HALF_CHECKSUM=$ZEROS_CHECKSUM
|
||||||
|
;;
|
||||||
|
"full")
|
||||||
|
log_must dd if=$ORIG1 of=$CLONE bs=$RECORDSIZE count=1 2>/dev/null
|
||||||
|
FIRST_HALF_CHECKSUM=$FIRST_HALF_ORIG1_CHECKSUM
|
||||||
|
SECOND_HALF_CHECKSUM=$SECOND_HALF_ORIG1_CHECKSUM
|
||||||
|
;;
|
||||||
|
"first half")
|
||||||
|
log_must dd if=$ORIG1 of=$CLONE bs=$HALFRECORDSIZE skip=0 seek=0 \
|
||||||
|
count=1 conv=notrunc 2>/dev/null
|
||||||
|
FIRST_HALF_CHECKSUM=$FIRST_HALF_ORIG1_CHECKSUM
|
||||||
|
;;
|
||||||
|
"second half")
|
||||||
|
log_must dd if=$ORIG1 of=$CLONE bs=$HALFRECORDSIZE skip=1 seek=1 \
|
||||||
|
count=1 conv=notrunc 2>/dev/null
|
||||||
|
SECOND_HALF_CHECKSUM=$SECOND_HALF_ORIG1_CHECKSUM
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_fail "invalid overwrite: $overwrite"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
function checksum_compare
|
||||||
|
{
|
||||||
|
typeset -r compare=$1
|
||||||
|
typeset first_half_calculated_checksum second_half_calculated_checksum
|
||||||
|
|
||||||
|
case "$compare" in
|
||||||
|
"no")
|
||||||
|
;;
|
||||||
|
"yes")
|
||||||
|
first_half_calculated_checksum=$(first_half_checksum $CLONE)
|
||||||
|
second_half_calculated_checksum=$(second_half_checksum $CLONE)
|
||||||
|
|
||||||
|
if [[ $first_half_calculated_checksum != $FIRST_HALF_CHECKSUM ]] || \
|
||||||
|
[[ $second_half_calculated_checksum != $SECOND_HALF_CHECKSUM ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_fail "invalid compare: $compare"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
function bclone_corner_cases_test
|
||||||
|
{
|
||||||
|
typeset cached existing
|
||||||
|
typeset first_clone first_overwrite
|
||||||
|
typeset read_after read_before
|
||||||
|
typeset second_clone second_overwrite
|
||||||
|
typeset -r srcdir=$1
|
||||||
|
typeset -r dstdir=$2
|
||||||
|
typeset limit=$3
|
||||||
|
typeset -i count=0
|
||||||
|
|
||||||
|
if [[ $srcdir != "count" ]]; then
|
||||||
|
if [[ -n "$limit" ]]; then
|
||||||
|
typeset -r total_count=$(bclone_corner_cases_test count)
|
||||||
|
limit=$(random_int_between 1 $total_count $((limit*2)) | sort -nu | head -n $limit | xargs)
|
||||||
|
fi
|
||||||
|
bclone_corner_cases_init $srcdir $dstdir
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# (create) / (cache) / (clone) / (overwrite) / (read) / (clone) / (overwrite) / (read) / read next txg
|
||||||
|
#
|
||||||
|
for existing in "no" "small empty" "full empty" "small data" "full data"; do
|
||||||
|
for cached in "uncached" "cached"; do
|
||||||
|
for first_clone in "no" "yes"; do
|
||||||
|
for first_overwrite in "no" "free" "full" "first half" "second half"; do
|
||||||
|
for read_before in "no" "yes"; do
|
||||||
|
for second_clone in "no" "yes"; do
|
||||||
|
for second_overwrite in "no" "free" "full" "first half" "second half"; do
|
||||||
|
for read_after in "no" "yes"; do
|
||||||
|
if [[ $first_clone = "no" ]] && \
|
||||||
|
[[ $second_clone = "no" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [[ $first_clone = "no" ]] && \
|
||||||
|
[[ $read_before = "yes" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [[ $second_clone = "no" ]] && \
|
||||||
|
[[ $read_before = "yes" ]] && \
|
||||||
|
[[ $read_after = "yes" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
count=$((count+1))
|
||||||
|
|
||||||
|
if [[ $srcdir = "count" ]]; then
|
||||||
|
# Just counting.
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$limit" ]]; then
|
||||||
|
if ! echo " $limit " | grep -q " $count "; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
FIRST_HALF_CHECKSUM=""
|
||||||
|
SECOND_HALF_CHECKSUM=""
|
||||||
|
|
||||||
|
log_must zpool export $TESTPOOL
|
||||||
|
log_must zpool import $TESTPOOL
|
||||||
|
|
||||||
|
create_existing "$existing"
|
||||||
|
|
||||||
|
log_must zpool export $TESTPOOL
|
||||||
|
log_must zpool import $TESTPOOL
|
||||||
|
|
||||||
|
cache_clone "$cached"
|
||||||
|
|
||||||
|
create_clone "$first_clone" "$ORIG0"
|
||||||
|
|
||||||
|
overwrite_clone "$first_overwrite"
|
||||||
|
|
||||||
|
if checksum_compare $read_before; then
|
||||||
|
log_note "existing: $existing / cached: $cached / first_clone: $first_clone / first_overwrite: $first_overwrite / read_before: $read_before"
|
||||||
|
else
|
||||||
|
log_fail "FAIL: existing: $existing / cached: $cached / first_clone: $first_clone / first_overwrite: $first_overwrite / read_before: $read_before"
|
||||||
|
fi
|
||||||
|
|
||||||
|
create_clone "$second_clone" "$ORIG2"
|
||||||
|
|
||||||
|
overwrite_clone "$second_overwrite"
|
||||||
|
|
||||||
|
if checksum_compare $read_after; then
|
||||||
|
log_note "existing: $existing / cached: $cached / first_clone: $first_clone / first_overwrite: $first_overwrite / read_before: $read_before / second_clone: $second_clone / read_after: $read_after"
|
||||||
|
else
|
||||||
|
log_fail "FAIL: existing: $existing / cached: $cached / first_clone: $first_clone / first_overwrite: $first_overwrite / read_before: $read_before / second_clone: $second_clone / read_after: $read_after"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_must zpool export $TESTPOOL
|
||||||
|
log_must zpool import $TESTPOOL
|
||||||
|
|
||||||
|
if checksum_compare "yes"; then
|
||||||
|
log_note "existing: $existing / cached: $cached / first_clone: $first_clone / first_overwrite: $first_overwrite / read_before: $read_before / second_clone: $second_clone / read_after: $read_after / read_next_txg"
|
||||||
|
else
|
||||||
|
log_fail "FAIL: existing: $existing / cached: $cached / first_clone: $first_clone / first_overwrite: $first_overwrite / read_before: $read_before / second_clone: $second_clone / read_after: $read_after / read_next_txg"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$CLONE"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $srcdir = "count" ]]; then
|
||||||
|
echo $count
|
||||||
|
fi
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_corner_cases.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
verify_crossfs_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify various corner cases in block cloning across datasets"
|
||||||
|
|
||||||
|
# Disable compression to make sure we won't use embedded blocks.
|
||||||
|
log_must zfs set compress=off $TESTSRCFS
|
||||||
|
log_must zfs set recordsize=$RECORDSIZE $TESTSRCFS
|
||||||
|
log_must zfs set compress=off $TESTDSTFS
|
||||||
|
log_must zfs set recordsize=$RECORDSIZE $TESTDSTFS
|
||||||
|
|
||||||
|
bclone_corner_cases_test $TESTSRCDIR $TESTDSTDIR
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,45 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_corner_cases.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
verify_crossfs_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify various corner cases in block cloning across datasets"
|
||||||
|
|
||||||
|
# Disable compression to make sure we won't use embedded blocks.
|
||||||
|
log_must zfs set compress=off $TESTSRCFS
|
||||||
|
log_must zfs set recordsize=$RECORDSIZE $TESTSRCFS
|
||||||
|
log_must zfs set compress=off $TESTDSTFS
|
||||||
|
log_must zfs set recordsize=$RECORDSIZE $TESTDSTFS
|
||||||
|
|
||||||
|
bclone_corner_cases_test $TESTSRCDIR $TESTDSTDIR 100
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,46 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_common.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
verify_crossfs_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify block cloning properly clones regular files across datasets"
|
||||||
|
|
||||||
|
# Disable compression to make sure we won't use embedded blocks.
|
||||||
|
log_must zfs set compress=off $TESTSRCFS
|
||||||
|
log_must zfs set compress=off $TESTDSTFS
|
||||||
|
|
||||||
|
for filesize in 1 107 113 511 512 513 4095 4096 4097 131071 131072 131073 \
|
||||||
|
1048575 1048576 1048577 4194303 4194304 4194305; do
|
||||||
|
bclone_test random $filesize false $TESTSRCDIR $TESTDSTDIR
|
||||||
|
done
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,50 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_common.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
verify_crossfs_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify block cloning properly clones small files (with embedded blocks) across datasets"
|
||||||
|
|
||||||
|
# Enable ZLE compression to make sure what is the maximum amount of data we
|
||||||
|
# can store in BP.
|
||||||
|
log_must zfs set compress=zle $TESTSRCFS
|
||||||
|
log_must zfs set compress=zle $TESTDSTFS
|
||||||
|
|
||||||
|
# Test BP_IS_EMBEDDED().
|
||||||
|
# Maximum embedded payload size is 112 bytes, but the buffer is extended to
|
||||||
|
# 512 bytes first and then compressed. 107 random bytes followed by 405 zeros
|
||||||
|
# gives exactly 112 bytes after compression with ZLE.
|
||||||
|
for filesize in 1 2 4 8 16 32 64 96 107; do
|
||||||
|
bclone_test random $filesize true $TESTSRCDIR $TESTDSTDIR
|
||||||
|
done
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,45 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_common.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
verify_crossfs_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify block cloning properly clones sparse files (files with holes) across datasets"
|
||||||
|
|
||||||
|
# Compression doesn't matter here.
|
||||||
|
|
||||||
|
# Test BP_IS_HOLE().
|
||||||
|
for filesize in 1 511 512 513 4095 4096 4097 131071 131072 131073 \
|
||||||
|
1048575 1048576 1048577 4194303 4194304 4194305; do
|
||||||
|
bclone_test hole $filesize false $TESTSRCDIR $TESTDSTDIR
|
||||||
|
done
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,86 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/include/math.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_common.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
verify_crossfs_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify block cloning across datasets with different properties"
|
||||||
|
|
||||||
|
log_must zfs set checksum=off $TESTSRCFS
|
||||||
|
log_must zfs set compress=off $TESTSRCFS
|
||||||
|
log_must zfs set copies=1 $TESTSRCFS
|
||||||
|
log_must zfs set recordsize=131072 $TESTSRCFS
|
||||||
|
log_must zfs set checksum=fletcher2 $TESTDSTFS
|
||||||
|
log_must zfs set compress=lz4 $TESTDSTFS
|
||||||
|
log_must zfs set copies=3 $TESTDSTFS
|
||||||
|
log_must zfs set recordsize=8192 $TESTDSTFS
|
||||||
|
|
||||||
|
FILESIZE=$(random_int_between 2 32767)
|
||||||
|
FILESIZE=$((FILESIZE * 64))
|
||||||
|
bclone_test text $FILESIZE false $TESTSRCDIR $TESTDSTDIR
|
||||||
|
|
||||||
|
log_must zfs set checksum=sha256 $TESTSRCFS
|
||||||
|
log_must zfs set compress=zstd $TESTSRCFS
|
||||||
|
log_must zfs set copies=2 $TESTSRCFS
|
||||||
|
log_must zfs set recordsize=262144 $TESTSRCFS
|
||||||
|
log_must zfs set checksum=off $TESTDSTFS
|
||||||
|
log_must zfs set compress=off $TESTDSTFS
|
||||||
|
log_must zfs set copies=1 $TESTDSTFS
|
||||||
|
log_must zfs set recordsize=131072 $TESTDSTFS
|
||||||
|
|
||||||
|
FILESIZE=$(random_int_between 2 32767)
|
||||||
|
FILESIZE=$((FILESIZE * 64))
|
||||||
|
bclone_test text $FILESIZE false $TESTSRCDIR $TESTDSTDIR
|
||||||
|
|
||||||
|
log_must zfs set checksum=sha512 $TESTSRCFS
|
||||||
|
log_must zfs set compress=gzip $TESTSRCFS
|
||||||
|
log_must zfs set copies=2 $TESTSRCFS
|
||||||
|
log_must zfs set recordsize=512 $TESTSRCFS
|
||||||
|
log_must zfs set checksum=fletcher4 $TESTDSTFS
|
||||||
|
log_must zfs set compress=lzjb $TESTDSTFS
|
||||||
|
log_must zfs set copies=3 $TESTDSTFS
|
||||||
|
log_must zfs set recordsize=16384 $TESTDSTFS
|
||||||
|
|
||||||
|
FILESIZE=$(random_int_between 2 32767)
|
||||||
|
FILESIZE=$((FILESIZE * 64))
|
||||||
|
bclone_test text $FILESIZE false $TESTSRCDIR $TESTDSTDIR
|
||||||
|
|
||||||
|
log_must zfs inherit checksum $TESTSRCFS
|
||||||
|
log_must zfs inherit compress $TESTSRCFS
|
||||||
|
log_must zfs inherit copies $TESTSRCFS
|
||||||
|
log_must zfs inherit recordsize $TESTSRCFS
|
||||||
|
log_must zfs inherit checksum $TESTDSTFS
|
||||||
|
log_must zfs inherit compress $TESTDSTFS
|
||||||
|
log_must zfs inherit copies $TESTDSTFS
|
||||||
|
log_must zfs inherit recordsize $TESTDSTFS
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,62 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/include/math.shlib
|
||||||
|
. $STF_SUITE/include/properties.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_common.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
verify_crossfs_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify block cloning across datasets with different checksum properties"
|
||||||
|
|
||||||
|
log_must zfs set compress=off $TESTSRCFS
|
||||||
|
log_must zfs set compress=off $TESTDSTFS
|
||||||
|
|
||||||
|
for srcprop in "${checksum_prop_vals[@]}"; do
|
||||||
|
for dstprop in "${checksum_prop_vals[@]}"; do
|
||||||
|
if [[ $srcprop == $dstprop ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
log_must zfs set checksum=$srcprop $TESTSRCFS
|
||||||
|
log_must zfs set checksum=$dstprop $TESTDSTFS
|
||||||
|
# 15*8=120, which is greater than 113, so we are sure the data won't
|
||||||
|
# be embedded into BP.
|
||||||
|
# 32767*8=262136, which is larger than a single default recordsize of
|
||||||
|
# 131072.
|
||||||
|
FILESIZE=$(random_int_between 15 32767)
|
||||||
|
FILESIZE=$((FILESIZE * 8))
|
||||||
|
bclone_test random $FILESIZE false $TESTSRCDIR $TESTDSTDIR
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
log_must zfs inherit checksum $TESTSRCFS
|
||||||
|
log_must zfs inherit checksum $TESTDSTFS
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,59 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/include/math.shlib
|
||||||
|
. $STF_SUITE/include/properties.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_common.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
verify_crossfs_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify block cloning across datasets with different compression properties"
|
||||||
|
|
||||||
|
for srcprop in "${compress_prop_vals[@]}"; do
|
||||||
|
for dstprop in "${compress_prop_vals[@]}"; do
|
||||||
|
if [[ $srcprop == $dstprop ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
log_must zfs set compress=$srcprop $TESTSRCFS
|
||||||
|
log_must zfs set compress=$dstprop $TESTDSTFS
|
||||||
|
# 15*8=120, which is greater than 113, so we are sure the data won't
|
||||||
|
# be embedded into BP.
|
||||||
|
# 32767*8=262136, which is larger than a single default recordsize of
|
||||||
|
# 131072.
|
||||||
|
FILESIZE=$(random_int_between 15 32767)
|
||||||
|
FILESIZE=$((FILESIZE * 8))
|
||||||
|
bclone_test text $FILESIZE false $TESTSRCDIR $TESTDSTDIR
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
log_must zfs inherit compress $TESTSRCFS
|
||||||
|
log_must zfs inherit compress $TESTDSTFS
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,59 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/include/math.shlib
|
||||||
|
. $STF_SUITE/include/properties.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_common.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
verify_crossfs_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify block cloning across datasets with different copies properties"
|
||||||
|
|
||||||
|
log_must zfs set compress=off $TESTSRCFS
|
||||||
|
log_must zfs set compress=off $TESTDSTFS
|
||||||
|
|
||||||
|
for srcprop in "${copies_prop_vals[@]}"; do
|
||||||
|
for dstprop in "${copies_prop_vals[@]}"; do
|
||||||
|
log_must zfs set copies=$srcprop $TESTSRCFS
|
||||||
|
log_must zfs set copies=$dstprop $TESTDSTFS
|
||||||
|
# 15*8=120, which is greater than 113, so we are sure the data won't
|
||||||
|
# be embedded into BP.
|
||||||
|
# 32767*8=262136, which is larger than a single default recordsize of
|
||||||
|
# 131072.
|
||||||
|
FILESIZE=$(random_int_between 15 32767)
|
||||||
|
FILESIZE=$((FILESIZE * 8))
|
||||||
|
bclone_test random $FILESIZE false $TESTSRCDIR $TESTDSTDIR
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
log_must zfs inherit copies $TESTSRCFS
|
||||||
|
log_must zfs inherit copies $TESTDSTFS
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,65 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/include/math.shlib
|
||||||
|
. $STF_SUITE/include/properties.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_common.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
verify_crossfs_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify block cloning across datasets with different recordsize properties"
|
||||||
|
|
||||||
|
log_must zfs set compress=off $TESTSRCFS
|
||||||
|
log_must zfs set compress=off $TESTDSTFS
|
||||||
|
|
||||||
|
# recsize_prop_vals[] array contains too many entries and the tests take too
|
||||||
|
# long. Let's use only a subset of them.
|
||||||
|
typeset -a bclone_recsize_prop_vals=('512' '4096' '131072' '1048576')
|
||||||
|
|
||||||
|
for srcprop in "${bclone_recsize_prop_vals[@]}"; do
|
||||||
|
for dstprop in "${bclone_recsize_prop_vals[@]}"; do
|
||||||
|
if [[ $srcprop == $dstprop ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
log_must zfs set recordsize=$srcprop $TESTSRCFS
|
||||||
|
log_must zfs set recordsize=$dstprop $TESTDSTFS
|
||||||
|
# 2*64=128, which is greater than 113, so we are sure the data won't
|
||||||
|
# be embedded into BP.
|
||||||
|
# 32767*64=2097088, which is larger than the largest recordsize (1MB).
|
||||||
|
FILESIZE=$(random_int_between 2 32767)
|
||||||
|
FILESIZE=$((FILESIZE * 64))
|
||||||
|
bclone_test random $FILESIZE false $TESTSRCDIR $TESTDSTDIR
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
log_must zfs inherit recordsize $TESTSRCFS
|
||||||
|
log_must zfs inherit recordsize $TESTDSTFS
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,66 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/include/math.shlib
|
||||||
|
. $STF_SUITE/include/properties.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_common.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
verify_crossfs_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify block cloning with all sync property settings"
|
||||||
|
|
||||||
|
log_must zfs set compress=zle $TESTSRCFS
|
||||||
|
log_must zfs set compress=zle $TESTDSTFS
|
||||||
|
|
||||||
|
for prop in "${sync_prop_vals[@]}"; do
|
||||||
|
log_must zfs set sync=$prop $TESTSRCFS
|
||||||
|
# 32767*8=262136, which is larger than a single default recordsize of
|
||||||
|
# 131072.
|
||||||
|
FILESIZE=$(random_int_between 1 32767)
|
||||||
|
FILESIZE=$((FILESIZE * 8))
|
||||||
|
bclone_test random $FILESIZE false $TESTSRCDIR $TESTSRCDIR
|
||||||
|
done
|
||||||
|
|
||||||
|
for srcprop in "${sync_prop_vals[@]}"; do
|
||||||
|
log_must zfs set sync=$srcprop $TESTSRCFS
|
||||||
|
for dstprop in "${sync_prop_vals[@]}"; do
|
||||||
|
log_must zfs set sync=$dstprop $TESTDSTFS
|
||||||
|
# 32767*8=262136, which is larger than a single default recordsize of
|
||||||
|
# 131072.
|
||||||
|
FILESIZE=$(random_int_between 1 32767)
|
||||||
|
FILESIZE=$((FILESIZE * 8))
|
||||||
|
bclone_test random $FILESIZE false $TESTSRCDIR $TESTDSTDIR
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
log_must zfs inherit sync $TESTSRCFS
|
||||||
|
log_must zfs inherit sync $TESTDSTFS
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,42 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_corner_cases.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify various corner cases in block cloning within the same dataset"
|
||||||
|
|
||||||
|
# Disable compression to make sure we won't use embedded blocks.
|
||||||
|
log_must zfs set compress=off $TESTSRCFS
|
||||||
|
log_must zfs set recordsize=$RECORDSIZE $TESTSRCFS
|
||||||
|
|
||||||
|
bclone_corner_cases_test $TESTSRCDIR $TESTSRCDIR
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,42 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_corner_cases.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify various corner cases in block cloning within the same dataset"
|
||||||
|
|
||||||
|
# Disable compression to make sure we won't use embedded blocks.
|
||||||
|
log_must zfs set compress=off $TESTSRCFS
|
||||||
|
log_must zfs set recordsize=$RECORDSIZE $TESTSRCFS
|
||||||
|
|
||||||
|
bclone_corner_cases_test $TESTSRCDIR $TESTSRCDIR 100
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,44 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_common.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify block cloning properly clones regular files within the same dataset"
|
||||||
|
|
||||||
|
# Disable compression to make sure we won't use embedded blocks.
|
||||||
|
log_must zfs set compress=off $TESTSRCFS
|
||||||
|
|
||||||
|
for filesize in 1 107 113 511 512 513 4095 4096 4097 131071 131072 131073 \
|
||||||
|
1048575 1048576 1048577 4194303 4194304 4194305; do
|
||||||
|
bclone_test random $filesize false $TESTSRCDIR $TESTSRCDIR
|
||||||
|
done
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,48 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_common.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify block cloning properly clones small files (with embedded blocks) within the same dataset"
|
||||||
|
|
||||||
|
# Enable ZLE compression to make sure what is the maximum amount of data we
|
||||||
|
# can store in BP.
|
||||||
|
log_must zfs set compress=zle $TESTSRCFS
|
||||||
|
|
||||||
|
# Test BP_IS_EMBEDDED().
|
||||||
|
# Maximum embedded payload size is 112 bytes, but the buffer is extended to
|
||||||
|
# 512 bytes first and then compressed. 107 random bytes followed by 405 zeros
|
||||||
|
# gives exactly 112 bytes after compression with ZLE.
|
||||||
|
for filesize in 1 2 4 8 16 32 64 96 107; do
|
||||||
|
bclone_test random $filesize true $TESTSRCDIR $TESTSRCDIR
|
||||||
|
done
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,44 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone_common.kshlib
|
||||||
|
|
||||||
|
verify_runnable "both"
|
||||||
|
|
||||||
|
verify_block_cloning
|
||||||
|
|
||||||
|
log_assert "Verify block cloning properly clones sparse files (files with holes) within the same dataset"
|
||||||
|
|
||||||
|
# Compression doesn't matter here.
|
||||||
|
|
||||||
|
# Test BP_IS_HOLE().
|
||||||
|
for filesize in 1 511 512 513 4095 4096 4097 131071 131072 131073 \
|
||||||
|
1048575 1048576 1048577 4194303 4194304 4194305; do
|
||||||
|
bclone_test hole $filesize false $TESTSRCDIR $TESTSRCDIR
|
||||||
|
done
|
||||||
|
|
||||||
|
log_pass
|
|
@ -0,0 +1,37 @@
|
||||||
|
#!/bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||||
|
# Use is subject to license terms.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone.cfg
|
||||||
|
|
||||||
|
log_must zfs destroy $TESTSRCFS
|
||||||
|
log_must zfs destroy $TESTDSTFS
|
||||||
|
default_cleanup
|
|
@ -0,0 +1,45 @@
|
||||||
|
#!/bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||||
|
# Use is subject to license terms.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 by Pawel Jakub Dawidek
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/tests/functional/bclone/bclone.cfg
|
||||||
|
|
||||||
|
if ! command -v clonefile > /dev/null ; then
|
||||||
|
log_unsupported "clonefile program required to test block cloning"
|
||||||
|
fi
|
||||||
|
|
||||||
|
DISK=${DISKS%% *}
|
||||||
|
|
||||||
|
default_setup_noexit $DISK "true"
|
||||||
|
log_must zpool set feature@block_cloning=enabled $TESTPOOL
|
||||||
|
log_must zfs create $TESTSRCFS
|
||||||
|
log_must zfs create $TESTDSTFS
|
||||||
|
log_pass
|
|
@ -44,28 +44,6 @@ function cleanup
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
|
||||||
# Get random number between min and max number.
|
|
||||||
#
|
|
||||||
# $1 Minimal value
|
|
||||||
# $2 Maximal value
|
|
||||||
#
|
|
||||||
function random
|
|
||||||
{
|
|
||||||
typeset -i min=$1
|
|
||||||
typeset -i max=$2
|
|
||||||
typeset -i value
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
((value = RANDOM % (max + 1)))
|
|
||||||
if ((value >= min)); then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo $value
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Get the number of checksum errors for the pool.
|
# Get the number of checksum errors for the pool.
|
||||||
#
|
#
|
||||||
|
|
Loading…
Reference in New Issue