Skip to content

Commit 57ea1ad

Browse files
committed
Adding test to test block cloning across encrypted datasets.
Added a test for: - Clone from encrypted sibling to encrypted sibling with non encrypted parent - Clone from encrypted parent to inherited encrypted child - Clone from child to sibling with encrypted parent - Clone from snapshot to the original datasets - Clone from foreign snapshot to a foreign dataset Signed-off-by: Kay Pedersen <mail@mkwg.de>
1 parent e76107c commit 57ea1ad

File tree

5 files changed

+167
-4
lines changed

5 files changed

+167
-4
lines changed

tests/runfiles/linux.run

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ tests = ['block_cloning_copyfilerange', 'block_cloning_copyfilerange_partial',
4242
'block_cloning_disabled_copyfilerange', 'block_cloning_disabled_ficlone',
4343
'block_cloning_disabled_ficlonerange',
4444
'block_cloning_copyfilerange_cross_dataset',
45+
'block_cloning_cross_enc_dataset',
4546
'block_cloning_copyfilerange_fallback_same_txg']
4647
tags = ['functional', 'block_cloning']
4748

tests/test-runner/bin/zts-report.py.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,8 @@ elif sys.platform.startswith('linux'):
305305
['SKIP', cfr_cross_reason],
306306
'block_cloning/block_cloning_copyfilerange_fallback_same_txg':
307307
['SKIP', cfr_cross_reason],
308+
'block_cloning/block_cloning_cross_enc_dataset':
309+
['SKIP', cfr_cross_reason],
308310
})
309311

310312

tests/zfs-tests/tests/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
451451
functional/block_cloning/block_cloning_ficlone.ksh \
452452
functional/block_cloning/block_cloning_ficlonerange.ksh \
453453
functional/block_cloning/block_cloning_ficlonerange_partial.ksh \
454+
functional/block_cloning/block_cloning_cross_enc_dataset.ksh \
454455
functional/bootfs/bootfs_001_pos.ksh \
455456
functional/bootfs/bootfs_002_neg.ksh \
456457
functional/bootfs/bootfs_003_pos.ksh \

tests/zfs-tests/tests/functional/block_cloning/block_cloning.kshlib

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828

