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 38verify_runnable "both" 39 40MOUNTDIR=$TEST_BASE_DIR/mount 41FILEPATH=$MOUNTDIR/badfile 42VDEV1=$TEST_BASE_DIR/vfile1 43VDEV2=$TEST_BASE_DIR/vfile2 44POOL=error_pool 45FILESIZE="10M" 46OLD_LEN_MAX=$(get_tunable ZEVENT_LEN_MAX) 47RETAIN_MAX=$(get_tunable ZEVENT_RETAIN_MAX) 48 49EREPORTS="$STF_SUITE/tests/functional/cli_root/zpool_events/ereports" 50 51duplicates=false 52 53function 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 64log_assert "Duplicate I/O ereport errors are not posted" 65log_note "zevent retain max setting: $RETAIN_MAX" 66 67log_onexit cleanup 68 69# Set our threshold high to avoid dropping events. 70set_tunable64 ZEVENT_LEN_MAX 20000 71 72log_must truncate -s $MINVDEVSIZE $VDEV1 $VDEV2 73log_must mkdir -p $MOUNTDIR 74 75# 76# $1: test type - corrupt (checksum error), io 77# $2: read, write 78function 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 for _ in {1..15}; do 106 dd if=$FILEPATH of=/dev/null bs=128K > /dev/null 2>&1 107 done 108 log_must zinject -c all 109 fi 110 111 log_must zinject -d $VDEV1 -e $ERR -T $RW -f 100 $POOL 112 113 if [ "$RW" == "write" ] ; then 114 log_must mkfile $FILESIZE $FILEPATH 115 sync_pool $POOL 116 fi 117 118 log_must zinject -c all 119 120 ereports="$($EREPORTS | sort)" 121 actual=$(echo "$ereports" | wc -l) 122 unique=$(echo "$ereports" | uniq | wc -l) 123 log_note "$actual total $ERR $RW ereports where $unique were unique" 124 125 if [ $actual -gt $unique ] ; then 126 log_note "UNEXPECTED -- $((actual-unique)) duplicate $ERR $RW ereports" 127 echo "$ereports" 128 duplicates=true 129 fi 130 131 log_must zpool destroy $POOL 132} 133 134do_dup_test "corrupt" "read" 135do_dup_test "io" "read" 136do_dup_test "io" "write" 137 138if $duplicates; then 139 log_fail "FAILED -- Duplicate I/O ereport errors encountered" 140else 141 log_pass "Duplicate I/O ereport errors are not posted" 142fi 143 144