1#!/bin/ksh -p 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# 24# Copyright 2007 Sun Microsystems, Inc. All rights reserved. 25# Use is subject to license terms. 26# 27 28# 29# Copyright (c) 2012, 2016 by Delphix. All rights reserved. 30# 31 32. $STF_SUITE/include/libtest.shlib 33. $STF_SUITE/tests/functional/cli_root/zpool_clear/zpool_clear.cfg 34 35# 36# DESCRIPTION: 37# Verify 'zpool clear' can clear pool errors. 38# 39# STRATEGY: 40# 1. Create various configuration pools 41# 2. Make errors to pool 42# 3. Use zpool clear to clear errors 43# 4. Verify the errors has been cleared. 44# 45 46verify_runnable "global" 47 48function cleanup 49{ 50 poolexists $TESTPOOL1 && \ 51 log_must zpool destroy -f $TESTPOOL1 52 53 for file in `ls $TESTDIR/file.*`; do 54 log_must rm -f $file 55 done 56} 57 58 59log_assert "Verify 'zpool clear' can clear errors of a storage pool." 60log_onexit cleanup 61 62#make raw files to create various configuration pools 63typeset -i i=0 64while (( i < 3 )); do 65 log_must mkfile $FILESIZE $TESTDIR/file.$i 66 67 (( i = i + 1 )) 68done 69 70fbase=$TESTDIR/file 71set -A poolconf "mirror $fbase.0 $fbase.1 $fbase.2" \ 72 "raidz1 $fbase.0 $fbase.1 $fbase.2" \ 73 "raidz2 $fbase.0 $fbase.1 $fbase.2" 74 75function check_err # <pool> [<vdev>] 76{ 77 typeset pool=$1 78 shift 79 if (( $# > 0 )); then 80 typeset checkvdev=$1 81 else 82 typeset checkvdev="" 83 fi 84 typeset -i errnum=0 85 typeset c_read=0 86 typeset c_write=0 87 typeset c_cksum=0 88 typeset tmpfile=/var/tmp/file.$$ 89 typeset healthstr="pool '$pool' is healthy" 90 typeset output="`zpool status -x $pool`" 91 92 [[ "$output" == "$healthstr" ]] && return $errnum 93 94 zpool status -x $pool | grep -v "^$" | grep -v "pool:" \ 95 | grep -v "state:" | grep -v "config:" \ 96 | grep -v "errors:" > $tmpfile 97 typeset line 98 typeset -i fetchbegin=1 99 while read line; do 100 if (( $fetchbegin != 0 )); then 101 echo $line | grep "NAME" >/dev/null 2>&1 102 (( $? == 0 )) && (( fetchbegin = 0 )) 103 continue 104 fi 105 106 if [[ -n $checkvdev ]]; then 107 echo $line | grep $checkvdev >/dev/null 2>&1 108 (( $? != 0 )) && continue 109 c_read=`echo $line | awk '{print $3}'` 110 c_write=`echo $line | awk '{print $4}'` 111 c_cksum=`echo $line | awk '{print $5}'` 112 if [ $c_read != 0 ] || [ $c_write != 0 ] || \ 113 [ $c_cksum != 0 ] 114 then 115 (( errnum = errnum + 1 )) 116 fi 117 break 118 fi 119 120 c_read=`echo $line | awk '{print $3}'` 121 c_write=`echo $line | awk '{print $4}'` 122 c_cksum=`echo $line | awk '{print $5}'` 123 if [ $c_read != 0 ] || [ $c_write != 0 ] || \ 124 [ $c_cksum != 0 ] 125 then 126 (( errnum = errnum + 1 )) 127 fi 128 done <$tmpfile 129 130 return $errnum 131} 132 133function do_testing #<clear type> <vdevs> 134{ 135 typeset FS=$TESTPOOL1/fs 136 typeset file=/$FS/f 137 typeset type=$1 138 shift 139 typeset vdev="$@" 140 141 log_must zpool create -f $TESTPOOL1 $vdev 142 log_must zfs create $FS 143 # 144 # Fully fill up the zfs filesystem in order to make data block errors 145 # zfs filesystem 146 # 147 typeset -i ret=0 148 typeset -i i=0 149 while true ; do 150 file_write -o create -f $file.$i -b $BLOCKSZ -c $NUM_WRITES 151 ret=$? 152 (( $ret != 0 )) && break 153 (( i = i + 1 )) 154 done 155 (( $ret != 28 )) && log_fail "file_write fails to fully fill up the $FS." 156 157 # 158 #Make errors to the testing pool by overwrite the vdev device with 159 #/usr/bin/dd command. We donot want to have a full overwrite. That 160 #may cause the system panic. So, we should skip the vdev label space. 161 # 162 (( i = $RANDOM % 3 )) 163 typeset -i wcount=0 164 typeset -i size 165 case $FILESIZE in 166 *g|*G) 167 (( size = ${FILESIZE%%[g|G]} )) 168 (( wcount = size*1024*1024 - 512 )) 169 ;; 170 *m|*M) 171 (( size = ${FILESIZE%%[m|M]} )) 172 (( wcount = size*1024 - 512 )) 173 ;; 174 *k|*K) 175 (( size = ${FILESIZE%%[k|K]} )) 176 (( wcount = size - 512 )) 177 ;; 178 *) 179 (( wcount = FILESIZE/1024 - 512 )) 180 ;; 181 esac 182 dd if=/dev/zero of=$fbase.$i seek=512 bs=1024 count=$wcount conv=notrunc \ 183 > /dev/null 2>&1 184 log_must sync 185 log_must zpool scrub $TESTPOOL1 186 # Wait for the completion of scrub operation 187 while is_pool_scrubbing $TESTPOOL1; do 188 sleep 1 189 done 190 191 check_err $TESTPOOL1 && \ 192 log_fail "No error generated." 193 if [[ $type == "device" ]]; then 194 log_must zpool clear $TESTPOOL1 $fbase.$i 195 ! check_err $TESTPOOL1 $fbase.$i && \ 196 log_fail "'zpool clear' fails to clear error for $fbase.$i device." 197 fi 198 199 if [[ $type == "pool" ]]; then 200 log_must zpool clear $TESTPOOL1 201 ! check_err $TESTPOOL1 && \ 202 log_fail "'zpool clear' fails to clear error for pool $TESTPOOL1." 203 fi 204 205 log_must zpool destroy $TESTPOOL1 206} 207 208log_note "'zpool clear' clears leaf-device error." 209for devconf in "${poolconf[@]}"; do 210 do_testing "device" $devconf 211done 212log_note "'zpool clear' clears top-level pool error." 213for devconf in "${poolconf[@]}"; do 214 do_testing "pool" $devconf 215done 216 217log_pass "'zpool clear' clears pool errors as expected." 218