1#!/usr/bin/ksh -p 2 3# 4# This file and its contents are supplied under the terms of the 5# Common Development and Distribution License ("CDDL"), version 1.0. 6# You may only use this file in accordance with the terms of version 7# 1.0 of the CDDL. 8# 9# A full copy of the text of the CDDL should have accompanied this 10# source. A copy of the CDDL is also available via the Internet at 11# http://www.illumos.org/license/CDDL. 12# 13 14# 15# Copyright (c) 2016 by Delphix. All rights reserved. 16# 17 18. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib 19 20# 21# DESCRIPTION: 22# A pool should be importable using an outdated cachefile that is unaware 23# of a zpool replace operation at different stages in time. 24# 25# STRATEGY: 26# 1. Create a pool with some devices and an alternate cachefile. 27# 2. Backup the cachefile. 28# 3. Initiate device replacement, backup cachefile again and export pool. 29# Special care must be taken so that resilvering doesn't complete 30# before we exported the pool. 31# 4. Verify that we can import the pool using the first cachefile backup. 32# (Test 1. cachefile: pre-replace, pool: resilvering) 33# 5. Wait for the resilvering to finish and export the pool. 34# 6. Verify that we can import the pool using the first cachefile backup. 35# (Test 2. cachefile: pre-replace, pool: post-replace) 36# 7. Export the pool. 37# 8. Verify that we can import the pool using the second cachefile backup. 38# (Test 3. cachefile: resilvering, pool: post-replace) 39# 40# STRATEGY TO SLOW DOWN RESILVERING: 41# 1. Reduce zfs_txg_timeout, which controls how long can we resilver for 42# each sync. 43# 2. Add data to pool 44# 3. Re-import the pool so that data isn't cached 45# 4. Use zinject to slow down device I/O 46# 5. Trigger the resilvering 47# 6. Use spa freeze to stop writing to the pool. 48# 7. Clear zinject events (needed to export the pool) 49# 8. Export the pool 50# 51 52verify_runnable "global" 53 54ZFS_TXG_TIMEOUT="" 55 56function custom_cleanup 57{ 58 # Revert zfs_txg_timeout to defaults 59 [[ -n ZFS_TXG_TIMEOUT ]] && 60 log_must set_zfs_txg_timeout $ZFS_TXG_TIMEOUT 61 62 cleanup 63} 64 65log_onexit custom_cleanup 66 67function test_replacing_vdevs 68{ 69 typeset poolcreate="$1" 70 typeset replacevdev="$2" 71 typeset replaceby="$3" 72 typeset poolfinalstate="$4" 73 typeset zinjectdevices="$5" 74 typeset earlyremove="$6" 75 76 log_note "$0: pool '$poolcreate', replace $replacevdev by $replaceby." 77 78 log_must zpool create -o cachefile=$CPATH $TESTPOOL1 $poolcreate 79 80 # Cachefile: pool in pre-replace state 81 log_must cp $CPATH $CPATHBKP 82 83 # Steps to insure resilvering happens very slowly. 84 log_must write_some_data $TESTPOOL1 85 log_must zpool export $TESTPOOL1 86 log_must cp $CPATHBKP $CPATH 87 log_must zpool import -c $CPATH -o cachefile=$CPATH $TESTPOOL1 88 typeset device 89 for device in $zinjectdevices ; do 90 log_must zinject -d $device -D 200:1 $TESTPOOL1 > /dev/null 91 done 92 log_must zpool replace $TESTPOOL1 $replacevdev $replaceby 93 94 # Cachefile: pool in resilvering state 95 log_must cp $CPATH $CPATHBKP2 96 97 # We must disable zinject in order to export the pool, so we freeze 98 # it first to prevent writing out subsequent resilvering progress. 99 log_must zpool freeze $TESTPOOL1 100 # Confirm pool is still replacing 101 log_must pool_is_replacing $TESTPOOL1 102 log_must zinject -c all > /dev/null 103 log_must zpool export $TESTPOOL1 104 105 ( $earlyremove ) && log_must rm $replacevdev 106 107 ############################################################ 108 # Test 1. Cachefile: pre-replace, pool: resilvering 109 ############################################################ 110 log_must cp $CPATHBKP $CPATH 111 log_must zpool import -c $CPATH $TESTPOOL1 112 113 # Wait for resilvering to finish 114 log_must wait_for_pool_config $TESTPOOL1 "$poolfinalstate" 115 log_must zpool export $TESTPOOL1 116 117 ( ! $earlyremove ) && log_must rm $replacevdev 118 119 ############################################################ 120 # Test 2. Cachefile: pre-replace, pool: post-replace 121 ############################################################ 122 log_must zpool import -c $CPATHBKP $TESTPOOL1 123 log_must check_pool_config $TESTPOOL1 "$poolfinalstate" 124 log_must zpool export $TESTPOOL1 125 126 ############################################################ 127 # Test 3. Cachefile: resilvering, pool: post-replace 128 ############################################################ 129 log_must zpool import -c $CPATHBKP2 $TESTPOOL1 130 log_must check_pool_config $TESTPOOL1 "$poolfinalstate" 131 132 # Cleanup 133 log_must zpool destroy $TESTPOOL1 134 log_must rm -f $CPATH $CPATHBKP $CPATHBKP2 135 log_must mkfile $FILE_SIZE $replacevdev 136 137 log_note "" 138} 139 140# We set zfs_txg_timeout to 1 to reduce resilvering time at each sync. 141ZFS_TXG_TIMEOUT=$(get_zfs_txg_timeout) 142set_zfs_txg_timeout 1 143 144test_replacing_vdevs "$VDEV0 $VDEV1" \ 145 "$VDEV1" "$VDEV2" \ 146 "$VDEV0 $VDEV2" \ 147 "$VDEV0 $VDEV1" \ 148 false 149 150test_replacing_vdevs "mirror $VDEV0 $VDEV1" \ 151 "$VDEV1" "$VDEV2" \ 152 "mirror $VDEV0 $VDEV2" \ 153 "$VDEV0 $VDEV1" \ 154 true 155 156test_replacing_vdevs "raidz $VDEV0 $VDEV1 $VDEV2" \ 157 "$VDEV1" "$VDEV3" \ 158 "raidz $VDEV0 $VDEV3 $VDEV2" \ 159 "$VDEV0 $VDEV1 $VDEV2" \ 160 true 161 162set_zfs_txg_timeout $ZFS_TXG_TIMEOUT 163 164log_pass "zpool import -c cachefile_unaware_of_replace passed." 165