diff options
author | Tom Caputi <tcaputi@datto.com> | 2019-06-28 13:00:25 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2019-06-28 15:39:40 +0000 |
commit | a60ca23dc52059ace3f92bb9a63e723ac49e649b (patch) | |
tree | 3aafd723790eec7fb8371024a7e99e6a6e1b5474 /usr/src/test | |
parent | b70e94852cee03960a3aed9ab79cbd643b648628 (diff) | |
download | illumos-joyent-a60ca23dc52059ace3f92bb9a63e723ac49e649b.tar.gz |
11276 Allow unencrypted children of encrypted datasets
Portions contributed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Jason King <jason.king@joyent.com>
Reviewed by: Sean Eric Fagan <sef@ixsystems.com>
Reviewed by: Richard Laager <rlaager@wiktel.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed by: Kody Kantor <kody.kantor@joyent.com>
Reviewed by: C Fraire <cfraire@me.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/test')
10 files changed, 608 insertions, 24 deletions
diff --git a/usr/src/test/zfs-tests/include/blkdev.shlib b/usr/src/test/zfs-tests/include/blkdev.shlib new file mode 100644 index 0000000000..bf4bfbbd87 --- /dev/null +++ b/usr/src/test/zfs-tests/include/blkdev.shlib @@ -0,0 +1,449 @@ +# +# 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. +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# Copyright (c) 2012, 2016 by Delphix. All rights reserved. +# Copyright 2016 Nexenta Systems, Inc. +# Copyright (c) 2016, 2017 by Intel Corporation. All rights reserved. +# Copyright (c) 2017 Lawrence Livermore National Security, LLC. +# Copyright (c) 2017 Datto Inc. +# Copyright (c) 2017 Open-E, Inc. All Rights Reserved. +# + +# +# Returns SCSI host number for the given disk +# +function get_scsi_host #disk +{ + typeset disk=$1 + ls /sys/block/${disk}/device/scsi_device | cut -d : -f 1 +} + +# +# Cause a scan of all scsi host adapters by default +# +# $1 optional host number +# +function scan_scsi_hosts +{ + typeset hostnum=${1} + + if is_linux; then + if [[ -z $hostnum ]]; then + for host in /sys/class/scsi_host/host*; do + log_must eval "echo '- - -' > $host/scan" + done + else + log_must eval \ + "echo /sys/class/scsi_host/host$hostnum/scan" \ + > /dev/null + log_must eval \ + "echo '- - -' > /sys/class/scsi_host/host$hostnum/scan" + fi + fi +} + +# +# Wait for newly created block devices to have their minors created. +# +function block_device_wait +{ + if is_linux; then + udevadm trigger + udevadm settle + fi +} + +# +# Check if the given device is physical device +# +function is_physical_device #device +{ + typeset device=${1#$DEV_DSKDIR} + device=${device#$DEV_RDSKDIR} + + if is_linux; then + [[ -b "$DEV_DSKDIR/$device" ]] && \ + [[ -f /sys/module/loop/parameters/max_part ]] + return $? + else + echo $device | egrep "^c[0-F]+([td][0-F]+)+$" > /dev/null 2>&1 + return $? + fi +} + +# +# Check if the given device is a real device (ie SCSI device) +# +function is_real_device #disk +{ + typeset disk=$1 + [[ -z $disk ]] && log_fail "No argument for disk given." + + if is_linux; then + lsblk $DEV_RDSKDIR/$disk -o TYPE 2>/dev/null | \ + egrep disk >/dev/null + return $? + fi +} + +# +# Check if the given device is a loop device +# +function is_loop_device #disk +{ + typeset disk=$1 + [[ -z $disk ]] && log_fail "No argument for disk given." + + if is_linux; then + lsblk $DEV_RDSKDIR/$disk -o TYPE 2>/dev/null | \ + egrep loop >/dev/null + return $? + fi +} + +# +# Check if the given device is a multipath device and if there is a symbolic +# link to a device mapper and to a disk +# Currently no support for dm devices alone without multipath +# +function is_mpath_device #disk +{ + typeset disk=$1 + [[ -z $disk ]] && log_fail "No argument for disk given." + + if is_linux; then + lsblk $DEV_MPATHDIR/$disk -o TYPE 2>/dev/null | \ + egrep mpath >/dev/null + if (($? == 0)); then + readlink $DEV_MPATHDIR/$disk > /dev/null 2>&1 + return $? + else + return $? + fi + fi +} + +# Set the slice prefix for disk partitioning depending +# on whether the device is a real, multipath, or loop device. +# Currently all disks have to be of the same type, so only +# checks first disk to determine slice prefix. +# +function set_slice_prefix +{ + typeset disk + typeset -i i=0 + + if is_linux; then + while (( i < $DISK_ARRAY_NUM )); do + disk="$(echo $DISKS | nawk '{print $(i + 1)}')" + if ( is_mpath_device $disk ) && [[ -z $(echo $disk | awk 'substr($1,18,1)\ + ~ /^[[:digit:]]+$/') ]] || ( is_real_device $disk ); then + export SLICE_PREFIX="" + return 0 + elif ( is_mpath_device $disk || is_loop_device \ + $disk ); then + export SLICE_PREFIX="p" + return 0 + else + log_fail "$disk not supported for partitioning." + fi + (( i = i + 1)) + done + fi +} + +# +# Set the directory path of the listed devices in $DISK_ARRAY_NUM +# Currently all disks have to be of the same type, so only +# checks first disk to determine device directory +# default = /dev (linux) +# real disk = /dev (linux) +# multipath device = /dev/mapper (linux) +# +function set_device_dir +{ + typeset disk + typeset -i i=0 + + if is_linux; then + while (( i < $DISK_ARRAY_NUM )); do + disk="$(echo $DISKS | nawk '{print $(i + 1)}')" + if is_mpath_device $disk; then + export DEV_DSKDIR=$DEV_MPATHDIR + return 0 + else + export DEV_DSKDIR=$DEV_RDSKDIR + return 0 + fi + (( i = i + 1)) + done + else + export DEV_DSKDIR=$DEV_RDSKDIR + fi +} + +# +# Get the directory path of given device +# +function get_device_dir #device +{ + typeset device=$1 + + if ! $(is_physical_device $device) ; then + if [[ $device != "/" ]]; then + device=${device%/*} + fi + if [[ -b "$DEV_DSKDIR/$device" ]]; then + device="$DEV_DSKDIR" + fi + echo $device + else + echo "$DEV_DSKDIR" + fi +} + +# +# Get persistent name for given disk +# +function get_persistent_disk_name #device +{ + typeset device=$1 + typeset dev_id + + if is_linux; then + if is_real_device $device; then + dev_id="$(udevadm info -q all -n $DEV_DSKDIR/$device \ + | egrep disk/by-id | nawk '{print $2; exit}' \ + | nawk -F / '{print $3}')" + echo $dev_id + elif is_mpath_device $device; then + dev_id="$(udevadm info -q all -n $DEV_DSKDIR/$device \ + | egrep disk/by-id/dm-uuid \ + | nawk '{print $2; exit}' \ + | nawk -F / '{print $3}')" + echo $dev_id + else + echo $device + fi + else + echo $device + fi +} + +# +# Online or offline a disk on the system +# +# First checks state of disk. Test will fail if disk is not properly onlined +# or offlined. Online is a full rescan of SCSI disks by echoing to every +# host entry. +# +function on_off_disk # disk state{online,offline} host +{ + typeset disk=$1 + typeset state=$2 + typeset host=$3 + + [[ -z $disk ]] || [[ -z $state ]] && \ + log_fail "Arguments invalid or missing" + + if is_linux; then + if [[ $state == "offline" ]] && ( is_mpath_device $disk ); then + dm_name="$(readlink $DEV_DSKDIR/$disk \ + | nawk -F / '{print $2}')" + slave="$(ls /sys/block/${dm_name}/slaves \ + | nawk '{print $1}')" + while [[ -n $slave ]]; do + #check if disk is online + lsscsi | egrep $slave > /dev/null + if (($? == 0)); then + slave_dir="/sys/block/${dm_name}" + slave_dir+="/slaves/${slave}/device" + ss="${slave_dir}/state" + sd="${slave_dir}/delete" + log_must eval "echo 'offline' > ${ss}" + log_must eval "echo '1' > ${sd}" + lsscsi | egrep $slave > /dev/null + if (($? == 0)); then + log_fail "Offlining" \ + "$disk failed" + fi + fi + slave="$(ls /sys/block/$dm_name/slaves \ + 2>/dev/null | nawk '{print $1}')" + done + elif [[ $state == "offline" ]] && ( is_real_device $disk ); then + #check if disk is online + lsscsi | egrep $disk > /dev/null + if (($? == 0)); then + dev_state="/sys/block/$disk/device/state" + dev_delete="/sys/block/$disk/device/delete" + log_must eval "echo 'offline' > ${dev_state}" + log_must eval "echo '1' > ${dev_delete}" + lsscsi | egrep $disk > /dev/null + if (($? == 0)); then + log_fail "Offlining $disk" \ + "failed" + fi + else + log_note "$disk is already offline" + fi + elif [[ $state == "online" ]]; then + #force a full rescan + scan_scsi_hosts $host + block_device_wait + if is_mpath_device $disk; then + dm_name="$(readlink $DEV_DSKDIR/$disk \ + | nawk -F / '{print $2}')" + slave="$(ls /sys/block/$dm_name/slaves \ + | nawk '{print $1}')" + lsscsi | egrep $slave > /dev/null + if (($? != 0)); then + log_fail "Onlining $disk failed" + fi + elif is_real_device $disk; then + block_device_wait + typeset -i retries=0 + while ! lsscsi | egrep -q $disk; do + if (( $retries > 2 )); then + log_fail "Onlining $disk failed" + break + fi + (( ++retries )) + sleep 1 + done + else + log_fail "$disk is not a real dev" + fi + else + log_fail "$disk failed to $state" + fi + fi +} + +# +# Simulate disk removal +# +function remove_disk #disk +{ + typeset disk=$1 + on_off_disk $disk "offline" + block_device_wait +} + +# +# Simulate disk insertion for the given SCSI host +# +function insert_disk #disk scsi_host +{ + typeset disk=$1 + typeset scsi_host=$2 + on_off_disk $disk "online" $scsi_host + block_device_wait +} + +# +# Load scsi_debug module with specified parameters +# $blksz can be either one of: < 512b | 512e | 4Kn > +# +function load_scsi_debug # dev_size_mb add_host num_tgts max_luns blksz +{ + typeset devsize=$1 + typeset hosts=$2 + typeset tgts=$3 + typeset luns=$4 + typeset blksz=$5 + + [[ -z $devsize ]] || [[ -z $hosts ]] || [[ -z $tgts ]] || \ + [[ -z $luns ]] || [[ -z $blksz ]] && \ + log_fail "Arguments invalid or missing" + + case "$5" in + '512b') + typeset sector=512 + typeset blkexp=0 + ;; + '512e') + typeset sector=512 + typeset blkexp=3 + ;; + '4Kn') + typeset sector=4096 + typeset blkexp=0 + ;; + *) log_fail "Unsupported blksz value: $5" ;; + esac + + if is_linux; then + modprobe -n scsi_debug + if (($? != 0)); then + log_unsupported "Platform does not have scsi_debug" + "module" + fi + lsmod | egrep scsi_debug > /dev/null + if (($? == 0)); then + log_fail "scsi_debug module already installed" + else + log_must modprobe scsi_debug dev_size_mb=$devsize \ + add_host=$hosts num_tgts=$tgts max_luns=$luns \ + sector_size=$sector physblk_exp=$blkexp + block_device_wait + lsscsi | egrep scsi_debug > /dev/null + if (($? == 1)); then + log_fail "scsi_debug module install failed" + fi + fi + fi +} + +# +# Unload scsi_debug module, if needed. +# +function unload_scsi_debug +{ + log_must_retry "in use" 5 modprobe -r scsi_debug +} + +# +# Get scsi_debug device name. +# Returns basename of scsi_debug device (for example "sdb"). +# +function get_debug_device +{ + for i in {1..10} ; do + val=$(lsscsi | nawk '/scsi_debug/ {print $6; exit}' | cut -d / -f3) + + # lsscsi can take time to settle + if [ "$val" != "-" ] ; then + break + fi + sleep 1 + done + echo "$val" +} + +# +# Get actual devices used by the pool (i.e. linux sdb1 not sdb). +# +function get_pool_devices #testpool #devdir +{ + typeset testpool=$1 + typeset devdir=$2 + typeset out="" + + if is_linux; then + out=$(zpool status -P $testpool |grep ${devdir} | awk '{print $1}') + out=$(echo $out | sed -e "s|${devdir}/||g" | tr '\n' ' ') + fi + echo $out +} diff --git a/usr/src/test/zfs-tests/include/default.cfg b/usr/src/test/zfs-tests/include/default.cfg index cf61660b76..a4e0e28bee 100644 --- a/usr/src/test/zfs-tests/include/default.cfg +++ b/usr/src/test/zfs-tests/include/default.cfg @@ -141,3 +141,10 @@ export ZFS_ALL_VERSIONS="1 2 3 4 5" for i in $ZFS_ALL_VERSIONS; do eval 'export ZFS_VERSION_$i="v${i}-fs"' done + +export ZVOL_DEVDIR="/dev/zvol/dsk" +export ZVOL_RDEVDIR="/dev/zvol/rdsk" +export DEV_DSKDIR="/dev/dsk" +export DEV_RDSKDIR="/dev/rdsk" + +export NEWFS_DEFAULT_FS="ufs" diff --git a/usr/src/test/zfs-tests/include/libtest.shlib b/usr/src/test/zfs-tests/include/libtest.shlib index bedd71c4b4..8bced82ee1 100644 --- a/usr/src/test/zfs-tests/include/libtest.shlib +++ b/usr/src/test/zfs-tests/include/libtest.shlib @@ -28,6 +28,20 @@ # . ${STF_TOOLS}/contrib/include/logapi.shlib +. ${STF_SUITE}/include/blkdev.shlib + +# Determine if this is a Linux test system +# +# Return 0 if platform Linux, 1 if otherwise + +function is_linux +{ + if [[ $(uname -o) == "GNU/Linux" ]]; then + return 0 + else + return 1 + fi +} # Determine whether a dataset is mounted # diff --git a/usr/src/test/zfs-tests/runfiles/delphix.run b/usr/src/test/zfs-tests/runfiles/delphix.run index fb5c8e7bbe..c1563223ec 100644 --- a/usr/src/test/zfs-tests/runfiles/delphix.run +++ b/usr/src/test/zfs-tests/runfiles/delphix.run @@ -606,7 +606,7 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos', 'send-c_recv_dedup', 'send_encrypted_files', 'send_encrypted_hierarchy', 'send_encrypted_truncated_files', 'send_realloc_encrypted_files', - 'send_mixed_raw'] + 'send_mixed_raw', 'send-wDR_encrypted_zvol'] [/opt/zfs-tests/tests/functional/scrub_mirror] tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos', diff --git a/usr/src/test/zfs-tests/runfiles/omnios.run b/usr/src/test/zfs-tests/runfiles/omnios.run index 5d3571307e..8c26d6dfbd 100644 --- a/usr/src/test/zfs-tests/runfiles/omnios.run +++ b/usr/src/test/zfs-tests/runfiles/omnios.run @@ -605,7 +605,7 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos', 'send-c_recv_dedup', 'send_encrypted_files', 'send_encrypted_hierarchy', 'send_encrypted_truncated_files', 'send_realloc_encrypted_files', - 'send_mixed_raw'] + 'send_mixed_raw', 'send-wDR_encrypted_zvol'] [/opt/zfs-tests/tests/functional/scrub_mirror] tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos', diff --git a/usr/src/test/zfs-tests/runfiles/openindiana.run b/usr/src/test/zfs-tests/runfiles/openindiana.run index 451852e863..5ee4230f66 100644 --- a/usr/src/test/zfs-tests/runfiles/openindiana.run +++ b/usr/src/test/zfs-tests/runfiles/openindiana.run @@ -605,7 +605,7 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos', 'send-c_recv_dedup', 'send_encrypted_files', 'send_encrypted_hierarchy', 'send_encrypted_truncated_files', 'send_realloc_encrypted_files', - 'send_mixed_raw'] + 'send_mixed_raw', 'send-wDR_encrypted_zvol'] [/opt/zfs-tests/tests/functional/scrub_mirror] tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos', diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh index 9d5ecab0df..7e5072f0d5 100644 --- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh @@ -51,10 +51,10 @@ # yes unspec 0 1 no no keyformat specified # yes unspec 1 0 yes new encryption root, crypt inherited # yes unspec 1 1 yes new encryption root, crypt inherited -# yes off 0 0 no unencrypted child of encrypted parent -# yes off 0 1 no unencrypted child of encrypted parent -# yes off 1 0 no unencrypted child of encrypted parent -# yes off 1 1 no unencrypted child of encrypted parent +# yes off 0 0 yes unencrypted child of encrypted parent +# yes off 0 1 no keylocation given, but crypt off +# yes off 1 0 no keyformat given, but crypt off +# yes off 1 1 no keyformat given, but crypt off # yes on 0 0 yes inherited encryption, local crypt # yes on 0 1 no no keyformat specified for new key # yes on 1 0 yes new encryption root @@ -113,7 +113,9 @@ log_must eval "echo $PASSPHRASE | zfs create -o keyformat=passphrase" \ log_must eval "echo $PASSPHRASE | zfs create -o keyformat=passphrase" \ "-o keylocation=prompt $TESTPOOL/$TESTFS2/c4" -log_mustnot zfs create -o encryption=off $TESTPOOL/$TESTFS2/c5 +log_must zfs create -o encryption=off $TESTPOOL/$TESTFS2/c5 +log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS2/c5)" == "off" + log_mustnot zfs create -o encryption=off -o keylocation=prompt \ $TESTPOOL/$TESTFS2/c5 log_mustnot zfs create -o encryption=off -o keyformat=passphrase \ @@ -122,13 +124,13 @@ log_mustnot zfs create -o encryption=off -o keyformat=passphrase \ -o keylocation=prompt $TESTPOOL/$TESTFS2/c5 log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \ - "$TESTPOOL/$TESTFS2/c5" + "$TESTPOOL/$TESTFS2/c6" log_mustnot zfs create -o encryption=on -o keylocation=prompt \ - $TESTPOOL/$TESTFS2/c6 + $TESTPOOL/$TESTFS2/c7 log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \ - "-o keyformat=passphrase $TESTPOOL/$TESTFS2/c6" + "-o keyformat=passphrase $TESTPOOL/$TESTFS2/c7" log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \ - "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2/c7" + "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2/c8" log_pass "ZFS creates datasets only if they have a valid combination of" \ "encryption properties set." diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh index 57896c6fd3..3ce5ddc36c 100644 --- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh @@ -46,7 +46,7 @@ function cleanup log_onexit cleanup -log_assert "ZFS should receive to an encrypted child dataset" +log_assert "ZFS should receive encrypted filesystems into child dataset" typeset passphrase="password" typeset snap="$TESTPOOL/$TESTFS@snap" @@ -57,14 +57,21 @@ log_must zfs snapshot $snap log_must eval "echo $passphrase | zfs create -o encryption=on" \ "-o keyformat=passphrase $TESTPOOL/$TESTFS1" +# XXX - on illumos we're currently conflicting on mount prop +log_must zfs set mountpoint=none $TESTPOOL/$TESTFS + log_note "Verifying ZFS will receive to an encrypted child" log_must eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS1/c1" -log_note "Verifying 'send -p' will not receive to an encrypted child" -log_mustnot eval "zfs send -p $snap | zfs receive $TESTPOOL/$TESTFS1/c2" +log_note "Verifying 'send -p' will receive to an encrypted child" +log_must eval "zfs send -p $snap | zfs receive $TESTPOOL/$TESTFS1/c2" +# XXX - on illumos, not sending encryption prop yet +# log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS1/c2)" == "off" -log_note "Verifying 'send -R' will not receive to an encrypted child" -log_mustnot eval "zfs send -R $snap | zfs receive $TESTPOOL/$TESTFS1/c3" +log_note "Verifying 'send -R' will receive to an encrypted child" +log_must eval "zfs send -R $snap | zfs receive $TESTPOOL/$TESTFS1/c3" +# XXX - on illumos, not sending encryption prop yet +# log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS1/c3)" == "off" log_note "Verifying ZFS will not receive to an encrypted child when the" \ "parent key is unloaded" @@ -72,4 +79,4 @@ log_must zfs unmount $TESTPOOL/$TESTFS1 log_must zfs unload-key $TESTPOOL/$TESTFS1 log_mustnot eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS1/c4" -log_pass "ZFS can receive to an encrypted child dataset" +log_pass "ZFS can receive encrypted filesystems into child dataset" diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh index 400592aaca..1b9c6e3c70 100644 --- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh @@ -23,12 +23,13 @@ # # DESCRIPTION: -# 'zfs rename' should not rename an unencrypted dataset to a child +# 'zfs rename' should be able to move an unencrypted dataset to a child # of an encrypted dataset # # STRATEGY: # 1. Create an encrypted dataset -# 2. Attempt to rename the default dataset to a child of the encrypted dataset +# 2. Rename the default dataset to a child of the encrypted dataset +# 3. Confirm the child dataset doesn't have any encryption properties # verify_runnable "both" @@ -36,16 +37,17 @@ verify_runnable "both" function cleanup { datasetexists $TESTPOOL/$TESTFS2 && \ - log_must zfs destroy $TESTPOOL/$TESTFS2 + log_must zfs destroy -r $TESTPOOL/$TESTFS2 } log_onexit cleanup -log_assert "'zfs rename' should not rename an unencrypted dataset to a" \ +log_assert "'zfs rename' should allow renaming an unencrypted dataset to a" \ "child of an encrypted dataset" log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2" -log_mustnot zfs rename $TESTPOOL/$TESTFS $TESTPOOL/$TESTFS2/$TESTFS +log_must zfs rename $TESTPOOL/$TESTFS $TESTPOOL/$TESTFS2/$TESTFS +log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS2/$TESTFS)" == "off" -log_pass "'zfs rename' does not rename an unencrypted dataset to a child" \ +log_pass "'zfs rename' allows renaming an unencrypted dataset to a child" \ "of an encrypted dataset" diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/send-wDR_encrypted_zvol.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/send-wDR_encrypted_zvol.ksh new file mode 100755 index 0000000000..83fe3556d4 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/rsend/send-wDR_encrypted_zvol.ksh @@ -0,0 +1,103 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# 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. +# +# CDDL HEADER END +# + +# +# Copyright (c) 2018 by Datto Inc. All rights reserved. +# Copyright 2019 Joyent, Inc. +# + +. $STF_SUITE/tests/functional/rsend/rsend.kshlib + +# +# DESCRIPTION: +# Verify that zvols with dedup=on and encryption=on can be sent and received +# with a deduplicated raw send stream. +# +# STRATEGY: +# 1. Create a zvol with dedup and encryption on and put a filesystem on it +# 2. Copy a file into the zvol a few times and take a snapshot +# 3. Repeat step 2 a few times to create more snapshots +# 4. Send all snapshots in a recursive, raw, deduplicated send stream +# 5. Mount the received zvol and verify that all of the data there is correct +# + +verify_runnable "both" + +function cleanup +{ + if is_linux; then + ismounted $recvmnt ext4 && log_must umount $recvmnt + ismounted $mntpnt ext4 && log_must umount $mntpnt + else + ismounted $recvmnt ufs && log_must umount $recvmnt + ismounted $mntpnt ufs && log_must umount $mntpnt + fi + [[ -d $recvmnt ]] && log_must rm -rf $keyfile + [[ -d $mntpnt ]] && log_must rm -rf $keyfile + destroy_dataset $TESTPOOL/recv "-r" + destroy_dataset $TESTPOOL/$TESTVOL "-r" + [[ -f $keyfile ]] && log_must rm $keyfile + [[ -f $sendfile ]] && log_must rm $sendfile +} +log_onexit cleanup + +log_assert "Verify zfs can receive raw, recursive, and deduplicated send streams" + +typeset keyfile=/$TESTPOOL/pkey +typeset snap_count=5 +typeset zdev=$ZVOL_DEVDIR/$TESTPOOL/$TESTVOL +typeset mntpnt=$TESTDIR/$TESTVOL +typeset recvdev=$ZVOL_DEVDIR/$TESTPOOL/recv +typeset recvmnt=$TESTDIR/recvmnt +typeset sendfile=$TESTDIR/sendfile + +log_must eval "echo 'password' > $keyfile" + +log_must zfs create -o dedup=on -o encryption=on -o keyformat=passphrase \ + -o keylocation=file://$keyfile -V 128M $TESTPOOL/$TESTVOL +log_must block_device_wait + +if is_linux; then + log_must eval "echo 'y' | newfs -t ext4 -v $zdev" +else + log_must eval "echo 'y' | newfs $zdev" +fi +log_must mkdir -p $mntpnt +log_must mkdir -p $recvmnt +log_must mount $zdev $mntpnt + +for ((i = 1; i <= $snap_count; i++)); do + log_must dd if=/dev/urandom of=$mntpnt/file bs=1M count=1 + for ((j = 0; j < 10; j++)); do + log_must cp $mntpnt/file $mntpnt/file$j + done + + log_must sync + log_must zfs snap $TESTPOOL/$TESTVOL@snap$i +done + +log_must eval "zfs send -wDR $TESTPOOL/$TESTVOL@snap$snap_count > $sendfile" +log_must eval "zfs recv $TESTPOOL/recv < $sendfile" +log_must zfs load-key $TESTPOOL/recv +log_must block_device_wait + +log_must mount $recvdev $recvmnt + +md5_1=$(cat $mntpnt/* | md5sum | awk '{print $1}') +md5_2=$(cat $recvmnt/* | md5sum | awk '{print $1}') +[[ "$md5_1" == "$md5_2" ]] || log_fail "md5 mismatch: $md5_1 != $md5_2" + +log_pass "zfs can receive raw, recursive, and deduplicated send streams" |