]>
Commit | Line | Data |
---|---|---|
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 $TESTPOOL1 | |
180 | # Wait for the completion of scrub operation | |
181 | while is_pool_scrubbing $TESTPOOL1; do | |
182 | sleep 1 | |
183 | done | |
184 | ||
185 | check_err $TESTPOOL1 && \ | |
186 | log_fail "No error generated." | |
187 | if [[ $type == "device" ]]; then | |
188 | log_must zpool clear $TESTPOOL1 $fbase.$i | |
189 | ! check_err $TESTPOOL1 $fbase.$i && \ | |
190 | log_fail "'zpool clear' fails to clear error for $fbase.$i device." | |
191 | fi | |
192 | ||
193 | if [[ $type == "pool" ]]; then | |
194 | log_must zpool clear $TESTPOOL1 | |
195 | ! check_err $TESTPOOL1 && \ | |
196 | log_fail "'zpool clear' fails to clear error for pool $TESTPOOL1." | |
197 | fi | |
198 | ||
199 | log_must zpool destroy $TESTPOOL1 | |
200 | } | |
201 | ||
202 | log_note "'zpool clear' clears leaf-device error." | |
203 | for devconf in "${poolconf[@]}"; do | |
204 | do_testing "device" $devconf | |
205 | done | |
206 | log_note "'zpool clear' clears top-level pool error." | |
207 | for devconf in "${poolconf[@]}"; do | |
208 | do_testing "pool" $devconf | |
209 | done | |
210 | ||
211 | log_pass "'zpool clear' clears pool errors as expected." |