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) 2021 by Delphix. All rights reserved.
28 # Verify that new errors after a pool scrub are considered a duplicate
31 # 1. Create a raidz pool with a file
32 # 2. Inject garbage into one of the vdevs
34 # 4. Observe the checksum error counts
35 # 5. Repeat inject and pool scrub
36 # 6. Verify that second pass also produces similar errors (i.e. not
37 # treated as a duplicate)
40 .
$STF_SUITE/include
/libtest.shlib
42 verify_runnable
"both"
44 MOUNTDIR
=$TEST_BASE_DIR/mount
45 FILEPATH
=$MOUNTDIR/target
46 VDEV1
=$TEST_BASE_DIR/vfile1
47 VDEV2
=$TEST_BASE_DIR/vfile2
48 VDEV3
=$TEST_BASE_DIR/vfile3
49 SUPPLY
=$TEST_BASE_DIR/supply
54 OLD_LEN_MAX
=$
(get_tunable ZEVENT_LEN_MAX
)
55 RETAIN_MAX
=$
(get_tunable ZEVENT_RETAIN_MAX
)
56 OLD_CHECKSUMS
=$
(get_tunable CHECKSUM_EVENTS_PER_SECOND
)
60 log_must set_tunable64 CHECKSUM_EVENTS_PER_SECOND
$OLD_CHECKSUMS
61 log_must set_tunable64 ZEVENT_LEN_MAX
$OLD_LEN_MAX
64 if poolexists
$POOL ; then
67 log_must
rm -f $VDEV1 $VDEV2 $VDEV3
70 function damage_and_repair
72 log_must zpool
clear $POOL $VDEV1
73 log_must zpool events
-c
75 log_note injecting damage to
$VDEV1
76 log_must
dd conv
=notrunc
if=$SUPPLY of
=$VDEV1 bs
=1M seek
=4 count
=$DAMAGEBLKS
77 log_must zpool scrub
$POOL
78 log_must zpool
wait -t scrub
$POOL
79 log_note
"pass $1 observed $(ereports | grep -c checksum) checksum ereports"
81 repaired
=$
(zpool status
$POOL |
awk '/scan: scrub repaired/ {print $4}')
82 if [ "$repaired" == "0B" ]; then
83 log_fail
"INVALID TEST -- expected scrub to repair some blocks"
85 log_note
"$repaired repaired during scrub"
89 function checksum_error_count
91 zpool status
-p $POOL |
awk -v dev
=$VDEV1 '$0 ~ dev {print $5}'
94 assertion
="Damage to recently repaired blocks should be reported/counted"
95 log_assert
"$assertion"
96 log_note
"zevent retain max setting: $RETAIN_MAX"
100 # Set our threshold high to avoid dropping events.
101 set_tunable64 ZEVENT_LEN_MAX
20000
102 set_tunable64 CHECKSUM_EVENTS_PER_SECOND
20000
104 # Initialize resources for the test
105 log_must truncate
-s $MINVDEVSIZE $VDEV1 $VDEV2 $VDEV3
106 log_must
dd if=/dev
/urandom of
=$SUPPLY bs
=1M count
=$DAMAGEBLKS
107 log_must mkdir
-p $MOUNTDIR
108 log_must zpool create
-f -m $MOUNTDIR -o failmode
=continue $POOL raidz
$VDEV1 $VDEV2 $VDEV3
109 log_must zfs
set compression
=off recordsize
=16k
$POOL
110 # create a file full of zeros
111 log_must mkfile
-v $FILESIZE $FILEPATH
114 # run once and observe the checksum errors
116 errcnt
=$
(checksum_error_count
)
117 log_note
"$errcnt errors observed"
118 # set expectaton of at least 75% of what we observed in first pass
119 (( expected
= (errcnt
* 75) / 100 ))
121 # run again and we should observe new checksum errors
123 errcnt
=$
(checksum_error_count
)
125 log_must zpool destroy
$POOL
127 if (( errcnt
< expected
)); then
128 log_fail
"FAILED -- expecting at least $expected checksum errors but only observed $errcnt"
130 log_note observed
$errcnt new checksum errors after a scrub
131 log_pass
"$assertion"