Skip to content

Commit

Permalink
Adding test to test block cloning across encrypted datasets.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
oromenahar committed Nov 28, 2023
1 parent 06b644a commit 1b0d7d8
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 2 deletions.
1 change: 1 addition & 0 deletions tests/runfiles/linux.run
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ tests = ['block_cloning_copyfilerange', 'block_cloning_copyfilerange_partial',
'block_cloning_disabled_copyfilerange', 'block_cloning_disabled_ficlone',
'block_cloning_disabled_ficlonerange',
'block_cloning_copyfilerange_cross_dataset',
'block_cloning_cross_enc_dataset',
'block_cloning_copyfilerange_fallback_same_txg']
tags = ['functional', 'block_cloning']

Expand Down
2 changes: 2 additions & 0 deletions tests/test-runner/bin/zts-report.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ elif sys.platform.startswith('linux'):
['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],
})


Expand Down
1 change: 1 addition & 0 deletions tests/zfs-tests/tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/block_cloning/block_cloning_ficlone.ksh \
functional/block_cloning/block_cloning_ficlonerange.ksh \
functional/block_cloning/block_cloning_ficlonerange_partial.ksh \
functional/block_cloning/block_cloning_cross_enc_dataset.ksh \
functional/bootfs/bootfs_001_pos.ksh \
functional/bootfs/bootfs_002_neg.ksh \
functional/bootfs/bootfs_003_pos.ksh \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,14 @@ function have_same_content
#
function get_same_blocks
{
KEY=$5
if [ ${#KEY} -gt 0 ]; then
KEY="--key=$KEY"
fi
typeset zdbout=${TMPDIR:-$TEST_BASE_DIR}/zdbout.$$
zdb -vvvvv $1 -O $2 | \
zdb $KEY -vvvvv $1 -O $2 | \
awk '/ L0 / { print l++ " " $3 " " $7 }' > $zdbout.a
zdb -vvvvv $3 -O $4 | \
zdb $KEY -vvvvv $3 -O $4 | \
awk '/ L0 / { print l++ " " $3 " " $7 }' > $zdbout.b
echo $(sort $zdbout.a $zdbout.b | uniq -d | cut -f1 -d' ')
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#!/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, Kay Pedersen <mail@mkwg.de>
#

. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/block_cloning/block_cloning.kshlib

verify_runnable "global"

if [[ $(linux_version) -lt $(linux_version "5.3") ]]; then
log_unsupported "copy_file_range can't copy cross-filesystem before Linux 5.3"
fi

claim="Block cloning across encrypted datasets."

log_assert $claim

DS1="$TESTPOOL/encrypted1"
DS2="$TESTPOOL/encrypted2"
PASSPHRASE="top_secret"

function prepare_enc
{
log_must zpool create -o feature@block_cloning=enabled $TESTPOOL $DISKS
log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
"-o keyformat=passphrase $DS1"
log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
"-o keyformat=passphrase -o keylocation=prompt $DS2"
log_must zfs create $DS1/child1
log_must zfs create $DS1/child2

log_note "Create test file"
# we must wait until the src file txg is written to the disk otherwise we
# will fallback to normal copy. See "dmu_read_l0_bps" in "zfs/module/zfs/dmu.c"
# and "zfs_clone_range" in "zfs/module/zfs/zfs_vnops.c"
log_must dd if=/dev/urandom of=/$DS1/file bs=128K count=4
log_must dd if=/dev/urandom of=/$DS1/child1/file bs=128K count=4
log_must sync_pool $TESTPOOL
}

function cleanup_enc
{
datasetexists $TESTPOOL && destroy_pool $TESTPOOL
}

function clone_and_check
{
I_FILE="$1"
O_FILE=$2
I_DS=$3
O_DS=$4
SAME_BLOCKS=$5
CLONE=$6
SNAPSHOT=$7
if [ ${#SNAPSHOT} -gt 0 ]; then
I_FILE=".zfs/snapshot/$SNAPSHOT/$1"
fi
if [ $CLONE ]; then
log_must clonefile -f "/$I_DS/$I_FILE" "/$O_DS/$O_FILE" 0 0 524288
else
log_must dd if="/$I_DS/$I_FILE" of="/$O_DS/$O_FILE" bs=128K
fi
log_must sync_pool $TESTPOOL

log_must have_same_content "/$I_DS/$I_FILE" "/$O_DS/$O_FILE"

if [ ${#SNAPSHOT} -gt 0 ]; then
I_DS="$I_DS@$SNAPSHOT"
I_FILE="$1"
fi
typeset blocks=$(get_same_blocks \
$I_DS $I_FILE $O_DS $O_FILE $PASSPHRASE)
log_must [ "$blocks" = "$SAME_BLOCKS" ]
}

log_onexit cleanup_enc

prepare_enc

log_note "Cloning entire file with copy_file_range across different enc roots, should fallback"
# we are expecting no same block map.
clone_and_check "file" "clone" $DS1 $DS2 "" true
typeset hash1=$(cat "/$DS1/file" | md5sum)
log_must zfs umount $DS1
typeset hash2=$(cat "/$DS2/clone" | md5sum)
log_must [ "$hash1" = "$hash2" ]

cleanup_enc
prepare_enc

log_note "Cloning entire file with copy_file_range across different child datasets"
# clone shouldn't work because of deriving a new master key for the child
# we are expecting no same block map.
clone_and_check "file" "clone" $DS1 "$DS1/child1" "" true
clone_and_check "file" "clone" "$DS1/child1" "$DS1/child2" "" true

cleanup_enc
prepare_enc

log_note "Copying entire file with copy_file_range across same snapshot"
log_must zfs snapshot -r $DS1@s1
log_must sync_pool $TESTPOOL
log_must rm -f "/$DS1/file"
log_must sync_pool $TESTPOOL
clone_and_check "file" "clone" "$DS1" "$DS1" "0 1 2 3" true "s1"

cleanup_enc
prepare_enc

log_note "Copying entire file with copy_file_range across different snapshot"
clone_and_check "file" "file" $DS1 $DS2 "" true
log_must zfs snapshot -r $DS2@s1
log_must sync_pool $TESTPOOL
log_must rm -f "/$DS1/file" "/$DS2/file"
log_must sync_pool $TESTPOOL
clone_and_check "file" "clone" "$DS2" "$DS1" "" true "s1"
typeset hash1=$(cat "/$DS1/.zfs/snapshot/s1/file" | md5sum)
log_must zfs destroy -r $DS2@s1
typeset hash2=$(cat "/$DS1/file" | md5sum)
log_must [ "$hash1" = "$hash2" ]

log_must sync_pool $TESTPOOL

log_pass $claim

0 comments on commit 1b0d7d8

Please sign in to comment.