4 # The contents of this file are subject to the terms of the
5 # Common Development and Distribution License (the "License").
6 # You may not use this file except in compliance with the License.
8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 # or http://www.opensolaris.org/os/licensing.
10 # See the License for the specific language governing permissions
11 # and limitations under the License.
13 # When distributing Covered Code, include this CDDL HEADER in each
14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 # If applicable, add the following below this CDDL HEADER, with the
16 # fields enclosed by brackets "[]" replaced with your own identifying
17 # information: Portions Copyright [yyyy] [name of copyright owner]
23 # Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 # Use is subject to license terms.
28 # Copyright (c) 2013, 2016 by Delphix. All rights reserved.
31 . $STF_SUITE/include/libtest.shlib
32 . $STF_SUITE/tests/functional/redundancy/redundancy.cfg
36 if poolexists $TESTPOOL; then
37 destroy_pool $TESTPOOL
40 for dir in $TESTDIR $BASEDIR; do
41 if [[ -d $dir ]]; then
48 # Get random number between min and max number.
60 ((value = RANDOM % (max + 1)))
61 if ((value >= min)); then
70 # Record the directories construction and checksum all the files which reside
71 # within the specified pool
73 # $1 The specified pool
74 # $2 The file which save the record.
81 [[ -z $pool ]] && log_fail "No specified pool."
82 [[ -f $recordfile ]] && log_must rm -f $recordfile
85 mntpnt=$(get_prop mountpoint $pool)
86 log_must eval "du -a $mntpnt > $recordfile 2>&1"
88 # When the data was damaged, checksum is failing and return 1
89 # So, will not use log_must
91 find $mntpnt -type f -exec cksum {} + >> $recordfile 2>&1
95 # Create test pool and fill with files and directories.
99 # $3 virtual devices number
101 function setup_test_env
105 typeset -i vdev_cnt=$3
109 while (( i < vdev_cnt )); do
110 vdevs="$vdevs $BASEDIR/vdev$i"
114 if [[ ! -d $BASEDIR ]]; then
115 log_must mkdir $BASEDIR
118 if poolexists $pool ; then
122 log_must mkfile $MINVDEVSIZE $vdevs
124 log_must zpool create -m $TESTDIR $pool $keyword $vdevs
126 log_note "Filling up the filesystem ..."
129 typeset file=$TESTDIR/file
131 file_write -o create -f $file.$i \
132 -b $BLOCKSZ -c $NUM_WRITES
134 (( $ret != 0 )) && break
137 (($ret != 28 )) && log_note "file_write return value($ret) is unexpected."
139 record_data $TESTPOOL $PRE_RECORD_FILE
143 # Check pool status is healthy
151 typeset healthy_output="pool '$pool' is healthy"
152 typeset real_output=$(zpool status -x $pool)
154 if [[ "$real_output" == "$healthy_output" ]]; then
158 zpool status -x $pool | grep "state:" | \
159 grep "FAULTED" >/dev/null 2>&1
161 (( $ret == 0 )) && return 1
164 l_scan=$(zpool status -x $pool | grep "scan:")
165 l_scan=${l_scan##*"with"}
166 errnum=$(echo $l_scan | awk '{print $1}')
173 # Check pool data is valid
177 function is_data_valid
181 record_data $pool $PST_RECORD_FILE
182 if ! diff $PRE_RECORD_FILE $PST_RECORD_FILE > /dev/null 2>&1; then
190 # Get the specified count devices name
195 function get_vdevs #pool cnt
200 typeset all_devs=$(zpool iostat -v $pool | awk '{print $1}'| \
201 egrep -v "^pool$|^capacity$|^mirror$|^raidz1$|^raidz2$|---" | \
202 egrep -v "/old$|^$pool$")
205 while ((i < cnt)); do
206 typeset dev=$(echo $all_devs | awk '{print $1}')
207 eval all_devs=\${all_devs##*$dev}
217 # Create and replace the same name virtual device files
220 # $2-n virtual device files
222 function replace_missing_devs
229 log_must gnudd if=/dev/zero of=$vdev \
230 bs=1024k count=$(($MINDEVSIZE / (1024 * 1024))) \
232 log_must zpool replace -wf $pool $vdev $vdev
237 # Damage the pool's virtual device files.
240 # $2 Failing devices count
241 # $3 damage vdevs method, if not null, we keep
242 # the label for the vdevs
250 typeset -i bs_count=$((64 * 1024))
252 vdevs=$(get_vdevs $pool $cnt)
254 if [[ -n $label ]]; then
255 for dev in $vdevs; do
256 dd if=/dev/zero of=$dev seek=512 bs=1024 \
257 count=$bs_count conv=notrunc >/dev/null 2>&1
260 for dev in $vdevs; do
261 dd if=/dev/zero of=$dev bs=1024 count=$bs_count \
262 conv=notrunc >/dev/null 2>&1
270 # Clear errors in the pool caused by data corruptions
274 function clear_errors
278 log_must zpool clear $pool
280 if ! is_healthy $pool ; then
281 log_note "$pool should be healthy."
284 if ! is_data_valid $pool ; then
285 log_note "Data should be valid in $pool."
293 # Remove the specified pool's virtual device files
296 # $2 Missing devices count
304 vdevs=$(get_vdevs $pool $cnt)
305 log_must rm -f $vdevs
311 # Recover the bad or missing device files in the pool
314 # $2 Missing devices count
316 function recover_bad_missing_devs
322 vdevs=$(get_vdevs $pool $cnt)
323 replace_missing_devs $pool $vdevs
325 if ! is_healthy $pool ; then
326 log_note "$pool should be healthy."
329 if ! is_data_valid $pool ; then
330 log_note "Data should be valid in $pool."