diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2018-02-14 12:41:01 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2018-02-14 12:41:01 +0000 |
commit | b765746f152284954a1f5d8b38a5db126d45645a (patch) | |
tree | 7b8e0dd6aeeb6310cd24a8e0464ac79fd33c38fa /usr/src/test | |
parent | 016c6e4a03266bfa546041c49c47c62000cded99 (diff) | |
parent | 750a7e45cc1795462d627c610964b7ceb020a0b0 (diff) | |
download | illumos-joyent-release-20180215.tar.gz |
[illumos-gate merge]release-20180215
commit 750a7e45cc1795462d627c610964b7ceb020a0b0
9078 Update hwdata - 20180208
commit d6e1c446d7897003fd9fd36ef5aa7da350b7f6af
8857 zio_remove_child() panic due to already destroyed parent zio
commit d9a54dd1ef75248420c035ec1d240674f8d1f4fb
9074 domount() interprets ZFS filesystem names as relative paths
commit 213fcdcbdccbdeb7d33fbae7ba8d2639a6f8fd01
9077 zloop misses core files because they're no longer written into cwd
commit 544132fce3fa6583f01318f9559adc46614343a7
8940 Sending an intra-pool resumable send stream may result in EXDEV
commit bdfded42e66b9fc1395ff2401aa2952f7c44ae34
9080 recursive enter of vdev_indirect_rwlock from vdev_indirect_remap()
commit 667ec66f1b4f491d5e839644e0912cad1c9e7122
9079 race condition in starting and ending condesing thread for indirect vdevs
commit 6f7938128a2c5e23f4b970ea101137eadd1470a1
9075 Improve ZFS pool import/load process and corrupted pool recovery
commit 6bb6b5762ca4b17cd5fb3c6c123f17489d5635aa
9100 remove sunman rules from the gate
Conflicts:
usr/src/cmd/smbios/smbios.c
Diffstat (limited to 'usr/src/test')
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 |