]>
Commit | Line | Data |
---|---|---|
29badadd | 1 | #!/bin/ksh -p |
6cb8e530 PZ |
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 | # | |
d2734cce | 15 | # Copyright (c) 2017 by Delphix. All rights reserved. |
6cb8e530 PZ |
16 | # |
17 | ||
18 | . $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib | |
19 | ||
20 | # | |
21 | # DESCRIPTION: | |
22 | # It should be possible to rewind a pool beyond a configuration change. | |
23 | # | |
24 | # STRATEGY: | |
25 | # 1. Create a pool. | |
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. | |
d2734cce SD |
31 | # 7. Checkpoint the pool as one last attempt to preserve old blocks. |
32 | # 8. Overwrite the files. | |
33 | # 9. Export the pool. | |
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. | |
6cb8e530 PZ |
36 | # |
37 | # DISCLAIMER: | |
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 | |
42 | # left untouched. | |
43 | # | |
44 | ||
45 | verify_runnable "global" | |
46 | ||
47 | function custom_cleanup | |
48 | { | |
49 | set_vdev_validate_skip 0 | |
50 | cleanup | |
d2734cce | 51 | log_must set_tunable64 vdev_min_ms_count 16 |
6cb8e530 PZ |
52 | } |
53 | ||
54 | log_onexit custom_cleanup | |
55 | ||
56 | function test_common | |
57 | { | |
58 | typeset poolcreate="$1" | |
59 | typeset addvdevs="$2" | |
60 | typeset attachargs="${3:-}" | |
61 | typeset detachvdev="${4:-}" | |
62 | typeset removevdev="${5:-}" | |
63 | typeset finalpool="${6:-}" | |
64 | ||
65 | typeset poolcheck="$poolcreate" | |
66 | ||
67 | log_must zpool create $TESTPOOL1 $poolcreate | |
68 | ||
69 | log_must generate_data $TESTPOOL1 $MD5FILE | |
70 | ||
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 | |
74 | typeset txg | |
75 | txg=$(get_last_txg_synced $TESTPOOL1) | |
76 | log_must zfs snapshot -r $TESTPOOL1@snap1 | |
77 | ||
78 | # | |
79 | # Perform config change operations | |
80 | # | |
d2734cce SD |
81 | if [[ -n $addvdevs ]]; then |
82 | log_must zpool add -f $TESTPOOL1 $addvdevs | |
6cb8e530 PZ |
83 | fi |
84 | if [[ -n $attachargs ]]; then | |
85 | log_must zpool attach $TESTPOOL1 $attachargs | |
86 | fi | |
87 | if [[ -n $detachvdev ]]; then | |
88 | log_must zpool detach $TESTPOOL1 $detachvdev | |
89 | fi | |
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" | |
95 | fi | |
96 | if [[ -n $pathstochange ]]; then | |
97 | # | |
98 | # Change device paths and re-import pool to update labels | |
99 | # | |
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") | |
105 | done | |
106 | zpool import -d $DEVICE_DIR $TESTPOOL1 | |
107 | fi | |
108 | ||
d2734cce SD |
109 | # |
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. | |
116 | # | |
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. | |
122 | # | |
123 | log_must zpool checkpoint $TESTPOOL1 | |
124 | ||
6cb8e530 PZ |
125 | log_must overwrite_data $TESTPOOL1 "" |
126 | ||
127 | log_must zpool export $TESTPOOL1 | |
128 | ||
129 | log_must zpool import -d $DEVICE_DIR -T $txg $TESTPOOL1 | |
130 | log_must check_pool_config $TESTPOOL1 "$poolcheck" | |
131 | ||
132 | log_must verify_data_md5sums $MD5FILE | |
133 | ||
134 | # Cleanup | |
135 | log_must zpool destroy $TESTPOOL1 | |
136 | if [[ -n $pathstochange ]]; then | |
137 | for dev in $pathstochange; do | |
138 | log_must mv "${dev}_new" $dev | |
139 | done | |
140 | fi | |
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 | |
144 | ||
145 | log_note "" | |
146 | } | |
147 | ||
148 | function test_add_vdevs | |
149 | { | |
150 | typeset poolcreate="$1" | |
151 | typeset addvdevs="$2" | |
152 | ||
153 | log_note "$0: pool '$poolcreate', add $addvdevs." | |
154 | ||
155 | test_common "$poolcreate" "$addvdevs" | |
156 | } | |
157 | ||
158 | function test_attach_vdev | |
159 | { | |
160 | typeset poolcreate="$1" | |
161 | typeset attachto="$2" | |
162 | typeset attachvdev="$3" | |
163 | ||
164 | log_note "$0: pool '$poolcreate', attach $attachvdev to $attachto." | |
165 | ||
166 | test_common "$poolcreate" "" "$attachto $attachvdev" | |
167 | } | |
168 | ||
169 | function test_detach_vdev | |
170 | { | |
171 | typeset poolcreate="$1" | |
172 | typeset detachvdev="$2" | |
173 | ||
174 | log_note "$0: pool '$poolcreate', detach $detachvdev." | |
175 | ||
176 | test_common "$poolcreate" "" "" "$detachvdev" | |
177 | } | |
178 | ||
179 | function test_attach_detach_vdev | |
180 | { | |
181 | typeset poolcreate="$1" | |
182 | typeset attachto="$2" | |
183 | typeset attachvdev="$3" | |
184 | typeset detachvdev="$4" | |
185 | ||
186 | log_note "$0: pool '$poolcreate', attach $attachvdev to $attachto," \ | |
187 | "then detach $detachvdev." | |
188 | ||
189 | test_common "$poolcreate" "" "$attachto $attachvdev" "$detachvdev" | |
190 | } | |
191 | ||
192 | function test_remove_vdev | |
193 | { | |
194 | typeset poolcreate="$1" | |
195 | typeset removevdev="$2" | |
196 | typeset finalpool="$3" | |
197 | ||
198 | log_note "$0: pool '$poolcreate', remove $removevdev." | |
199 | ||
200 | test_common "$poolcreate" "" "" "" "$removevdev" "$finalpool" | |
201 | } | |
202 | ||
203 | # Record txg history | |
204 | is_linux && log_must set_tunable32 zfs_txg_history 100 | |
205 | ||
206 | # Make the devices bigger to reduce chances of overwriting MOS metadata. | |
207 | increase_device_sizes $(( FILE_SIZE * 4 )) | |
208 | ||
d2734cce SD |
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 vdev_min_ms_count 150 | |
212 | ||
6cb8e530 PZ |
213 | # Part of the rewind test is to see how it reacts to path changes |
214 | typeset pathstochange="$VDEV0 $VDEV1 $VDEV2 $VDEV3" | |
215 | ||
216 | log_note " == test rewind after device addition == " | |
217 | ||
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" | |
225 | ||
226 | log_note " == test rewind after device attach == " | |
227 | ||
228 | test_attach_vdev "$VDEV0" "$VDEV0" "$VDEV1" | |
229 | test_attach_vdev "mirror $VDEV0 $VDEV1" "$VDEV0" "$VDEV2" | |
230 | test_attach_vdev "$VDEV0 $VDEV1" "$VDEV0" "$VDEV2" | |
231 | ||
232 | log_note " == test rewind after device removal == " | |
233 | ||
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" | |
238 | ||
239 | # | |
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. | |
242 | # | |
243 | pathstochange="" | |
244 | ||
245 | log_note " == test rewind after device detach == " | |
246 | ||
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" | |
250 | ||
251 | log_note " == test rewind after device attach followed by device detach == " | |
252 | ||
253 | # | |
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. | |
256 | # | |
257 | set_vdev_validate_skip 1 | |
258 | test_attach_detach_vdev "$VDEV0" "$VDEV0" "$VDEV1" "$VDEV1" | |
259 | set_vdev_validate_skip 0 | |
260 | ||
261 | log_pass "zpool import rewind after configuration change passed." |