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