summaryrefslogtreecommitdiff
path: root/usr/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/test')
-rw-r--r--usr/src/test/zfs-tests/runfiles/delphix.run12
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_device_added.ksh76
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_device_removed.ksh145
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_device_replaced.ksh164
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_mirror_attached.ksh72
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_mirror_detached.ksh70
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_shared_device.ksh113
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_devices_missing.ksh122
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_paths_changed.ksh98
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_config_changed.ksh236
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_device_replaced.ksh181
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import.cfg10
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import.kshlib367
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib10
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/rsend_019_pos.ksh4
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/rsend_020_pos.ksh2
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/rsend_021_pos.ksh2
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/rsend_022_pos.ksh2
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/rsend_024_pos.ksh2
-rw-r--r--usr/src/test/zfs-tests/tests/functional/rsend/send-c_resume.ksh2
20 files changed, 1675 insertions, 15 deletions
diff --git a/usr/src/test/zfs-tests/runfiles/delphix.run b/usr/src/test/zfs-tests/runfiles/delphix.run
index 88d6e368ab..9c59485b2a 100644
--- a/usr/src/test/zfs-tests/runfiles/delphix.run
+++ b/usr/src/test/zfs-tests/runfiles/delphix.run
@@ -279,7 +279,17 @@ tests = ['zpool_import_001_pos', 'zpool_import_002_pos',
'zpool_import_features_001_pos', 'zpool_import_features_002_neg',
'zpool_import_features_003_pos', 'zpool_import_missing_001_pos',
'zpool_import_missing_002_pos', 'zpool_import_missing_003_pos',
- 'zpool_import_rename_001_pos']
+ 'zpool_import_rename_001_pos',
+ 'import_cachefile_device_added',
+ 'import_cachefile_device_removed',
+ 'import_cachefile_mirror_attached',
+ 'import_cachefile_mirror_detached',
+ 'import_cachefile_device_replaced',
+ 'import_rewind_config_changed',
+ 'import_rewind_device_replaced',
+ 'import_cachefile_shared_device',
+ 'import_paths_changed',
+ 'import_devices_missing']
[/opt/zfs-tests/tests/functional/cli_root/zpool_labelclear]
tests = ['zpool_labelclear_active', 'zpool_labelclear_exported']
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_device_added.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_device_added.ksh
new file mode 100644
index 0000000000..bda6b891b9
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_device_added.ksh
@@ -0,0 +1,76 @@
+#!/usr/bin/ksh -p
+
+#
+# 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 (c) 2016 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
+
+#
+# DESCRIPTION:
+# A pool should be importable using an outdated cachefile that is unaware
+# that one or two top-level vdevs were added.
+#
+# STRATEGY:
+# 1. Create a pool with some devices and an alternate cachefile.
+# 2. Backup the cachefile.
+# 3. Add a device/mirror/raid to the pool.
+# 4. Export the pool.
+# 5. Verify that we can import the pool using the backed-up cachefile.
+#
+
+verify_runnable "global"
+
+log_onexit cleanup
+
+function test_add_vdevs
+{
+ typeset poolcreate="$1"
+ typeset addvdevs="$2"
+ typeset poolcheck="$3"
+
+ log_note "$0: pool '$poolcreate', add $addvdevs."
+
+ log_must zpool create -o cachefile=$CPATH $TESTPOOL1 $poolcreate
+
+ log_must cp $CPATH $CPATHBKP
+
+ log_must zpool add -f $TESTPOOL1 $addvdevs
+
+ log_must zpool export $TESTPOOL1
+
+ log_must zpool import -c $CPATHBKP $TESTPOOL1
+ log_must check_pool_config $TESTPOOL1 "$poolcheck"
+
+ # Cleanup
+ log_must zpool destroy $TESTPOOL1
+ log_must rm -f $CPATH $CPATHBKP
+
+ log_note ""
+}
+
+test_add_vdevs "$VDEV0" "$VDEV1" "$VDEV0 $VDEV1"
+test_add_vdevs "$VDEV0 $VDEV1" "$VDEV2" "$VDEV0 $VDEV1 $VDEV2"
+test_add_vdevs "$VDEV0" "$VDEV1 $VDEV2" "$VDEV0 $VDEV1 $VDEV2"
+test_add_vdevs "$VDEV0" "mirror $VDEV1 $VDEV2" \
+ "$VDEV0 mirror $VDEV1 $VDEV2"
+test_add_vdevs "mirror $VDEV0 $VDEV1" "mirror $VDEV2 $VDEV3" \
+ "mirror $VDEV0 $VDEV1 mirror $VDEV2 $VDEV3"
+test_add_vdevs "$VDEV0" "raidz $VDEV1 $VDEV2 $VDEV3" \
+ "$VDEV0 raidz $VDEV1 $VDEV2 $VDEV3"
+test_add_vdevs "$VDEV0" "log $VDEV1" "$VDEV0 log $VDEV1"
+test_add_vdevs "$VDEV0 log $VDEV1" "$VDEV2" "$VDEV0 $VDEV2 log $VDEV1"
+test_add_vdevs "$VDEV0" "$VDEV1 log $VDEV2" "$VDEV0 $VDEV1 log $VDEV2"
+
+log_pass "zpool import -c cachefile_unaware_of_add passed."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_device_removed.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_device_removed.ksh
new file mode 100644
index 0000000000..1d878b7a25
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_device_removed.ksh
@@ -0,0 +1,145 @@
+#!/usr/bin/ksh -p
+
+#
+# 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 (c) 2016 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
+
+#
+# DESCRIPTION:
+# A pool should be importable using an outdated cachefile that is unaware
+# that one or more vdevs were removed.
+#
+# STRATEGY:
+# 1. Create a pool with some devices and an alternate cachefile.
+# 2. Backup the cachefile.
+# 3. Remove device(s) from the pool and remove them.
+# 4. (Optionally) Add device(s) to pool.
+# 5. Export the pool.
+# 6. Verify that we can import the pool using the backed-up cachefile.
+#
+
+verify_runnable "global"
+
+function custom_cleanup
+{
+ cleanup
+}
+
+log_onexit custom_cleanup
+
+function test_remove_vdev
+{
+ typeset poolcreate="$1"
+ typeset removevdev="$2"
+ typeset poolcheck="$3"
+
+ log_note "$0: pool '$poolcreate', remove $2."
+
+ log_must zpool create -o cachefile=$CPATH $TESTPOOL1 $poolcreate
+
+ log_must cp $CPATH $CPATHBKP
+
+ log_must zpool remove $TESTPOOL1 $removevdev
+ log_must wait_for_pool_config $TESTPOOL1 "$poolcheck"
+ log_must rm $removevdev
+
+ log_must zpool export $TESTPOOL1
+
+ log_must zpool import -c $CPATHBKP $TESTPOOL1
+ log_must check_pool_config $TESTPOOL1 "$poolcheck"
+
+ # Cleanup
+ log_must zpool destroy $TESTPOOL1
+ log_must rm -f $CPATH $CPATHBKP
+ log_must mkfile $FILE_SIZE $removevdev
+
+ log_note ""
+}
+
+#
+# We have to remove top-level non-log vdevs one by one, else there is a high
+# chance pool will report busy and command will fail for the second vdev.
+#
+function test_remove_two_vdevs
+{
+ log_note "$0."
+ log_must zpool create -o cachefile=$CPATH $TESTPOOL1 \
+ $VDEV0 $VDEV1 $VDEV2 $VDEV3 $VDEV4
+
+ log_must cp $CPATH $CPATHBKP
+
+ log_must zpool remove $TESTPOOL1 $VDEV4
+ log_must wait_for_pool_config $TESTPOOL1 \
+ "$VDEV0 $VDEV1 $VDEV2 $VDEV3"
+ log_must zpool remove $TESTPOOL1 $VDEV3
+ log_must wait_for_pool_config $TESTPOOL1 "$VDEV0 $VDEV1 $VDEV2"
+ log_must rm $VDEV3 $VDEV4
+
+ log_must zpool export $TESTPOOL1
+
+ log_must zpool import -c $CPATHBKP $TESTPOOL1
+ log_must check_pool_config $TESTPOOL1 "$VDEV0 $VDEV1 $VDEV2"
+
+ # Cleanup
+ log_must zpool destroy $TESTPOOL1
+ log_must rm -f $CPATH $CPATHBKP
+ log_must mkfile $FILE_SIZE $VDEV3 $VDEV4
+
+ log_note ""
+}
+
+#
+# We want to test the case where a whole created by a log device is filled
+# by a regular device
+#
+function test_remove_log_then_add_vdev
+{
+ log_note "$0."
+ log_must zpool create -o cachefile=$CPATH $TESTPOOL1 \
+ $VDEV0 $VDEV1 $VDEV2 log $VDEV3
+
+ log_must cp $CPATH $CPATHBKP
+
+ log_must zpool remove $TESTPOOL1 $VDEV1
+ log_must wait_for_pool_config $TESTPOOL1 "$VDEV0 $VDEV2 log $VDEV3"
+ log_must zpool remove $TESTPOOL1 $VDEV3
+ log_must check_pool_config $TESTPOOL1 "$VDEV0 $VDEV2"
+ log_must rm $VDEV1 $VDEV3
+ log_must zpool add $TESTPOOL1 $VDEV4
+
+ log_must zpool export $TESTPOOL1
+
+ log_must zpool import -c $CPATHBKP $TESTPOOL1
+ log_must check_pool_config $TESTPOOL1 "$VDEV0 $VDEV2 $VDEV4"
+
+ # Cleanup
+ log_must zpool destroy $TESTPOOL1
+ log_must rm -f $CPATH $CPATHBKP
+ log_must mkfile $FILE_SIZE $VDEV1 $VDEV3
+
+ log_note ""
+}
+
+test_remove_vdev "$VDEV0 $VDEV1 $VDEV2" "$VDEV2" "$VDEV0 $VDEV1"
+test_remove_vdev "$VDEV0 $VDEV1 $VDEV2" "$VDEV1" "$VDEV0 $VDEV2"
+test_remove_vdev "$VDEV0 log $VDEV1" "$VDEV1" "$VDEV0"
+test_remove_vdev "$VDEV0 log $VDEV1 $VDEV2" "$VDEV1 $VDEV2" "$VDEV0"
+test_remove_vdev "$VDEV0 $VDEV1 $VDEV2 log $VDEV3" "$VDEV2" \
+ "$VDEV0 $VDEV1 log $VDEV3"
+test_remove_two_vdevs
+test_remove_log_then_add_vdev
+
+log_pass "zpool import -c cachefile_unaware_of_remove passed."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_device_replaced.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_device_replaced.ksh
new file mode 100644
index 0000000000..74957770cb
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_device_replaced.ksh
@@ -0,0 +1,164 @@
+#!/usr/bin/ksh -p
+
+#
+# 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 (c) 2016 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
+
+#
+# DESCRIPTION:
+# A pool should be importable using an outdated cachefile that is unaware
+# of a zpool replace operation at different stages in time.
+#
+# STRATEGY:
+# 1. Create a pool with some devices and an alternate cachefile.
+# 2. Backup the cachefile.
+# 3. Initiate device replacement, backup cachefile again and export pool.
+# Special care must be taken so that resilvering doesn't complete
+# before we exported the pool.
+# 4. Verify that we can import the pool using the first cachefile backup.
+# (Test 1. cachefile: pre-replace, pool: resilvering)
+# 5. Wait for the resilvering to finish and export the pool.
+# 6. Verify that we can import the pool using the first cachefile backup.
+# (Test 2. cachefile: pre-replace, pool: post-replace)
+# 7. Export the pool.
+# 8. Verify that we can import the pool using the second cachefile backup.
+# (Test 3. cachefile: resilvering, pool: post-replace)
+#
+# STRATEGY TO SLOW DOWN RESILVERING:
+# 1. Reduce zfs_txg_timeout, which controls how long can we resilver for
+# each sync.
+# 2. Add data to pool
+# 3. Re-import the pool so that data isn't cached
+# 4. Use zinject to slow down device I/O
+# 5. Trigger the resilvering
+# 6. Use spa freeze to stop writing to the pool.
+# 7. Clear zinject events (needed to export the pool)
+# 8. Export the pool
+#
+
+verify_runnable "global"
+
+ZFS_TXG_TIMEOUT=""
+
+function custom_cleanup
+{
+ # Revert zfs_txg_timeout to defaults
+ [[ -n ZFS_TXG_TIMEOUT ]] &&
+ log_must set_zfs_txg_timeout $ZFS_TXG_TIMEOUT
+
+ cleanup
+}
+
+log_onexit custom_cleanup
+
+function test_replacing_vdevs
+{
+ typeset poolcreate="$1"
+ typeset replacevdev="$2"
+ typeset replaceby="$3"
+ typeset poolfinalstate="$4"
+ typeset zinjectdevices="$5"
+ typeset earlyremove="$6"
+
+ log_note "$0: pool '$poolcreate', replace $replacevdev by $replaceby."
+
+ log_must zpool create -o cachefile=$CPATH $TESTPOOL1 $poolcreate
+
+ # Cachefile: pool in pre-replace state
+ log_must cp $CPATH $CPATHBKP
+
+ # Steps to insure resilvering happens very slowly.
+ log_must write_some_data $TESTPOOL1
+ log_must zpool export $TESTPOOL1
+ log_must cp $CPATHBKP $CPATH
+ log_must zpool import -c $CPATH -o cachefile=$CPATH $TESTPOOL1
+ typeset device
+ for device in $zinjectdevices ; do
+ log_must zinject -d $device -D 200:1 $TESTPOOL1 > /dev/null
+ done
+ log_must zpool replace $TESTPOOL1 $replacevdev $replaceby
+
+ # Cachefile: pool in resilvering state
+ log_must cp $CPATH $CPATHBKP2
+
+ # We must disable zinject in order to export the pool, so we freeze
+ # it first to prevent writing out subsequent resilvering progress.
+ log_must zpool freeze $TESTPOOL1
+ # Confirm pool is still replacing
+ log_must pool_is_replacing $TESTPOOL1
+ log_must zinject -c all > /dev/null
+ log_must zpool export $TESTPOOL1
+
+ ( $earlyremove ) && log_must rm $replacevdev
+
+ ############################################################
+ # Test 1. Cachefile: pre-replace, pool: resilvering
+ ############################################################
+ log_must cp $CPATHBKP $CPATH
+ log_must zpool import -c $CPATH $TESTPOOL1
+
+ # Wait for resilvering to finish
+ log_must wait_for_pool_config $TESTPOOL1 "$poolfinalstate"
+ log_must zpool export $TESTPOOL1
+
+ ( ! $earlyremove ) && log_must rm $replacevdev
+
+ ############################################################
+ # Test 2. Cachefile: pre-replace, pool: post-replace
+ ############################################################
+ log_must zpool import -c $CPATHBKP $TESTPOOL1
+ log_must check_pool_config $TESTPOOL1 "$poolfinalstate"
+ log_must zpool export $TESTPOOL1
+
+ ############################################################
+ # Test 3. Cachefile: resilvering, pool: post-replace
+ ############################################################
+ log_must zpool import -c $CPATHBKP2 $TESTPOOL1
+ log_must check_pool_config $TESTPOOL1 "$poolfinalstate"
+
+ # Cleanup
+ log_must zpool destroy $TESTPOOL1
+ log_must rm -f $CPATH $CPATHBKP $CPATHBKP2
+ log_must mkfile $FILE_SIZE $replacevdev
+
+ log_note ""
+}
+
+# We set zfs_txg_timeout to 1 to reduce resilvering time at each sync.
+ZFS_TXG_TIMEOUT=$(get_zfs_txg_timeout)
+set_zfs_txg_timeout 1
+
+test_replacing_vdevs "$VDEV0 $VDEV1" \
+ "$VDEV1" "$VDEV2" \
+ "$VDEV0 $VDEV2" \
+ "$VDEV0 $VDEV1" \
+ false
+
+test_replacing_vdevs "mirror $VDEV0 $VDEV1" \
+ "$VDEV1" "$VDEV2" \
+ "mirror $VDEV0 $VDEV2" \
+ "$VDEV0 $VDEV1" \
+ true
+
+test_replacing_vdevs "raidz $VDEV0 $VDEV1 $VDEV2" \
+ "$VDEV1" "$VDEV3" \
+ "raidz $VDEV0 $VDEV3 $VDEV2" \
+ "$VDEV0 $VDEV1 $VDEV2" \
+ true
+
+set_zfs_txg_timeout $ZFS_TXG_TIMEOUT
+
+log_pass "zpool import -c cachefile_unaware_of_replace passed."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_mirror_attached.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_mirror_attached.ksh
new file mode 100644
index 0000000000..987b745b91
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_mirror_attached.ksh
@@ -0,0 +1,72 @@
+#!/usr/bin/ksh -p
+
+#
+# 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 (c) 2016 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
+
+#
+# DESCRIPTION:
+# A pool should be importable using an outdated cachefile that misses a
+# mirror that was attached.
+#
+# STRATEGY:
+# 1. Create a pool with some devices and an alternate cachefile.
+# 2. Backup the cachefile.
+# 3. Attach a mirror to one of the devices in the pool.
+# 4. Export the pool.
+# 5. Verify that we can import the pool using the backed-up cachefile.
+#
+
+verify_runnable "global"
+
+log_onexit cleanup
+
+function test_attach_vdev
+{
+ typeset poolcreate="$1"
+ typeset attachto="$2"
+ typeset attachvdev="$3"
+ typeset poolcheck="$4"
+
+ log_note "$0: pool '$poolcreate', attach $attachvdev to $attachto."
+
+ log_must zpool create -o cachefile=$CPATH $TESTPOOL1 $poolcreate
+
+ log_must cp $CPATH $CPATHBKP
+
+ log_must zpool attach $TESTPOOL1 $attachto $attachvdev
+
+ log_must zpool export $TESTPOOL1
+
+ log_must zpool import -c $CPATHBKP $TESTPOOL1
+ log_must check_pool_config $TESTPOOL1 "$poolcheck"
+
+ # Cleanup
+ log_must zpool destroy $TESTPOOL1
+ log_must rm -f $CPATH $CPATHBKP
+
+ log_note ""
+}
+
+test_attach_vdev "$VDEV0" "$VDEV0" "$VDEV4" "mirror $VDEV0 $VDEV4"
+test_attach_vdev "$VDEV0 $VDEV1" "$VDEV1" "$VDEV4" \
+ "$VDEV0 mirror $VDEV1 $VDEV4"
+test_attach_vdev "mirror $VDEV0 $VDEV1" "$VDEV0" "$VDEV4" \
+ "mirror $VDEV0 $VDEV1 $VDEV4"
+test_attach_vdev "$VDEV0 log $VDEV1" "$VDEV1" "$VDEV4" \
+ "$VDEV0 log mirror $VDEV1 $VDEV4"
+
+log_pass "zpool import -c cachefile_unaware_of_attach passed."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_mirror_detached.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_mirror_detached.ksh
new file mode 100644
index 0000000000..85ec51673b
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_mirror_detached.ksh
@@ -0,0 +1,70 @@
+#!/usr/bin/ksh -p
+
+#
+# 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 (c) 2016 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
+
+#
+# DESCRIPTION:
+# A pool should be importable using an outdated cachefile that is unaware
+# that a mirror was detached.
+#
+# STRATEGY:
+# 1. Create a pool with some devices mirrored and an alternate cachefile.
+# 2. Backup the cachefile.
+# 3. Detach a mirror from the pool.
+# 4. Export the pool.
+# 5. Verify that we can import the pool using the backed-up cachefile.
+#
+
+verify_runnable "global"
+
+log_onexit cleanup
+
+function test_detach_vdev
+{
+ typeset poolcreate="$1"
+ typeset poolcheck="$2"
+
+ log_note "$0: pool '$poolcreate', detach $VDEV4."
+
+ log_must zpool create -o cachefile=$CPATH $TESTPOOL1 $poolcreate
+
+ log_must cp $CPATH $CPATHBKP
+
+ log_must zpool detach $TESTPOOL1 $VDEV4
+ log_must rm -f $VDEV4
+
+ log_must zpool export $TESTPOOL1
+
+ log_must zpool import -c $CPATHBKP $TESTPOOL1
+ log_must check_pool_config $TESTPOOL1 "$poolcheck"
+
+ # Cleanup
+ log_must zpool destroy $TESTPOOL1
+ log_must rm -f $CPATH $CPATHBKP
+ log_must mkfile $FILE_SIZE $VDEV4
+
+ log_note ""
+}
+
+test_detach_vdev "mirror $VDEV0 $VDEV4" "$VDEV0"
+test_detach_vdev "mirror $VDEV0 $VDEV4 mirror $VDEV1 $VDEV2" \
+ "$VDEV0 mirror $VDEV1 $VDEV2"
+test_detach_vdev "mirror $VDEV0 $VDEV1 $VDEV4" "mirror $VDEV0 $VDEV1"
+test_detach_vdev "$VDEV0 log mirror $VDEV1 $VDEV4" "$VDEV0 log $VDEV1"
+
+log_pass "zpool import -c cachefile_unaware_of_detach passed."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_shared_device.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_shared_device.ksh
new file mode 100644
index 0000000000..66225c11b9
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_shared_device.ksh
@@ -0,0 +1,113 @@
+#!/usr/bin/ksh -p
+
+#
+# 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 (c) 2016 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
+
+#
+# DESCRIPTION:
+# A pool should not try to write to a device that doesn't belong to it
+# anymore, even if the device is in its cachefile.
+#
+# STRATEGY:
+# 1. Create pool1 with some devices and an alternate cachefile.
+# 2. Backup the cachefile.
+# 3. Export pool1.
+# 4. Create pool2 using a device that belongs to pool1.
+# 5. Export pool2.
+# 6. Compute checksum of the shared device.
+# 7. Import pool1 and write some data to it.
+# 8. Verify that the checksum of the shared device hasn't changed.
+#
+
+verify_runnable "global"
+
+function custom_cleanup
+{
+ destroy_pool $TESTPOOL2
+ cleanup
+}
+
+log_onexit custom_cleanup
+
+function dev_checksum
+{
+ typeset dev="$1"
+ typeset checksum
+
+ log_note "Compute checksum of '$dev'"
+
+ checksum=$(md5sum $dev)
+ if [[ $? -ne 0 ]]; then
+ log_fail "Failed to compute checksum of '$dev'"
+ return 1
+ fi
+
+ echo "$checksum"
+ return 0
+}
+
+function test_shared_device
+{
+ typeset pool1="$1"
+ typeset pool2="$2"
+ typeset sharedvdev="$3"
+ typeset importflags="${4:-}"
+
+ log_note "$0: pool1 '$pool1', pool2 '$pool2' takes $sharedvdev."
+
+ log_must zpool create -o cachefile=$CPATH $TESTPOOL1 $pool1
+
+ log_must cp $CPATH $CPATHBKP
+
+ log_must zpool export $TESTPOOL1
+
+ log_must zpool create -f $TESTPOOL2 $pool2
+
+ log_must zpool export $TESTPOOL2
+
+ typeset checksum1=$(dev_checksum $sharedvdev)
+
+ log_must zpool import -c $CPATHBKP $importflags $TESTPOOL1
+
+ log_must write_some_data $TESTPOOL1 2
+
+ log_must zpool destroy $TESTPOOL1
+
+ typeset checksum2=$(dev_checksum $sharedvdev)
+
+ if [[ $checksum1 == $checksum2 ]]; then
+ log_pos "Device hasn't been modified by original pool"
+ else
+ log_fail "Device has been modified by original pool." \
+ "Checksum mismatch: $checksum1 != $checksum2."
+ fi
+
+ # Cleanup
+ log_must zpool import -d $DEVICE_DIR $TESTPOOL2
+ log_must zpool destroy $TESTPOOL2
+ log_must rm -f $CPATH $CPATHBKP
+
+ log_note ""
+}
+
+test_shared_device "mirror $VDEV0 $VDEV1" "mirror $VDEV1 $VDEV2" "$VDEV1"
+test_shared_device "mirror $VDEV0 $VDEV1 $VDEV2" "mirror $VDEV2 $VDEV3" \
+ "$VDEV2"
+test_shared_device "raidz $VDEV0 $VDEV1 $VDEV2" "$VDEV2" "$VDEV2"
+test_shared_device "$VDEV0 log $VDEV1" "$VDEV2 log $VDEV1" "$VDEV1" "-m"
+
+log_pass "Pool doesn't write to a device it doesn't own anymore."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_devices_missing.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_devices_missing.ksh
new file mode 100644
index 0000000000..3f45ada6ee
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_devices_missing.ksh
@@ -0,0 +1,122 @@
+#!/usr/bin/ksh -p
+
+#
+# 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 (c) 2016 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
+
+#
+# DESCRIPTION:
+# A pool should be importable when up to 2 top-level devices are missing.
+#
+# STRATEGY:
+# 1. Create a pool.
+# 2. Write some data to the pool and checksum it.
+# 3. Add one or more devices.
+# 4. Write more data to the pool and checksum it.
+# 5. Export the pool.
+# 6. Move added devices out of the devices directory.
+# 7. Import the pool with missing devices.
+# 8. Verify that the first batch of data is intact.
+# 9. Verify that accessing the second batch of data doesn't suspend pool.
+# 10. Export the pool, move back missing devices, Re-import the pool.
+# 11. Verify that all the data is intact.
+#
+
+verify_runnable "global"
+
+function custom_cleanup
+{
+ log_must set_spa_load_verify_metadata 1
+ log_must set_spa_load_verify_data 1
+ log_must set_zfs_max_missing_tvds 0
+ log_must rm -rf $BACKUP_DEVICE_DIR
+ # Highly damaged pools may fail to be destroyed, so we export them.
+ poolexists $TESTPOOL1 && log_must zpool export $TESTPOOL1
+ cleanup
+}
+
+log_onexit custom_cleanup
+
+function test_devices_missing
+{
+ typeset poolcreate="$1"
+ typeset addvdevs="$2"
+ typeset missingvdevs="$3"
+ typeset -i missingtvds="$4"
+
+ log_note "$0: pool '$poolcreate', adding $addvdevs, then" \
+ "moving away $missingvdevs."
+
+ log_must zpool create $TESTPOOL1 $poolcreate
+
+ log_must generate_data $TESTPOOL1 $MD5FILE "first"
+
+ log_must zpool add $TESTPOOL1 $addvdevs
+
+ log_must generate_data $TESTPOOL1 $MD5FILE2 "second"
+
+ log_must zpool export $TESTPOOL1
+
+ log_must mv $missingvdevs $BACKUP_DEVICE_DIR
+
+ # Tell zfs that it is ok to import a pool with missing top-level vdevs
+ log_must set_zfs_max_missing_tvds $missingtvds
+ # Missing devices means that data or metadata may be corrupted.
+ (( missingtvds > 1 )) && log_must set_spa_load_verify_metadata 0
+ log_must set_spa_load_verify_data 0
+ log_must zpool import -o readonly=on -d $DEVICE_DIR $TESTPOOL1
+
+ log_must verify_data_md5sums $MD5FILE
+
+ log_note "Try reading second batch of data, make sure pool doesn't" \
+ "get suspended."
+ verify_data_md5sums $MD5FILE >/dev/null 2>&1
+
+ log_must zpool export $TESTPOOL1
+
+ typeset newpaths=$(echo "$missingvdevs" | \
+ sed "s:$DEVICE_DIR:$BACKUP_DEVICE_DIR:g")
+ log_must mv $newpaths $DEVICE_DIR
+ log_must set_spa_load_verify_metadata 1
+ log_must set_spa_load_verify_data 1
+ log_must set_zfs_max_missing_tvds 0
+ log_must zpool import -d $DEVICE_DIR $TESTPOOL1
+
+ log_must verify_data_md5sums $MD5FILE
+ log_must verify_data_md5sums $MD5FILE2
+
+ # Cleanup
+ log_must zpool destroy $TESTPOOL1
+
+ log_note ""
+}
+
+log_must mkdir $BACKUP_DEVICE_DIR
+
+test_devices_missing "$VDEV0" "$VDEV1" "$VDEV1" 1
+test_devices_missing "$VDEV0" "$VDEV1 $VDEV2" "$VDEV1" 1
+test_devices_missing "mirror $VDEV0 $VDEV1" "mirror $VDEV2 $VDEV3" \
+ "$VDEV2 $VDEV3" 1
+test_devices_missing "$VDEV0 log $VDEV1" "$VDEV2" "$VDEV2" 1
+
+#
+# Note that we are testing for 2 non-consecutive missing devices.
+# Missing consecutive devices results in missing metadata. Because of
+# Missing metadata can cause the root dataset to fail to mount.
+#
+test_devices_missing "$VDEV0" "$VDEV1 $VDEV2 $VDEV3" "$VDEV1 $VDEV3" 2
+
+log_pass "zpool import succeeded with missing devices."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_paths_changed.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_paths_changed.ksh
new file mode 100644
index 0000000000..457eb6a14a
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_paths_changed.ksh
@@ -0,0 +1,98 @@
+#!/usr/bin/ksh -p
+
+#
+# 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 (c) 2016 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
+
+#
+# DESCRIPTION:
+# A pool should be importable even if device paths have changed.
+#
+# STRATEGY:
+# 1. Create a pool.
+# 2. Export the pool.
+# 3. Change the paths of some of the devices.
+# 4. Verify that we can import the pool in a healthy state.
+#
+
+verify_runnable "global"
+
+log_onexit cleanup
+
+function test_new_paths
+{
+ typeset poolcreate="$1"
+ typeset pathstochange="$2"
+
+ log_note "$0: pool '$poolcreate', changing paths of $pathstochange."
+
+ log_must zpool create $TESTPOOL1 $poolcreate
+
+ log_must zpool export $TESTPOOL1
+
+ for dev in $pathstochange; do
+ log_must mv $dev "${dev}_new"
+ done
+
+ log_must zpool import -d $DEVICE_DIR $TESTPOOL1
+ log_must check_pool_healthy $TESTPOOL1
+
+ # Cleanup
+ log_must zpool destroy $TESTPOOL1
+ for dev in $pathstochange; do
+ log_must mv "${dev}_new" $dev
+ done
+
+ log_note ""
+}
+
+function test_swap_paths
+{
+ typeset poolcreate="$1"
+ typeset pathtoswap1="$2"
+ typeset pathtoswap2="$3"
+
+ log_note "$0: pool '$poolcreate', swapping paths of $pathtoswap1" \
+ "and $pathtoswap2."
+
+ log_must zpool create $TESTPOOL1 $poolcreate
+
+ log_must zpool export $TESTPOOL1
+
+ log_must mv $pathtoswap2 "$pathtoswap2.tmp"
+ log_must mv $pathtoswap1 "$pathtoswap2"
+ log_must mv "$pathtoswap2.tmp" $pathtoswap1
+
+ log_must zpool import -d $DEVICE_DIR $TESTPOOL1
+ log_must check_pool_healthy $TESTPOOL1
+
+ # Cleanup
+ log_must zpool destroy $TESTPOOL1
+
+ log_note ""
+}
+
+test_new_paths "$VDEV0 $VDEV1" "$VDEV0 $VDEV1"
+test_new_paths "mirror $VDEV0 $VDEV1" "$VDEV0 $VDEV1"
+test_new_paths "$VDEV0 log $VDEV1" "$VDEV1"
+test_new_paths "raidz $VDEV0 $VDEV1 $VDEV2" "$VDEV1"
+
+test_swap_paths "$VDEV0 $VDEV1" "$VDEV0" "$VDEV1"
+test_swap_paths "raidz $VDEV0 $VDEV1 $VDEV2" "$VDEV0" "$VDEV1"
+test_swap_paths "mirror $VDEV0 $VDEV1 mirror $VDEV2 $VDEV3" \
+ "$VDEV0" "$VDEV2"
+
+log_pass "zpool import succeeded after changing device paths."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_config_changed.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_config_changed.ksh
new file mode 100644
index 0000000000..dda30a09df
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_config_changed.ksh
@@ -0,0 +1,236 @@
+#!/usr/bin/ksh -p
+
+#
+# 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 (c) 2016 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
+
+#
+# DESCRIPTION:
+# It should be possible to rewind a pool beyond a configuration change.
+#
+# STRATEGY:
+# 1. Create a pool.
+# 2. Generate files and remember their md5sum.
+# 3. Note last synced txg.
+# 4. Take a snapshot to make sure old blocks are not overwritten.
+# 5. Perform zpool add/attach/detach/remove operation.
+# 6. Change device paths if requested and re-import pool.
+# 7. Overwrite the files.
+# 8. Export the pool.
+# 9. Verify that we can rewind the pool to the noted txg.
+# 10. Verify that the files are readable and retain their old data.
+#
+# DISCLAIMER:
+# This test can fail since nothing guarantees that old MOS blocks aren't
+# overwritten. Snapshots protect datasets and data files but not the MOS.
+# sync_some_data_a_few_times interleaves file data and MOS data for a few
+# txgs, thus increasing the odds that some txgs will have their MOS data
+# left untouched.
+#
+
+verify_runnable "global"
+
+function custom_cleanup
+{
+ set_vdev_validate_skip 0
+ cleanup
+}
+
+log_onexit custom_cleanup
+
+function test_common
+{
+ typeset poolcreate="$1"
+ typeset addvdevs="$2"
+ typeset attachargs="${3:-}"
+ typeset detachvdev="${4:-}"
+ typeset removevdev="${5:-}"
+ typeset finalpool="${6:-}"
+
+ typeset poolcheck="$poolcreate"
+
+ log_must zpool create $TESTPOOL1 $poolcreate
+
+ log_must generate_data $TESTPOOL1 $MD5FILE
+
+ # syncing a few times while writing new data increases the odds that MOS
+ # metadata for some of the txgs will survive
+ log_must sync_some_data_a_few_times $TESTPOOL1
+ typeset txg
+ txg=$(get_last_txg_synced $TESTPOOL1)
+ log_must zfs snapshot -r $TESTPOOL1@snap1
+
+ #
+ # Perform config change operations
+ #
+ if [[ -n $addvdev ]]; then
+ log_must zpool add -f $TESTPOOL1 $addvdev
+ fi
+ if [[ -n $attachargs ]]; then
+ log_must zpool attach $TESTPOOL1 $attachargs
+ fi
+ if [[ -n $detachvdev ]]; then
+ log_must zpool detach $TESTPOOL1 $detachvdev
+ fi
+ if [[ -n $removevdev ]]; then
+ [[ -z $finalpool ]] &&
+ log_fail "Must provide final pool status!"
+ log_must zpool remove $TESTPOOL1 $removevdev
+ log_must wait_for_pool_config $TESTPOOL1 "$finalpool"
+ fi
+ if [[ -n $pathstochange ]]; then
+ #
+ # Change device paths and re-import pool to update labels
+ #
+ sudo zpool export $TESTPOOL1
+ for dev in $pathstochange; do
+ log_must mv $dev "${dev}_new"
+ poolcheck=$(echo "$poolcheck" | \
+ sed "s:$dev:${dev}_new:g")
+ done
+ sudo zpool import -d $DEVICE_DIR $TESTPOOL1
+ fi
+
+ log_must overwrite_data $TESTPOOL1 ""
+
+ log_must zpool export $TESTPOOL1
+
+ log_must zpool import -d $DEVICE_DIR -T $txg $TESTPOOL1
+ log_must check_pool_config $TESTPOOL1 "$poolcheck"
+
+ log_must verify_data_md5sums $MD5FILE
+
+ # Cleanup
+ log_must zpool destroy $TESTPOOL1
+ if [[ -n $pathstochange ]]; then
+ for dev in $pathstochange; do
+ log_must mv "${dev}_new" $dev
+ done
+ fi
+ # Fast way to clear vdev labels
+ log_must zpool create -f $TESTPOOL2 $VDEV0 $VDEV1 $VDEV2 $VDEV3 $VDEV4
+ log_must zpool destroy $TESTPOOL2
+
+ log_note ""
+}
+
+function test_add_vdevs
+{
+ typeset poolcreate="$1"
+ typeset addvdevs="$2"
+
+ log_note "$0: pool '$poolcreate', add $addvdevs."
+
+ test_common "$poolcreate" "$addvdevs"
+}
+
+function test_attach_vdev
+{
+ typeset poolcreate="$1"
+ typeset attachto="$2"
+ typeset attachvdev="$3"
+
+ log_note "$0: pool '$poolcreate', attach $attachvdev to $attachto."
+
+ test_common "$poolcreate" "" "$attachto $attachvdev"
+}
+
+function test_detach_vdev
+{
+ typeset poolcreate="$1"
+ typeset detachvdev="$2"
+
+ log_note "$0: pool '$poolcreate', detach $detachvdev."
+
+ test_common "$poolcreate" "" "" "$detachvdev"
+}
+
+function test_attach_detach_vdev
+{
+ typeset poolcreate="$1"
+ typeset attachto="$2"
+ typeset attachvdev="$3"
+ typeset detachvdev="$4"
+
+ log_note "$0: pool '$poolcreate', attach $attachvdev to $attachto," \
+ "then detach $detachvdev."
+
+ test_common "$poolcreate" "" "$attachto $attachvdev" "$detachvdev"
+}
+
+function test_remove_vdev
+{
+ typeset poolcreate="$1"
+ typeset removevdev="$2"
+ typeset finalpool="$3"
+
+ log_note "$0: pool '$poolcreate', remove $removevdev."
+
+ test_common "$poolcreate" "" "" "" "$removevdev" "$finalpool"
+}
+
+# Make the devices bigger to reduce chances of overwriting MOS metadata.
+increase_device_sizes $(( FILE_SIZE * 4 ))
+
+# Part of the rewind test is to see how it reacts to path changes
+typeset pathstochange="$VDEV0 $VDEV1 $VDEV2 $VDEV3"
+
+log_note " == test rewind after device addition == "
+
+test_add_vdevs "$VDEV0" "$VDEV1"
+test_add_vdevs "$VDEV0 $VDEV1" "$VDEV2"
+test_add_vdevs "$VDEV0" "$VDEV1 $VDEV2"
+test_add_vdevs "mirror $VDEV0 $VDEV1" "mirror $VDEV2 $VDEV3"
+test_add_vdevs "$VDEV0" "raidz $VDEV1 $VDEV2 $VDEV3"
+test_add_vdevs "$VDEV0" "log $VDEV1"
+test_add_vdevs "$VDEV0 log $VDEV1" "$VDEV2"
+
+log_note " == test rewind after device attach == "
+
+test_attach_vdev "$VDEV0" "$VDEV0" "$VDEV1"
+test_attach_vdev "mirror $VDEV0 $VDEV1" "$VDEV0" "$VDEV2"
+test_attach_vdev "$VDEV0 $VDEV1" "$VDEV0" "$VDEV2"
+
+log_note " == test rewind after device removal == "
+
+# Once we remove a device it will be overlooked in the device scan, so we must
+# preserve its original path
+pathstochange="$VDEV0 $VDEV2"
+test_remove_vdev "$VDEV0 $VDEV1 $VDEV2" "$VDEV1" "$VDEV0 $VDEV2"
+
+#
+# Path change and detach are incompatible. Detach changes the guid of the vdev
+# so we have no direct way to link the new path to an existing vdev.
+#
+pathstochange=""
+
+log_note " == test rewind after device detach == "
+
+test_detach_vdev "mirror $VDEV0 $VDEV1" "$VDEV1"
+test_detach_vdev "mirror $VDEV0 $VDEV1 mirror $VDEV2 $VDEV3" "$VDEV1"
+test_detach_vdev "$VDEV0 log mirror $VDEV1 $VDEV2" "$VDEV2"
+
+log_note " == test rewind after device attach followed by device detach == "
+
+#
+# We need to disable vdev validation since once we detach VDEV1, VDEV0 will
+# inherit the mirror tvd's guid and lose its original guid.
+#
+set_vdev_validate_skip 1
+test_attach_detach_vdev "$VDEV0" "$VDEV0" "$VDEV1" "$VDEV1"
+set_vdev_validate_skip 0
+
+log_pass "zpool import rewind after configuration change passed."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_device_replaced.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_device_replaced.ksh
new file mode 100644
index 0000000000..d57ced1040
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_device_replaced.ksh
@@ -0,0 +1,181 @@
+#!/usr/bin/ksh -p
+
+#
+# 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 (c) 2016 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
+
+#
+# DESCRIPTION:
+# It should be possible to rewind a pool beyond a device replacement.
+#
+# STRATEGY:
+# 1. Create a pool.
+# 2. Generate files and remember their md5sum.
+# 3. Sync a few times and note last synced txg.
+# 4. Take a snapshot to make sure old blocks are not overwritten.
+# 5. Initiate device replacement and export the pool. Special care must
+# be taken so that resilvering doesn't complete before the export.
+# 6. Test 1: Rewind pool to noted txg and then verify data checksums.
+# Import it read-only so that we do not overwrite blocks in later txgs.
+# 7. Re-import pool at latest txg and let the replacement finish.
+# 8. Export the pool an remove the new device - we shouldn't need it.
+# 9. Test 2: Rewind pool to noted txg and then verify data checksums.
+#
+# STRATEGY TO SLOW DOWN RESILVERING:
+# 1. Reduce zfs_txg_timeout, which controls how long can we resilver for
+# each sync.
+# 2. Add data to pool
+# 3. Re-import the pool so that data isn't cached
+# 4. Use zinject to slow down device I/O
+# 5. Trigger the resilvering
+# 6. Use spa freeze to stop writing to the pool.
+# 7. Clear zinject events (needed to export the pool)
+# 8. Export the pool
+#
+# DISCLAIMER:
+# This test can fail since nothing guarantees that old MOS blocks aren't
+# overwritten. Snapshots protect datasets and data files but not the MOS.
+# sync_some_data_a_few_times interleaves file data and MOS data for a few
+# txgs, thus increasing the odds that some txgs will have their MOS data
+# left untouched.
+#
+
+verify_runnable "global"
+
+ZFS_TXG_TIMEOUT=""
+
+function custom_cleanup
+{
+ # Revert zfs_txg_timeout to defaults
+ [[ -n ZFS_TXG_TIMEOUT ]] &&
+ log_must set_zfs_txg_timeout $ZFS_TXG_TIMEOUT
+ log_must rm -rf $BACKUP_DEVICE_DIR
+ cleanup
+}
+
+log_onexit custom_cleanup
+
+function test_replace_vdev
+{
+ typeset poolcreate="$1"
+ typeset replacevdev="$2"
+ typeset replaceby="$3"
+ typeset poolfinalstate="$4"
+ typeset zinjectdevices="$5"
+
+ log_note "$0: pool '$poolcreate', replace $replacevdev by $replaceby."
+
+ log_must zpool create $TESTPOOL1 $poolcreate
+
+ # generate data and checksum it
+ log_must generate_data $TESTPOOL1 $MD5FILE
+
+ # add more data so that resilver takes longer
+ log_must write_some_data $TESTPOOL1
+
+ # Syncing a few times while writing new data increases the odds that
+ # MOS metadata for some of the txgs will survive.
+ log_must sync_some_data_a_few_times $TESTPOOL1
+ typeset txg
+ txg=$(get_last_txg_synced $TESTPOOL1)
+ log_must zfs snapshot -r $TESTPOOL1@snap1
+
+ # This should not free original data.
+ log_must overwrite_data $TESTPOOL1 ""
+
+ # Steps to insure resilvering happens very slowly.
+ log_must zpool export $TESTPOOL1
+ log_must zpool import -d $DEVICE_DIR $TESTPOOL1
+ typeset device
+ for device in $zinjectdevices ; do
+ log_must zinject -d $device -D 200:1 $TESTPOOL1 > /dev/null
+ done
+ log_must zpool replace $TESTPOOL1 $replacevdev $replaceby
+
+ # We must disable zinject in order to export the pool, so we freeze
+ # it first to prevent writing out subsequent resilvering progress.
+ log_must zpool freeze $TESTPOOL1
+ # Confirm pool is still replacing
+ log_must pool_is_replacing $TESTPOOL1
+ log_must zinject -c all > /dev/null
+ log_must zpool export $TESTPOOL1
+
+ ############################################################
+ # Test 1: rewind while device is resilvering.
+ # Import read only to avoid overwriting more recent blocks.
+ ############################################################
+ log_must zpool import -d $DEVICE_DIR -o readonly=on -T $txg $TESTPOOL1
+ log_must check_pool_config $TESTPOOL1 "$poolcreate"
+
+ log_must verify_data_md5sums $MD5FILE
+
+ log_must zpool export $TESTPOOL1
+
+ # Import pool at latest txg to finish the resilvering
+ log_must zpool import -d $DEVICE_DIR $TESTPOOL1
+ log_must overwrite_data $TESTPOOL1 ""
+ log_must wait_for_pool_config $TESTPOOL1 "$poolfinalstate"
+ log_must zpool export $TESTPOOL1
+
+ # Move out the new device
+ log_must mv $replaceby $BACKUP_DEVICE_DIR/
+
+ ############################################################
+ # Test 2: rewind after device has been replaced.
+ # Import read-write since we won't need the pool anymore.
+ ############################################################
+ log_must zpool import -d $DEVICE_DIR -T $txg $TESTPOOL1
+ log_must check_pool_config $TESTPOOL1 "$poolcreate"
+
+ log_must verify_data_md5sums $MD5FILE
+
+ # Cleanup
+ log_must zpool destroy $TESTPOOL1
+ # Restore the device we moved out
+ log_must mv "$BACKUP_DEVICE_DIR/$(basename $replaceby)" $DEVICE_DIR/
+ # Fast way to clear vdev labels
+ log_must zpool create -f $TESTPOOL2 $VDEV0 $VDEV1 $VDEV2 $VDEV3 $VDEV4
+ log_must zpool destroy $TESTPOOL2
+
+ log_note ""
+}
+
+log_must mkdir $BACKUP_DEVICE_DIR
+# Make the devices bigger to reduce chances of overwriting MOS metadata.
+increase_device_sizes $(( FILE_SIZE * 4 ))
+
+# We set zfs_txg_timeout to 1 to reduce resilvering time at each sync.
+ZFS_TXG_TIMEOUT=$(get_zfs_txg_timeout)
+set_zfs_txg_timeout 1
+
+test_replace_vdev "$VDEV0 $VDEV1" \
+ "$VDEV1" "$VDEV2" \
+ "$VDEV0 $VDEV2" \
+ "$VDEV0 $VDEV1"
+
+test_replace_vdev "mirror $VDEV0 $VDEV1" \
+ "$VDEV1" "$VDEV2" \
+ "mirror $VDEV0 $VDEV2" \
+ "$VDEV0 $VDEV1"
+
+test_replace_vdev "raidz $VDEV0 $VDEV1 $VDEV2" \
+ "$VDEV1" "$VDEV3" \
+ "raidz $VDEV0 $VDEV3 $VDEV2" \
+ "$VDEV0 $VDEV1 $VDEV2"
+
+set_zfs_txg_timeout $ZFS_TXG_TIMEOUT
+
+log_pass "zpool import rewind after device replacement passed."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import.cfg b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import.cfg
index 08cb5f63e8..193c32c8ce 100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import.cfg
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import.cfg
@@ -25,7 +25,7 @@
#
#
-# Copyright (c) 2012, 2015 by Delphix. All rights reserved.
+# Copyright (c) 2012, 2016 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
@@ -64,11 +64,17 @@ export SLICE_SIZE="$((MINVDEVSIZE / (1024 * 1024)))m"
export MAX_NUM=5
export GROUP_NUM=3
export DEVICE_DIR=/dev_import-test
-export BACKUP_DEVICE_DIR=/bakdev_import-test
+export BACKUP_DEVICE_DIR=$DEVICE_DIR/backup
export DEVICE_FILE=disk
export DEVICE_ARCHIVE=archive_import-test
export MYTESTFILE=$STF_SUITE/include/libtest.shlib
+export CPATH=/var/tmp/cachefile.$$
+export CPATHBKP=/var/tmp/cachefile.$$.bkp
+export CPATHBKP2=/var/tmp/cachefile.$$.bkp2
+export MD5FILE=/var/tmp/md5sums.$$
+export MD5FILE2=/var/tmp/md5sums.$$.2
+
typeset -i num=0
while (( num < $GROUP_NUM )); do
DEVICE_FILES="$DEVICE_FILES ${DEVICE_DIR}/${DEVICE_FILE}$num"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import.kshlib b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import.kshlib
new file mode 100644
index 0000000000..04ce5f858d
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import.kshlib
@@ -0,0 +1,367 @@
+#!/usr/bin/ksh
+
+#
+# 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 (c) 2016 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.cfg
+
+#
+# Prototype cleanup function for zpool_import tests.
+#
+function cleanup
+{
+ destroy_pool $TESTPOOL1
+
+ log_must rm -f $CPATH $CPATHBKP $CPATHBKP2 $MD5FILE $MD5FILE2
+
+ log_must rm -rf $DEVICE_DIR/*
+ typeset i=0
+ while (( i < $MAX_NUM )); do
+ log_must mkfile $FILE_SIZE ${DEVICE_DIR}/${DEVICE_FILE}$i
+ ((i += 1))
+ done
+}
+
+#
+# Write a bit of data and sync several times.
+# This function is intended to be used by zpool rewind tests.
+#
+function sync_some_data_a_few_times
+{
+ typeset pool=$1
+ typeset -i a_few_times=${2:-10}
+
+ typeset file="/$pool/tmpfile"
+ for i in {0..$a_few_times}; do
+ dd if=/dev/urandom of=${file}_$i bs=128k count=10
+ sync
+ done
+
+ return 0
+}
+
+#
+# Just write a moderate amount of data to the pool.
+#
+function write_some_data
+{
+ typeset pool=$1
+ typeset files10mb=${2:-10}
+
+ typeset ds="$pool/fillerds"
+ zfs create $ds
+ [[ $? -ne 0 ]] && return 1
+
+ # Create 100 MB of data
+ typeset file="/$ds/fillerfile"
+ for i in {1..$files10mb}; do
+ dd if=/dev/urandom of=$file.$i bs=128k count=80
+ [[ $? -ne 0 ]] && return 1
+ done
+
+ return 0
+}
+
+#
+# Create/overwrite a few datasets with files.
+# Apply md5sum on all the files and store checksums in a file.
+#
+# newdata: overwrite existing files if false.
+# md5file: file where to store md5sums
+# datasetname: base name for datasets
+#
+function _generate_data_common
+{
+ typeset pool=$1
+ typeset newdata=$2
+ typeset md5file=$3
+ typeset datasetname=$4
+
+ typeset -i datasets=3
+ typeset -i files=5
+ typeset -i blocks=10
+
+ [[ -n $md5file ]] && rm -f $md5file
+ for i in {1..$datasets}; do
+ ( $newdata ) && log_must zfs create "$pool/$datasetname$i"
+ for j in {1..$files}; do
+ typeset file="/$pool/$datasetname$i/file$j"
+ dd if=/dev/urandom of=$file bs=128k count=$blocks > /dev/null
+ [[ -n $md5file ]] && md5sum $file >> $md5file
+ done
+ ( $newdata ) && sync
+ done
+
+ return 0
+}
+
+function generate_data
+{
+ typeset pool=$1
+ typeset md5file="$2"
+ typeset datasetname=${3:-ds}
+
+ _generate_data_common $pool true "$md5file" $datasetname
+}
+
+function overwrite_data
+{
+ typeset pool=$1
+ typeset md5file="$2"
+ typeset datasetname=${3:-ds}
+
+ _generate_data_common $1 false "$md5file" $datasetname
+}
+
+#
+# Verify md5sums of every file in md5sum file $1.
+#
+function verify_data_md5sums
+{
+ typeset md5file=$1
+
+ if [[ ! -f $md5file ]]; then
+ log_note "md5 sums file '$md5file' doesn't exist"
+ return 1
+ fi
+
+ md5sum -c --quiet $md5file
+ return $?
+}
+
+#
+# Set devices size in DEVICE_DIR to $1.
+#
+function increase_device_sizes
+{
+ typeset newfilesize=$1
+
+ typeset -i i=0
+ while (( i < $MAX_NUM )); do
+ log_must mkfile $newfilesize ${DEVICE_DIR}/${DEVICE_FILE}$i
+ ((i += 1))
+ done
+}
+
+#
+# Translate vdev names returned by zpool status into more generic names.
+#
+# eg: mirror-2 --> mirror
+#
+function _translate_vdev
+{
+ typeset vdev=$1
+
+ typeset keywords="mirror replacing raidz1 raidz2 raidz3 indirect"
+ for word in $keywords; do
+ echo $vdev | egrep "^${word}-[0-9]+\$" > /dev/null
+ if [[ $? -eq 0 ]]; then
+ vdev=$word
+ break
+ fi
+ done
+
+ [[ $vdev == "logs" ]] && echo "log" && return 0
+ [[ $vdev == "raidz1" ]] && echo "raidz" && return 0
+
+ echo $vdev
+ return 0
+}
+
+#
+# Check that pool configuration returned by zpool status matches expected
+# configuration. Format for the check string is same as the vdev arguments for
+# creating a pool
+# Add -q for quiet mode.
+#
+# eg: check_pool_config pool1 "mirror c0t0d0s0 c0t1d0s0 log c1t1d0s0"
+#
+function check_pool_config
+{
+ typeset logfailure=true
+ if [[ $1 == '-q' ]]; then
+ logfailure=false
+ shift
+ fi
+
+ typeset poolname=$1
+ typeset expected=$2
+
+ typeset status
+ status=$(zpool status $poolname 2>&1)
+ if [[ $? -ne 0 ]]; then
+ if ( $logfailure ); then
+ log_note "zpool status $poolname failed: $status"
+ fi
+ return 1
+ fi
+
+ typeset actual=""
+ typeset began=false
+ printf "$status\n" | while read line; do
+ typeset vdev=$(echo "$line" | awk '{printf $1}')
+ if ( ! $began ) && [[ $vdev == NAME ]]; then
+ began=true
+ continue
+ fi
+ ( $began ) && [[ -z $vdev ]] && break;
+
+ if ( $began ); then
+ [[ -z $actual ]] && actual="$vdev" && continue
+ vdev=$(_translate_vdev $vdev)
+ actual="$actual $vdev"
+ fi
+ done
+
+ expected="$poolname $expected"
+
+ if [[ "$actual" != "$expected" ]]; then
+ if ( $logfailure ); then
+ log_note "expected pool vdevs:"
+ log_note "> '$expected'"
+ log_note "actual pool vdevs:"
+ log_note "> '$actual'"
+ fi
+ return 1
+ fi
+
+ return 0
+}
+
+#
+# Check that pool configuration returned by zpool status matches expected
+# configuration within a given timeout in seconds. See check_pool_config().
+#
+# eg: wait_for_pool_config pool1 "mirror c0t0d0s0 c0t1d0s0" 60
+#
+function wait_for_pool_config
+{
+ typeset poolname=$1
+ typeset expectedconfig="$2"
+ typeset -i timeout=${3:-60}
+
+ timeout=$(( $timeout + $(date +%s) ))
+
+ while (( $(date +%s) < $timeout )); do
+ check_pool_config -q $poolname "$expectedconfig"
+ [[ $? -eq 0 ]] && return 0
+ sleep 3
+ done
+
+ check_pool_config $poolname "$expectedconfig"
+ return $?
+}
+
+#
+# Check that pool status is ONLINE
+#
+function check_pool_healthy
+{
+ typeset pool=$1
+
+ typeset status
+ status=$(zpool status $pool 2>&1)
+ if [[ $? -ne 0 ]]; then
+ log_note "zpool status $pool failed: $status"
+ return 1
+ fi
+
+ status=$(echo "$status" | grep "$pool" | grep -v "pool:" | \
+ awk '{print $2}')
+
+ if [[ $status != "ONLINE" ]]; then
+ log_note "Invalid zpool status for '$pool': '$status'" \
+ "!= 'ONLINE'"
+ return 1
+ fi
+
+ return 0
+}
+
+#
+# Return 0 if a device is currently being replaced in the pool.
+#
+function pool_is_replacing
+{
+ typeset pool=$1
+
+ zpool status $pool | grep "replacing" | grep "ONLINE" > /dev/null
+
+ return $?
+}
+
+function set_vdev_validate_skip
+{
+ mdb_set_uint32 "vdev_validate_skip" "$1"
+}
+
+function get_zfs_txg_timeout
+{
+ echo $(mdb_get_uint32 "zfs_txg_timeout")
+}
+
+function set_zfs_txg_timeout
+{
+ mdb_set_uint32 "zfs_txg_timeout" "$1"
+}
+
+function set_spa_load_verify_metadata
+{
+ mdb_set_uint32 "spa_load_verify_metadata" "$1"
+}
+
+function set_spa_load_verify_data
+{
+ mdb_set_uint32 "spa_load_verify_data" "$1"
+}
+
+function set_zfs_max_missing_tvds
+{
+ mdb_set_uint32 "zfs_max_missing_tvds" "$1"
+}
+
+#
+# Use mdb to find the last txg that was synced in an active pool.
+#
+function get_last_txg_synced
+{
+ typeset pool=$1
+
+ typeset spas
+ spas=$(mdb -k -e "::spa")
+ [[ $? -ne 0 ]] && return 1
+
+ typeset spa=""
+ print "$spas\n" | while read line; do
+ typeset poolname=$(echo "$line" | awk '{print $3}')
+ typeset addr=$(echo "$line" | awk '{print $1}')
+ if [[ $poolname == $pool ]]; then
+ spa=$addr
+ break
+ fi
+ done
+ if [[ -z $spa ]]; then
+ log_fail "Couldn't find pool '$pool'"
+ return 1
+ fi
+ typeset mdbcmd="$spa::print spa_t spa_ubsync.ub_txg | ::eval '.=E'"
+ typeset -i txg
+ txg=$(mdb -k -e "$mdbcmd")
+ [[ $? -ne 0 ]] && return 1
+
+ echo $txg
+ return 0
+}
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib b/usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib
index a82d3b3d59..8f1f30ed26 100644
--- a/usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/rsend.kshlib
@@ -512,11 +512,13 @@ function test_fs_setup
{
typeset sendfs=$1
typeset recvfs=$2
+ typeset streamfs=$3
typeset sendpool=${sendfs%%/*}
typeset recvpool=${recvfs%%/*}
datasetexists $sendfs && log_must zfs destroy -r $sendpool
datasetexists $recvfs && log_must zfs destroy -r $recvpool
+ datasetexists $streamfs && log_must zfs destroy -r $streamfs
if $(datasetexists $sendfs || zfs create -o compress=lz4 $sendfs); then
mk_files 1000 256 0 $sendfs &
@@ -545,10 +547,7 @@ function test_fs_setup
">/$sendpool/incremental.zsend"
fi
- if datasetexists $streamfs; then
- log_must zfs destroy -r $streamfs
- fi
- log_must zfs create -o compress=lz4 $sendpool/stream
+ log_must zfs create -o compress=lz4 $streamfs
}
#
@@ -661,9 +660,10 @@ function resume_cleanup
{
typeset sendfs=$1
typeset streamfs=$2
+ typeset sendpool=${sendfs%%/*}
datasetexists $sendfs && log_must zfs destroy -r $sendfs
datasetexists $streamfs && log_must zfs destroy -r $streamfs
cleanup_pool $POOL2
- rm -f /$POOL/initial.zsend /$POOL/incremental.zsend
+ rm -f /$sendpool/initial.zsend /$sendpool/incremental.zsend
}
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_019_pos.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_019_pos.ksh
index 79c9bb6d9b..3cd1a8eece 100644
--- a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_019_pos.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_019_pos.ksh
@@ -43,8 +43,8 @@ sendfs=$POOL/sendfs
recvfs=$POOL3/recvfs
streamfs=$POOL2/stream
-for sendfs in $POOL2/sendfs $POOL2; do
- test_fs_setup $sendfs $recvfs
+for sendfs in $POOL2/sendfs $POOL3; do
+ test_fs_setup $sendfs $recvfs $streamfs
resume_test "zfs send -v $sendfs@a" $streamfs $recvfs
resume_test "zfs send -v -i @a $sendfs@b" $streamfs $recvfs
file_check $sendfs $recvfs
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_020_pos.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_020_pos.ksh
index 97c19f505a..958131e6d9 100644
--- a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_020_pos.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_020_pos.ksh
@@ -42,7 +42,7 @@ streamfs=$POOL/stream
log_onexit resume_cleanup $sendfs $streamfs
-test_fs_setup $sendfs $recvfs
+test_fs_setup $sendfs $recvfs $streamfs
resume_test "zfs send -D -v $sendfs@a" $streamfs $recvfs
file_check $sendfs $recvfs
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_021_pos.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_021_pos.ksh
index 2d2a3304da..39121b12ec 100644
--- a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_021_pos.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_021_pos.ksh
@@ -44,7 +44,7 @@ streamfs=$POOL/stream
log_onexit resume_cleanup $sendfs $streamfs
-test_fs_setup $sendfs $recvfs
+test_fs_setup $sendfs $recvfs $streamfs
resume_test "zfs send -v -e $sendfs@a" $streamfs $recvfs
resume_test "zfs send -v -e -i @a $sendfs@b" $streamfs $recvfs
file_check $sendfs $recvfs
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_022_pos.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_022_pos.ksh
index 9592cb9a79..57eb594051 100644
--- a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_022_pos.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_022_pos.ksh
@@ -47,7 +47,7 @@ streamfs=$POOL/stream
log_onexit resume_cleanup $sendfs $streamfs
-test_fs_setup $sendfs $recvfs
+test_fs_setup $sendfs $recvfs $streamfs
log_must zfs bookmark $sendfs@a $sendfs#bm_a
log_must zfs destroy $sendfs@a
log_must zfs receive -v $recvfs </$POOL/initial.zsend
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_024_pos.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_024_pos.ksh
index d5d938e4b7..fc586cf8ee 100644
--- a/usr/src/test/zfs-tests/tests/functional/rsend/rsend_024_pos.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/rsend_024_pos.ksh
@@ -44,7 +44,7 @@ streamfs=$POOL/stream
log_onexit resume_cleanup $sendfs $streamfs
-test_fs_setup $sendfs $recvfs
+test_fs_setup $sendfs $recvfs $streamfs
log_must zfs unmount $sendfs
resume_test "zfs send $sendfs" $streamfs $recvfs
file_check $sendfs $recvfs
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/send-c_resume.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/send-c_resume.ksh
index 8b36177647..d5873788d9 100644
--- a/usr/src/test/zfs-tests/tests/functional/rsend/send-c_resume.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/send-c_resume.ksh
@@ -41,7 +41,7 @@ streamfs=$POOL/stream
log_assert "Verify compressed send streams can be resumed if interrupted"
log_onexit resume_cleanup $sendfs $streamfs
-test_fs_setup $sendfs $recvfs
+test_fs_setup $sendfs $recvfs $streamfs
resume_test "zfs send -c -v $sendfs@a" $streamfs $recvfs
resume_test "zfs send -c -v -i @a $sendfs@b" $streamfs $recvfs
file_check $sendfs $recvfs