]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/zfs-tests/tests/functional/cli_root/zpool_clear/zpool_clear_001_pos.ksh
Vendor import of openzfs master @ 184df27eef0abdc7ab2105b21257f753834b936b
[FreeBSD/FreeBSD.git] / tests / zfs-tests / tests / functional / cli_root / zpool_clear / zpool_clear_001_pos.ksh
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
46 verify_runnable "global"
47
48 function cleanup
49 {
50         poolexists $TESTPOOL1 && \
51                 log_must zpool destroy -f $TESTPOOL1
52
53         for file in `ls $TEST_BASE_DIR/file.*`; do
54                 log_must rm -f $file
55         done
56 }
57
58
59 log_assert "Verify 'zpool clear' can clear errors of a storage pool."
60 log_onexit cleanup
61
62 #make raw files to create various configuration pools
63 typeset -i i=0
64 while (( i < 3 )); do
65         log_must truncate -s $FILESIZE $TEST_BASE_DIR/file.$i
66
67         (( i = i + 1 ))
68 done
69
70 fbase=$TEST_BASE_DIR/file
71 set -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
75 function 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=$TEST_BASE_DIR/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
133 function 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         # Partially fill up the zfs filesystem in order to make data block
145         # errors.  It's not necessary to fill the entire filesystem.
146         #
147         avail=$(get_prop available $FS)
148         fill_mb=$(((avail / 1024 / 1024) * 25 / 100))
149         log_must dd if=/dev/urandom of=$file.$i bs=$BLOCKSZ count=$fill_mb
150
151         #
152         # Make errors to the testing pool by overwrite the vdev device with
153         # dd command. We do not want to have a full overwrite. That
154         # may cause the system panic. So, we should skip the vdev label space.
155         #
156         (( i = $RANDOM % 3 ))
157         typeset -i wcount=0
158         typeset -i size
159         case $FILESIZE in
160                 *g|*G)
161                         (( size = ${FILESIZE%%[g|G]} ))
162                         (( wcount = size*1024*1024 - 512 ))
163                         ;;
164                 *m|*M)
165                         (( size = ${FILESIZE%%[m|M]} ))
166                         (( wcount = size*1024 - 512 ))
167                         ;;
168                 *k|*K)
169                         (( size = ${FILESIZE%%[k|K]} ))
170                         (( wcount = size - 512 ))
171                         ;;
172                 *)
173                         (( wcount = FILESIZE/1024 - 512 ))
174                         ;;
175         esac
176         dd if=/dev/zero of=$fbase.$i seek=512 bs=1024 count=$wcount conv=notrunc \
177                         > /dev/null 2>&1
178         log_must sync
179         log_must zpool scrub -w $TESTPOOL1
180
181         check_err $TESTPOOL1 && \
182                 log_fail "No error generated."
183         if [[ $type == "device" ]]; then
184                 log_must zpool clear $TESTPOOL1 $fbase.$i
185                 ! check_err $TESTPOOL1 $fbase.$i && \
186                     log_fail "'zpool clear' fails to clear error for $fbase.$i device."
187         fi
188
189         if [[ $type == "pool" ]]; then
190                 log_must zpool clear $TESTPOOL1
191                 ! check_err $TESTPOOL1 && \
192                     log_fail "'zpool clear' fails to clear error for pool $TESTPOOL1."
193         fi
194
195         log_must zpool destroy $TESTPOOL1
196 }
197
198 log_note "'zpool clear' clears leaf-device error."
199 for devconf in "${poolconf[@]}"; do
200         do_testing "device" $devconf
201 done
202 log_note "'zpool clear' clears top-level pool error."
203 for devconf in "${poolconf[@]}"; do
204         do_testing "pool" $devconf
205 done
206
207 log_pass "'zpool clear' clears pool errors as expected."