]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_events/zpool_events_duplicates.ksh
MFV 2.0-rc2
[FreeBSD/FreeBSD.git] / sys / contrib / openzfs / tests / zfs-tests / tests / functional / cli_root / zpool_events / zpool_events_duplicates.ksh
1 #!/bin/ksh -p
2 # CDDL HEADER START
3 #
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.
7 #
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.
12 #
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]
18 #
19 # CDDL HEADER END
20 #
21
22 #
23 # Copyright (c) 2018 by Lawrence Livermore National Security, LLC.
24 # Copyright (c) 2020 by Delphix. All rights reserved.
25 #
26
27 # DESCRIPTION:
28 #       Verify that duplicate I/O ereport errors are not posted
29 #
30 # STRATEGY:
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
34 #
35
36 . $STF_SUITE/include/libtest.shlib
37
38 verify_runnable "both"
39
40 MOUNTDIR=$TEST_BASE_DIR/mount
41 FILEPATH=$MOUNTDIR/badfile
42 VDEV1=$TEST_BASE_DIR/vfile1
43 VDEV2=$TEST_BASE_DIR/vfile2
44 POOL=error_pool
45 FILESIZE="10M"
46 OLD_LEN_MAX=$(get_tunable ZEVENT_LEN_MAX)
47 RETAIN_MAX=$(get_tunable ZEVENT_RETAIN_MAX)
48
49 EREPORTS="$STF_SUITE/tests/functional/cli_root/zpool_events/ereports"
50
51 duplicates=false
52
53 function cleanup
54 {
55         log_must set_tunable64 ZEVENT_LEN_MAX $OLD_LEN_MAX
56
57         log_must zinject -c all
58         if poolexists $POOL ; then
59                 destroy_pool $POOL
60         fi
61         log_must rm -f $VDEV1 $VDEV2
62 }
63
64 log_assert "Duplicate I/O ereport errors are not posted"
65 log_note "zevent retain max setting: $RETAIN_MAX"
66
67 log_onexit cleanup
68
69 # Set our threshold high to avoid dropping events.
70 set_tunable64 ZEVENT_LEN_MAX 20000
71
72 log_must truncate -s $MINVDEVSIZE $VDEV1 $VDEV2
73 log_must mkdir -p $MOUNTDIR
74
75 #
76 # $1: test type - corrupt (checksum error), io
77 # $2: read, write
78 function do_dup_test
79 {
80         ERR=$1
81         RW=$2
82
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
87
88         if [ "$RW" == "read" ] ; then
89                 log_must mkfile $FILESIZE $FILEPATH
90
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
95
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
99                 else
100                         log_must zinject -a -t data -e io -T read $FILEPATH
101                 fi
102
103                 # Read the file a few times to generate some
104                 # duplicate errors of the same blocks
105                 # shellcheck disable=SC2034
106                 for i in {1..15}; do
107                         dd if=$FILEPATH of=/dev/null bs=128K > /dev/null 2>&1
108                 done
109                 log_must zinject -c all
110         fi
111
112         log_must zinject -d $VDEV1 -e $ERR -T $RW -f 100 $POOL
113
114         if [ "$RW" == "write" ] ; then
115                 log_must mkfile $FILESIZE $FILEPATH
116                 log_must zpool sync $POOL
117         else
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
123         fi
124
125         log_must zinject -c all
126
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
131
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"
136
137         if [ $actual -gt $unique ] ; then
138                 log_note "UNEXPECTED -- $((actual-unique)) duplicate $ERR $RW ereports"
139                 echo "$ereports"
140                 duplicates=true
141         fi
142
143         log_must zpool destroy $POOL
144 }
145
146 do_dup_test "corrupt" "read"
147 do_dup_test "io" "read"
148 do_dup_test "io" "write"
149
150 if $duplicates; then
151         log_fail "FAILED -- Duplicate I/O ereport errors encountered"
152 else
153         log_pass "Duplicate I/O ereport errors are not posted"
154 fi
155