1# vim: filetype=sh 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or http://www.opensolaris.org/os/licensing. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22 23# $FreeBSD$ 24 25# 26# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 27# Use is subject to license terms. 28# 29# ident "@(#)zinject.kshlib 1.6 09/06/22 SMI" 30# 31 32. $STF_SUITE/include/libtest.kshlib 33. $STF_SUITE/tests/cli_root/zfs_set/zfs_set_common.kshlib 34. $STF_SUITE/tests/cache/cache.kshlib 35 36function cleanup_env 37{ 38 inject_clear 39 poolexists $TESTPOOL && \ 40 destroy_pool $TESTPOOL 41 [[ -d $TESTDIR ]] && \ 42 log_must $RM -rf $TESTDIR 43} 44 45# 46# Inject an error into object 47# $1: data,dnode,mos,mosdir,config,bplist,spacemap,metaslab,errlog 48# $2: if $1 is data or dnode, $2 should be a file or dir. 49# otherwise, $2 should be poolname 50# $3: "io" or "checksum" 51# $4: expect return value of zinject, default is 0 52# 53function inject_fault #type, object, error, expect 54{ 55 typeset type=$1 56 typeset object=$2 57 typeset error=${3:-io} 58 typeset -i expect=${4:-0} 59 60 if (( expect == 0 )); then 61 log_must eval '$ZINJECT -t $type -e $error \ 62 -m -a -q $object > /dev/null 2>&1' 63 else 64 log_mustnot eval '$ZINJECT -t $type -e $error \ 65 -m -a -q $object > /dev/null 2>&1' 66 fi 67 $SLEEP 1 68 return 0 69} 70 71# 72# Clear all registrated handler and do scrub to keep integrity 73# 74function inject_clear 75{ 76 log_must eval '$ZINJECT -c all > /dev/null 2>&1' 77 $SLEEP 1 78 if poolexists $TESTPOOL ; then 79 while ! check_pool_status $TESTPOOL "state" "ONLINE" ; do 80 log_must $ZPOOL clear $TESTPOOL 81 $SLEEP 2 82 done 83 log_must $ZPOOL scrub $TESTPOOL 84 while ! is_pool_scrubbed $TESTPOOL && ! is_pool_resilvered $TESTPOOL ; do 85 $SLEEP 2 86 done 87 fi 88 return 0 89} 90 91# 92# Inject a fault into a particular device 93# $1: device name 94# $2: pool name 95# $3: errno, can either be 'nxio' (the default) or 'io'. 96# 97function inject_device #device, pool, errno 98{ 99 typeset device=$1 100 typeset pool=$2 101 typeset errno=$3 102 103 log_must eval '$ZINJECT -d $device -e $errno -q $pool > /dev/null 2>&1' 104 $SLEEP 1 105 return 0 106} 107 108# 109# Check if the ereport is occurred after the given timestamp 110# 111function check_ereport #timestamp, etype 112{ 113 typeset etime=$1 114 typeset ereport 115 typeset -i i=0 116 typeset -i maxtimes=20 117 118 shift 119 120 for type in $@ ; do 121 i=0 122 while (( i < maxtimes )); do 123 (( i = i + 1 )) 124 ereport=$($FMDUMP -t "$etime" -e -v -c $type | \ 125 $NAWK '(NR != 1) {print $0}') 126 if [[ -n $ereport ]]; then 127 break 128 elif (( i == maxtimes )) ; then 129 $FMDUMP -t "$etime" -e -v 130 log_fail "$type not found" 131 fi 132 $SLEEP 3 133 done 134 done 135 return 0 136} 137 138# 139# Check if the fault is occurred after the given timestamp 140# 141function check_fault #timestamp, fault_class 142{ 143 typeset after_time=$1 144 typeset ereport 145 typeset -i i=0 146 typeset -i maxtimes=20 147 148 shift 149 150 for fault in $@ ; do 151 i=0 152 while (( i < maxtimes )); do 153 (( i = i + 1 )) 154 ereport=$($FMDUMP -av -t "$after_time" | $GREP $fault) 155 if [[ -n $ereport ]]; then 156 break 157 elif (( i == maxtimes )) ; then 158 $FMDUMP -av -t "$after_time" 159 log_fail "$fault not found" 160 fi 161 $SLEEP 3 162 done 163 done 164 return 0 165} 166 167# 168# Check if 'zpool status -v' contain the permanent error as expected 169# 170function check_status #poolname, errors 171{ 172 typeset poolname=$1 173 typeset errors=$2 174 175 for err in $errors ; do 176 ereport=$($ZPOOL status -v $poolname | $GREP "$err") 177 if [[ -z $ereport ]]; then 178 $ZPOOL status -v $poolname 179 log_fail "$err not found" 180 fi 181 done 182 return 0 183} 184 185# 186# Invoke the trigger function according to the fault type corresponded 187# 188function trigger_inject #etype, object, objtype 189{ 190 typeset etype=$1 191 typeset object=$2 192 typeset objtype=$3 193 194 if [[ $etype == "bplist" ]] ; then 195 $ECHO "ZFS Fault Harness" > $object 196 fi 197 198 case $objtype in 199 dir) 200 $LS -l $object > /dev/null 2>&1 201 ;; 202 file) 203 $CAT $object > /dev/null 2>&1 204 ;; 205 esac 206} 207 208function populate_test_env #basedir #count 209{ 210 typeset basedir=$1 211 typeset -i count=$2 212 typeset -i i=1 213 214 if [[ -d $basedir ]]; then 215 log_must $RM -rf $basedir/* 216 else 217 log_must $MKDIR -p $basedir 218 fi 219 220 while (( i <= count )); do 221 $ECHO "ZFS Fault Harness" > $basedir/testfile.$i 222 $MKDIR -p $basedir/testdir.$i 223 (( i = i + 1 )) 224 done 225 226 return 0 227} 228