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 https://opensource.org/licenses/CDDL-1.0. 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) 2021 by Delphix. All rights reserved. 25# 26 27# DESCRIPTION: 28# Verify that new errors after a pool scrub are considered a duplicate 29# 30# STRATEGY: 31# 1. Create a raidz pool with a file 32# 2. Inject garbage into one of the vdevs 33# 3. Scrub the pool 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) 38# 39 40. $STF_SUITE/include/libtest.shlib 41 42verify_runnable "both" 43 44MOUNTDIR=$TEST_BASE_DIR/mount 45FILEPATH=$MOUNTDIR/target 46VDEV1=$TEST_BASE_DIR/vfile1 47VDEV2=$TEST_BASE_DIR/vfile2 48VDEV3=$TEST_BASE_DIR/vfile3 49SUPPLY=$TEST_BASE_DIR/supply 50POOL=test_pool 51FILESIZE="15M" 52DAMAGEBLKS=10 53 54OLD_LEN_MAX=$(get_tunable ZEVENT_LEN_MAX) 55RETAIN_MAX=$(get_tunable ZEVENT_RETAIN_MAX) 56OLD_CHECKSUMS=$(get_tunable CHECKSUM_EVENTS_PER_SECOND) 57 58function cleanup 59{ 60 log_must set_tunable64 CHECKSUM_EVENTS_PER_SECOND $OLD_CHECKSUMS 61 log_must set_tunable64 ZEVENT_LEN_MAX $OLD_LEN_MAX 62 63 zpool events -c 64 if poolexists $POOL ; then 65 zpool export $POOL 66 fi 67 log_must rm -fd $VDEV1 $VDEV2 $VDEV3 $SUPPLY $MOUNTDIR 68} 69 70function damage_and_repair 71{ 72 log_must zpool clear $POOL $VDEV1 73 log_must zpool events -c 74 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" 80 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" 84 else 85 log_note "$repaired repaired during scrub" 86 fi 87} 88 89function checksum_error_count 90{ 91 zpool status -p $POOL | awk -v dev=$VDEV1 '$0 ~ dev {print $5}' 92} 93 94assertion="Damage to recently repaired blocks should be reported/counted" 95log_assert "$assertion" 96log_note "zevent retain max setting: $RETAIN_MAX" 97 98log_onexit cleanup 99 100# Set our threshold high to avoid dropping events. 101set_tunable64 ZEVENT_LEN_MAX 20000 102set_tunable64 CHECKSUM_EVENTS_PER_SECOND 20000 103 104# Initialize resources for the test 105log_must truncate -s $MINVDEVSIZE $VDEV1 $VDEV2 $VDEV3 106log_must dd if=/dev/urandom of=$SUPPLY bs=1M count=$DAMAGEBLKS 107log_must mkdir -p $MOUNTDIR 108log_must zpool create -f -m $MOUNTDIR -o failmode=continue $POOL raidz $VDEV1 $VDEV2 $VDEV3 109log_must zfs set compression=off recordsize=16k $POOL 110# create a file full of zeros 111log_must mkfile -v $FILESIZE $FILEPATH 112sync_pool $POOL 113 114# run once and observe the checksum errors 115damage_and_repair 1 116errcnt=$(checksum_error_count) 117log_note "$errcnt errors observed" 118# set expectaton of at least 75% of what we observed in first pass 119(( expected = (errcnt * 75) / 100 )) 120 121# run again and we should observe new checksum errors 122damage_and_repair 2 123errcnt=$(checksum_error_count) 124 125log_must zpool destroy $POOL 126 127if (( errcnt < expected )); then 128 log_fail "FAILED -- expecting at least $expected checksum errors but only observed $errcnt" 129else 130 log_note observed $errcnt new checksum errors after a scrub 131 log_pass "$assertion" 132fi 133