2929
function have_same_content
3030
{
31-
typeset hash1=$(cat $1 | md5sum)
32-
typeset hash2=$(cat $2 | md5sum)
31+
typeset hash1=$(md5digest $1)
32+
typeset hash2=$(md5digest $2)
3333

3434
log_must [ "$hash1" = "$hash2" ]
3535
}
@@ -44,10 +44,14 @@ function have_same_content
4444
#
4545
function get_same_blocks
4646
{
47+
KEY=$5
48+
if [ ${#KEY} -gt 0 ]; then
49+
KEY="--key=$KEY"
50+
fi
4751
typeset zdbout=${TMPDIR:-$TEST_BASE_DIR}/zdbout.$$
48-
zdb -vvvvv $1 -O $2 | \
52+
zdb $KEY -vvvvv $1 -O $2 | \
4953
awk '/ L0 / { print l++ " " $3 " " $7 }' > $zdbout.a
50-
zdb -vvvvv $3 -O $4 | \
54+
zdb $KEY -vvvvv $3 -O $4 | \
5155
awk '/ L0 / { print l++ " " $3 " " $7 }' > $zdbout.b
5256
echo $(sort $zdbout.a $zdbout.b | uniq -d | cut -f1 -d' ')
5357
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
#!/bin/ksh -p
2+
#
3+
# CDDL HEADER START
4+
#
5+
# The contents of this file are subject to the terms of the
6+
# Common Development and Distribution License (the "License").
7+
# You may not use this file except in compliance with the License.
8+
#
9+
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10+
# or https://opensource.org/licenses/CDDL-1.0.
11+
# See the License for the specific language governing permissions
12+
# and limitations under the License.
13+
#
14+
# When distributing Covered Code, include this CDDL HEADER in each
15+
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16+
# If applicable, add the following below this CDDL HEADER, with the
17+
# fields enclosed by brackets "[]" replaced with your own identifying
18+
# information: Portions Copyright [yyyy] [name of copyright owner]
19+
#
20+
# CDDL HEADER END
21+
#
22+
23+
#
24+
# Copyright (c) 2023, Kay Pedersen <mail@mkwg.de>
25+
#
26+
27+
. $STF_SUITE/include/libtest.shlib
28+
. $STF_SUITE/tests/functional/block_cloning/block_cloning.kshlib
29+
30+
verify_runnable "global"
31+
32+
if [[ $(linux_version) -lt $(linux_version "5.3") ]]; then
33+
log_unsupported "copy_file_range can't copy cross-filesystem before Linux 5.3"
34+
fi
35+
36+
claim="Block cloning across encrypted datasets."
37+
38+
log_assert $claim
39+
40+
DS1="$TESTPOOL/encrypted1"
41+
DS2="$TESTPOOL/encrypted2"
42+
PASSPHRASE="top_secret"
43+
44+
function prepare_enc
45+
{
46+
log_must zpool create -o feature@block_cloning=enabled $TESTPOOL $DISKS
47+
log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
48+
"-o keyformat=passphrase $DS1"
49+
log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
50+
"-o keyformat=passphrase -o keylocation=prompt $DS2"
51+
log_must zfs create $DS1/child1
52+
log_must zfs create $DS1/child2
53+
54+
log_note "Create test file"
55+
# we must wait until the src file txg is written to the disk otherwise we
56+
# will fallback to normal copy. See "dmu_read_l0_bps" in
57+
# "zfs/module/zfs/dmu.c" and "zfs_clone_range" in
58+
# "zfs/module/zfs/zfs_vnops.c"
59+
log_must dd if=/dev/urandom of=/$DS1/file bs=128K count=4
60+
log_must dd if=/dev/urandom of=/$DS1/child1/file bs=128K count=4
61+
log_must sync_pool $TESTPOOL
62+
}
63+
64+
function cleanup_enc
65+
{
66+
datasetexists $TESTPOOL && destroy_pool $TESTPOOL
67+
}
68+
69+
function clone_and_check
70+
{
71+
I_FILE="$1"
72+
O_FILE=$2
73+
I_DS=$3
74+
O_DS=$4
75+
SAME_BLOCKS=$5
76+
# the CLONE option provides a choice between copy_file_range
77+
# which should clone and a dd which is a copy no matter what
78+
CLONE=$6
79+
SNAPSHOT=$7
80+
if [ ${#SNAPSHOT} -gt 0 ]; then
81+
I_FILE=".zfs/snapshot/$SNAPSHOT/$1"
82+
fi
83+
if [ $CLONE ]; then
84+
log_must clonefile -f "/$I_DS/$I_FILE" "/$O_DS/$O_FILE" 0 0 524288
85+
else
86+
log_must dd if="/$I_DS/$I_FILE" of="/$O_DS/$O_FILE" bs=128K
87+
fi
88+
log_must sync_pool $TESTPOOL
89+
90+
log_must have_same_content "/$I_DS/$I_FILE" "/$O_DS/$O_FILE"
91+
92+
if [ ${#SNAPSHOT} -gt 0 ]; then
93+
I_DS="$I_DS@$SNAPSHOT"
94+
I_FILE="$1"
95+
fi
96+
typeset blocks=$(get_same_blocks \
97+
$I_DS $I_FILE $O_DS $O_FILE $PASSPHRASE)
98+
log_must [ "$blocks" = "$SAME_BLOCKS" ]
99+
}
100+
101+
log_onexit cleanup_enc
102+
103+
prepare_enc
104+
105+
log_note "Cloning entire file with copy_file_range across different enc" \
106+
"roots, should fallback"
107+
# we are expecting no same block map.
108+
clone_and_check "file" "clone" $DS1 $DS2 "" true
109+
log_note "check if the file is still readable and the same after" \
110+
"unmount and key unload, shouldn't fail"
111+
typeset hash1=$(md5digest "/$DS1/file")
112+
log_must zfs umount $DS1 && zfs unload-key $DS1
113+
typeset hash2=$(md5digest "/$DS2/clone")
114+
log_must [ "$hash1" = "$hash2" ]
115+
116+
cleanup_enc
117+
prepare_enc
118+
119+
log_note "Cloning entire file with copy_file_range across different child datasets"
120+
# clone shouldn't work because of deriving a new master key for the child
121+
# we are expecting no same block map.
122+
clone_and_check "file" "clone" $DS1 "$DS1/child1" "" true
123+
clone_and_check "file" "clone" "$DS1/child1" "$DS1/child2" "" true
124+
125+
cleanup_enc
126+
prepare_enc
127+
128+
log_note "Copying entire file with copy_file_range across same snapshot"
129+
log_must zfs snapshot -r $DS1@s1
130+
log_must sync_pool $TESTPOOL
131+
log_must rm -f "/$DS1/file"
132+
log_must sync_pool $TESTPOOL
133+
clone_and_check "file" "clone" "$DS1" "$DS1" "0 1 2 3" true "s1"
134+
135+
cleanup_enc
136+
prepare_enc
137+
138+
log_note "Copying entire file with copy_file_range across different snapshot"
139+
clone_and_check "file" "file" $DS1 $DS2 "" true
140+
log_must zfs snapshot -r $DS2@s1
141+
log_must sync_pool $TESTPOOL
142+
log_must rm -f "/$DS1/file" "/$DS2/file"
143+
log_must sync_pool $TESTPOOL
144+
clone_and_check "file" "clone" "$DS2" "$DS1" "" true "s1"
145+
typeset hash1=$(md5digest "/$DS1/.zfs/snapshot/s1/file")
146+
log_note "destroy the snapshot and check if the file is still readable and" \
147+
"has the same content"
148+
log_must zfs destroy -r $DS2@s1
149+
log_must sync_pool $TESTPOOL
150+
typeset hash2=$(md5digest "/$DS1/file")
151+
log_must [ "$hash1" = "$hash2" ]
152+
153+
log_must sync_pool $TESTPOOL
154+
155+
log_pass $claim

0 commit comments

Comments
 (0)