]>
Commit | Line | Data |
---|---|---|
6bb24f4d BB |
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 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 | ||
c6ced726 BB |
48 | # See issue: https://github.com/zfsonlinux/zfs/issues/5479 |
49 | if is_kmemleak; then | |
50 | log_unsupported "Test case runs slowly when kmemleak is enabled" | |
51 | fi | |
52 | ||
6bb24f4d BB |
53 | function cleanup |
54 | { | |
55 | poolexists $TESTPOOL1 && \ | |
56 | log_must $ZPOOL destroy -f $TESTPOOL1 | |
57 | ||
58 | for file in `$LS $TESTDIR/file.*`; do | |
59 | log_must $RM -f $file | |
60 | done | |
61 | } | |
62 | ||
6bb24f4d BB |
63 | log_assert "Verify 'zpool clear' can clear errors of a storage pool." |
64 | log_onexit cleanup | |
65 | ||
66 | #make raw files to create various configuration pools | |
67 | typeset -i i=0 | |
68 | while (( i < 3 )); do | |
69 | log_must $MKFILE $FILESIZE $TESTDIR/file.$i | |
70 | ||
71 | (( i = i + 1 )) | |
72 | done | |
73 | ||
74 | fbase=$TESTDIR/file | |
75 | set -A poolconf "mirror $fbase.0 $fbase.1 $fbase.2" \ | |
76 | "raidz1 $fbase.0 $fbase.1 $fbase.2" \ | |
77 | "raidz2 $fbase.0 $fbase.1 $fbase.2" | |
78 | ||
79 | function check_err # <pool> [<vdev>] | |
80 | { | |
81 | typeset pool=$1 | |
82 | shift | |
83 | if (( $# > 0 )); then | |
84 | typeset checkvdev=$1 | |
85 | else | |
86 | typeset checkvdev="" | |
87 | fi | |
88 | typeset -i errnum=0 | |
89 | typeset c_read=0 | |
90 | typeset c_write=0 | |
91 | typeset c_cksum=0 | |
92 | typeset tmpfile=/var/tmp/file.$$ | |
93 | typeset healthstr="pool '$pool' is healthy" | |
94 | typeset output="`$ZPOOL status -x $pool`" | |
95 | ||
96 | [[ "$output" == "$healthstr" ]] && return $errnum | |
97 | ||
98 | $ZPOOL status -x $pool | $GREP -v "^$" | $GREP -v "pool:" \ | |
99 | | $GREP -v "state:" | $GREP -v "config:" \ | |
100 | | $GREP -v "errors:" > $tmpfile | |
101 | typeset line | |
102 | typeset -i fetchbegin=1 | |
103 | while read line; do | |
104 | if (( $fetchbegin != 0 )); then | |
105 | $ECHO $line | $GREP "NAME" >/dev/null 2>&1 | |
106 | (( $? == 0 )) && (( fetchbegin = 0 )) | |
107 | continue | |
108 | fi | |
109 | ||
110 | if [[ -n $checkvdev ]]; then | |
111 | $ECHO $line | $GREP $checkvdev >/dev/null 2>&1 | |
112 | (( $? != 0 )) && continue | |
113 | c_read=`$ECHO $line | $AWK '{print $3}'` | |
114 | c_write=`$ECHO $line | $AWK '{print $4}'` | |
115 | c_cksum=`$ECHO $line | $AWK '{print $5}'` | |
116 | if [ $c_read != 0 ] || [ $c_write != 0 ] || \ | |
117 | [ $c_cksum != 0 ] | |
118 | then | |
119 | (( errnum = errnum + 1 )) | |
120 | fi | |
121 | break | |
122 | fi | |
123 | ||
124 | c_read=`$ECHO $line | $AWK '{print $3}'` | |
125 | c_write=`$ECHO $line | $AWK '{print $4}'` | |
126 | c_cksum=`$ECHO $line | $AWK '{print $5}'` | |
127 | if [ $c_read != 0 ] || [ $c_write != 0 ] || \ | |
128 | [ $c_cksum != 0 ] | |
129 | then | |
130 | (( errnum = errnum + 1 )) | |
131 | fi | |
132 | done <$tmpfile | |
133 | ||
134 | return $errnum | |
135 | } | |
136 | ||
137 | function do_testing #<clear type> <vdevs> | |
138 | { | |
139 | typeset FS=$TESTPOOL1/fs | |
140 | typeset file=/$FS/f | |
141 | typeset type=$1 | |
142 | shift | |
143 | typeset vdev="$@" | |
144 | ||
145 | log_must $ZPOOL create -f $TESTPOOL1 $vdev | |
146 | log_must $ZFS create $FS | |
147 | # | |
148 | # Fully fill up the zfs filesystem in order to make data block errors | |
149 | # zfs filesystem | |
150 | # | |
151 | typeset -i ret=0 | |
152 | typeset -i i=0 | |
153 | while $TRUE ; do | |
154 | $FILE_WRITE -o create -f $file.$i -b $BLOCKSZ -c $NUM_WRITES | |
155 | ret=$? | |
156 | (( $ret != 0 )) && break | |
157 | (( i = i + 1 )) | |
158 | done | |
159 | (( $ret != 28 )) && log_fail "$FILE_WRITE fails to fully fill up the $FS." | |
160 | ||
161 | # | |
162 | #Make errors to the testing pool by overwrite the vdev device with | |
163 | #/usr/bin/dd command. We donot want to have a full overwrite. That | |
164 | #may cause the system panic. So, we should skip the vdev label space. | |
165 | # | |
166 | (( i = $RANDOM % 3 )) | |
167 | typeset -i wcount=0 | |
168 | typeset -i size | |
169 | case $FILESIZE in | |
170 | *g|*G) | |
171 | (( size = ${FILESIZE%%[g|G]} )) | |
172 | (( wcount = size*1024*1024 - 512 )) | |
173 | ;; | |
174 | *m|*M) | |
175 | (( size = ${FILESIZE%%[m|M]} )) | |
176 | (( wcount = size*1024 - 512 )) | |
177 | ;; | |
178 | *k|*K) | |
179 | (( size = ${FILESIZE%%[k|K]} )) | |
180 | (( wcount = size - 512 )) | |
181 | ;; | |
182 | *) | |
183 | (( wcount = FILESIZE/1024 - 512 )) | |
184 | ;; | |
185 | esac | |
186 | $DD if=/dev/zero of=$fbase.$i seek=512 bs=1024 count=$wcount conv=notrunc \ | |
187 | > /dev/null 2>&1 | |
188 | log_must $SYNC | |
189 | log_must $ZPOOL scrub $TESTPOOL1 | |
190 | # Wait for the completion of scrub operation | |
191 | while is_pool_scrubbing $TESTPOOL1; do | |
192 | $SLEEP 1 | |
193 | done | |
194 | ||
195 | check_err $TESTPOOL1 && \ | |
196 | log_fail "No error generated." | |
197 | if [[ $type == "device" ]]; then | |
198 | log_must $ZPOOL clear $TESTPOOL1 $fbase.$i | |
199 | ! check_err $TESTPOOL1 $fbase.$i && \ | |
200 | log_fail "'zpool clear' fails to clear error for $fbase.$i device." | |
201 | fi | |
202 | ||
203 | if [[ $type == "pool" ]]; then | |
204 | log_must $ZPOOL clear $TESTPOOL1 | |
205 | ! check_err $TESTPOOL1 && \ | |
206 | log_fail "'zpool clear' fails to clear error for pool $TESTPOOL1." | |
207 | fi | |
208 | ||
209 | log_must $ZPOOL destroy $TESTPOOL1 | |
210 | } | |
211 | ||
212 | log_note "'zpool clear' clears leaf-device error." | |
213 | for devconf in "${poolconf[@]}"; do | |
214 | do_testing "device" $devconf | |
215 | done | |
216 | log_note "'zpool clear' clears top-level pool error." | |
217 | for devconf in "${poolconf[@]}"; do | |
218 | do_testing "pool" $devconf | |
219 | done | |
220 | ||
221 | log_pass "'zpool clear' clears pool errors as expected." |