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 zfs_scan_suspend_progress to ensure resilvers don't progress 46# 5. Trigger the resilvering 47# 6. Use spa freeze to stop writing to the pool. 48# 7. Re-enable scan progress 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 log_must set_tunable32 zfs_scan_suspend_progress 0 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 log_must set_tunable32 zfs_scan_suspend_progress 1 89 log_must zpool replace $TESTPOOL1 $replacevdev $replaceby 90 91 # Cachefile: pool in resilvering state 92 log_must cp $CPATH $CPATHBKP2 93 94 # Confirm pool is still replacing 95 log_must pool_is_replacing $TESTPOOL1 96 log_must zpool export $TESTPOOL1 97 log_must set_tunable32 zfs_scan_suspend_progress 0 98 99 ( $earlyremove ) && log_must rm $replacevdev 100 101 ############################################################ 102 # Test 1. Cachefile: pre-replace, pool: resilvering 103 ############################################################ 104 log_must cp $CPATHBKP $CPATH 105 log_must zpool import -c $CPATH $TESTPOOL1 106 107 # Wait for resilvering to finish 108 log_must wait_for_pool_config $TESTPOOL1 "$poolfinalstate" 109 log_must zpool export $TESTPOOL1 110 111 ( ! $earlyremove ) && log_must rm $replacevdev 112 113 ############################################################ 114 # Test 2. Cachefile: pre-replace, pool: post-replace 115 ############################################################ 116 log_must zpool import -c $CPATHBKP $TESTPOOL1 117 log_must check_pool_config $TESTPOOL1 "$poolfinalstate" 118 log_must zpool export $TESTPOOL1 119 120 ############################################################ 121 # Test 3. Cachefile: resilvering, pool: post-replace 122 ############################################################ 123 log_must zpool import -c $CPATHBKP2 $TESTPOOL1 124 log_must check_pool_config $TESTPOOL1 "$poolfinalstate" 125 126 # Cleanup 127 log_must zpool destroy $TESTPOOL1 128 log_must rm -f $CPATH $CPATHBKP $CPATHBKP2 129 log_must mkfile $FILE_SIZE $replacevdev 130 131 log_note "" 132} 133 134# We set zfs_txg_timeout to 1 to reduce resilvering time at each sync. 135ZFS_TXG_TIMEOUT=$(get_zfs_txg_timeout) 136set_zfs_txg_timeout 1 137 138test_replacing_vdevs "$VDEV0 $VDEV1" \ 139 "$VDEV1" "$VDEV2" \ 140 "$VDEV0 $VDEV2" \ 141 "$VDEV0 $VDEV1" \ 142 false 143 144test_replacing_vdevs "mirror $VDEV0 $VDEV1" \ 145 "$VDEV1" "$VDEV2" \ 146 "mirror $VDEV0 $VDEV2" \ 147 "$VDEV0 $VDEV1" \ 148 true 149 150test_replacing_vdevs "raidz $VDEV0 $VDEV1 $VDEV2" \ 151 "$VDEV1" "$VDEV3" \ 152 "raidz $VDEV0 $VDEV3 $VDEV2" \ 153 "$VDEV0 $VDEV1 $VDEV2" \ 154 true 155 156set_zfs_txg_timeout $ZFS_TXG_TIMEOUT 157 158log_pass "zpool import -c cachefile_unaware_of_replace passed." 159