Sindbad~EG File Manager
# vim: filetype=sh
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
# $FreeBSD$
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "@(#)redundancy.kshlib 1.8 09/01/12 SMI"
#
. ${STF_SUITE}/include/libtest.kshlib
function cleanup
{
# Log the status of the pool to assist failures.
poolexists $TESTPOOL && $ZPOOL status -v $TESTPOOL
destroy_pool $TESTPOOL
typeset dir
for dir in $TESTDIR $BASEDIR; do
if [[ -d $dir ]]; then
log_must $RM -rf $dir
fi
done
}
#
# Record the directories construction and checksum all the files which reside
# within the specified pool
#
# $1 The specified pool
# $2 The file which save the record.
#
function record_data
{
typeset pool=$1
typeset recordfile=$2
[[ -z $pool ]] && log_fail "No specified pool."
[[ -f $recordfile ]] && log_must $RM -f $recordfile
typeset mntpnt
mntpnt=$(get_prop mountpoint $pool)
log_must eval "$DU -a $mntpnt > $recordfile 2>&1"
#
# When the data was damaged, checksum is failing and return 1
# So, will not use log_must
#
$FIND $mntpnt -type f -exec $CKSUM {} + >> $recordfile 2>&1
}
#
# Create test pool and fill with files and directories.
#
# $1 pool name
# $2 pool type
# $3 virtual devices number
#
function setup_test_env
{
typeset pool=$1
typeset keyword=$2
typeset -i vdev_cnt=$3
typeset vdevs
typeset -i i=0
while (( i < vdev_cnt )); do
vdevs="$vdevs $BASEDIR/vdev$i"
((i += 1))
done
log_must $MKDIR -p $BASEDIR
destroy_pool $pool
log_must create_vdevs $vdevs
$ECHO $vdevs | tr ' ' '\n' > $BASEDIR/vdevs
log_must $ZPOOL create -m $TESTDIR $pool $keyword $vdevs
typeset file=$TESTDIR/file
log_must $FILE_WRITE -o create -f $file -b $BLOCKSZ -c $NUM_WRITES
force_sync_path $BASEDIR
record_data $TESTPOOL $PRE_RECORD_FILE
}
#
# Check pool data is valid
#
# $1 pool
#
function is_data_valid
{
typeset pool=$1
record_data $pool $PST_RECORD_FILE
if ! $DIFF $PRE_RECORD_FILE $PST_RECORD_FILE > /dev/null 2>&1; then
return 1
fi
return 0
}
#
# Get the specified count devices name
#
# $1 pool name
# $2 devices count
#
function get_vdevs #pool cnt
{
typeset pool=$1
typeset -i cnt=$2
head -$cnt $BASEDIR/vdevs | tr '\n' ' '
}
#
# Synchronize all the data in pool
#
# $1 pool name
#
function sync_pool #pool
{
typeset pool=$1
force_sync_path $BASEDIR
# If the OS has detected corruption on the pool, it will have
# automatically initiated a scrub. In that case, our "zpool scrub"
# command will fail. So we ignore its exit status and just check that
# the pool is scrubbing or has been scrubbed.
$ZPOOL scrub $pool >/dev/null 2>&1
is_pool_scrubbing $pool || is_pool_scrubbed $pool || \
log_fail "$ZPOOL scrub $pool failed."
log_note "$pool: $ZPOOL scrub issued."
}
#
# Create and replace the same name virtual device files
#
# $1 pool name
# $2-n virtual device files
#
function replace_missing_devs
{
typeset pool=$1
shift
typeset vdev
for vdev in $@; do
[ ! -f $vdev ] && log_must create_vdevs $vdev
log_must $ZPOOL replace -f $pool $vdev $vdev
wait_for 20 1 is_pool_resilvered $pool
done
}
#
# Damage the labels of the specified devices. Returns 0 if all such devices
# are UNAVAIL, 1 otherwise.
#
function damage_dev_labels # pool <vdev> [vdev ...]
{
typeset pool=$1
typeset -i ret=0
shift
for vdev in $*; do
check_state $pool $vdev UNAVAIL && continue
log_must create_vdevs $vdev
ret=1
done
[ $ret -eq 0 ] && return $ret
sync_pool $pool
return $ret
}
#
# Damage the pool's virtual device files.
#
# $1 pool name
# $2 Failing devices count
# $3 damage vdevs method, if not null, we keep the label for the vdevs
#
function damage_devs
{
typeset pool=$1
typeset -i cnt=$2
typeset label="$3"
typeset vdevs
typeset -i bs_count
vdevs=$(get_vdevs $pool $cnt)
log_note "Damaging pool $pool devices: $vdevs"
if [[ -n $label ]]; then
typeset -i i=0
log_mustnot pool_has_errors $pool
while [ $i -lt $cnt ]; do
corrupt_file $TESTPOOL $TESTDIR/file $i
(( i += 1 ))
done
sync_pool $pool
wait_for 20 1 is_pool_scrubbed $pool
log_must pool_has_errors $pool
else
# The pool can be syncing, thus fixing its labels. So we
# have to keep trying until all the devices go offline.
wait_for 20 1 damage_dev_labels $pool $vdevs
fi
log_note "Pool $pool vdevs $vdevs damage completed."
}
#
# Clear errors in the pool caused by data corruptions
#
# $1 pool name
#
function clear_errors
{
typeset pool=$1
log_must $ZPOOL clear $pool
# The pool may need to resilver (issued async by 'zpool clear'),
# give it a chance to do so.
wait_for 30 1 is_pool_healthy $pool
if ! is_data_valid $pool ; then
$ZPOOL status -x $pool
log_note "Data should be valid in $pool."
return 1
fi
return 0
}
#
# Remove the specified pool's virtual device files
#
# $1 Pool name
# $2 Missing devices count
#
function remove_devs
{
typeset pool=$1
typeset -i cnt=$2
typeset vdevs
vdevs=$(get_vdevs $pool $cnt)
log_note "Removing pool $pool vdevs: $vdevs"
log_must $RM -f $vdevs
sync_pool $pool
for vdev in $vdevs; do
wait_for 20 1 check_state $pool $vdev UNAVAIL
done
}
#
# Recover the bad or missing device files in the pool
#
# $1 Pool name
# $2 Missing devices count
#
function recover_bad_missing_devs
{
typeset pool=$1
typeset -i cnt=$2
typeset vdevs
vdevs=$(get_vdevs $pool $cnt)
log_note "Replacing missing pool $pool vdevs: $vdevs"
replace_missing_devs $pool $vdevs
if ! is_pool_healthy $pool ; then
log_note "$pool should be healthy."
return 1
fi
if ! is_data_valid $pool ; then
log_note "Data should be valid in $pool."
return 1
fi
return 0
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists