16f793812SPavel Zakharov#!/usr/bin/ksh -p
26f793812SPavel Zakharov
36f793812SPavel Zakharov#
46f793812SPavel Zakharov# This file and its contents are supplied under the terms of the
56f793812SPavel Zakharov# Common Development and Distribution License ("CDDL"), version 1.0.
66f793812SPavel Zakharov# You may only use this file in accordance with the terms of version
76f793812SPavel Zakharov# 1.0 of the CDDL.
86f793812SPavel Zakharov#
96f793812SPavel Zakharov# A full copy of the text of the CDDL should have accompanied this
106f793812SPavel Zakharov# source.  A copy of the CDDL is also available via the Internet at
116f793812SPavel Zakharov# http://www.illumos.org/license/CDDL.
126f793812SPavel Zakharov#
136f793812SPavel Zakharov
146f793812SPavel Zakharov#
15f78cdc34SPaul Dagnelie# Copyright (c) 2016, 2018 by Delphix. All rights reserved.
166f793812SPavel Zakharov#
176f793812SPavel Zakharov
186f793812SPavel Zakharov. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
196f793812SPavel Zakharov
206f793812SPavel Zakharov#
216f793812SPavel Zakharov# DESCRIPTION:
226f793812SPavel Zakharov#	It should be possible to rewind a pool beyond a configuration change.
236f793812SPavel Zakharov#
246f793812SPavel Zakharov# STRATEGY:
256f793812SPavel Zakharov#	1. Create a pool.
266f793812SPavel Zakharov#	2. Generate files and remember their md5sum.
276f793812SPavel Zakharov#	3. Note last synced txg.
286f793812SPavel Zakharov#	4. Take a snapshot to make sure old blocks are not overwritten.
296f793812SPavel Zakharov#	5. Perform zpool add/attach/detach/remove operation.
306f793812SPavel Zakharov#	6. Change device paths if requested and re-import pool.
3186714001SSerapheim Dimitropoulos#	7. Checkpoint the pool as one last attempt to preserve old blocks.
3286714001SSerapheim Dimitropoulos#	8. Overwrite the files.
3386714001SSerapheim Dimitropoulos#	9. Export the pool.
3486714001SSerapheim Dimitropoulos#	10. Verify that we can rewind the pool to the noted txg.
3586714001SSerapheim Dimitropoulos#	11. Verify that the files are readable and retain their old data.
366f793812SPavel Zakharov#
376f793812SPavel Zakharov# DISCLAIMER:
386f793812SPavel Zakharov#	This test can fail since nothing guarantees that old MOS blocks aren't
396f793812SPavel Zakharov#	overwritten. Snapshots protect datasets and data files but not the MOS.
406f793812SPavel Zakharov#	sync_some_data_a_few_times interleaves file data and MOS data for a few
416f793812SPavel Zakharov#	txgs, thus increasing the odds that some txgs will have their MOS data
426f793812SPavel Zakharov#	left untouched.
436f793812SPavel Zakharov#
446f793812SPavel Zakharov
456f793812SPavel Zakharovverify_runnable "global"
466f793812SPavel Zakharov
476f793812SPavel Zakharovfunction custom_cleanup
486f793812SPavel Zakharov{
496f793812SPavel Zakharov	set_vdev_validate_skip 0
506f793812SPavel Zakharov	cleanup
51a0b03b16SSerapheim Dimitropoulos	log_must mdb_ctf_set_int zfs_vdev_min_ms_count 0t16
52f78cdc34SPaul Dagnelie	log_must mdb_ctf_set_int spa_allocators 0t4
536f793812SPavel Zakharov}
546f793812SPavel Zakharov
556f793812SPavel Zakharovlog_onexit custom_cleanup
566f793812SPavel Zakharov
576f793812SPavel Zakharovfunction test_common
586f793812SPavel Zakharov{
596f793812SPavel Zakharov	typeset poolcreate="$1"
606f793812SPavel Zakharov	typeset addvdevs="$2"
616f793812SPavel Zakharov	typeset attachargs="${3:-}"
626f793812SPavel Zakharov	typeset detachvdev="${4:-}"
636f793812SPavel Zakharov	typeset removevdev="${5:-}"
646f793812SPavel Zakharov	typeset finalpool="${6:-}"
656f793812SPavel Zakharov
666f793812SPavel Zakharov	typeset poolcheck="$poolcreate"
676f793812SPavel Zakharov
686f793812SPavel Zakharov	log_must zpool create $TESTPOOL1 $poolcreate
696f793812SPavel Zakharov
706f793812SPavel Zakharov	log_must generate_data $TESTPOOL1 $MD5FILE
716f793812SPavel Zakharov
726f793812SPavel Zakharov	# syncing a few times while writing new data increases the odds that MOS
736f793812SPavel Zakharov	# metadata for some of the txgs will survive
746f793812SPavel Zakharov	log_must sync_some_data_a_few_times $TESTPOOL1
756f793812SPavel Zakharov	typeset txg
766f793812SPavel Zakharov	txg=$(get_last_txg_synced $TESTPOOL1)
776f793812SPavel Zakharov	log_must zfs snapshot -r $TESTPOOL1@snap1
786f793812SPavel Zakharov
796f793812SPavel Zakharov	#
806f793812SPavel Zakharov	# Perform config change operations
816f793812SPavel Zakharov	#
8286714001SSerapheim Dimitropoulos	if [[ -n $addvdevs ]]; then
8386714001SSerapheim Dimitropoulos		log_must zpool add -f $TESTPOOL1 $addvdevs
846f793812SPavel Zakharov	fi
856f793812SPavel Zakharov	if [[ -n $attachargs ]]; then
866f793812SPavel Zakharov		log_must zpool attach $TESTPOOL1 $attachargs
876f793812SPavel Zakharov	fi
886f793812SPavel Zakharov	if [[ -n $detachvdev ]]; then
896f793812SPavel Zakharov		log_must zpool detach $TESTPOOL1 $detachvdev
906f793812SPavel Zakharov	fi
916f793812SPavel Zakharov	if [[ -n $removevdev ]]; then
926f793812SPavel Zakharov		[[ -z $finalpool ]] &&
936f793812SPavel Zakharov		    log_fail "Must provide final pool status!"
946f793812SPavel Zakharov		log_must zpool remove $TESTPOOL1 $removevdev
956f793812SPavel Zakharov		log_must wait_for_pool_config $TESTPOOL1 "$finalpool"
966f793812SPavel Zakharov	fi
976f793812SPavel Zakharov	if [[ -n $pathstochange ]]; then
986f793812SPavel Zakharov		#
996f793812SPavel Zakharov		# Change device paths and re-import pool to update labels
1006f793812SPavel Zakharov		#
101*cf4e3805SToomas Soome		zpool export $TESTPOOL1
1026f793812SPavel Zakharov		for dev in $pathstochange; do
1036f793812SPavel Zakharov			log_must mv $dev "${dev}_new"
1046f793812SPavel Zakharov			poolcheck=$(echo "$poolcheck" | \
1056f793812SPavel Zakharov			    sed "s:$dev:${dev}_new:g")
1066f793812SPavel Zakharov		done
107*cf4e3805SToomas Soome		zpool import -d $DEVICE_DIR $TESTPOOL1
1086f793812SPavel Zakharov	fi
1096f793812SPavel Zakharov
11086714001SSerapheim Dimitropoulos	#
11186714001SSerapheim Dimitropoulos	# In an attempt to leave MOS data untouched so extreme
11286714001SSerapheim Dimitropoulos	# rewind is successful during import we checkpoint the
11386714001SSerapheim Dimitropoulos	# pool and hope that these MOS data are part of the
11486714001SSerapheim Dimitropoulos	# checkpoint (e.g they stay around). If this goes as
11586714001SSerapheim Dimitropoulos	# expected, then extreme rewind should rewind back even
11686714001SSerapheim Dimitropoulos	# further than the time that we took the checkpoint.
11786714001SSerapheim Dimitropoulos	#
11886714001SSerapheim Dimitropoulos	# Note that, ideally we would want to take a checkpoint
11986714001SSerapheim Dimitropoulos	# right after we recond the txg we plan to rewind to.
12086714001SSerapheim Dimitropoulos	# But since we can't attach, detach or remove devices
12186714001SSerapheim Dimitropoulos	# while having a checkpoint, we take it after the
12286714001SSerapheim Dimitropoulos	# operation that changes the config.
12386714001SSerapheim Dimitropoulos	#
12486714001SSerapheim Dimitropoulos	log_must zpool checkpoint $TESTPOOL1
12586714001SSerapheim Dimitropoulos
1266f793812SPavel Zakharov	log_must overwrite_data $TESTPOOL1 ""
1276f793812SPavel Zakharov
1286f793812SPavel Zakharov	log_must zpool export $TESTPOOL1
1296f793812SPavel Zakharov
1306f793812SPavel Zakharov	log_must zpool import -d $DEVICE_DIR -T $txg $TESTPOOL1
1316f793812SPavel Zakharov	log_must check_pool_config $TESTPOOL1 "$poolcheck"
1326f793812SPavel Zakharov
1336f793812SPavel Zakharov	log_must verify_data_md5sums $MD5FILE
1346f793812SPavel Zakharov
1356f793812SPavel Zakharov	# Cleanup
1366f793812SPavel Zakharov	log_must zpool destroy $TESTPOOL1
1376f793812SPavel Zakharov	if [[ -n $pathstochange ]]; then
1386f793812SPavel Zakharov		for dev in $pathstochange; do
1396f793812SPavel Zakharov			log_must mv "${dev}_new" $dev
1406f793812SPavel Zakharov		done
1416f793812SPavel Zakharov	fi
1426f793812SPavel Zakharov	# Fast way to clear vdev labels
1436f793812SPavel Zakharov	log_must zpool create -f $TESTPOOL2 $VDEV0 $VDEV1 $VDEV2 $VDEV3 $VDEV4
1446f793812SPavel Zakharov	log_must zpool destroy $TESTPOOL2
1456f793812SPavel Zakharov
1466f793812SPavel Zakharov	log_note ""
1476f793812SPavel Zakharov}
1486f793812SPavel Zakharov
1496f793812SPavel Zakharovfunction test_add_vdevs
1506f793812SPavel Zakharov{
1516f793812SPavel Zakharov	typeset poolcreate="$1"
1526f793812SPavel Zakharov	typeset addvdevs="$2"
1536f793812SPavel Zakharov
1546f793812SPavel Zakharov	log_note "$0: pool '$poolcreate', add $addvdevs."
1556f793812SPavel Zakharov
1566f793812SPavel Zakharov	test_common "$poolcreate" "$addvdevs"
1576f793812SPavel Zakharov}
1586f793812SPavel Zakharov
1596f793812SPavel Zakharovfunction test_attach_vdev
1606f793812SPavel Zakharov{
1616f793812SPavel Zakharov	typeset poolcreate="$1"
1626f793812SPavel Zakharov	typeset attachto="$2"
1636f793812SPavel Zakharov	typeset attachvdev="$3"
1646f793812SPavel Zakharov
1656f793812SPavel Zakharov	log_note "$0: pool '$poolcreate', attach $attachvdev to $attachto."
1666f793812SPavel Zakharov
1676f793812SPavel Zakharov	test_common "$poolcreate" "" "$attachto $attachvdev"
1686f793812SPavel Zakharov}
1696f793812SPavel Zakharov
1706f793812SPavel Zakharovfunction test_detach_vdev
1716f793812SPavel Zakharov{
1726f793812SPavel Zakharov	typeset poolcreate="$1"
1736f793812SPavel Zakharov	typeset detachvdev="$2"
1746f793812SPavel Zakharov
1756f793812SPavel Zakharov	log_note "$0: pool '$poolcreate', detach $detachvdev."
1766f793812SPavel Zakharov
1776f793812SPavel Zakharov	test_common "$poolcreate" "" "" "$detachvdev"
1786f793812SPavel Zakharov}
1796f793812SPavel Zakharov
1806f793812SPavel Zakharovfunction test_attach_detach_vdev
1816f793812SPavel Zakharov{
1826f793812SPavel Zakharov	typeset poolcreate="$1"
1836f793812SPavel Zakharov	typeset attachto="$2"
1846f793812SPavel Zakharov	typeset attachvdev="$3"
1856f793812SPavel Zakharov	typeset detachvdev="$4"
1866f793812SPavel Zakharov
1876f793812SPavel Zakharov	log_note "$0: pool '$poolcreate', attach $attachvdev to $attachto," \
1886f793812SPavel Zakharov	    "then detach $detachvdev."
1896f793812SPavel Zakharov
1906f793812SPavel Zakharov	test_common "$poolcreate" "" "$attachto $attachvdev" "$detachvdev"
1916f793812SPavel Zakharov}
1926f793812SPavel Zakharov
1936f793812SPavel Zakharovfunction test_remove_vdev
1946f793812SPavel Zakharov{
1956f793812SPavel Zakharov	typeset poolcreate="$1"
1966f793812SPavel Zakharov	typeset removevdev="$2"
1976f793812SPavel Zakharov	typeset finalpool="$3"
1986f793812SPavel Zakharov
1996f793812SPavel Zakharov	log_note "$0: pool '$poolcreate', remove $removevdev."
2006f793812SPavel Zakharov
2016f793812SPavel Zakharov	test_common "$poolcreate" "" "" "" "$removevdev" "$finalpool"
2026f793812SPavel Zakharov}
2036f793812SPavel Zakharov
2046f793812SPavel Zakharov# Make the devices bigger to reduce chances of overwriting MOS metadata.
2056f793812SPavel Zakharovincrease_device_sizes $(( FILE_SIZE * 4 ))
2066f793812SPavel Zakharov
20786714001SSerapheim Dimitropoulos# Increase the number of metaslabs for small pools temporarily to
20886714001SSerapheim Dimitropoulos# reduce the chance of reusing a metaslab that holds old MOS metadata.
209a0b03b16SSerapheim Dimitropouloslog_must mdb_ctf_set_int zfs_vdev_min_ms_count 0t150
21086714001SSerapheim Dimitropoulos
211f78cdc34SPaul Dagnelie# Decrease the number of allocators for pools created during this test,
212f78cdc34SPaul Dagnelie# to increase the odds that metadata survives from old txgs.
213f78cdc34SPaul Dagnelielog_must mdb_ctf_set_int spa_allocators 0t1
214f78cdc34SPaul Dagnelie
2156f793812SPavel Zakharov# Part of the rewind test is to see how it reacts to path changes
2166f793812SPavel Zakharovtypeset pathstochange="$VDEV0 $VDEV1 $VDEV2 $VDEV3"
2176f793812SPavel Zakharov
2186f793812SPavel Zakharovlog_note " == test rewind after device addition == "
2196f793812SPavel Zakharov
2206f793812SPavel Zakharovtest_add_vdevs "$VDEV0" "$VDEV1"
2216f793812SPavel Zakharovtest_add_vdevs "$VDEV0 $VDEV1" "$VDEV2"
2226f793812SPavel Zakharovtest_add_vdevs "$VDEV0" "$VDEV1 $VDEV2"
2236f793812SPavel Zakharovtest_add_vdevs "mirror $VDEV0 $VDEV1" "mirror $VDEV2 $VDEV3"
2246f793812SPavel Zakharovtest_add_vdevs "$VDEV0" "raidz $VDEV1 $VDEV2 $VDEV3"
2256f793812SPavel Zakharovtest_add_vdevs "$VDEV0" "log $VDEV1"
2266f793812SPavel Zakharovtest_add_vdevs "$VDEV0 log $VDEV1" "$VDEV2"
2276f793812SPavel Zakharov
2286f793812SPavel Zakharovlog_note " == test rewind after device attach == "
2296f793812SPavel Zakharov
2306f793812SPavel Zakharovtest_attach_vdev "$VDEV0" "$VDEV0" "$VDEV1"
2316f793812SPavel Zakharovtest_attach_vdev "mirror $VDEV0 $VDEV1" "$VDEV0" "$VDEV2"
2326f793812SPavel Zakharovtest_attach_vdev "$VDEV0 $VDEV1" "$VDEV0" "$VDEV2"
2336f793812SPavel Zakharov
2346f793812SPavel Zakharovlog_note " == test rewind after device removal == "
2356f793812SPavel Zakharov
2366f793812SPavel Zakharov# Once we remove a device it will be overlooked in the device scan, so we must
2376f793812SPavel Zakharov# preserve its original path
2386f793812SPavel Zakharovpathstochange="$VDEV0 $VDEV2"
2396f793812SPavel Zakharovtest_remove_vdev "$VDEV0 $VDEV1 $VDEV2" "$VDEV1" "$VDEV0 $VDEV2"
2406f793812SPavel Zakharov
2416f793812SPavel Zakharov#
2426f793812SPavel Zakharov# Path change and detach are incompatible. Detach changes the guid of the vdev
2436f793812SPavel Zakharov# so we have no direct way to link the new path to an existing vdev.
2446f793812SPavel Zakharov#
2456f793812SPavel Zakharovpathstochange=""
2466f793812SPavel Zakharov
2476f793812SPavel Zakharovlog_note " == test rewind after device detach == "
2486f793812SPavel Zakharov
2496f793812SPavel Zakharovtest_detach_vdev "mirror $VDEV0 $VDEV1" "$VDEV1"
2506f793812SPavel Zakharovtest_detach_vdev "mirror $VDEV0 $VDEV1 mirror $VDEV2 $VDEV3" "$VDEV1"
2516f793812SPavel Zakharovtest_detach_vdev "$VDEV0 log mirror $VDEV1 $VDEV2" "$VDEV2"
2526f793812SPavel Zakharov
2536f793812SPavel Zakharovlog_note " == test rewind after device attach followed by device detach == "
2546f793812SPavel Zakharov
2556f793812SPavel Zakharov#
2566f793812SPavel Zakharov# We need to disable vdev validation since once we detach VDEV1, VDEV0 will
2576f793812SPavel Zakharov# inherit the mirror tvd's guid and lose its original guid.
2586f793812SPavel Zakharov#
2596f793812SPavel Zakharovset_vdev_validate_skip 1
2606f793812SPavel Zakharovtest_attach_detach_vdev "$VDEV0" "$VDEV0" "$VDEV1" "$VDEV1"
2616f793812SPavel Zakharovset_vdev_validate_skip 0
2626f793812SPavel Zakharov
2636f793812SPavel Zakharovlog_pass "zpool import rewind after configuration change passed."
264