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
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.
15 # Copyright (c) 2017 by Delphix. All rights reserved.
18 .
$STF_SUITE/tests
/functional
/cli_root
/zpool_import
/zpool_import.kshlib
22 # It should be possible to rewind a pool beyond a configuration change.
26 # 2. Generate files and remember their md5sum.
27 # 3. Note last synced txg.
28 # 4. Take a snapshot to make sure old blocks are not overwritten.
29 # 5. Perform zpool add/attach/detach/remove operation.
30 # 6. Change device paths if requested and re-import pool.
31 # 7. Checkpoint the pool as one last attempt to preserve old blocks.
32 # 8. Overwrite the files.
34 # 10. Verify that we can rewind the pool to the noted txg.
35 # 11. Verify that the files are readable and retain their old data.
38 # This test can fail since nothing guarantees that old MOS blocks aren't
39 # overwritten. Snapshots protect datasets and data files but not the MOS.
40 # sync_some_data_a_few_times interleaves file data and MOS data for a few
41 # txgs, thus increasing the odds that some txgs will have their MOS data
45 verify_runnable
"global"
47 function custom_cleanup
49 set_vdev_validate_skip
0
51 log_must set_tunable64 zfs_vdev_min_ms_count
16
54 log_onexit custom_cleanup
58 typeset poolcreate
="$1"
60 typeset attachargs
="${3:-}"
61 typeset detachvdev
="${4:-}"
62 typeset removevdev
="${5:-}"
63 typeset finalpool
="${6:-}"
65 typeset poolcheck
="$poolcreate"
67 log_must zpool create
$TESTPOOL1 $poolcreate
69 log_must generate_data
$TESTPOOL1 $MD5FILE
71 # syncing a few times while writing new data increases the odds that MOS
72 # metadata for some of the txgs will survive
73 log_must sync_some_data_a_few_times
$TESTPOOL1
75 txg
=$
(get_last_txg_synced
$TESTPOOL1)
76 log_must zfs snapshot
-r $TESTPOOL1@snap1
79 # Perform config change operations
81 if [[ -n $addvdevs ]]; then
82 log_must zpool add
-f $TESTPOOL1 $addvdevs
84 if [[ -n $attachargs ]]; then
85 log_must zpool attach
$TESTPOOL1 $attachargs
87 if [[ -n $detachvdev ]]; then
88 log_must zpool detach
$TESTPOOL1 $detachvdev
90 if [[ -n $removevdev ]]; then
91 [[ -z $finalpool ]] &&
92 log_fail
"Must provide final pool status!"
93 log_must zpool remove
$TESTPOOL1 $removevdev
94 log_must wait_for_pool_config
$TESTPOOL1 "$finalpool"
96 if [[ -n $pathstochange ]]; then
98 # Change device paths and re-import pool to update labels
100 zpool
export $TESTPOOL1
101 for dev
in $pathstochange; do
102 log_must
mv $dev "${dev}_new"
103 poolcheck
=$
(echo "$poolcheck" | \
104 sed "s:$dev:${dev}_new:g")
106 zpool import
-d $DEVICE_DIR $TESTPOOL1
110 # In an attempt to leave MOS data untouched so extreme
111 # rewind is successful during import we checkpoint the
112 # pool and hope that these MOS data are part of the
113 # checkpoint (e.g they stay around). If this goes as
114 # expected, then extreme rewind should rewind back even
115 # further than the time that we took the checkpoint.
117 # Note that, ideally we would want to take a checkpoint
118 # right after we recond the txg we plan to rewind to.
119 # But since we can't attach, detach or remove devices
120 # while having a checkpoint, we take it after the
121 # operation that changes the config.
123 log_must zpool checkpoint
$TESTPOOL1
125 log_must overwrite_data
$TESTPOOL1 ""
127 log_must zpool
export $TESTPOOL1
129 log_must zpool import
-d $DEVICE_DIR -T $txg $TESTPOOL1
130 log_must check_pool_config
$TESTPOOL1 "$poolcheck"
132 log_must verify_data_md5sums
$MD5FILE
135 log_must zpool destroy
$TESTPOOL1
136 if [[ -n $pathstochange ]]; then
137 for dev
in $pathstochange; do
138 log_must
mv "${dev}_new" $dev
141 # Fast way to clear vdev labels
142 log_must zpool create
-f $TESTPOOL2 $VDEV0 $VDEV1 $VDEV2 $VDEV3 $VDEV4
143 log_must zpool destroy
$TESTPOOL2
148 function test_add_vdevs
150 typeset poolcreate
="$1"
151 typeset addvdevs
="$2"
153 log_note
"$0: pool '$poolcreate', add $addvdevs."
155 test_common
"$poolcreate" "$addvdevs"
158 function test_attach_vdev
160 typeset poolcreate
="$1"
161 typeset attachto
="$2"
162 typeset attachvdev
="$3"
164 log_note
"$0: pool '$poolcreate', attach $attachvdev to $attachto."
166 test_common
"$poolcreate" "" "$attachto $attachvdev"
169 function test_detach_vdev
171 typeset poolcreate
="$1"
172 typeset detachvdev
="$2"
174 log_note
"$0: pool '$poolcreate', detach $detachvdev."
176 test_common
"$poolcreate" "" "" "$detachvdev"
179 function test_attach_detach_vdev
181 typeset poolcreate
="$1"
182 typeset attachto
="$2"
183 typeset attachvdev
="$3"
184 typeset detachvdev
="$4"
186 log_note
"$0: pool '$poolcreate', attach $attachvdev to $attachto," \
187 "then detach $detachvdev."
189 test_common
"$poolcreate" "" "$attachto $attachvdev" "$detachvdev"
192 function test_remove_vdev
194 typeset poolcreate
="$1"
195 typeset removevdev
="$2"
196 typeset finalpool
="$3"
198 log_note
"$0: pool '$poolcreate', remove $removevdev."
200 test_common
"$poolcreate" "" "" "" "$removevdev" "$finalpool"
204 is_linux
&& log_must set_tunable32 zfs_txg_history
100
206 # Make the devices bigger to reduce chances of overwriting MOS metadata.
207 increase_device_sizes $
(( FILE_SIZE
* 4 ))
209 # Increase the number of metaslabs for small pools temporarily to
210 # reduce the chance of reusing a metaslab that holds old MOS metadata.
211 log_must set_tunable64 zfs_vdev_min_ms_count
150
213 # Part of the rewind test is to see how it reacts to path changes
214 typeset pathstochange
="$VDEV0 $VDEV1 $VDEV2 $VDEV3"
216 log_note
" == test rewind after device addition == "
218 test_add_vdevs
"$VDEV0" "$VDEV1"
219 test_add_vdevs
"$VDEV0 $VDEV1" "$VDEV2"
220 test_add_vdevs
"$VDEV0" "$VDEV1 $VDEV2"
221 test_add_vdevs
"mirror $VDEV0 $VDEV1" "mirror $VDEV2 $VDEV3"
222 test_add_vdevs
"$VDEV0" "raidz $VDEV1 $VDEV2 $VDEV3"
223 test_add_vdevs
"$VDEV0" "log $VDEV1"
224 test_add_vdevs
"$VDEV0 log $VDEV1" "$VDEV2"
226 log_note
" == test rewind after device attach == "
228 test_attach_vdev
"$VDEV0" "$VDEV0" "$VDEV1"
229 test_attach_vdev
"mirror $VDEV0 $VDEV1" "$VDEV0" "$VDEV2"
230 test_attach_vdev
"$VDEV0 $VDEV1" "$VDEV0" "$VDEV2"
232 log_note
" == test rewind after device removal == "
234 # Once we remove a device it will be overlooked in the device scan, so we must
235 # preserve its original path
236 pathstochange
="$VDEV0 $VDEV2"
237 test_remove_vdev
"$VDEV0 $VDEV1 $VDEV2" "$VDEV1" "$VDEV0 $VDEV2"
240 # Path change and detach are incompatible. Detach changes the guid of the vdev
241 # so we have no direct way to link the new path to an existing vdev.
245 log_note
" == test rewind after device detach == "
247 test_detach_vdev
"mirror $VDEV0 $VDEV1" "$VDEV1"
248 test_detach_vdev
"mirror $VDEV0 $VDEV1 mirror $VDEV2 $VDEV3" "$VDEV1"
249 test_detach_vdev
"$VDEV0 log mirror $VDEV1 $VDEV2" "$VDEV2"
251 log_note
" == test rewind after device attach followed by device detach == "
254 # We need to disable vdev validation since once we detach VDEV1, VDEV0 will
255 # inherit the mirror tvd's guid and lose its original guid.
257 set_vdev_validate_skip
1
258 test_attach_detach_vdev
"$VDEV0" "$VDEV0" "$VDEV1" "$VDEV1"
259 set_vdev_validate_skip
0
261 log_pass
"zpool import rewind after configuration change passed."