1#!/bin/ksh -p 2 3# 4# CDDL HEADER START 5# 6# This file and its contents are supplied under the terms of the 7# Common Development and Distribution License ("CDDL"), version 1.0. 8# You may only use this file in accordance with the terms of version 9# 1.0 of the CDDL. 10# 11# A full copy of the text of the CDDL should have accompanied this 12# source. A copy of the CDDL is also available via the Internet at 13# http://www.illumos.org/license/CDDL. 14# 15# CDDL HEADER END 16# 17 18# 19# Copyright (c) 2020, Datto Inc. All rights reserved. 20# 21 22. $STF_SUITE/include/libtest.shlib 23. $STF_SUITE/tests/functional/replacement/replacement.cfg 24 25# 26# DESCRIPTION: 27# Testing resilver completes when scan errors are encountered, but relevant 28# DTL's have not been lost. 29# 30# STRATEGY: 31# 1. Create a pool (1k recordsize) 32# 2. Create a 32m file (32k records) 33# 3. Inject an error halfway through the file 34# 4. Start a resilver, ensure the error is triggered and that the resilver 35# does not restart after finishing 36# 37# NB: use legacy scanning to ensure scan of specific block causes error 38# 39 40function cleanup 41{ 42 log_must zinject -c all 43 destroy_pool $TESTPOOL1 44 rm -f ${VDEV_FILES[@]} $SPARE_VDEV_FILE 45 log_must set_tunable32 SCAN_LEGACY $ORIG_SCAN_LEGACY 46} 47 48log_assert "Check for resilver restarts caused by scan errors" 49 50ORIG_SCAN_LEGACY=$(get_tunable SCAN_LEGACY) 51 52log_onexit cleanup 53 54# use legacy scan to ensure injected error will be triggered 55log_must set_tunable32 SCAN_LEGACY 1 56 57 # create the pool and a 32M file (32k blocks) 58log_must truncate -s $VDEV_FILE_SIZE ${VDEV_FILES[0]} $SPARE_VDEV_FILE 59log_must zpool create -f -O recordsize=1k $TESTPOOL1 ${VDEV_FILES[0]} 60log_must eval "dd if=/dev/urandom of=/$TESTPOOL1/file bs=1M count=32 2>/dev/null" 61 62# determine objset/object 63objset=$(zdb -d $TESTPOOL1/ | sed -ne 's/.*ID \([0-9]*\).*/\1/p') 64object=$(ls -i /$TESTPOOL1/file | awk '{print $1}') 65 66# inject event to cause error during resilver 67log_must zinject -b $(printf "%x:%x:0:3fff" $objset $object) $TESTPOOL1 68 69# clear events and start resilver 70log_must zpool events -c 71log_must zpool attach $TESTPOOL1 ${VDEV_FILES[0]} $SPARE_VDEV_FILE 72 73log_note "waiting for read errors to start showing up" 74for iter in {0..59} 75do 76 sync_pool $TESTPOOL1 77 err=$(zpool status $TESTPOOL1 | awk -v dev=${VDEV_FILES[0]} '$0 ~ dev {print $3}') 78 (( $err > 0 )) && break 79 sleep 1 80done 81 82(( $err == 0 )) && log_fail "Unable to induce errors in resilver" 83 84log_note "waiting for resilver to finish" 85for iter in {0..59} 86do 87 finish=$(zpool events | grep -cF "sysevent.fs.zfs.resilver_finish") 88 (( $finish > 0 )) && break 89 sleep 1 90done 91 92(( $finish == 0 )) && log_fail "resilver took too long to finish" 93 94# wait a few syncs to ensure that zfs does not restart the resilver 95sync_pool $TESTPOOL1 96sync_pool $TESTPOOL1 97 98# check if resilver was restarted 99start=$(zpool events | grep -cF "sysevent.fs.zfs.resilver_start") 100(( $start != 1 )) && log_fail "resilver restarted unnecessarily" 101 102log_pass "Resilver did not restart unnecessarily from scan errors" 103