1#!/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) 2017 by Delphix. All rights reserved.
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.
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.
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
45verify_runnable "global"
46
47function custom_cleanup
48{
49	set_vdev_validate_skip 0
50	cleanup
51	log_must set_tunable64 VDEV_MIN_MS_COUNT 16
52}
53
54log_onexit custom_cleanup
55
56function 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	#
81	if [[ -n $addvdevs ]]; then
82		log_must zpool add -f $TESTPOOL1 $addvdevs
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
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 record 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
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
148function 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
158function 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
169function 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
179function 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
192function 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
204is_linux && log_must set_tunable32 TXG_HISTORY 100
205
206# Make the devices bigger to reduce chances of overwriting MOS metadata.
207increase_device_sizes $(( FILE_SIZE * 4 ))
208
209# Increase the number of metaslabs for small pools temporarily to
210# reduce the chance of reusing a metaslab that holds old MOS metadata.
211log_must set_tunable64 VDEV_MIN_MS_COUNT 150
212
213# Part of the rewind test is to see how it reacts to path changes
214typeset pathstochange="$VDEV0 $VDEV1 $VDEV2 $VDEV3"
215
216log_note " == test rewind after device addition == "
217
218test_add_vdevs "$VDEV0" "$VDEV1"
219test_add_vdevs "$VDEV0 $VDEV1" "$VDEV2"
220test_add_vdevs "$VDEV0" "$VDEV1 $VDEV2"
221test_add_vdevs "mirror $VDEV0 $VDEV1" "mirror $VDEV2 $VDEV3"
222test_add_vdevs "$VDEV0" "raidz $VDEV1 $VDEV2 $VDEV3"
223test_add_vdevs "$VDEV0" "draid $VDEV1 $VDEV2 $VDEV3"
224test_add_vdevs "$VDEV0" "log $VDEV1"
225test_add_vdevs "$VDEV0 log $VDEV1" "$VDEV2"
226
227log_note " == test rewind after device attach == "
228
229test_attach_vdev "$VDEV0" "$VDEV0" "$VDEV1"
230test_attach_vdev "mirror $VDEV0 $VDEV1" "$VDEV0" "$VDEV2"
231test_attach_vdev "$VDEV0 $VDEV1" "$VDEV0" "$VDEV2"
232
233log_note " == test rewind after device removal == "
234
235# Once we remove a device it will be overlooked in the device scan, so we must
236# preserve its original path
237pathstochange="$VDEV0 $VDEV2"
238test_remove_vdev "$VDEV0 $VDEV1 $VDEV2" "$VDEV1" "$VDEV0 $VDEV2"
239
240#
241# Path change and detach are incompatible. Detach changes the guid of the vdev
242# so we have no direct way to link the new path to an existing vdev.
243#
244pathstochange=""
245
246log_note " == test rewind after device detach == "
247
248test_detach_vdev "mirror $VDEV0 $VDEV1" "$VDEV1"
249test_detach_vdev "mirror $VDEV0 $VDEV1 mirror $VDEV2 $VDEV3" "$VDEV1"
250test_detach_vdev "$VDEV0 log mirror $VDEV1 $VDEV2" "$VDEV2"
251
252log_note " == test rewind after device attach followed by device detach == "
253
254#
255# We need to disable vdev validation since once we detach VDEV1, VDEV0 will
256# inherit the mirror tvd's guid and lose its original guid.
257#
258set_vdev_validate_skip 1
259test_attach_detach_vdev "$VDEV0" "$VDEV0" "$VDEV1" "$VDEV1"
260set_vdev_validate_skip 0
261
262log_pass "zpool import rewind after configuration change passed."
263