]> git.proxmox.com Git - mirror_zfs.git/blob - tests/zfs-tests/tests/functional/cli_root/zpool_import/import_cache_device_replaced.ksh
OpenZFS 9075 - Improve ZFS pool import/load process and corrupted pool recovery
[mirror_zfs.git] / tests / zfs-tests / tests / functional / cli_root / zpool_import / import_cache_device_replaced.ksh
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
52 verify_runnable "global"
53
54 ZFS_TXG_TIMEOUT=""
55
56 function 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 zinject -c all
63 cleanup
64 }
65
66 log_onexit custom_cleanup
67
68 function test_replacing_vdevs
69 {
70 typeset poolcreate="$1"
71 typeset replacevdev="$2"
72 typeset replaceby="$3"
73 typeset poolfinalstate="$4"
74 typeset zinjectdevices="$5"
75 typeset earlyremove="$6"
76 typeset writedata="$7"
77
78 log_note "$0: pool '$poolcreate', replace $replacevdev by $replaceby."
79
80 log_must zpool create -o cachefile=$CPATH $TESTPOOL1 $poolcreate
81
82 # Cachefile: pool in pre-replace state
83 log_must cp $CPATH $CPATHBKP
84
85 # Steps to insure resilvering happens very slowly.
86 log_must write_some_data $TESTPOOL1 $writedata
87 log_must zpool export $TESTPOOL1
88 log_must cp $CPATHBKP $CPATH
89 log_must zpool import -c $CPATH -o cachefile=$CPATH $TESTPOOL1
90 typeset device
91 for device in $zinjectdevices ; do
92 log_must zinject -d $device -D 200:1 $TESTPOOL1 > /dev/null
93 done
94 log_must zpool replace $TESTPOOL1 $replacevdev $replaceby
95
96 # Cachefile: pool in resilvering state
97 log_must cp $CPATH $CPATHBKP2
98
99 # We must disable zinject in order to export the pool, so we freeze
100 # it first to prevent writing out subsequent resilvering progress.
101 log_must zpool freeze $TESTPOOL1
102 # Confirm pool is still replacing
103 log_must pool_is_replacing $TESTPOOL1
104 log_must zinject -c all > /dev/null
105 log_must zpool export $TESTPOOL1
106
107 ( $earlyremove ) && log_must rm $replacevdev
108
109 ############################################################
110 # Test 1. Cachefile: pre-replace, pool: resilvering
111 ############################################################
112 log_must cp $CPATHBKP $CPATH
113 log_must zpool import -c $CPATH $TESTPOOL1
114
115 # Wait for resilvering to finish
116 log_must wait_for_pool_config $TESTPOOL1 "$poolfinalstate"
117 log_must zpool export $TESTPOOL1
118
119 ( ! $earlyremove ) && log_must rm $replacevdev
120
121 ############################################################
122 # Test 2. Cachefile: pre-replace, pool: post-replace
123 ############################################################
124 log_must zpool import -c $CPATHBKP $TESTPOOL1
125 log_must check_pool_config $TESTPOOL1 "$poolfinalstate"
126 log_must zpool export $TESTPOOL1
127
128 ############################################################
129 # Test 3. Cachefile: resilvering, pool: post-replace
130 ############################################################
131 log_must zpool import -c $CPATHBKP2 $TESTPOOL1
132 log_must check_pool_config $TESTPOOL1 "$poolfinalstate"
133
134 # Cleanup
135 log_must zpool destroy $TESTPOOL1
136 log_must rm -f $CPATH $CPATHBKP $CPATHBKP2
137 log_must mkfile $FILE_SIZE $replacevdev
138
139 log_note ""
140 }
141
142 # We set zfs_txg_timeout to 1 to reduce resilvering time at each sync.
143 ZFS_TXG_TIMEOUT=$(get_zfs_txg_timeout)
144 set_zfs_txg_timeout 1
145
146 test_replacing_vdevs "$VDEV0 $VDEV1" \
147 "$VDEV1" "$VDEV2" \
148 "$VDEV0 $VDEV2" \
149 "$VDEV0 $VDEV1" \
150 false 20
151
152 test_replacing_vdevs "mirror $VDEV0 $VDEV1" \
153 "$VDEV1" "$VDEV2" \
154 "mirror $VDEV0 $VDEV2" \
155 "$VDEV0 $VDEV1" \
156 true 10
157
158 test_replacing_vdevs "raidz $VDEV0 $VDEV1 $VDEV2" \
159 "$VDEV1" "$VDEV3" \
160 "raidz $VDEV0 $VDEV3 $VDEV2" \
161 "$VDEV0 $VDEV1 $VDEV2" \
162 true 20
163
164 set_zfs_txg_timeout $ZFS_TXG_TIMEOUT
165
166 log_pass "zpool import -c cachefile_unaware_of_replace passed."