4 # The contents of this file are subject to the terms of the
5 # Common Development and Distribution License (the "License").
6 # You may not use this file except in compliance with the License.
8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 # or http://www.opensolaris.org/os/licensing.
10 # See the License for the specific language governing permissions
11 # and limitations under the License.
13 # When distributing Covered Code, include this CDDL HEADER in each
14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 # If applicable, add the following below this CDDL HEADER, with the
16 # fields enclosed by brackets "[]" replaced with your own identifying
17 # information: Portions Copyright [yyyy] [name of copyright owner]
23 # Copyright (c) 2018 by Lawrence Livermore National Security, LLC.
24 # Copyright (c) 2020 by Delphix. All rights reserved.
28 # Verify that duplicate I/O ereport errors are not posted
31 # 1. Create a mirror pool
32 # 2. Inject duplicate read/write IO errors and checksum errors
33 # 3. Verify there are no duplicate events being posted
36 . $STF_SUITE/include/libtest.shlib
38 verify_runnable "both"
40 MOUNTDIR=$TEST_BASE_DIR/mount
41 FILEPATH=$MOUNTDIR/badfile
42 VDEV1=$TEST_BASE_DIR/vfile1
43 VDEV2=$TEST_BASE_DIR/vfile2
46 OLD_LEN_MAX=$(get_tunable ZEVENT_LEN_MAX)
47 RETAIN_MAX=$(get_tunable ZEVENT_RETAIN_MAX)
49 EREPORTS="$STF_SUITE/tests/functional/cli_root/zpool_events/ereports"
55 log_must set_tunable64 ZEVENT_LEN_MAX $OLD_LEN_MAX
57 log_must zinject -c all
58 if poolexists $POOL ; then
61 log_must rm -f $VDEV1 $VDEV2
64 log_assert "Duplicate I/O ereport errors are not posted"
65 log_note "zevent retain max setting: $RETAIN_MAX"
69 # Set our threshold high to avoid dropping events.
70 set_tunable64 ZEVENT_LEN_MAX 20000
72 log_must truncate -s $MINVDEVSIZE $VDEV1 $VDEV2
73 log_must mkdir -p $MOUNTDIR
76 # $1: test type - corrupt (checksum error), io
83 log_note "Testing $ERR $RW ereports"
84 log_must zpool create -f -m $MOUNTDIR -o failmode=continue $POOL mirror $VDEV1 $VDEV2
85 log_must zpool events -c
86 log_must zfs set compression=off $POOL
88 if [ "$RW" == "read" ] ; then
89 log_must mkfile $FILESIZE $FILEPATH
91 # unmount and mount filesystems to purge file from ARC
92 # to force reads to go through error inject handler
93 log_must zfs unmount $POOL
94 log_must zfs mount $POOL
96 # all reads from this file get an error
97 if [ "$ERR" == "corrupt" ] ; then
98 log_must zinject -a -t data -e checksum -T read $FILEPATH
100 log_must zinject -a -t data -e io -T read $FILEPATH
103 # Read the file a few times to generate some
104 # duplicate errors of the same blocks
105 # shellcheck disable=SC2034
107 dd if=$FILEPATH of=/dev/null bs=128K > /dev/null 2>&1
109 log_must zinject -c all
112 log_must zinject -d $VDEV1 -e $ERR -T $RW -f 100 $POOL
114 if [ "$RW" == "write" ] ; then
115 log_must mkfile $FILESIZE $FILEPATH
116 log_must zpool sync $POOL
118 # scrub twice to generate some duplicates
119 log_must zpool scrub $POOL
120 log_must zpool wait -t scrub $POOL
121 log_must zpool scrub $POOL
122 log_must zpool wait -t scrub $POOL
125 log_must zinject -c all
127 # Wait for the pool to settle down and finish resilvering (if
128 # necessary). We want the errors to stop incrementing before we
129 # check for duplicates.
130 zpool wait -t resilver $POOL
132 ereports="$($EREPORTS | sort)"
133 actual=$(echo "$ereports" | wc -l)
134 unique=$(echo "$ereports" | uniq | wc -l)
135 log_note "$actual total $ERR $RW ereports where $unique were unique"
137 if [ $actual -gt $unique ] ; then
138 log_note "UNEXPECTED -- $((actual-unique)) duplicate $ERR $RW ereports"
143 log_must zpool destroy $POOL
146 do_dup_test "corrupt" "read"
147 do_dup_test "io" "read"
148 do_dup_test "io" "write"
151 log_fail "FAILED -- Duplicate I/O ereport errors encountered"
153 log_pass "Duplicate I/O ereport errors are not posted"