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