1*f38cb554SJohn Wren Kennedy# 2*f38cb554SJohn Wren Kennedy# CDDL HEADER START 3*f38cb554SJohn Wren Kennedy# 4*f38cb554SJohn Wren Kennedy# The contents of this file are subject to the terms of the 5*f38cb554SJohn Wren Kennedy# Common Development and Distribution License (the "License"). 6*f38cb554SJohn Wren Kennedy# You may not use this file except in compliance with the License. 7*f38cb554SJohn Wren Kennedy# 8*f38cb554SJohn Wren Kennedy# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*f38cb554SJohn Wren Kennedy# or http://www.opensolaris.org/os/licensing. 10*f38cb554SJohn Wren Kennedy# See the License for the specific language governing permissions 11*f38cb554SJohn Wren Kennedy# and limitations under the License. 12*f38cb554SJohn Wren Kennedy# 13*f38cb554SJohn Wren Kennedy# When distributing Covered Code, include this CDDL HEADER in each 14*f38cb554SJohn Wren Kennedy# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*f38cb554SJohn Wren Kennedy# If applicable, add the following below this CDDL HEADER, with the 16*f38cb554SJohn Wren Kennedy# fields enclosed by brackets "[]" replaced with your own identifying 17*f38cb554SJohn Wren Kennedy# information: Portions Copyright [yyyy] [name of copyright owner] 18*f38cb554SJohn Wren Kennedy# 19*f38cb554SJohn Wren Kennedy# CDDL HEADER END 20*f38cb554SJohn Wren Kennedy# 21*f38cb554SJohn Wren Kennedy 22*f38cb554SJohn Wren Kennedy# 23*f38cb554SJohn Wren Kennedy# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*f38cb554SJohn Wren Kennedy# Use is subject to license terms. 25*f38cb554SJohn Wren Kennedy# 26*f38cb554SJohn Wren Kennedy 27*f38cb554SJohn Wren Kennedy# 28*f38cb554SJohn Wren Kennedy# Copyright (c) 2013 by Delphix. All rights reserved. 29*f38cb554SJohn Wren Kennedy# 30*f38cb554SJohn Wren Kennedy 31*f38cb554SJohn Wren Kennedy. $STF_SUITE/include/libtest.shlib 32*f38cb554SJohn Wren Kennedy. $STF_SUITE/tests/functional/redundancy/redundancy.cfg 33*f38cb554SJohn Wren Kennedy 34*f38cb554SJohn Wren Kennedyfunction cleanup 35*f38cb554SJohn Wren Kennedy{ 36*f38cb554SJohn Wren Kennedy if poolexists $TESTPOOL; then 37*f38cb554SJohn Wren Kennedy destroy_pool $TESTPOOL 38*f38cb554SJohn Wren Kennedy fi 39*f38cb554SJohn Wren Kennedy typeset dir 40*f38cb554SJohn Wren Kennedy for dir in $TESTDIR $BASEDIR; do 41*f38cb554SJohn Wren Kennedy if [[ -d $dir ]]; then 42*f38cb554SJohn Wren Kennedy log_must $RM -rf $dir 43*f38cb554SJohn Wren Kennedy fi 44*f38cb554SJohn Wren Kennedy done 45*f38cb554SJohn Wren Kennedy} 46*f38cb554SJohn Wren Kennedy 47*f38cb554SJohn Wren Kennedy# 48*f38cb554SJohn Wren Kennedy# Get random number between min and max number. 49*f38cb554SJohn Wren Kennedy# 50*f38cb554SJohn Wren Kennedy# $1 Minimal value 51*f38cb554SJohn Wren Kennedy# $2 Maximal value 52*f38cb554SJohn Wren Kennedy# 53*f38cb554SJohn Wren Kennedyfunction random 54*f38cb554SJohn Wren Kennedy{ 55*f38cb554SJohn Wren Kennedy typeset -i min=$1 56*f38cb554SJohn Wren Kennedy typeset -i max=$2 57*f38cb554SJohn Wren Kennedy typeset -i value 58*f38cb554SJohn Wren Kennedy 59*f38cb554SJohn Wren Kennedy while true; do 60*f38cb554SJohn Wren Kennedy ((value = RANDOM % (max + 1))) 61*f38cb554SJohn Wren Kennedy if ((value >= min)); then 62*f38cb554SJohn Wren Kennedy break 63*f38cb554SJohn Wren Kennedy fi 64*f38cb554SJohn Wren Kennedy done 65*f38cb554SJohn Wren Kennedy 66*f38cb554SJohn Wren Kennedy $ECHO $value 67*f38cb554SJohn Wren Kennedy} 68*f38cb554SJohn Wren Kennedy 69*f38cb554SJohn Wren Kennedy# 70*f38cb554SJohn Wren Kennedy# Record the directories construction and checksum all the files which reside 71*f38cb554SJohn Wren Kennedy# within the specified pool 72*f38cb554SJohn Wren Kennedy# 73*f38cb554SJohn Wren Kennedy# $1 The specified pool 74*f38cb554SJohn Wren Kennedy# $2 The file which save the record. 75*f38cb554SJohn Wren Kennedy# 76*f38cb554SJohn Wren Kennedyfunction record_data 77*f38cb554SJohn Wren Kennedy{ 78*f38cb554SJohn Wren Kennedy typeset pool=$1 79*f38cb554SJohn Wren Kennedy typeset recordfile=$2 80*f38cb554SJohn Wren Kennedy 81*f38cb554SJohn Wren Kennedy [[ -z $pool ]] && log_fail "No specified pool." 82*f38cb554SJohn Wren Kennedy [[ -f $recordfile ]] && log_must $RM -f $recordfile 83*f38cb554SJohn Wren Kennedy 84*f38cb554SJohn Wren Kennedy typeset mntpnt 85*f38cb554SJohn Wren Kennedy mntpnt=$(get_prop mountpoint $pool) 86*f38cb554SJohn Wren Kennedy log_must eval "$DU -a $mntpnt > $recordfile 2>&1" 87*f38cb554SJohn Wren Kennedy # 88*f38cb554SJohn Wren Kennedy # When the data was damaged, checksum is failing and return 1 89*f38cb554SJohn Wren Kennedy # So, will not use log_must 90*f38cb554SJohn Wren Kennedy # 91*f38cb554SJohn Wren Kennedy $FIND $mntpnt -type f -exec $CKSUM {} + >> $recordfile 2>&1 92*f38cb554SJohn Wren Kennedy} 93*f38cb554SJohn Wren Kennedy 94*f38cb554SJohn Wren Kennedy# 95*f38cb554SJohn Wren Kennedy# Create test pool and fill with files and directories. 96*f38cb554SJohn Wren Kennedy# 97*f38cb554SJohn Wren Kennedy# $1 pool name 98*f38cb554SJohn Wren Kennedy# $2 pool type 99*f38cb554SJohn Wren Kennedy# $3 virtual devices number 100*f38cb554SJohn Wren Kennedy# 101*f38cb554SJohn Wren Kennedyfunction setup_test_env 102*f38cb554SJohn Wren Kennedy{ 103*f38cb554SJohn Wren Kennedy typeset pool=$1 104*f38cb554SJohn Wren Kennedy typeset keyword=$2 105*f38cb554SJohn Wren Kennedy typeset -i vdev_cnt=$3 106*f38cb554SJohn Wren Kennedy typeset vdevs 107*f38cb554SJohn Wren Kennedy 108*f38cb554SJohn Wren Kennedy typeset -i i=0 109*f38cb554SJohn Wren Kennedy while (( i < vdev_cnt )); do 110*f38cb554SJohn Wren Kennedy vdevs="$vdevs $BASEDIR/vdev$i" 111*f38cb554SJohn Wren Kennedy ((i += 1)) 112*f38cb554SJohn Wren Kennedy done 113*f38cb554SJohn Wren Kennedy 114*f38cb554SJohn Wren Kennedy if [[ ! -d $BASEDIR ]]; then 115*f38cb554SJohn Wren Kennedy log_must $MKDIR $BASEDIR 116*f38cb554SJohn Wren Kennedy fi 117*f38cb554SJohn Wren Kennedy 118*f38cb554SJohn Wren Kennedy if poolexists $pool ; then 119*f38cb554SJohn Wren Kennedy destroy_pool $pool 120*f38cb554SJohn Wren Kennedy fi 121*f38cb554SJohn Wren Kennedy 122*f38cb554SJohn Wren Kennedy log_must $MKFILE $DEV_SIZE $vdevs 123*f38cb554SJohn Wren Kennedy 124*f38cb554SJohn Wren Kennedy log_must $ZPOOL create -m $TESTDIR $pool $keyword $vdevs 125*f38cb554SJohn Wren Kennedy 126*f38cb554SJohn Wren Kennedy log_note "Filling up the filesystem ..." 127*f38cb554SJohn Wren Kennedy typeset -i ret=0 128*f38cb554SJohn Wren Kennedy typeset -i i=0 129*f38cb554SJohn Wren Kennedy typeset file=$TESTDIR/file 130*f38cb554SJohn Wren Kennedy while $TRUE ; do 131*f38cb554SJohn Wren Kennedy $FILE_WRITE -o create -f $file.$i \ 132*f38cb554SJohn Wren Kennedy -b $BLOCKSZ -c $NUM_WRITES 133*f38cb554SJohn Wren Kennedy ret=$? 134*f38cb554SJohn Wren Kennedy (( $ret != 0 )) && break 135*f38cb554SJohn Wren Kennedy (( i = i + 1 )) 136*f38cb554SJohn Wren Kennedy done 137*f38cb554SJohn Wren Kennedy (($ret != 28 )) && log_note "$FILE_WRITE return value($ret) is unexpected." 138*f38cb554SJohn Wren Kennedy 139*f38cb554SJohn Wren Kennedy record_data $TESTPOOL $PRE_RECORD_FILE 140*f38cb554SJohn Wren Kennedy} 141*f38cb554SJohn Wren Kennedy 142*f38cb554SJohn Wren Kennedy# 143*f38cb554SJohn Wren Kennedy# Check pool status is healthy 144*f38cb554SJohn Wren Kennedy# 145*f38cb554SJohn Wren Kennedy# $1 pool 146*f38cb554SJohn Wren Kennedy# 147*f38cb554SJohn Wren Kennedyfunction is_healthy 148*f38cb554SJohn Wren Kennedy{ 149*f38cb554SJohn Wren Kennedy typeset pool=$1 150*f38cb554SJohn Wren Kennedy 151*f38cb554SJohn Wren Kennedy typeset healthy_output="pool '$pool' is healthy" 152*f38cb554SJohn Wren Kennedy typeset real_output=$($ZPOOL status -x $pool) 153*f38cb554SJohn Wren Kennedy 154*f38cb554SJohn Wren Kennedy if [[ "$real_output" == "$healthy_output" ]]; then 155*f38cb554SJohn Wren Kennedy return 0 156*f38cb554SJohn Wren Kennedy else 157*f38cb554SJohn Wren Kennedy typeset -i ret 158*f38cb554SJohn Wren Kennedy $ZPOOL status -x $pool | $GREP "state:" | \ 159*f38cb554SJohn Wren Kennedy $GREP "FAULTED" >/dev/null 2>&1 160*f38cb554SJohn Wren Kennedy ret=$? 161*f38cb554SJohn Wren Kennedy (( $ret == 0 )) && return 1 162*f38cb554SJohn Wren Kennedy typeset l_scan 163*f38cb554SJohn Wren Kennedy typeset errnum 164*f38cb554SJohn Wren Kennedy l_scan=$($ZPOOL status -x $pool | $GREP "scan:") 165*f38cb554SJohn Wren Kennedy l_scan=${l_scan##*"with"} 166*f38cb554SJohn Wren Kennedy errnum=$($ECHO $l_scan | $AWK '{print $1}') 167*f38cb554SJohn Wren Kennedy 168*f38cb554SJohn Wren Kennedy return $errnum 169*f38cb554SJohn Wren Kennedy fi 170*f38cb554SJohn Wren Kennedy} 171*f38cb554SJohn Wren Kennedy 172*f38cb554SJohn Wren Kennedy# 173*f38cb554SJohn Wren Kennedy# Check pool data is valid 174*f38cb554SJohn Wren Kennedy# 175*f38cb554SJohn Wren Kennedy# $1 pool 176*f38cb554SJohn Wren Kennedy# 177*f38cb554SJohn Wren Kennedyfunction is_data_valid 178*f38cb554SJohn Wren Kennedy{ 179*f38cb554SJohn Wren Kennedy typeset pool=$1 180*f38cb554SJohn Wren Kennedy 181*f38cb554SJohn Wren Kennedy record_data $pool $PST_RECORD_FILE 182*f38cb554SJohn Wren Kennedy if ! $DIFF $PRE_RECORD_FILE $PST_RECORD_FILE > /dev/null 2>&1; then 183*f38cb554SJohn Wren Kennedy return 1 184*f38cb554SJohn Wren Kennedy fi 185*f38cb554SJohn Wren Kennedy 186*f38cb554SJohn Wren Kennedy return 0 187*f38cb554SJohn Wren Kennedy} 188*f38cb554SJohn Wren Kennedy 189*f38cb554SJohn Wren Kennedy# 190*f38cb554SJohn Wren Kennedy# Get the specified count devices name 191*f38cb554SJohn Wren Kennedy# 192*f38cb554SJohn Wren Kennedy# $1 pool name 193*f38cb554SJohn Wren Kennedy# $2 devices count 194*f38cb554SJohn Wren Kennedy# 195*f38cb554SJohn Wren Kennedyfunction get_vdevs #pool cnt 196*f38cb554SJohn Wren Kennedy{ 197*f38cb554SJohn Wren Kennedy typeset pool=$1 198*f38cb554SJohn Wren Kennedy typeset -i cnt=$2 199*f38cb554SJohn Wren Kennedy 200*f38cb554SJohn Wren Kennedy typeset all_devs=$($ZPOOL iostat -v $pool | $AWK '{print $1}'| \ 201*f38cb554SJohn Wren Kennedy $EGREP -v "^pool$|^capacity$|^mirror$|^raidz1$|^raidz2$|---" | \ 202*f38cb554SJohn Wren Kennedy $EGREP -v "/old$|^$pool$") 203*f38cb554SJohn Wren Kennedy typeset -i i=0 204*f38cb554SJohn Wren Kennedy typeset vdevs 205*f38cb554SJohn Wren Kennedy while ((i < cnt)); do 206*f38cb554SJohn Wren Kennedy typeset dev=$($ECHO $all_devs | $AWK '{print $1}') 207*f38cb554SJohn Wren Kennedy eval all_devs=\${all_devs##*$dev} 208*f38cb554SJohn Wren Kennedy 209*f38cb554SJohn Wren Kennedy vdevs="$dev $vdevs" 210*f38cb554SJohn Wren Kennedy ((i += 1)) 211*f38cb554SJohn Wren Kennedy done 212*f38cb554SJohn Wren Kennedy 213*f38cb554SJohn Wren Kennedy $ECHO "$vdevs" 214*f38cb554SJohn Wren Kennedy} 215*f38cb554SJohn Wren Kennedy 216*f38cb554SJohn Wren Kennedy# 217*f38cb554SJohn Wren Kennedy# Synchronize all the data in pool 218*f38cb554SJohn Wren Kennedy# 219*f38cb554SJohn Wren Kennedy# $1 pool name 220*f38cb554SJohn Wren Kennedy# 221*f38cb554SJohn Wren Kennedyfunction sync_pool #pool 222*f38cb554SJohn Wren Kennedy{ 223*f38cb554SJohn Wren Kennedy typeset pool=$1 224*f38cb554SJohn Wren Kennedy 225*f38cb554SJohn Wren Kennedy log_must $SYNC 226*f38cb554SJohn Wren Kennedy log_must $SLEEP 2 227*f38cb554SJohn Wren Kennedy # Flush all the pool data. 228*f38cb554SJohn Wren Kennedy typeset -i ret 229*f38cb554SJohn Wren Kennedy $ZPOOL scrub $pool >/dev/null 2>&1 230*f38cb554SJohn Wren Kennedy ret=$? 231*f38cb554SJohn Wren Kennedy (( $ret != 0 )) && \ 232*f38cb554SJohn Wren Kennedy log_fail "$ZPOOL scrub $pool failed." 233*f38cb554SJohn Wren Kennedy 234*f38cb554SJohn Wren Kennedy while ! is_pool_scrubbed $pool; do 235*f38cb554SJohn Wren Kennedy if is_pool_resilvered $pool ; then 236*f38cb554SJohn Wren Kennedy log_fail "$pool should not be resilver completed." 237*f38cb554SJohn Wren Kennedy fi 238*f38cb554SJohn Wren Kennedy log_must $SLEEP 2 239*f38cb554SJohn Wren Kennedy done 240*f38cb554SJohn Wren Kennedy} 241*f38cb554SJohn Wren Kennedy 242*f38cb554SJohn Wren Kennedy# 243*f38cb554SJohn Wren Kennedy# Create and replace the same name virtual device files 244*f38cb554SJohn Wren Kennedy# 245*f38cb554SJohn Wren Kennedy# $1 pool name 246*f38cb554SJohn Wren Kennedy# $2-n virtual device files 247*f38cb554SJohn Wren Kennedy# 248*f38cb554SJohn Wren Kennedyfunction replace_missing_devs 249*f38cb554SJohn Wren Kennedy{ 250*f38cb554SJohn Wren Kennedy typeset pool=$1 251*f38cb554SJohn Wren Kennedy shift 252*f38cb554SJohn Wren Kennedy 253*f38cb554SJohn Wren Kennedy typeset vdev 254*f38cb554SJohn Wren Kennedy for vdev in $@; do 255*f38cb554SJohn Wren Kennedy log_must $MKFILE $DEV_SIZE $vdev 256*f38cb554SJohn Wren Kennedy log_must $ZPOOL replace -f $pool $vdev $vdev 257*f38cb554SJohn Wren Kennedy while true; do 258*f38cb554SJohn Wren Kennedy if ! is_pool_resilvered $pool ; then 259*f38cb554SJohn Wren Kennedy log_must $SLEEP 2 260*f38cb554SJohn Wren Kennedy else 261*f38cb554SJohn Wren Kennedy break 262*f38cb554SJohn Wren Kennedy fi 263*f38cb554SJohn Wren Kennedy done 264*f38cb554SJohn Wren Kennedy done 265*f38cb554SJohn Wren Kennedy} 266*f38cb554SJohn Wren Kennedy 267*f38cb554SJohn Wren Kennedy# 268*f38cb554SJohn Wren Kennedy# Damage the pool's virtual device files. 269*f38cb554SJohn Wren Kennedy# 270*f38cb554SJohn Wren Kennedy# $1 pool name 271*f38cb554SJohn Wren Kennedy# $2 Failing devices count 272*f38cb554SJohn Wren Kennedy# $3 damage vdevs method, if not null, we keep 273*f38cb554SJohn Wren Kennedy# the label for the vdevs 274*f38cb554SJohn Wren Kennedy# 275*f38cb554SJohn Wren Kennedyfunction damage_devs 276*f38cb554SJohn Wren Kennedy{ 277*f38cb554SJohn Wren Kennedy typeset pool=$1 278*f38cb554SJohn Wren Kennedy typeset -i cnt=$2 279*f38cb554SJohn Wren Kennedy typeset label="$3" 280*f38cb554SJohn Wren Kennedy typeset vdevs 281*f38cb554SJohn Wren Kennedy typeset -i bs_count 282*f38cb554SJohn Wren Kennedy 283*f38cb554SJohn Wren Kennedy vdevs=$(get_vdevs $pool $cnt) 284*f38cb554SJohn Wren Kennedy if [[ -n $label ]]; then 285*f38cb554SJohn Wren Kennedy typeset dev 286*f38cb554SJohn Wren Kennedy for dev in $vdevs; do 287*f38cb554SJohn Wren Kennedy bs_count=$($LS -l $dev | $AWK '{print $5}') 288*f38cb554SJohn Wren Kennedy (( bs_count = bs_count/1024 - 512 )) 289*f38cb554SJohn Wren Kennedy $DD if=/dev/zero of=$dev seek=512 bs=1024 \ 290*f38cb554SJohn Wren Kennedy count=$bs_count conv=notrunc >/dev/null 2>&1 291*f38cb554SJohn Wren Kennedy done 292*f38cb554SJohn Wren Kennedy else 293*f38cb554SJohn Wren Kennedy log_must $MKFILE $DEV_SIZE $vdevs 294*f38cb554SJohn Wren Kennedy fi 295*f38cb554SJohn Wren Kennedy 296*f38cb554SJohn Wren Kennedy sync_pool $pool 297*f38cb554SJohn Wren Kennedy} 298*f38cb554SJohn Wren Kennedy 299*f38cb554SJohn Wren Kennedy# 300*f38cb554SJohn Wren Kennedy# Clear errors in the pool caused by data corruptions 301*f38cb554SJohn Wren Kennedy# 302*f38cb554SJohn Wren Kennedy# $1 pool name 303*f38cb554SJohn Wren Kennedy# 304*f38cb554SJohn Wren Kennedyfunction clear_errors 305*f38cb554SJohn Wren Kennedy{ 306*f38cb554SJohn Wren Kennedy typeset pool=$1 307*f38cb554SJohn Wren Kennedy 308*f38cb554SJohn Wren Kennedy log_must $ZPOOL clear $pool 309*f38cb554SJohn Wren Kennedy 310*f38cb554SJohn Wren Kennedy if ! is_healthy $pool ; then 311*f38cb554SJohn Wren Kennedy log_note "$pool should be healthy." 312*f38cb554SJohn Wren Kennedy return 1 313*f38cb554SJohn Wren Kennedy fi 314*f38cb554SJohn Wren Kennedy if ! is_data_valid $pool ; then 315*f38cb554SJohn Wren Kennedy log_note "Data should be valid in $pool." 316*f38cb554SJohn Wren Kennedy return 1 317*f38cb554SJohn Wren Kennedy fi 318*f38cb554SJohn Wren Kennedy 319*f38cb554SJohn Wren Kennedy return 0 320*f38cb554SJohn Wren Kennedy} 321*f38cb554SJohn Wren Kennedy 322*f38cb554SJohn Wren Kennedy# 323*f38cb554SJohn Wren Kennedy# Remove the specified pool's virtual device files 324*f38cb554SJohn Wren Kennedy# 325*f38cb554SJohn Wren Kennedy# $1 Pool name 326*f38cb554SJohn Wren Kennedy# $2 Missing devices count 327*f38cb554SJohn Wren Kennedy# 328*f38cb554SJohn Wren Kennedyfunction remove_devs 329*f38cb554SJohn Wren Kennedy{ 330*f38cb554SJohn Wren Kennedy typeset pool=$1 331*f38cb554SJohn Wren Kennedy typeset -i cnt=$2 332*f38cb554SJohn Wren Kennedy typeset vdevs 333*f38cb554SJohn Wren Kennedy 334*f38cb554SJohn Wren Kennedy vdevs=$(get_vdevs $pool $cnt) 335*f38cb554SJohn Wren Kennedy log_must $RM -f $vdevs 336*f38cb554SJohn Wren Kennedy 337*f38cb554SJohn Wren Kennedy sync_pool $pool 338*f38cb554SJohn Wren Kennedy} 339*f38cb554SJohn Wren Kennedy 340*f38cb554SJohn Wren Kennedy# 341*f38cb554SJohn Wren Kennedy# Recover the bad or missing device files in the pool 342*f38cb554SJohn Wren Kennedy# 343*f38cb554SJohn Wren Kennedy# $1 Pool name 344*f38cb554SJohn Wren Kennedy# $2 Missing devices count 345*f38cb554SJohn Wren Kennedy# 346*f38cb554SJohn Wren Kennedyfunction recover_bad_missing_devs 347*f38cb554SJohn Wren Kennedy{ 348*f38cb554SJohn Wren Kennedy typeset pool=$1 349*f38cb554SJohn Wren Kennedy typeset -i cnt=$2 350*f38cb554SJohn Wren Kennedy typeset vdevs 351*f38cb554SJohn Wren Kennedy 352*f38cb554SJohn Wren Kennedy vdevs=$(get_vdevs $pool $cnt) 353*f38cb554SJohn Wren Kennedy replace_missing_devs $pool $vdevs 354*f38cb554SJohn Wren Kennedy 355*f38cb554SJohn Wren Kennedy if ! is_healthy $pool ; then 356*f38cb554SJohn Wren Kennedy log_note "$pool should be healthy." 357*f38cb554SJohn Wren Kennedy return 1 358*f38cb554SJohn Wren Kennedy fi 359*f38cb554SJohn Wren Kennedy if ! is_data_valid $pool ; then 360*f38cb554SJohn Wren Kennedy log_note "Data should be valid in $pool." 361*f38cb554SJohn Wren Kennedy return 1 362*f38cb554SJohn Wren Kennedy fi 363*f38cb554SJohn Wren Kennedy 364*f38cb554SJohn Wren Kennedy return 0 365*f38cb554SJohn Wren Kennedy} 366