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# 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. Overwrite the files. 32# 8. Export the pool. 33# 9. Verify that we can rewind the pool to the noted txg. 34# 10. Verify that the files are readable and retain their old data. 35# 36# DISCLAIMER: 37# This test can fail since nothing guarantees that old MOS blocks aren't 38# overwritten. Snapshots protect datasets and data files but not the MOS. 39# sync_some_data_a_few_times interleaves file data and MOS data for a few 40# txgs, thus increasing the odds that some txgs will have their MOS data 41# left untouched. 42# 43 44verify_runnable "global" 45 46function custom_cleanup 47{ 48 set_vdev_validate_skip 0 49 cleanup 50} 51 52log_onexit custom_cleanup 53 54function test_common 55{ 56 typeset poolcreate="$1" 57 typeset addvdevs="$2" 58 typeset attachargs="${3:-}" 59 typeset detachvdev="${4:-}" 60 typeset removevdev="${5:-}" 61 typeset finalpool="${6:-}" 62 63 typeset poolcheck="$poolcreate" 64 65 log_must zpool create $TESTPOOL1 $poolcreate 66 67 log_must generate_data $TESTPOOL1 $MD5FILE 68 69 # syncing a few times while writing new data increases the odds that MOS 70 # metadata for some of the txgs will survive 71 log_must sync_some_data_a_few_times $TESTPOOL1 72 typeset txg 73 txg=$(get_last_txg_synced $TESTPOOL1) 74 log_must zfs snapshot -r $TESTPOOL1@snap1 75 76 # 77 # Perform config change operations 78 # 79 if [[ -n $addvdev ]]; then 80 log_must zpool add -f $TESTPOOL1 $addvdev 81 fi 82 if [[ -n $attachargs ]]; then 83 log_must zpool attach $TESTPOOL1 $attachargs 84 fi 85 if [[ -n $detachvdev ]]; then 86 log_must zpool detach $TESTPOOL1 $detachvdev 87 fi 88 if [[ -n $removevdev ]]; then 89 [[ -z $finalpool ]] && 90 log_fail "Must provide final pool status!" 91 log_must zpool remove $TESTPOOL1 $removevdev 92 log_must wait_for_pool_config $TESTPOOL1 "$finalpool" 93 fi 94 if [[ -n $pathstochange ]]; then 95 # 96 # Change device paths and re-import pool to update labels 97 # 98 sudo zpool export $TESTPOOL1 99 for dev in $pathstochange; do 100 log_must mv $dev "${dev}_new" 101 poolcheck=$(echo "$poolcheck" | \ 102 sed "s:$dev:${dev}_new:g") 103 done 104 sudo zpool import -d $DEVICE_DIR $TESTPOOL1 105 fi 106 107 log_must overwrite_data $TESTPOOL1 "" 108 109 log_must zpool export $TESTPOOL1 110 111 log_must zpool import -d $DEVICE_DIR -T $txg $TESTPOOL1 112 log_must check_pool_config $TESTPOOL1 "$poolcheck" 113 114 log_must verify_data_md5sums $MD5FILE 115 116 # Cleanup 117 log_must zpool destroy $TESTPOOL1 118 if [[ -n $pathstochange ]]; then 119 for dev in $pathstochange; do 120 log_must mv "${dev}_new" $dev 121 done 122 fi 123 # Fast way to clear vdev labels 124 log_must zpool create -f $TESTPOOL2 $VDEV0 $VDEV1 $VDEV2 $VDEV3 $VDEV4 125 log_must zpool destroy $TESTPOOL2 126 127 log_note "" 128} 129 130function test_add_vdevs 131{ 132 typeset poolcreate="$1" 133 typeset addvdevs="$2" 134 135 log_note "$0: pool '$poolcreate', add $addvdevs." 136 137 test_common "$poolcreate" "$addvdevs" 138} 139 140function test_attach_vdev 141{ 142 typeset poolcreate="$1" 143 typeset attachto="$2" 144 typeset attachvdev="$3" 145 146 log_note "$0: pool '$poolcreate', attach $attachvdev to $attachto." 147 148 test_common "$poolcreate" "" "$attachto $attachvdev" 149} 150 151function test_detach_vdev 152{ 153 typeset poolcreate="$1" 154 typeset detachvdev="$2" 155 156 log_note "$0: pool '$poolcreate', detach $detachvdev." 157 158 test_common "$poolcreate" "" "" "$detachvdev" 159} 160 161function test_attach_detach_vdev 162{ 163 typeset poolcreate="$1" 164 typeset attachto="$2" 165 typeset attachvdev="$3" 166 typeset detachvdev="$4" 167 168 log_note "$0: pool '$poolcreate', attach $attachvdev to $attachto," \ 169 "then detach $detachvdev." 170 171 test_common "$poolcreate" "" "$attachto $attachvdev" "$detachvdev" 172} 173 174function test_remove_vdev 175{ 176 typeset poolcreate="$1" 177 typeset removevdev="$2" 178 typeset finalpool="$3" 179 180 log_note "$0: pool '$poolcreate', remove $removevdev." 181 182 test_common "$poolcreate" "" "" "" "$removevdev" "$finalpool" 183} 184 185# Make the devices bigger to reduce chances of overwriting MOS metadata. 186increase_device_sizes $(( FILE_SIZE * 4 )) 187 188# Part of the rewind test is to see how it reacts to path changes 189typeset pathstochange="$VDEV0 $VDEV1 $VDEV2 $VDEV3" 190 191log_note " == test rewind after device addition == " 192 193test_add_vdevs "$VDEV0" "$VDEV1" 194test_add_vdevs "$VDEV0 $VDEV1" "$VDEV2" 195test_add_vdevs "$VDEV0" "$VDEV1 $VDEV2" 196test_add_vdevs "mirror $VDEV0 $VDEV1" "mirror $VDEV2 $VDEV3" 197test_add_vdevs "$VDEV0" "raidz $VDEV1 $VDEV2 $VDEV3" 198test_add_vdevs "$VDEV0" "log $VDEV1" 199test_add_vdevs "$VDEV0 log $VDEV1" "$VDEV2" 200 201log_note " == test rewind after device attach == " 202 203test_attach_vdev "$VDEV0" "$VDEV0" "$VDEV1" 204test_attach_vdev "mirror $VDEV0 $VDEV1" "$VDEV0" "$VDEV2" 205test_attach_vdev "$VDEV0 $VDEV1" "$VDEV0" "$VDEV2" 206 207log_note " == test rewind after device removal == " 208 209# Once we remove a device it will be overlooked in the device scan, so we must 210# preserve its original path 211pathstochange="$VDEV0 $VDEV2" 212test_remove_vdev "$VDEV0 $VDEV1 $VDEV2" "$VDEV1" "$VDEV0 $VDEV2" 213 214# 215# Path change and detach are incompatible. Detach changes the guid of the vdev 216# so we have no direct way to link the new path to an existing vdev. 217# 218pathstochange="" 219 220log_note " == test rewind after device detach == " 221 222test_detach_vdev "mirror $VDEV0 $VDEV1" "$VDEV1" 223test_detach_vdev "mirror $VDEV0 $VDEV1 mirror $VDEV2 $VDEV3" "$VDEV1" 224test_detach_vdev "$VDEV0 log mirror $VDEV1 $VDEV2" "$VDEV2" 225 226log_note " == test rewind after device attach followed by device detach == " 227 228# 229# We need to disable vdev validation since once we detach VDEV1, VDEV0 will 230# inherit the mirror tvd's guid and lose its original guid. 231# 232set_vdev_validate_skip 1 233test_attach_detach_vdev "$VDEV0" "$VDEV0" "$VDEV1" "$VDEV1" 234set_vdev_validate_skip 0 235 236log_pass "zpool import rewind after configuration change passed." 237