12fae26bdSAlan Somers# vim: filetype=sh 22fae26bdSAlan Somers# 32fae26bdSAlan Somers# CDDL HEADER START 42fae26bdSAlan Somers# 52fae26bdSAlan Somers# The contents of this file are subject to the terms of the 62fae26bdSAlan Somers# Common Development and Distribution License (the "License"). 72fae26bdSAlan Somers# You may not use this file except in compliance with the License. 82fae26bdSAlan Somers# 92fae26bdSAlan Somers# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 102fae26bdSAlan Somers# or http://www.opensolaris.org/os/licensing. 112fae26bdSAlan Somers# See the License for the specific language governing permissions 122fae26bdSAlan Somers# and limitations under the License. 132fae26bdSAlan Somers# 142fae26bdSAlan Somers# When distributing Covered Code, include this CDDL HEADER in each 152fae26bdSAlan Somers# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 162fae26bdSAlan Somers# If applicable, add the following below this CDDL HEADER, with the 172fae26bdSAlan Somers# fields enclosed by brackets "[]" replaced with your own identifying 182fae26bdSAlan Somers# information: Portions Copyright [yyyy] [name of copyright owner] 192fae26bdSAlan Somers# 202fae26bdSAlan Somers# CDDL HEADER END 212fae26bdSAlan Somers# 222fae26bdSAlan Somers 232fae26bdSAlan Somers# 242fae26bdSAlan Somers# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 252fae26bdSAlan Somers# Use is subject to license terms. 262fae26bdSAlan Somers 272fae26bdSAlan Somers. ${STF_SUITE}/include/logapi.kshlib 282fae26bdSAlan Somers 292fae26bdSAlan SomersZFS=${ZFS:-/sbin/zfs} 302fae26bdSAlan SomersZPOOL=${ZPOOL:-/sbin/zpool} 312fae26bdSAlan Somersos_name=`uname -s` 322fae26bdSAlan Somers 332fae26bdSAlan Somers# Determine if a test has the necessary requirements to run 342fae26bdSAlan Somers 352fae26bdSAlan Somersfunction test_requires 362fae26bdSAlan Somers{ 372fae26bdSAlan Somers integer unsupported=0 382fae26bdSAlan Somers unsupported_list="" 392fae26bdSAlan Somers until [[ $# -eq 0 ]];do 402fae26bdSAlan Somers var_name=$1 412fae26bdSAlan Somers cmd=$(eval echo \$${1}) 422fae26bdSAlan Somers if [[ ! "$cmd" != "" ]] ; then 432fae26bdSAlan Somers print $var_name is not set 442fae26bdSAlan Somers unsupported_list="$var_name $unsupported_list" 452fae26bdSAlan Somers ((unsupported=unsupported+1)) 462fae26bdSAlan Somers fi 472fae26bdSAlan Somers shift 482fae26bdSAlan Somers done 492fae26bdSAlan Somers if [[ unsupported -gt 0 ]] ; then 502fae26bdSAlan Somers log_unsupported "$unsupported_list commands are unsupported" 512fae26bdSAlan Somers else 522fae26bdSAlan Somers log_note "All commands are supported" 532fae26bdSAlan Somers fi 542fae26bdSAlan Somers} 552fae26bdSAlan Somers 562fae26bdSAlan Somers# Determine whether a dataset is mounted 572fae26bdSAlan Somers# 582fae26bdSAlan Somers# $1 dataset name 592fae26bdSAlan Somers# $2 filesystem type; optional - defaulted to zfs 602fae26bdSAlan Somers# 612fae26bdSAlan Somers# Return 0 if dataset is mounted; 1 if unmounted; 2 on error 622fae26bdSAlan Somers 632fae26bdSAlan Somersfunction ismounted 642fae26bdSAlan Somers{ 652fae26bdSAlan Somers typeset fstype=$2 662fae26bdSAlan Somers [[ -z $fstype ]] && fstype=zfs 672fae26bdSAlan Somers typeset out dir name ret 682fae26bdSAlan Somers 692fae26bdSAlan Somers case $fstype in 702fae26bdSAlan Somers zfs) 712fae26bdSAlan Somers if [[ "$1" == "/"* ]] ; then 722fae26bdSAlan Somers for out in $($ZFS mount | $AWK '{print $2}') ; do 732fae26bdSAlan Somers [[ $1 == $out ]] && return 0 742fae26bdSAlan Somers done 752fae26bdSAlan Somers else 762fae26bdSAlan Somers for out in $($ZFS mount | $AWK '{print $1}') ; do 772fae26bdSAlan Somers [[ $1 == $out ]] && return 0 782fae26bdSAlan Somers done 792fae26bdSAlan Somers fi 802fae26bdSAlan Somers ;; 812fae26bdSAlan Somers ufs|nfs) 822fae26bdSAlan Somers # a = device, b = "on", c = mount point", d = flags 832fae26bdSAlan Somers $MOUNT | $GREP $fstype | while read a b c d 842fae26bdSAlan Somers do 852fae26bdSAlan Somers [[ "$1" == "$a" || "$1" == "$c" ]] && return 0 862fae26bdSAlan Somers done 872fae26bdSAlan Somers ;; 882fae26bdSAlan Somers esac 892fae26bdSAlan Somers 902fae26bdSAlan Somers return 1 912fae26bdSAlan Somers} 922fae26bdSAlan Somers 932fae26bdSAlan Somers# Return 0 if a dataset is mounted; 1 otherwise 942fae26bdSAlan Somers# 952fae26bdSAlan Somers# $1 dataset name 962fae26bdSAlan Somers# $2 filesystem type; optional - defaulted to zfs 972fae26bdSAlan Somers 982fae26bdSAlan Somersfunction mounted 992fae26bdSAlan Somers{ 1002fae26bdSAlan Somers ismounted $1 $2 1012fae26bdSAlan Somers (( $? == 0 )) && return 0 1022fae26bdSAlan Somers return 1 1032fae26bdSAlan Somers} 1042fae26bdSAlan Somers 1052fae26bdSAlan Somers# Return 0 if a dataset is unmounted; 1 otherwise 1062fae26bdSAlan Somers# 1072fae26bdSAlan Somers# $1 dataset name 1082fae26bdSAlan Somers# $2 filesystem type; optional - defaulted to zfs 1092fae26bdSAlan Somers 1102fae26bdSAlan Somersfunction unmounted 1112fae26bdSAlan Somers{ 1122fae26bdSAlan Somers ismounted $1 $2 1132fae26bdSAlan Somers (( $? == 1 )) && return 0 1142fae26bdSAlan Somers return 1 1152fae26bdSAlan Somers} 1162fae26bdSAlan Somers 1172fae26bdSAlan Somers# split line on "," 1182fae26bdSAlan Somers# 1192fae26bdSAlan Somers# $1 - line to split 1202fae26bdSAlan Somers 1212fae26bdSAlan Somersfunction splitline 1222fae26bdSAlan Somers{ 1232fae26bdSAlan Somers $ECHO $1 | $SED "s/,/ /g" 1242fae26bdSAlan Somers} 1252fae26bdSAlan Somers 1262fae26bdSAlan Somersfunction default_setup 1272fae26bdSAlan Somers{ 1282fae26bdSAlan Somers default_setup_noexit "$@" 1292fae26bdSAlan Somers 1302fae26bdSAlan Somers log_pass 1312fae26bdSAlan Somers} 1322fae26bdSAlan Somers 1332fae26bdSAlan Somers# 1342fae26bdSAlan Somers# Given a list of disks, setup storage pools and datasets. 1352fae26bdSAlan Somers# 1362fae26bdSAlan Somersfunction default_setup_noexit 1372fae26bdSAlan Somers{ 1382fae26bdSAlan Somers typeset disklist=$1 1392fae26bdSAlan Somers typeset container=$2 1402fae26bdSAlan Somers typeset volume=$3 1412fae26bdSAlan Somers 1422fae26bdSAlan Somers if is_global_zone; then 1432fae26bdSAlan Somers if poolexists $TESTPOOL ; then 1442fae26bdSAlan Somers destroy_pool $TESTPOOL 1452fae26bdSAlan Somers fi 1462fae26bdSAlan Somers [[ -d /$TESTPOOL ]] && $RM -rf /$TESTPOOL 1472fae26bdSAlan Somers log_must $ZPOOL create -f $TESTPOOL $disklist 1482fae26bdSAlan Somers else 1492fae26bdSAlan Somers reexport_pool 1502fae26bdSAlan Somers fi 1512fae26bdSAlan Somers 1522fae26bdSAlan Somers $RM -rf $TESTDIR || log_unresolved Could not remove $TESTDIR 1532fae26bdSAlan Somers $MKDIR -p $TESTDIR || log_unresolved Could not create $TESTDIR 1542fae26bdSAlan Somers 1552fae26bdSAlan Somers log_must $ZFS create $TESTPOOL/$TESTFS 1562fae26bdSAlan Somers log_must $ZFS set mountpoint=$TESTDIR $TESTPOOL/$TESTFS 1572fae26bdSAlan Somers 1582fae26bdSAlan Somers if [[ -n $container ]]; then 1592fae26bdSAlan Somers $RM -rf $TESTDIR1 || \ 1602fae26bdSAlan Somers log_unresolved Could not remove $TESTDIR1 1612fae26bdSAlan Somers $MKDIR -p $TESTDIR1 || \ 1622fae26bdSAlan Somers log_unresolved Could not create $TESTDIR1 1632fae26bdSAlan Somers 1642fae26bdSAlan Somers log_must $ZFS create $TESTPOOL/$TESTCTR 1652fae26bdSAlan Somers log_must $ZFS set canmount=off $TESTPOOL/$TESTCTR 1662fae26bdSAlan Somers log_must $ZFS create $TESTPOOL/$TESTCTR/$TESTFS1 1672fae26bdSAlan Somers log_must $ZFS set mountpoint=$TESTDIR1 \ 1682fae26bdSAlan Somers $TESTPOOL/$TESTCTR/$TESTFS1 1692fae26bdSAlan Somers fi 1702fae26bdSAlan Somers 1712fae26bdSAlan Somers if [[ -n $volume ]]; then 1722fae26bdSAlan Somers if is_global_zone ; then 1732fae26bdSAlan Somers log_must $ZFS create -V $VOLSIZE $TESTPOOL/$TESTVOL 1742fae26bdSAlan Somers else 1752fae26bdSAlan Somers log_must $ZFS create $TESTPOOL/$TESTVOL 1762fae26bdSAlan Somers fi 1772fae26bdSAlan Somers 1782fae26bdSAlan Somers fi 1792fae26bdSAlan Somers} 1802fae26bdSAlan Somers 1812fae26bdSAlan Somers# 1822fae26bdSAlan Somers# Given a list of disks, setup a storage pool, file system and 1832fae26bdSAlan Somers# a container. 1842fae26bdSAlan Somers# 1852fae26bdSAlan Somersfunction default_container_setup 1862fae26bdSAlan Somers{ 1872fae26bdSAlan Somers typeset disklist=$1 1882fae26bdSAlan Somers 1892fae26bdSAlan Somers default_setup "$disklist" "true" 1902fae26bdSAlan Somers} 1912fae26bdSAlan Somers 1922fae26bdSAlan Somers# 1932fae26bdSAlan Somers# Given a list of disks, setup a storage pool,file system 1942fae26bdSAlan Somers# and a volume. 1952fae26bdSAlan Somers# 1962fae26bdSAlan Somersfunction default_volume_setup 1972fae26bdSAlan Somers{ 1982fae26bdSAlan Somers typeset disklist=$1 1992fae26bdSAlan Somers 2002fae26bdSAlan Somers default_setup "$disklist" "" "true" 2012fae26bdSAlan Somers} 2022fae26bdSAlan Somers 2032fae26bdSAlan Somers# 2042fae26bdSAlan Somers# Given a list of disks, setup a storage pool,file system, 2052fae26bdSAlan Somers# a container and a volume. 2062fae26bdSAlan Somers# 2072fae26bdSAlan Somersfunction default_container_volume_setup 2082fae26bdSAlan Somers{ 2092fae26bdSAlan Somers typeset disklist=$1 2102fae26bdSAlan Somers 2112fae26bdSAlan Somers default_setup "$disklist" "true" "true" 2122fae26bdSAlan Somers} 2132fae26bdSAlan Somers 2142fae26bdSAlan Somers# 2152fae26bdSAlan Somers# Create a snapshot on a filesystem or volume. Defaultly create a snapshot on 2162fae26bdSAlan Somers# filesystem 2172fae26bdSAlan Somers# 2182fae26bdSAlan Somers# $1 Existing filesystem or volume name. Default, $TESTFS 2192fae26bdSAlan Somers# $2 snapshot name. Default, $TESTSNAP 2202fae26bdSAlan Somers# 2212fae26bdSAlan Somersfunction create_snapshot 2222fae26bdSAlan Somers{ 2232fae26bdSAlan Somers typeset fs_vol=${1:-$TESTFS} 2242fae26bdSAlan Somers typeset snap=${2:-$TESTSNAP} 2252fae26bdSAlan Somers 2262fae26bdSAlan Somers [[ -z $fs_vol ]] && log_fail "Filesystem or volume's name is undefined." 2272fae26bdSAlan Somers [[ -z $snap ]] && log_fail "Snapshot's name is undefined." 2282fae26bdSAlan Somers 2292fae26bdSAlan Somers if snapexists $fs_vol@$snap; then 2302fae26bdSAlan Somers log_fail "$fs_vol@$snap already exists." 2312fae26bdSAlan Somers fi 2322fae26bdSAlan Somers datasetexists $fs_vol || \ 2332fae26bdSAlan Somers log_fail "$fs_vol must exist." 2342fae26bdSAlan Somers 2352fae26bdSAlan Somers log_must $ZFS snapshot $fs_vol@$snap 2362fae26bdSAlan Somers} 2372fae26bdSAlan Somers 2382fae26bdSAlan Somers# 2392fae26bdSAlan Somers# Create a clone from a snapshot, default clone name is $TESTCLONE. 2402fae26bdSAlan Somers# 2412fae26bdSAlan Somers# $1 Existing snapshot, $TESTPOOL/$TESTFS@$TESTSNAP is default. 2422fae26bdSAlan Somers# $2 Clone name, $TESTPOOL/$TESTCLONE is default. 2432fae26bdSAlan Somers# 2442fae26bdSAlan Somersfunction create_clone # snapshot clone 2452fae26bdSAlan Somers{ 2462fae26bdSAlan Somers typeset snap=${1:-$TESTPOOL/$TESTFS@$TESTSNAP} 2472fae26bdSAlan Somers typeset clone=${2:-$TESTPOOL/$TESTCLONE} 2482fae26bdSAlan Somers 2492fae26bdSAlan Somers [[ -z $snap ]] && \ 2502fae26bdSAlan Somers log_fail "Snapshot name is undefined." 2512fae26bdSAlan Somers [[ -z $clone ]] && \ 2522fae26bdSAlan Somers log_fail "Clone name is undefined." 2532fae26bdSAlan Somers 2542fae26bdSAlan Somers log_must $ZFS clone $snap $clone 2552fae26bdSAlan Somers} 2562fae26bdSAlan Somers 2572fae26bdSAlan Somersfunction default_mirror_setup 2582fae26bdSAlan Somers{ 2592fae26bdSAlan Somers default_mirror_setup_noexit $1 $2 $3 2602fae26bdSAlan Somers 2612fae26bdSAlan Somers log_pass 2622fae26bdSAlan Somers} 2632fae26bdSAlan Somers 2642fae26bdSAlan Somers# 2652fae26bdSAlan Somers# Given a pair of disks, set up a storage pool and dataset for the mirror 2662fae26bdSAlan Somers# @parameters: $1 the primary side of the mirror 2672fae26bdSAlan Somers# $2 the secondary side of the mirror 2682fae26bdSAlan Somers# @uses: ZPOOL ZFS TESTPOOL TESTFS 2692fae26bdSAlan Somersfunction default_mirror_setup_noexit 2702fae26bdSAlan Somers{ 2712fae26bdSAlan Somers readonly func="default_mirror_setup_noexit" 2722fae26bdSAlan Somers typeset primary=$1 2732fae26bdSAlan Somers typeset secondary=$2 2742fae26bdSAlan Somers 2752fae26bdSAlan Somers [[ -z $primary ]] && \ 2762fae26bdSAlan Somers log_fail "$func: No parameters passed" 2772fae26bdSAlan Somers [[ -z $secondary ]] && \ 2782fae26bdSAlan Somers log_fail "$func: No secondary partition passed" 2792fae26bdSAlan Somers [[ -d /$TESTPOOL ]] && $RM -rf /$TESTPOOL 2802fae26bdSAlan Somers log_must $ZPOOL create -f $TESTPOOL mirror $@ 2812fae26bdSAlan Somers log_must $ZFS create $TESTPOOL/$TESTFS 2822fae26bdSAlan Somers log_must $ZFS set mountpoint=$TESTDIR $TESTPOOL/$TESTFS 2832fae26bdSAlan Somers} 2842fae26bdSAlan Somers 2852fae26bdSAlan Somers# 2862fae26bdSAlan Somers# create a number of mirrors. 2872fae26bdSAlan Somers# We create a number($1) of 2 way mirrors using the pairs of disks named 2882fae26bdSAlan Somers# on the command line. These mirrors are *not* mounted 2892fae26bdSAlan Somers# @parameters: $1 the number of mirrors to create 2902fae26bdSAlan Somers# $... the devices to use to create the mirrors on 2912fae26bdSAlan Somers# @uses: ZPOOL ZFS TESTPOOL 2922fae26bdSAlan Somersfunction setup_mirrors 2932fae26bdSAlan Somers{ 2942fae26bdSAlan Somers typeset -i nmirrors=$1 2952fae26bdSAlan Somers 2962fae26bdSAlan Somers shift 2972fae26bdSAlan Somers while (( nmirrors > 0 )); do 2982fae26bdSAlan Somers log_must test -n "$1" -a -n "$2" 2992fae26bdSAlan Somers [[ -d /$TESTPOOL$nmirrors ]] && $RM -rf /$TESTPOOL$nmirrors 3002fae26bdSAlan Somers log_must $ZPOOL create -f $TESTPOOL$nmirrors mirror $1 $2 3012fae26bdSAlan Somers shift 2 3022fae26bdSAlan Somers (( nmirrors = nmirrors - 1 )) 3032fae26bdSAlan Somers done 3042fae26bdSAlan Somers} 3052fae26bdSAlan Somers 3062fae26bdSAlan Somers# 3072fae26bdSAlan Somers# create a number of raidz pools. 3082fae26bdSAlan Somers# We create a number($1) of 2 raidz pools using the pairs of disks named 3092fae26bdSAlan Somers# on the command line. These pools are *not* mounted 3102fae26bdSAlan Somers# @parameters: $1 the number of pools to create 3112fae26bdSAlan Somers# $... the devices to use to create the pools on 3122fae26bdSAlan Somers# @uses: ZPOOL ZFS TESTPOOL 3132fae26bdSAlan Somersfunction setup_raidzs 3142fae26bdSAlan Somers{ 3152fae26bdSAlan Somers typeset -i nraidzs=$1 3162fae26bdSAlan Somers 3172fae26bdSAlan Somers shift 3182fae26bdSAlan Somers while (( nraidzs > 0 )); do 3192fae26bdSAlan Somers log_must test -n "$1" -a -n "$2" 3202fae26bdSAlan Somers [[ -d /$TESTPOOL$nraidzs ]] && $RM -rf /$TESTPOOL$nraidzs 3212fae26bdSAlan Somers log_must $ZPOOL create -f $TESTPOOL$nraidzs raidz $1 $2 3222fae26bdSAlan Somers shift 2 3232fae26bdSAlan Somers (( nraidzs = nraidzs - 1 )) 3242fae26bdSAlan Somers done 3252fae26bdSAlan Somers} 3262fae26bdSAlan Somers 3272fae26bdSAlan Somers# 3282fae26bdSAlan Somers# Destroy the configured testpool mirrors. 3292fae26bdSAlan Somers# the mirrors are of the form ${TESTPOOL}{number} 3302fae26bdSAlan Somers# @uses: ZPOOL ZFS TESTPOOL 3312fae26bdSAlan Somersfunction destroy_mirrors 3322fae26bdSAlan Somers{ 3332fae26bdSAlan Somers default_cleanup_noexit 3342fae26bdSAlan Somers 3352fae26bdSAlan Somers log_pass 3362fae26bdSAlan Somers} 3372fae26bdSAlan Somers 3382fae26bdSAlan Somers# 3392fae26bdSAlan Somers# Given a minimum of two disks, set up a storage pool and dataset for the raid-z 3402fae26bdSAlan Somers# $1 the list of disks 3412fae26bdSAlan Somers# 3422fae26bdSAlan Somersfunction default_raidz_setup 3432fae26bdSAlan Somers{ 3442fae26bdSAlan Somers typeset disklist="$*" 3452fae26bdSAlan Somers set -A disks $disklist 3462fae26bdSAlan Somers 3472fae26bdSAlan Somers if [[ ${#disks[*]} -lt 2 ]]; then 3482fae26bdSAlan Somers log_fail "A raid-z requires a minimum of two disks." 3492fae26bdSAlan Somers fi 3502fae26bdSAlan Somers 3512fae26bdSAlan Somers [[ -d /$TESTPOOL ]] && $RM -rf /$TESTPOOL 3522fae26bdSAlan Somers log_must $ZPOOL create -f $TESTPOOL raidz $1 $2 $3 3532fae26bdSAlan Somers log_must $ZFS create $TESTPOOL/$TESTFS 3542fae26bdSAlan Somers log_must $ZFS set mountpoint=$TESTDIR $TESTPOOL/$TESTFS 3552fae26bdSAlan Somers 3562fae26bdSAlan Somers log_pass 3572fae26bdSAlan Somers} 3582fae26bdSAlan Somers 3592fae26bdSAlan Somers# 3602fae26bdSAlan Somers# Common function used to cleanup storage pools and datasets. 3612fae26bdSAlan Somers# 3622fae26bdSAlan Somers# Invoked at the start of the test suite to ensure the system 3632fae26bdSAlan Somers# is in a known state, and also at the end of each set of 3642fae26bdSAlan Somers# sub-tests to ensure errors from one set of tests doesn't 3652fae26bdSAlan Somers# impact the execution of the next set. 3662fae26bdSAlan Somers 3672fae26bdSAlan Somersfunction default_cleanup 3682fae26bdSAlan Somers{ 3692fae26bdSAlan Somers default_cleanup_noexit 3702fae26bdSAlan Somers 3712fae26bdSAlan Somers log_pass 3722fae26bdSAlan Somers} 3732fae26bdSAlan Somers 3742fae26bdSAlan Somersfunction all_pools 3752fae26bdSAlan Somers{ 3762fae26bdSAlan Somers cmd="$ZPOOL list -H -o name | $GREP 'testpool'" 3772fae26bdSAlan Somers eval $cmd 3782fae26bdSAlan Somers} 3792fae26bdSAlan Somers 3802fae26bdSAlan Somers# 3812fae26bdSAlan Somers# Returns 0 if the system contains any pools that must not be modified by the 3822fae26bdSAlan Somers# ZFS tests. 3832fae26bdSAlan Somers# 3842fae26bdSAlan Somersfunction other_pools_exist 3852fae26bdSAlan Somers{ 3862fae26bdSAlan Somers typeset pool_count=`$ZPOOL list -H | $GREP -v '^testpool' | $WC -l` 3872fae26bdSAlan Somers [ "$pool_count" -ne 0 ] 3882fae26bdSAlan Somers} 3892fae26bdSAlan Somers 3902fae26bdSAlan Somersfunction default_cleanup_noexit 3912fae26bdSAlan Somers{ 3922fae26bdSAlan Somers typeset exclude="" 3932fae26bdSAlan Somers typeset pool="" 3942fae26bdSAlan Somers # 3952fae26bdSAlan Somers # Destroying the pool will also destroy any 3962fae26bdSAlan Somers # filesystems it contains. 3972fae26bdSAlan Somers # 3982fae26bdSAlan Somers if is_global_zone; then 3992fae26bdSAlan Somers # Here, we loop through the pools we're allowed to 4002fae26bdSAlan Somers # destroy, only destroying them if it's safe to do 4012fae26bdSAlan Somers # so. 4022fae26bdSAlan Somers for pool in $(all_pools); do 4032fae26bdSAlan Somers if safe_to_destroy_pool $pool; then 4042fae26bdSAlan Somers destroy_pool $pool 4052fae26bdSAlan Somers fi 4062fae26bdSAlan Somers done 4072fae26bdSAlan Somers else 4082fae26bdSAlan Somers typeset fs="" 4092fae26bdSAlan Somers for fs in $($ZFS list -H -o name \ 4102fae26bdSAlan Somers | $GREP "^$ZONE_POOL/$ZONE_CTR[01234]/"); do 4112fae26bdSAlan Somers datasetexists $fs && \ 4122fae26bdSAlan Somers log_must $ZFS destroy -Rf $fs 4132fae26bdSAlan Somers done 4142fae26bdSAlan Somers 4152fae26bdSAlan Somers # Need cleanup here to avoid garbage dir left. 4162fae26bdSAlan Somers for fs in $($ZFS list -H -o name \ 4172fae26bdSAlan Somers ); do 4182fae26bdSAlan Somers [[ $fs == /$ZONE_POOL ]] && continue 4192fae26bdSAlan Somers [[ -d $fs ]] && log_must $RM -rf $fs/* 4202fae26bdSAlan Somers done 4212fae26bdSAlan Somers 4222fae26bdSAlan Somers # 4232fae26bdSAlan Somers # Reset the $ZONE_POOL/$ZONE_CTR[01234] file systems property to 4242fae26bdSAlan Somers # the default value 4252fae26bdSAlan Somers # 4262fae26bdSAlan Somers for fs in $($ZFS list -H -o name \ 4272fae26bdSAlan Somers ); do 4282fae26bdSAlan Somers if [[ $fs == $ZONE_POOL/$ZONE_CTR[01234] ]]; then 4292fae26bdSAlan Somers log_must $ZFS set reservation=none $fs 4302fae26bdSAlan Somers log_must $ZFS set recordsize=128K $fs 4312fae26bdSAlan Somers log_must $ZFS set mountpoint=/$fs $fs 4322fae26bdSAlan Somers typeset enc="" 4332fae26bdSAlan Somers enc=$(get_prop encryption $fs) 4342fae26bdSAlan Somers if [[ $? -ne 0 ]] || [[ -z "$enc" ]] || \ 4352fae26bdSAlan Somers [[ "$enc" == "off" ]]; then 4362fae26bdSAlan Somers log_must $ZFS set checksum=on $fs 4372fae26bdSAlan Somers fi 4382fae26bdSAlan Somers log_must $ZFS set compression=off $fs 4392fae26bdSAlan Somers log_must $ZFS set atime=on $fs 4402fae26bdSAlan Somers log_must $ZFS set devices=off $fs 4412fae26bdSAlan Somers log_must $ZFS set exec=on $fs 4422fae26bdSAlan Somers log_must $ZFS set setuid=on $fs 4432fae26bdSAlan Somers log_must $ZFS set readonly=off $fs 4442fae26bdSAlan Somers log_must $ZFS set snapdir=hidden $fs 4452fae26bdSAlan Somers log_must $ZFS set aclmode=groupmask $fs 4462fae26bdSAlan Somers log_must $ZFS set aclinherit=secure $fs 4472fae26bdSAlan Somers fi 4482fae26bdSAlan Somers done 4492fae26bdSAlan Somers fi 4502fae26bdSAlan Somers 4512fae26bdSAlan Somers [[ -d $TESTDIR ]] && \ 4522fae26bdSAlan Somers log_must $RM -rf $TESTDIR 4532fae26bdSAlan Somers} 4542fae26bdSAlan Somers 4552fae26bdSAlan Somers 4562fae26bdSAlan Somers# 4572fae26bdSAlan Somers# Common function used to cleanup storage pools, file systems 4582fae26bdSAlan Somers# and containers. 4592fae26bdSAlan Somers# 4602fae26bdSAlan Somersfunction default_container_cleanup 4612fae26bdSAlan Somers{ 4622fae26bdSAlan Somers if ! is_global_zone; then 4632fae26bdSAlan Somers reexport_pool 4642fae26bdSAlan Somers fi 4652fae26bdSAlan Somers 4662fae26bdSAlan Somers ismounted $TESTPOOL/$TESTCTR/$TESTFS1 4672fae26bdSAlan Somers [[ $? -eq 0 ]] && \ 4682fae26bdSAlan Somers log_must $ZFS unmount $TESTPOOL/$TESTCTR/$TESTFS1 4692fae26bdSAlan Somers 4702fae26bdSAlan Somers datasetexists $TESTPOOL/$TESTCTR/$TESTFS1 && \ 4712fae26bdSAlan Somers log_must $ZFS destroy -R $TESTPOOL/$TESTCTR/$TESTFS1 4722fae26bdSAlan Somers 4732fae26bdSAlan Somers datasetexists $TESTPOOL/$TESTCTR && \ 4742fae26bdSAlan Somers log_must $ZFS destroy -Rf $TESTPOOL/$TESTCTR 4752fae26bdSAlan Somers 4762fae26bdSAlan Somers [[ -e $TESTDIR1 ]] && \ 4772fae26bdSAlan Somers log_must $RM -rf $TESTDIR1 > /dev/null 2>&1 4782fae26bdSAlan Somers 4792fae26bdSAlan Somers default_cleanup 4802fae26bdSAlan Somers} 4812fae26bdSAlan Somers 4822fae26bdSAlan Somers# 4832fae26bdSAlan Somers# Common function used to cleanup snapshot of file system or volume. Default to 4842fae26bdSAlan Somers# delete the file system's snapshot 4852fae26bdSAlan Somers# 4862fae26bdSAlan Somers# $1 snapshot name 4872fae26bdSAlan Somers# 4882fae26bdSAlan Somersfunction destroy_snapshot 4892fae26bdSAlan Somers{ 4902fae26bdSAlan Somers typeset snap=${1:-$TESTPOOL/$TESTFS@$TESTSNAP} 4912fae26bdSAlan Somers 4922fae26bdSAlan Somers if ! snapexists $snap; then 4932fae26bdSAlan Somers log_fail "'$snap' does not existed." 4942fae26bdSAlan Somers fi 4952fae26bdSAlan Somers 4962fae26bdSAlan Somers # 4972fae26bdSAlan Somers # For the sake of the value which come from 'get_prop' is not equal 4982fae26bdSAlan Somers # to the really mountpoint when the snapshot is unmounted. So, firstly 4992fae26bdSAlan Somers # check and make sure this snapshot's been mounted in current system. 5002fae26bdSAlan Somers # 5012fae26bdSAlan Somers typeset mtpt="" 5022fae26bdSAlan Somers if ismounted $snap; then 5032fae26bdSAlan Somers mtpt=$(get_prop mountpoint $snap) 5042fae26bdSAlan Somers (( $? != 0 )) && \ 5052fae26bdSAlan Somers log_fail "get_prop mountpoint $snap failed." 5062fae26bdSAlan Somers fi 5072fae26bdSAlan Somers 5082fae26bdSAlan Somers log_must $ZFS destroy $snap 5092fae26bdSAlan Somers [[ $mtpt != "" && -d $mtpt ]] && \ 5102fae26bdSAlan Somers log_must $RM -rf $mtpt 5112fae26bdSAlan Somers} 5122fae26bdSAlan Somers 5132fae26bdSAlan Somers# 5142fae26bdSAlan Somers# Common function used to cleanup clone. 5152fae26bdSAlan Somers# 5162fae26bdSAlan Somers# $1 clone name 5172fae26bdSAlan Somers# 5182fae26bdSAlan Somersfunction destroy_clone 5192fae26bdSAlan Somers{ 5202fae26bdSAlan Somers typeset clone=${1:-$TESTPOOL/$TESTCLONE} 5212fae26bdSAlan Somers 5222fae26bdSAlan Somers if ! datasetexists $clone; then 5232fae26bdSAlan Somers log_fail "'$clone' does not existed." 5242fae26bdSAlan Somers fi 5252fae26bdSAlan Somers 5262fae26bdSAlan Somers # With the same reason in destroy_snapshot 5272fae26bdSAlan Somers typeset mtpt="" 5282fae26bdSAlan Somers if ismounted $clone; then 5292fae26bdSAlan Somers mtpt=$(get_prop mountpoint $clone) 5302fae26bdSAlan Somers (( $? != 0 )) && \ 5312fae26bdSAlan Somers log_fail "get_prop mountpoint $clone failed." 5322fae26bdSAlan Somers fi 5332fae26bdSAlan Somers 5342fae26bdSAlan Somers log_must $ZFS destroy $clone 5352fae26bdSAlan Somers [[ $mtpt != "" && -d $mtpt ]] && \ 5362fae26bdSAlan Somers log_must $RM -rf $mtpt 5372fae26bdSAlan Somers} 5382fae26bdSAlan Somers 5392fae26bdSAlan Somers# Return 0 if a snapshot exists; $? otherwise 5402fae26bdSAlan Somers# 5412fae26bdSAlan Somers# $1 - snapshot name 5422fae26bdSAlan Somers 5432fae26bdSAlan Somersfunction snapexists 5442fae26bdSAlan Somers{ 5452fae26bdSAlan Somers $ZFS list -H -t snapshot "$1" > /dev/null 2>&1 5462fae26bdSAlan Somers return $? 5472fae26bdSAlan Somers} 5482fae26bdSAlan Somers 5492fae26bdSAlan Somers# 5502fae26bdSAlan Somers# Set a property to a certain value on a dataset. 5512fae26bdSAlan Somers# Sets a property of the dataset to the value as passed in. 5522fae26bdSAlan Somers# @param: 5532fae26bdSAlan Somers# $1 dataset who's property is being set 5542fae26bdSAlan Somers# $2 property to set 5552fae26bdSAlan Somers# $3 value to set property to 5562fae26bdSAlan Somers# @return: 5572fae26bdSAlan Somers# 0 if the property could be set. 5582fae26bdSAlan Somers# non-zero otherwise. 5592fae26bdSAlan Somers# @use: ZFS 5602fae26bdSAlan Somers# 5612fae26bdSAlan Somersfunction dataset_setprop 5622fae26bdSAlan Somers{ 5632fae26bdSAlan Somers typeset fn=dataset_setprop 5642fae26bdSAlan Somers 5652fae26bdSAlan Somers if (( $# < 3 )); then 5662fae26bdSAlan Somers log_note "$fn: Insufficient parameters (need 3, had $#)" 5672fae26bdSAlan Somers return 1 5682fae26bdSAlan Somers fi 5692fae26bdSAlan Somers typeset output= 5702fae26bdSAlan Somers output=$($ZFS set $2=$3 $1 2>&1) 5712fae26bdSAlan Somers typeset rv=$? 5722fae26bdSAlan Somers if (( rv != 0 )); then 5732fae26bdSAlan Somers log_note "Setting property on $1 failed." 5742fae26bdSAlan Somers log_note "property $2=$3" 5752fae26bdSAlan Somers log_note "Return Code: $rv" 5762fae26bdSAlan Somers log_note "Output: $output" 5772fae26bdSAlan Somers return $rv 5782fae26bdSAlan Somers fi 5792fae26bdSAlan Somers return 0 5802fae26bdSAlan Somers} 5812fae26bdSAlan Somers 5822fae26bdSAlan Somers# 5832fae26bdSAlan Somers# Assign suite defined dataset properties. 5842fae26bdSAlan Somers# This function is used to apply the suite's defined default set of 5852fae26bdSAlan Somers# properties to a dataset. 5862fae26bdSAlan Somers# @parameters: $1 dataset to use 5872fae26bdSAlan Somers# @uses: ZFS COMPRESSION_PROP CHECKSUM_PROP 5882fae26bdSAlan Somers# @returns: 5892fae26bdSAlan Somers# 0 if the dataset has been altered. 5902fae26bdSAlan Somers# 1 if no pool name was passed in. 5912fae26bdSAlan Somers# 2 if the dataset could not be found. 5922fae26bdSAlan Somers# 3 if the dataset could not have it's properties set. 5932fae26bdSAlan Somers# 5942fae26bdSAlan Somersfunction dataset_set_defaultproperties 5952fae26bdSAlan Somers{ 5962fae26bdSAlan Somers typeset dataset="$1" 5972fae26bdSAlan Somers 5982fae26bdSAlan Somers [[ -z $dataset ]] && return 1 5992fae26bdSAlan Somers 6002fae26bdSAlan Somers typeset confset= 6012fae26bdSAlan Somers typeset -i found=0 6022fae26bdSAlan Somers for confset in $($ZFS list); do 6032fae26bdSAlan Somers if [[ $dataset = $confset ]]; then 6042fae26bdSAlan Somers found=1 6052fae26bdSAlan Somers break 6062fae26bdSAlan Somers fi 6072fae26bdSAlan Somers done 6082fae26bdSAlan Somers [[ $found -eq 0 ]] && return 2 6092fae26bdSAlan Somers if [[ -n $COMPRESSION_PROP ]]; then 6102fae26bdSAlan Somers dataset_setprop $dataset compression $COMPRESSION_PROP || \ 6112fae26bdSAlan Somers return 3 6122fae26bdSAlan Somers log_note "Compression set to '$COMPRESSION_PROP' on $dataset" 6132fae26bdSAlan Somers fi 6142fae26bdSAlan Somers if [[ -n $CHECKSUM_PROP && $WRAPPER != *"crypto"* ]]; then 6152fae26bdSAlan Somers dataset_setprop $dataset checksum $CHECKSUM_PROP || \ 6162fae26bdSAlan Somers return 3 6172fae26bdSAlan Somers log_note "Checksum set to '$CHECKSUM_PROP' on $dataset" 6182fae26bdSAlan Somers fi 6192fae26bdSAlan Somers return 0 6202fae26bdSAlan Somers} 6212fae26bdSAlan Somers 6222fae26bdSAlan Somers# 6232fae26bdSAlan Somers# Check a numeric assertion 6242fae26bdSAlan Somers# @parameter: $@ the assertion to check 6252fae26bdSAlan Somers# @output: big loud notice if assertion failed 6262fae26bdSAlan Somers# @use: log_fail 6272fae26bdSAlan Somers# 6282fae26bdSAlan Somersfunction assert 6292fae26bdSAlan Somers{ 6302fae26bdSAlan Somers (( $@ )) || log_fail $@ 6312fae26bdSAlan Somers} 6322fae26bdSAlan Somers 6332fae26bdSAlan Somersfunction wipe_partition_table #<whole_disk_name> [<whole_disk_name> ...] 6342fae26bdSAlan Somers{ 6352fae26bdSAlan Somers while [[ -n $* ]]; do 6362fae26bdSAlan Somers typeset diskname=$1 6372fae26bdSAlan Somers [ ! -e $diskname ] && log_fail "ERROR: $diskname doesn't exist" 638a7478ad1SAndriy Gapon if gpart list ${diskname#/dev/} >/dev/null 2>&1; then 6392fae26bdSAlan Somers wait_for 5 1 $GPART destroy -F $diskname 6402fae26bdSAlan Somers else 6412fae26bdSAlan Somers log_note "No GPT partitions detected on $diskname" 6422fae26bdSAlan Somers fi 6432fae26bdSAlan Somers log_must $GPART create -s gpt $diskname 6442fae26bdSAlan Somers shift 6452fae26bdSAlan Somers done 6462fae26bdSAlan Somers} 6472fae26bdSAlan Somers 6482fae26bdSAlan Somers# 6492fae26bdSAlan Somers# Given a slice, size and disk, this function 6502fae26bdSAlan Somers# formats the slice to the specified size. 6512fae26bdSAlan Somers# Size should be specified with units as per 6522fae26bdSAlan Somers# the `format` command requirements eg. 100mb 3gb 6532fae26bdSAlan Somers# 6542fae26bdSAlan Somersfunction set_partition #<slice_num> <slice_start> <size_plus_units> <whole_disk_name> 6552fae26bdSAlan Somers{ 6562fae26bdSAlan Somers typeset -i slicenum=$1 6572fae26bdSAlan Somers typeset start=$2 6582fae26bdSAlan Somers typeset size=$3 6592fae26bdSAlan Somers typeset disk=$4 6602fae26bdSAlan Somers set -A devmap a b c d e f g h 6612fae26bdSAlan Somers [[ -z $slicenum || -z $size || -z $disk ]] && \ 6622fae26bdSAlan Somers log_fail "The slice, size or disk name is unspecified." 6632fae26bdSAlan Somers 6642fae26bdSAlan Somers size=`$ECHO $size| sed s/mb/M/` 6652fae26bdSAlan Somers size=`$ECHO $size| sed s/m/M/` 6662fae26bdSAlan Somers size=`$ECHO $size| sed s/gb/G/` 6672fae26bdSAlan Somers size=`$ECHO $size| sed s/g/G/` 6682fae26bdSAlan Somers [[ -n $start ]] && start="-b $start" 6692fae26bdSAlan Somers log_must $GPART add -t efi $start -s $size -i $slicenum $disk 6702fae26bdSAlan Somers return 0 6712fae26bdSAlan Somers} 6722fae26bdSAlan Somers 6732fae26bdSAlan Somersfunction get_disk_size #<disk> 6742fae26bdSAlan Somers{ 6752fae26bdSAlan Somers typeset disk=$1 676ee00e55cSAndriy Gapon diskinfo $disk | awk '{print $3}' 6772fae26bdSAlan Somers} 6782fae26bdSAlan Somers 6792fae26bdSAlan Somersfunction get_available_disk_size #<disk> 6802fae26bdSAlan Somers{ 6812fae26bdSAlan Somers typeset disk=$1 6822fae26bdSAlan Somers raw_size=`get_disk_size $disk` 6832fae26bdSAlan Somers (( available_size = raw_size * 95 / 100 )) 6842fae26bdSAlan Somers echo $available_size 6852fae26bdSAlan Somers} 6862fae26bdSAlan Somers 6872fae26bdSAlan Somers# 6882fae26bdSAlan Somers# Get the end cyl of the given slice 6892fae26bdSAlan Somers# #TODO: fix this to be GPT-compatible if we want to use the SMI WRAPPER. This 6902fae26bdSAlan Somers# function is not necessary on FreeBSD 6912fae26bdSAlan Somers# 6922fae26bdSAlan Somersfunction get_endslice #<disk> <slice> 6932fae26bdSAlan Somers{ 6942fae26bdSAlan Somers log_fail "get_endslice has not been updated for GPT partitions" 6952fae26bdSAlan Somers} 6962fae26bdSAlan Somers 6972fae26bdSAlan Somers# 6982fae26bdSAlan Somers# Get the first LBA that is beyond the end of the given partition 6992fae26bdSAlan Somersfunction get_partition_end #<disk> <partition_index> 7002fae26bdSAlan Somers{ 7012fae26bdSAlan Somers typeset disk=$1 7022fae26bdSAlan Somers typeset partition_index=$2 7032fae26bdSAlan Somers export partition_index 7042fae26bdSAlan Somers $GPART show $disk | $AWK \ 7052fae26bdSAlan Somers '/^[ \t]/ && $3 ~ ENVIRON["partition_index"] {print $1 + $2}' 7062fae26bdSAlan Somers} 7072fae26bdSAlan Somers 7082fae26bdSAlan Somers 7092fae26bdSAlan Somers# 7102fae26bdSAlan Somers# Given a size,disk and total number of partitions, this function formats the 7112fae26bdSAlan Somers# disk partitions from 0 to the total partition number with the same specified 7122fae26bdSAlan Somers# size. 7132fae26bdSAlan Somers# 7142fae26bdSAlan Somersfunction partition_disk #<part_size> <whole_disk_name> <total_parts> 7152fae26bdSAlan Somers{ 7162fae26bdSAlan Somers typeset -i i=1 7172fae26bdSAlan Somers typeset part_size=$1 7182fae26bdSAlan Somers typeset disk_name=$2 7192fae26bdSAlan Somers typeset total_parts=$3 7202fae26bdSAlan Somers typeset cyl 7212fae26bdSAlan Somers 7222fae26bdSAlan Somers wipe_partition_table $disk_name 7232fae26bdSAlan Somers while (( i <= $total_parts )); do 7242fae26bdSAlan Somers set_partition $i "" $part_size $disk_name 7252fae26bdSAlan Somers (( i = i+1 )) 7262fae26bdSAlan Somers done 7272fae26bdSAlan Somers} 7282fae26bdSAlan Somers 7292fae26bdSAlan Somersfunction size_of_file # fname 7302fae26bdSAlan Somers{ 7312fae26bdSAlan Somers typeset fname=$1 7322fae26bdSAlan Somers sz=`stat -f '%z' $fname` 7332fae26bdSAlan Somers [[ -z "$sz" ]] && log_fail "stat($fname) failed" 7342fae26bdSAlan Somers $ECHO $sz 7352fae26bdSAlan Somers return 0 7362fae26bdSAlan Somers} 7372fae26bdSAlan Somers 7382fae26bdSAlan Somers# 7392fae26bdSAlan Somers# This function continues to write to a filenum number of files into dirnum 7402fae26bdSAlan Somers# number of directories until either $FILE_WRITE returns an error or the 7412fae26bdSAlan Somers# maximum number of files per directory have been written. 7422fae26bdSAlan Somers# 7432fae26bdSAlan Somers# Usage: 7442fae26bdSAlan Somers# fill_fs [destdir] [dirnum] [filenum] [bytes] [num_writes] [data] 7452fae26bdSAlan Somers# 7462fae26bdSAlan Somers# Return value: 0 on success 7472fae26bdSAlan Somers# non 0 on error 7482fae26bdSAlan Somers# 7492fae26bdSAlan Somers# Where : 7502fae26bdSAlan Somers# destdir: is the directory where everything is to be created under 7512fae26bdSAlan Somers# dirnum: the maximum number of subdirectories to use, -1 no limit 7522fae26bdSAlan Somers# filenum: the maximum number of files per subdirectory 7532fae26bdSAlan Somers# blocksz: number of bytes per block 7542fae26bdSAlan Somers# num_writes: number of blocks to write 7552fae26bdSAlan Somers# data: the data that will be written 7562fae26bdSAlan Somers# 7572fae26bdSAlan Somers# E.g. 7582fae26bdSAlan Somers# file_fs /testdir 20 25 1024 256 0 7592fae26bdSAlan Somers# 7602fae26bdSAlan Somers# Note: blocksz * num_writes equals the size of the testfile 7612fae26bdSAlan Somers# 7622fae26bdSAlan Somersfunction fill_fs # destdir dirnum filenum blocksz num_writes data 7632fae26bdSAlan Somers{ 7642fae26bdSAlan Somers typeset destdir=${1:-$TESTDIR} 7652fae26bdSAlan Somers typeset -i dirnum=${2:-50} 7662fae26bdSAlan Somers typeset -i filenum=${3:-50} 7672fae26bdSAlan Somers typeset -i blocksz=${4:-8192} 7682fae26bdSAlan Somers typeset -i num_writes=${5:-10240} 7692fae26bdSAlan Somers typeset -i data=${6:-0} 7702fae26bdSAlan Somers 7712fae26bdSAlan Somers typeset -i retval=0 7722fae26bdSAlan Somers typeset -i dn=0 # current dir number 7732fae26bdSAlan Somers typeset -i fn=0 # current file number 7742fae26bdSAlan Somers while (( retval == 0 )); do 7752fae26bdSAlan Somers (( dirnum >= 0 && dn >= dirnum )) && break 7762fae26bdSAlan Somers typeset curdir=$destdir/$dn 7772fae26bdSAlan Somers log_must $MKDIR -p $curdir 7782fae26bdSAlan Somers for (( fn = 0; $fn < $filenum && $retval == 0; fn++ )); do 7792fae26bdSAlan Somers log_cmd $FILE_WRITE -o create -f $curdir/$TESTFILE.$fn \ 7802fae26bdSAlan Somers -b $blocksz -c $num_writes -d $data 7812fae26bdSAlan Somers retval=$? 7822fae26bdSAlan Somers done 7832fae26bdSAlan Somers (( dn = dn + 1 )) 7842fae26bdSAlan Somers done 7852fae26bdSAlan Somers return $retval 7862fae26bdSAlan Somers} 7872fae26bdSAlan Somers 7882fae26bdSAlan Somers# 7892fae26bdSAlan Somers# Simple function to get the specified property. If unable to 7902fae26bdSAlan Somers# get the property then exits. 7912fae26bdSAlan Somers# 7922fae26bdSAlan Somers# Note property is in 'parsable' format (-p) 7932fae26bdSAlan Somers# 7942fae26bdSAlan Somersfunction get_prop # property dataset 7952fae26bdSAlan Somers{ 7962fae26bdSAlan Somers typeset prop_val 7972fae26bdSAlan Somers typeset prop=$1 7982fae26bdSAlan Somers typeset dataset=$2 7992fae26bdSAlan Somers 8002fae26bdSAlan Somers prop_val=$($ZFS get -pH -o value $prop $dataset 2>/dev/null) 8012fae26bdSAlan Somers if [[ $? -ne 0 ]]; then 8022fae26bdSAlan Somers log_note "Unable to get $prop property for dataset $dataset" 8032fae26bdSAlan Somers return 1 8042fae26bdSAlan Somers fi 8052fae26bdSAlan Somers 8062fae26bdSAlan Somers $ECHO $prop_val 8072fae26bdSAlan Somers return 0 8082fae26bdSAlan Somers} 8092fae26bdSAlan Somers 8102fae26bdSAlan Somers# 8112fae26bdSAlan Somers# Simple function to return the lesser of two values. 8122fae26bdSAlan Somers# 8132fae26bdSAlan Somersfunction min 8142fae26bdSAlan Somers{ 8152fae26bdSAlan Somers typeset first_arg=$1 8162fae26bdSAlan Somers typeset second_arg=$2 8172fae26bdSAlan Somers 8182fae26bdSAlan Somers if (( first_arg < second_arg )); then 8192fae26bdSAlan Somers $ECHO $first_arg 8202fae26bdSAlan Somers else 8212fae26bdSAlan Somers $ECHO $second_arg 8222fae26bdSAlan Somers fi 8232fae26bdSAlan Somers return 0 8242fae26bdSAlan Somers} 8252fae26bdSAlan Somers 8262fae26bdSAlan Somers# 8272fae26bdSAlan Somers# Simple function to get the specified property of pool. If unable to 8282fae26bdSAlan Somers# get the property then exits. 8292fae26bdSAlan Somers# 8302fae26bdSAlan Somersfunction get_pool_prop # property pool 8312fae26bdSAlan Somers{ 8322fae26bdSAlan Somers typeset prop_val 8332fae26bdSAlan Somers typeset prop=$1 8342fae26bdSAlan Somers typeset pool=$2 8352fae26bdSAlan Somers 8362fae26bdSAlan Somers if poolexists $pool ; then 8372fae26bdSAlan Somers prop_val=$($ZPOOL get $prop $pool 2>/dev/null | $TAIL -1 | \ 8382fae26bdSAlan Somers $AWK '{print $3}') 8392fae26bdSAlan Somers if [[ $? -ne 0 ]]; then 8402fae26bdSAlan Somers log_note "Unable to get $prop property for pool " \ 8412fae26bdSAlan Somers "$pool" 8422fae26bdSAlan Somers return 1 8432fae26bdSAlan Somers fi 8442fae26bdSAlan Somers else 8452fae26bdSAlan Somers log_note "Pool $pool not exists." 8462fae26bdSAlan Somers return 1 8472fae26bdSAlan Somers fi 8482fae26bdSAlan Somers 8492fae26bdSAlan Somers $ECHO $prop_val 8502fae26bdSAlan Somers return 0 8512fae26bdSAlan Somers} 8522fae26bdSAlan Somers 8532fae26bdSAlan Somers# Return 0 if a pool exists; $? otherwise 8542fae26bdSAlan Somers# 8552fae26bdSAlan Somers# $1 - pool name 8562fae26bdSAlan Somers 8572fae26bdSAlan Somersfunction poolexists 8582fae26bdSAlan Somers{ 8592fae26bdSAlan Somers typeset pool=$1 8602fae26bdSAlan Somers 8612fae26bdSAlan Somers if [[ -z $pool ]]; then 8622fae26bdSAlan Somers log_note "No pool name given." 8632fae26bdSAlan Somers return 1 8642fae26bdSAlan Somers fi 8652fae26bdSAlan Somers 8662fae26bdSAlan Somers $ZPOOL list -H "$pool" > /dev/null 2>&1 8672fae26bdSAlan Somers return $? 8682fae26bdSAlan Somers} 8692fae26bdSAlan Somers 8702fae26bdSAlan Somers# Return 0 if all the specified datasets exist; $? otherwise 8712fae26bdSAlan Somers# 8722fae26bdSAlan Somers# $1-n dataset name 8732fae26bdSAlan Somersfunction datasetexists 8742fae26bdSAlan Somers{ 8752fae26bdSAlan Somers if (( $# == 0 )); then 8762fae26bdSAlan Somers log_note "No dataset name given." 8772fae26bdSAlan Somers return 1 8782fae26bdSAlan Somers fi 8792fae26bdSAlan Somers 8802fae26bdSAlan Somers while (( $# > 0 )); do 8812fae26bdSAlan Somers $ZFS list -H -t filesystem,snapshot,volume $1 > /dev/null 2>&1 || \ 8822fae26bdSAlan Somers return $? 8832fae26bdSAlan Somers shift 8842fae26bdSAlan Somers done 8852fae26bdSAlan Somers 8862fae26bdSAlan Somers return 0 8872fae26bdSAlan Somers} 8882fae26bdSAlan Somers 8892fae26bdSAlan Somers# return 0 if none of the specified datasets exists, otherwise return 1. 8902fae26bdSAlan Somers# 8912fae26bdSAlan Somers# $1-n dataset name 8922fae26bdSAlan Somersfunction datasetnonexists 8932fae26bdSAlan Somers{ 8942fae26bdSAlan Somers if (( $# == 0 )); then 8952fae26bdSAlan Somers log_note "No dataset name given." 8962fae26bdSAlan Somers return 1 8972fae26bdSAlan Somers fi 8982fae26bdSAlan Somers 8992fae26bdSAlan Somers while (( $# > 0 )); do 9002fae26bdSAlan Somers $ZFS list -H -t filesystem,snapshot,volume $1 > /dev/null 2>&1 && \ 9012fae26bdSAlan Somers return 1 9022fae26bdSAlan Somers shift 9032fae26bdSAlan Somers done 9042fae26bdSAlan Somers 9052fae26bdSAlan Somers return 0 9062fae26bdSAlan Somers} 9072fae26bdSAlan Somers 9082fae26bdSAlan Somers# 9092fae26bdSAlan Somers# Given a mountpoint, or a dataset name, determine if it is shared. 9102fae26bdSAlan Somers# 9112fae26bdSAlan Somers# Returns 0 if shared, 1 otherwise. 9122fae26bdSAlan Somers# 9132fae26bdSAlan Somersfunction is_shared 9142fae26bdSAlan Somers{ 9152fae26bdSAlan Somers typeset fs=$1 9162fae26bdSAlan Somers typeset mtpt 9172fae26bdSAlan Somers 9182fae26bdSAlan Somers if [[ $fs != "/"* ]] ; then 9192fae26bdSAlan Somers if datasetnonexists "$fs" ; then 9202fae26bdSAlan Somers return 1 9212fae26bdSAlan Somers else 9222fae26bdSAlan Somers mtpt=$(get_prop mountpoint "$fs") 9232fae26bdSAlan Somers case $mtpt in 9242fae26bdSAlan Somers none|legacy|-) return 1 9252fae26bdSAlan Somers ;; 9262fae26bdSAlan Somers *) fs=$mtpt 9272fae26bdSAlan Somers ;; 9282fae26bdSAlan Somers esac 9292fae26bdSAlan Somers fi 9302fae26bdSAlan Somers fi 9312fae26bdSAlan Somers 9322fae26bdSAlan Somers for mtpt in `$SHARE | $AWK '{print $2}'` ; do 9332fae26bdSAlan Somers if [[ $mtpt == $fs ]] ; then 9342fae26bdSAlan Somers return 0 9352fae26bdSAlan Somers fi 9362fae26bdSAlan Somers done 9372fae26bdSAlan Somers 9382fae26bdSAlan Somers typeset stat=$($SVCS -H -o STA nfs/server:default) 9392fae26bdSAlan Somers if [[ $stat != "ON" ]]; then 9402fae26bdSAlan Somers log_note "Current nfs/server status: $stat" 9412fae26bdSAlan Somers fi 9422fae26bdSAlan Somers 9432fae26bdSAlan Somers return 1 9442fae26bdSAlan Somers} 9452fae26bdSAlan Somers 9462fae26bdSAlan Somers# 9472fae26bdSAlan Somers# Given a mountpoint, determine if it is not shared. 9482fae26bdSAlan Somers# 9492fae26bdSAlan Somers# Returns 0 if not shared, 1 otherwise. 9502fae26bdSAlan Somers# 9512fae26bdSAlan Somersfunction not_shared 9522fae26bdSAlan Somers{ 9532fae26bdSAlan Somers typeset fs=$1 9542fae26bdSAlan Somers 9552fae26bdSAlan Somers is_shared $fs 9562fae26bdSAlan Somers if (( $? == 0)); then 9572fae26bdSAlan Somers return 1 9582fae26bdSAlan Somers fi 9592fae26bdSAlan Somers 9602fae26bdSAlan Somers return 0 9612fae26bdSAlan Somers} 9622fae26bdSAlan Somers 9632fae26bdSAlan Somers# 9642fae26bdSAlan Somers# Helper function to unshare a mountpoint. 9652fae26bdSAlan Somers# 9662fae26bdSAlan Somersfunction unshare_fs #fs 9672fae26bdSAlan Somers{ 9682fae26bdSAlan Somers typeset fs=$1 9692fae26bdSAlan Somers 9702fae26bdSAlan Somers is_shared $fs 9712fae26bdSAlan Somers if (( $? == 0 )); then 9722fae26bdSAlan Somers log_must $ZFS unshare $fs 9732fae26bdSAlan Somers fi 9742fae26bdSAlan Somers 9752fae26bdSAlan Somers return 0 9762fae26bdSAlan Somers} 9772fae26bdSAlan Somers 9782fae26bdSAlan Somers# 9792fae26bdSAlan Somers# Check NFS server status and trigger it online. 9802fae26bdSAlan Somers# 9812fae26bdSAlan Somersfunction setup_nfs_server 9822fae26bdSAlan Somers{ 9832fae26bdSAlan Somers # Cannot share directory in non-global zone. 9842fae26bdSAlan Somers # 9852fae26bdSAlan Somers if ! is_global_zone; then 9862fae26bdSAlan Somers log_note "Cannot trigger NFS server by sharing in LZ." 9872fae26bdSAlan Somers return 9882fae26bdSAlan Somers fi 9892fae26bdSAlan Somers 9902fae26bdSAlan Somers typeset nfs_fmri="svc:/network/nfs/server:default" 9912fae26bdSAlan Somers if [[ $($SVCS -Ho STA $nfs_fmri) != "ON" ]]; then 9922fae26bdSAlan Somers # 9932fae26bdSAlan Somers # Only really sharing operation can enable NFS server 9942fae26bdSAlan Somers # to online permanently. 9952fae26bdSAlan Somers # 9962fae26bdSAlan Somers typeset dummy=$TMPDIR/dummy 9972fae26bdSAlan Somers 9982fae26bdSAlan Somers if [[ -d $dummy ]]; then 9992fae26bdSAlan Somers log_must $RM -rf $dummy 10002fae26bdSAlan Somers fi 10012fae26bdSAlan Somers 10022fae26bdSAlan Somers log_must $MKDIR $dummy 10032fae26bdSAlan Somers log_must $SHARE $dummy 10042fae26bdSAlan Somers 10052fae26bdSAlan Somers # 10062fae26bdSAlan Somers # Waiting for fmri's status to be the final status. 10072fae26bdSAlan Somers # Otherwise, in transition, an asterisk (*) is appended for 10082fae26bdSAlan Somers # instances, unshare will reverse status to 'DIS' again. 10092fae26bdSAlan Somers # 10102fae26bdSAlan Somers # Waiting for 1's at least. 10112fae26bdSAlan Somers # 10122fae26bdSAlan Somers log_must $SLEEP 1 10132fae26bdSAlan Somers timeout=10 10142fae26bdSAlan Somers while [[ timeout -ne 0 && $($SVCS -Ho STA $nfs_fmri) == *'*' ]] 10152fae26bdSAlan Somers do 10162fae26bdSAlan Somers log_must $SLEEP 1 10172fae26bdSAlan Somers 10182fae26bdSAlan Somers (( timeout -= 1 )) 10192fae26bdSAlan Somers done 10202fae26bdSAlan Somers 10212fae26bdSAlan Somers log_must $UNSHARE $dummy 10222fae26bdSAlan Somers log_must $RM -rf $dummy 10232fae26bdSAlan Somers fi 10242fae26bdSAlan Somers 10252fae26bdSAlan Somers log_note "Current NFS status: '$($SVCS -Ho STA,FMRI $nfs_fmri)'" 10262fae26bdSAlan Somers} 10272fae26bdSAlan Somers 10282fae26bdSAlan Somers# 10292fae26bdSAlan Somers# To verify whether calling process is in global zone 10302fae26bdSAlan Somers# 10312fae26bdSAlan Somers# Return 0 if in global zone, 1 in non-global zone 10322fae26bdSAlan Somers# 10332fae26bdSAlan Somersfunction is_global_zone 10342fae26bdSAlan Somers{ 10352fae26bdSAlan Somers typeset cur_zone=$($ZONENAME 2>/dev/null) 10362fae26bdSAlan Somers 10372fae26bdSAlan Somers # Zones are not supported on FreeBSD. 10382fae26bdSAlan Somers if [[ $os_name == "FreeBSD" ]]; then 10392fae26bdSAlan Somers return 0 10402fae26bdSAlan Somers fi 10412fae26bdSAlan Somers 10422fae26bdSAlan Somers if [[ $cur_zone != "global" ]]; then 10432fae26bdSAlan Somers return 1 10442fae26bdSAlan Somers fi 10452fae26bdSAlan Somers return 0 10462fae26bdSAlan Somers} 10472fae26bdSAlan Somers 10482fae26bdSAlan Somers# 10492fae26bdSAlan Somers# Verify whether test is permit to run from 10502fae26bdSAlan Somers# global zone, local zone, or both 10512fae26bdSAlan Somers# 10522fae26bdSAlan Somers# $1 zone limit, could be "global", "local", or "both"(no limit) 10532fae26bdSAlan Somers# 10542fae26bdSAlan Somers# Return 0 if permit, otherwise exit with log_unsupported 10552fae26bdSAlan Somers# 10562fae26bdSAlan Somersfunction verify_runnable # zone limit 10572fae26bdSAlan Somers{ 10582fae26bdSAlan Somers typeset limit=$1 10592fae26bdSAlan Somers 10602fae26bdSAlan Somers [[ -z $limit ]] && return 0 10612fae26bdSAlan Somers 10622fae26bdSAlan Somers if is_global_zone ; then 10632fae26bdSAlan Somers case $limit in 10642fae26bdSAlan Somers global|both) 10652fae26bdSAlan Somers break 10662fae26bdSAlan Somers ;; 10672fae26bdSAlan Somers local) log_unsupported "Test is unable to run from \ 10682fae26bdSAlan Somers global zone." 10692fae26bdSAlan Somers break 10702fae26bdSAlan Somers ;; 10712fae26bdSAlan Somers *) log_note "Warning: unknown limit $limit - use both." 10722fae26bdSAlan Somers ;; 10732fae26bdSAlan Somers esac 10742fae26bdSAlan Somers else 10752fae26bdSAlan Somers case $limit in 10762fae26bdSAlan Somers local|both) 10772fae26bdSAlan Somers break 10782fae26bdSAlan Somers ;; 10792fae26bdSAlan Somers global) log_unsupported "Test is unable to run from \ 10802fae26bdSAlan Somers local zone." 10812fae26bdSAlan Somers break 10822fae26bdSAlan Somers ;; 10832fae26bdSAlan Somers *) log_note "Warning: unknown limit $limit - use both." 10842fae26bdSAlan Somers ;; 10852fae26bdSAlan Somers esac 10862fae26bdSAlan Somers 10872fae26bdSAlan Somers reexport_pool 10882fae26bdSAlan Somers fi 10892fae26bdSAlan Somers 10902fae26bdSAlan Somers return 0 10912fae26bdSAlan Somers} 10922fae26bdSAlan Somers 10932fae26bdSAlan Somers# Return 0 if create successfully or the pool exists; $? otherwise 10942fae26bdSAlan Somers# Note: In local zones, this function should return 0 silently. 10952fae26bdSAlan Somers# 10962fae26bdSAlan Somers# $1 - pool name 10972fae26bdSAlan Somers# $2-n - [keyword] devs_list 10982fae26bdSAlan Somers 10992fae26bdSAlan Somersfunction create_pool #pool devs_list 11002fae26bdSAlan Somers{ 11012fae26bdSAlan Somers typeset pool=${1%%/*} 11022fae26bdSAlan Somers 11032fae26bdSAlan Somers shift 11042fae26bdSAlan Somers 11052fae26bdSAlan Somers if [[ -z $pool ]]; then 11062fae26bdSAlan Somers log_note "Missing pool name." 11072fae26bdSAlan Somers return 1 11082fae26bdSAlan Somers fi 11092fae26bdSAlan Somers 11102fae26bdSAlan Somers if poolexists $pool ; then 11112fae26bdSAlan Somers destroy_pool $pool 11122fae26bdSAlan Somers fi 11132fae26bdSAlan Somers 11142fae26bdSAlan Somers if is_global_zone ; then 11152fae26bdSAlan Somers [[ -d /$pool ]] && $RM -rf /$pool 11162fae26bdSAlan Somers log_must $ZPOOL create -f $pool $@ 11172fae26bdSAlan Somers fi 11182fae26bdSAlan Somers 11192fae26bdSAlan Somers return 0 11202fae26bdSAlan Somers} 11212fae26bdSAlan Somers 11222fae26bdSAlan Somers# Return 0 if destroy successfully or the pool exists; $? otherwise 11232fae26bdSAlan Somers# Note: In local zones, this function should return 0 silently. 11242fae26bdSAlan Somers# 11252fae26bdSAlan Somers# $1 - pool name 11262fae26bdSAlan Somers# Destroy pool with the given parameters. 11272fae26bdSAlan Somers 11282fae26bdSAlan Somersfunction destroy_pool #pool 11292fae26bdSAlan Somers{ 11302fae26bdSAlan Somers typeset pool=${1%%/*} 11312fae26bdSAlan Somers typeset mtpt 11322fae26bdSAlan Somers 11332fae26bdSAlan Somers if [[ -z $pool ]]; then 11342fae26bdSAlan Somers log_note "No pool name given." 11352fae26bdSAlan Somers return 1 11362fae26bdSAlan Somers fi 11372fae26bdSAlan Somers 11382fae26bdSAlan Somers if is_global_zone ; then 11392fae26bdSAlan Somers if poolexists "$pool" ; then 11402fae26bdSAlan Somers mtpt=$(get_prop mountpoint "$pool") 11412fae26bdSAlan Somers log_must $ZPOOL destroy -f $pool 11422fae26bdSAlan Somers 11432fae26bdSAlan Somers [[ -d $mtpt ]] && \ 11442fae26bdSAlan Somers log_must $RM -rf $mtpt 11452fae26bdSAlan Somers else 11462fae26bdSAlan Somers log_note "Pool $pool does not exist, skipping destroy." 11472fae26bdSAlan Somers return 1 11482fae26bdSAlan Somers fi 11492fae26bdSAlan Somers fi 11502fae26bdSAlan Somers 11512fae26bdSAlan Somers return 0 11522fae26bdSAlan Somers} 11532fae26bdSAlan Somers 11542fae26bdSAlan Somers# 11552fae26bdSAlan Somers# Create file vdevs. 11562fae26bdSAlan Somers# By default this generates sparse vdevs 10GB in size, for performance. 11572fae26bdSAlan Somers# 11582fae26bdSAlan Somersfunction create_vdevs # vdevs 11592fae26bdSAlan Somers{ 11602fae26bdSAlan Somers typeset vdsize=10G 11612fae26bdSAlan Somers 11622fae26bdSAlan Somers [ -n "$VDEV_SIZE" ] && vdsize=$VDEV_SIZE 11632fae26bdSAlan Somers rm -f $@ || return 1 11642fae26bdSAlan Somers truncate -s $vdsize $@ 11652fae26bdSAlan Somers} 11662fae26bdSAlan Somers 11672fae26bdSAlan Somers# 11682fae26bdSAlan Somers# Firstly, create a pool with 5 datasets. Then, create a single zone and 11692fae26bdSAlan Somers# export the 5 datasets to it. In addition, we also add a ZFS filesystem 11702fae26bdSAlan Somers# and a zvol device to the zone. 11712fae26bdSAlan Somers# 11722fae26bdSAlan Somers# $1 zone name 11732fae26bdSAlan Somers# $2 zone root directory prefix 11742fae26bdSAlan Somers# $3 zone ip 11752fae26bdSAlan Somers# 11762fae26bdSAlan Somersfunction zfs_zones_setup #zone_name zone_root zone_ip 11772fae26bdSAlan Somers{ 11782fae26bdSAlan Somers typeset zone_name=${1:-$(hostname)-z} 11792fae26bdSAlan Somers typeset zone_root=${2:-"/zone_root"} 11802fae26bdSAlan Somers typeset zone_ip=${3:-"10.1.1.10"} 11812fae26bdSAlan Somers typeset prefix_ctr=$ZONE_CTR 11822fae26bdSAlan Somers typeset pool_name=$ZONE_POOL 11832fae26bdSAlan Somers typeset -i cntctr=5 11842fae26bdSAlan Somers typeset -i i=0 11852fae26bdSAlan Somers 11862fae26bdSAlan Somers # Create pool and 5 container within it 11872fae26bdSAlan Somers # 11882fae26bdSAlan Somers [[ -d /$pool_name ]] && $RM -rf /$pool_name 11892fae26bdSAlan Somers log_must $ZPOOL create -f $pool_name $DISKS 11902fae26bdSAlan Somers while (( i < cntctr )); do 11912fae26bdSAlan Somers log_must $ZFS create $pool_name/$prefix_ctr$i 11922fae26bdSAlan Somers (( i += 1 )) 11932fae26bdSAlan Somers done 11942fae26bdSAlan Somers 11952fae26bdSAlan Somers # create a zvol 11962fae26bdSAlan Somers log_must $ZFS create -V 1g $pool_name/zone_zvol 11972fae26bdSAlan Somers 11982fae26bdSAlan Somers # 11992fae26bdSAlan Somers # If current system support slog, add slog device for pool 12002fae26bdSAlan Somers # 12012fae26bdSAlan Somers typeset sdevs="$TMPDIR/sdev1 $TMPDIR/sdev2" 12022fae26bdSAlan Somers log_must create_vdevs $sdevs 12032fae26bdSAlan Somers log_must $ZPOOL add $pool_name log mirror $sdevs 12042fae26bdSAlan Somers 12052fae26bdSAlan Somers # this isn't supported just yet. 12062fae26bdSAlan Somers # Create a filesystem. In order to add this to 12072fae26bdSAlan Somers # the zone, it must have it's mountpoint set to 'legacy' 12082fae26bdSAlan Somers # log_must $ZFS create $pool_name/zfs_filesystem 12092fae26bdSAlan Somers # log_must $ZFS set mountpoint=legacy $pool_name/zfs_filesystem 12102fae26bdSAlan Somers 12112fae26bdSAlan Somers [[ -d $zone_root ]] && \ 12122fae26bdSAlan Somers log_must $RM -rf $zone_root/$zone_name 12132fae26bdSAlan Somers [[ ! -d $zone_root ]] && \ 12142fae26bdSAlan Somers log_must $MKDIR -p -m 0700 $zone_root/$zone_name 12152fae26bdSAlan Somers 12162fae26bdSAlan Somers # Create zone configure file and configure the zone 12172fae26bdSAlan Somers # 12182fae26bdSAlan Somers typeset zone_conf=$TMPDIR/zone_conf.${TESTCASE_ID} 12192fae26bdSAlan Somers $ECHO "create" > $zone_conf 12202fae26bdSAlan Somers $ECHO "set zonepath=$zone_root/$zone_name" >> $zone_conf 12212fae26bdSAlan Somers $ECHO "set autoboot=true" >> $zone_conf 12222fae26bdSAlan Somers i=0 12232fae26bdSAlan Somers while (( i < cntctr )); do 12242fae26bdSAlan Somers $ECHO "add dataset" >> $zone_conf 12252fae26bdSAlan Somers $ECHO "set name=$pool_name/$prefix_ctr$i" >> \ 12262fae26bdSAlan Somers $zone_conf 12272fae26bdSAlan Somers $ECHO "end" >> $zone_conf 12282fae26bdSAlan Somers (( i += 1 )) 12292fae26bdSAlan Somers done 12302fae26bdSAlan Somers 12312fae26bdSAlan Somers # add our zvol to the zone 12322fae26bdSAlan Somers $ECHO "add device" >> $zone_conf 12335a2fc464SAndriy Gapon $ECHO "set match=/dev/zvol/$pool_name/zone_zvol" >> $zone_conf 12342fae26bdSAlan Somers $ECHO "end" >> $zone_conf 12352fae26bdSAlan Somers 12365a2fc464SAndriy Gapon # add a corresponding zvol to the zone 12372fae26bdSAlan Somers $ECHO "add device" >> $zone_conf 12385a2fc464SAndriy Gapon $ECHO "set match=/dev/zvol/$pool_name/zone_zvol" >> $zone_conf 12392fae26bdSAlan Somers $ECHO "end" >> $zone_conf 12402fae26bdSAlan Somers 12412fae26bdSAlan Somers # once it's supported, we'll add our filesystem to the zone 12422fae26bdSAlan Somers # $ECHO "add fs" >> $zone_conf 12432fae26bdSAlan Somers # $ECHO "set type=zfs" >> $zone_conf 12442fae26bdSAlan Somers # $ECHO "set special=$pool_name/zfs_filesystem" >> $zone_conf 12452fae26bdSAlan Somers # $ECHO "set dir=/export/zfs_filesystem" >> $zone_conf 12462fae26bdSAlan Somers # $ECHO "end" >> $zone_conf 12472fae26bdSAlan Somers 12482fae26bdSAlan Somers $ECHO "verify" >> $zone_conf 12492fae26bdSAlan Somers $ECHO "commit" >> $zone_conf 12502fae26bdSAlan Somers log_must $ZONECFG -z $zone_name -f $zone_conf 12512fae26bdSAlan Somers log_must $RM -f $zone_conf 12522fae26bdSAlan Somers 12532fae26bdSAlan Somers # Install the zone 12542fae26bdSAlan Somers $ZONEADM -z $zone_name install 12552fae26bdSAlan Somers if (( $? == 0 )); then 12562fae26bdSAlan Somers log_note "SUCCESS: $ZONEADM -z $zone_name install" 12572fae26bdSAlan Somers else 12582fae26bdSAlan Somers log_fail "FAIL: $ZONEADM -z $zone_name install" 12592fae26bdSAlan Somers fi 12602fae26bdSAlan Somers 12612fae26bdSAlan Somers # Install sysidcfg file 12622fae26bdSAlan Somers # 12632fae26bdSAlan Somers typeset sysidcfg=$zone_root/$zone_name/root/etc/sysidcfg 12642fae26bdSAlan Somers $ECHO "system_locale=C" > $sysidcfg 12652fae26bdSAlan Somers $ECHO "terminal=dtterm" >> $sysidcfg 12662fae26bdSAlan Somers $ECHO "network_interface=primary {" >> $sysidcfg 12672fae26bdSAlan Somers $ECHO "hostname=$zone_name" >> $sysidcfg 12682fae26bdSAlan Somers $ECHO "}" >> $sysidcfg 12692fae26bdSAlan Somers $ECHO "name_service=NONE" >> $sysidcfg 12702fae26bdSAlan Somers $ECHO "root_password=mo791xfZ/SFiw" >> $sysidcfg 12712fae26bdSAlan Somers $ECHO "security_policy=NONE" >> $sysidcfg 12722fae26bdSAlan Somers $ECHO "timezone=US/Eastern" >> $sysidcfg 12732fae26bdSAlan Somers 12742fae26bdSAlan Somers # Boot this zone 12752fae26bdSAlan Somers log_must $ZONEADM -z $zone_name boot 12762fae26bdSAlan Somers} 12772fae26bdSAlan Somers 12782fae26bdSAlan Somers# 12792fae26bdSAlan Somers# Reexport TESTPOOL & TESTPOOL(1-4) 12802fae26bdSAlan Somers# 12812fae26bdSAlan Somersfunction reexport_pool 12822fae26bdSAlan Somers{ 12832fae26bdSAlan Somers typeset -i cntctr=5 12842fae26bdSAlan Somers typeset -i i=0 12852fae26bdSAlan Somers 12862fae26bdSAlan Somers while (( i < cntctr )); do 12872fae26bdSAlan Somers if (( i == 0 )); then 12882fae26bdSAlan Somers TESTPOOL=$ZONE_POOL/$ZONE_CTR$i 12892fae26bdSAlan Somers if ! ismounted $TESTPOOL; then 12902fae26bdSAlan Somers log_must $ZFS mount $TESTPOOL 12912fae26bdSAlan Somers fi 12922fae26bdSAlan Somers else 12932fae26bdSAlan Somers eval TESTPOOL$i=$ZONE_POOL/$ZONE_CTR$i 12942fae26bdSAlan Somers if eval ! ismounted \$TESTPOOL$i; then 12952fae26bdSAlan Somers log_must eval $ZFS mount \$TESTPOOL$i 12962fae26bdSAlan Somers fi 12972fae26bdSAlan Somers fi 12982fae26bdSAlan Somers (( i += 1 )) 12992fae26bdSAlan Somers done 13002fae26bdSAlan Somers} 13012fae26bdSAlan Somers 13022fae26bdSAlan Somers# 13032fae26bdSAlan Somers# Wait for something to return true, checked by the caller. 13042fae26bdSAlan Somers# 13052fae26bdSAlan Somersfunction wait_for_checked # timeout dt <method> [args...] 13062fae26bdSAlan Somers{ 13072fae26bdSAlan Somers typeset timeout=$1 13082fae26bdSAlan Somers typeset dt=$2 13092fae26bdSAlan Somers shift; shift 13102fae26bdSAlan Somers typeset -i start=$(date '+%s') 13112fae26bdSAlan Somers typeset -i endtime 13122fae26bdSAlan Somers 13132fae26bdSAlan Somers log_note "Waiting $timeout seconds (checked every $dt seconds) for: $*" 13142fae26bdSAlan Somers ((endtime = start + timeout)) 13152fae26bdSAlan Somers while :; do 13162fae26bdSAlan Somers $* 13172fae26bdSAlan Somers [ $? -eq 0 ] && return 13182fae26bdSAlan Somers curtime=$(date '+%s') 13192fae26bdSAlan Somers [ $curtime -gt $endtime ] && return 1 13202fae26bdSAlan Somers sleep $dt 13212fae26bdSAlan Somers done 13222fae26bdSAlan Somers return 0 13232fae26bdSAlan Somers} 13242fae26bdSAlan Somers 13252fae26bdSAlan Somers# 13262fae26bdSAlan Somers# Wait for something to return true. 13272fae26bdSAlan Somers# 13282fae26bdSAlan Somersfunction wait_for # timeout dt <method> [args...] 13292fae26bdSAlan Somers{ 13302fae26bdSAlan Somers typeset timeout=$1 13312fae26bdSAlan Somers typeset dt=$2 13322fae26bdSAlan Somers shift; shift 13332fae26bdSAlan Somers 13342fae26bdSAlan Somers wait_for_checked $timeout $dt $* || \ 13352fae26bdSAlan Somers log_fail "ERROR: Timed out waiting for: $*" 13362fae26bdSAlan Somers} 13372fae26bdSAlan Somers 13382fae26bdSAlan Somers# 13392fae26bdSAlan Somers# Verify a given disk is online or offline 13402fae26bdSAlan Somers# 13412fae26bdSAlan Somers# Return 0 is pool/disk matches expected state, 1 otherwise 13422fae26bdSAlan Somers# stateexpr is a regex like ONLINE or REMOVED|UNAVAIL 13432fae26bdSAlan Somers# 13442fae26bdSAlan Somersfunction check_state # pool disk stateexpr 13452fae26bdSAlan Somers{ 13462fae26bdSAlan Somers typeset pool=$1 13475a2fc464SAndriy Gapon typeset disk=${2#/dev/} 13485a2fc464SAndriy Gapon disk=${disk#/dev/} 13492fae26bdSAlan Somers disk=${disk#/dev/} 13502fae26bdSAlan Somers typeset stateexpr=$3 13512fae26bdSAlan Somers 13522fae26bdSAlan Somers $ZPOOL status -v $pool | grep "$disk" \ 13532fae26bdSAlan Somers | egrep -i "$stateexpr" > /dev/null 2>&1 13542fae26bdSAlan Somers 13552fae26bdSAlan Somers return $? 13562fae26bdSAlan Somers} 13572fae26bdSAlan Somers 13582fae26bdSAlan Somers# 13592fae26bdSAlan Somers# Wait for a given disk to leave a state 13602fae26bdSAlan Somers# 13612fae26bdSAlan Somersfunction wait_for_state_exit 13622fae26bdSAlan Somers{ 13632fae26bdSAlan Somers typeset pool=$1 13642fae26bdSAlan Somers typeset disk=$2 13652fae26bdSAlan Somers typeset state=$3 13662fae26bdSAlan Somers 13672fae26bdSAlan Somers while check_state "$pool" "$disk" "$state"; do 13682fae26bdSAlan Somers $SLEEP 1 13692fae26bdSAlan Somers done 13702fae26bdSAlan Somers} 13712fae26bdSAlan Somers 13722fae26bdSAlan Somers# 13732fae26bdSAlan Somers# Wait for a given disk to enter a state 13742fae26bdSAlan Somers# 13752fae26bdSAlan Somersfunction wait_for_state_enter 13762fae26bdSAlan Somers{ 13772fae26bdSAlan Somers typeset -i timeout=$1 13782fae26bdSAlan Somers typeset pool=$2 13792fae26bdSAlan Somers typeset disk=$3 13802fae26bdSAlan Somers typeset state=$4 13812fae26bdSAlan Somers 13822fae26bdSAlan Somers log_note "Waiting up to $timeout seconds for $disk to become $state ..." 13832fae26bdSAlan Somers for ((; $timeout > 0; timeout=$timeout-1)); do 13842fae26bdSAlan Somers check_state $pool "$disk" "$state" 13852fae26bdSAlan Somers [ $? -eq 0 ] && return 13862fae26bdSAlan Somers $SLEEP 1 13872fae26bdSAlan Somers done 13882fae26bdSAlan Somers log_must $ZPOOL status $pool 13892fae26bdSAlan Somers log_fail "ERROR: Disk $disk not marked as $state in $pool" 13902fae26bdSAlan Somers} 13912fae26bdSAlan Somers 13922fae26bdSAlan Somers# 13932fae26bdSAlan Somers# Get the mountpoint of snapshot 13942fae26bdSAlan Somers# as its mountpoint 13952fae26bdSAlan Somers# 13962fae26bdSAlan Somersfunction snapshot_mountpoint 13972fae26bdSAlan Somers{ 13982fae26bdSAlan Somers typeset dataset=${1:-$TESTPOOL/$TESTFS@$TESTSNAP} 13992fae26bdSAlan Somers 14002fae26bdSAlan Somers if [[ $dataset != *@* ]]; then 14012fae26bdSAlan Somers log_fail "Error name of snapshot '$dataset'." 14022fae26bdSAlan Somers fi 14032fae26bdSAlan Somers 14042fae26bdSAlan Somers typeset fs=${dataset%@*} 14052fae26bdSAlan Somers typeset snap=${dataset#*@} 14062fae26bdSAlan Somers 14072fae26bdSAlan Somers if [[ -z $fs || -z $snap ]]; then 14082fae26bdSAlan Somers log_fail "Error name of snapshot '$dataset'." 14092fae26bdSAlan Somers fi 14102fae26bdSAlan Somers 14112fae26bdSAlan Somers $ECHO $(get_prop mountpoint $fs)/$(get_snapdir_name)/$snap 14122fae26bdSAlan Somers} 14132fae26bdSAlan Somers 14142fae26bdSAlan Somersfunction pool_maps_intact # pool 14152fae26bdSAlan Somers{ 14162fae26bdSAlan Somers typeset pool="$1" 14172fae26bdSAlan Somers 14182fae26bdSAlan Somers if ! $ZDB -bcv $pool; then 14192fae26bdSAlan Somers return 1 14202fae26bdSAlan Somers fi 14212fae26bdSAlan Somers return 0 14222fae26bdSAlan Somers} 14232fae26bdSAlan Somers 14242fae26bdSAlan Somersfunction filesys_has_zil # filesystem 14252fae26bdSAlan Somers{ 14262fae26bdSAlan Somers typeset filesys="$1" 14272fae26bdSAlan Somers 14282fae26bdSAlan Somers if ! $ZDB -ivv $filesys | $GREP "ZIL header"; then 14292fae26bdSAlan Somers return 1 14302fae26bdSAlan Somers fi 14312fae26bdSAlan Somers return 0 14322fae26bdSAlan Somers} 14332fae26bdSAlan Somers 14342fae26bdSAlan Somers# 14352fae26bdSAlan Somers# Given a pool and file system, this function will verify the file system 14362fae26bdSAlan Somers# using the zdb internal tool. Note that the pool is exported and imported 14372fae26bdSAlan Somers# to ensure it has consistent state. 14382fae26bdSAlan Somers# 14392fae26bdSAlan Somersfunction verify_filesys # pool filesystem dir 14402fae26bdSAlan Somers{ 14412fae26bdSAlan Somers typeset pool="$1" 14422fae26bdSAlan Somers typeset filesys="$2" 14432fae26bdSAlan Somers typeset zdbout="$TMPDIR/zdbout.${TESTCASE_ID}" 14442fae26bdSAlan Somers 14452fae26bdSAlan Somers shift 14462fae26bdSAlan Somers shift 14472fae26bdSAlan Somers typeset dirs=$@ 14482fae26bdSAlan Somers typeset search_path="" 14492fae26bdSAlan Somers 14502fae26bdSAlan Somers log_note "Calling $ZDB to verify filesystem '$filesys'" 14512fae26bdSAlan Somers log_must $ZPOOL export $pool 14522fae26bdSAlan Somers 14532fae26bdSAlan Somers if [[ -n $dirs ]] ; then 14542fae26bdSAlan Somers for dir in $dirs ; do 14552fae26bdSAlan Somers search_path="$search_path -d $dir" 14562fae26bdSAlan Somers done 14572fae26bdSAlan Somers fi 14582fae26bdSAlan Somers 14592fae26bdSAlan Somers log_must $ZPOOL import $search_path $pool 14602fae26bdSAlan Somers 14612fae26bdSAlan Somers $ZDB -cudi $filesys > $zdbout 2>&1 14622fae26bdSAlan Somers if [[ $? != 0 ]]; then 14632fae26bdSAlan Somers log_note "Output: $ZDB -cudi $filesys" 14642fae26bdSAlan Somers $CAT $zdbout 14652fae26bdSAlan Somers log_fail "$ZDB detected errors with: '$filesys'" 14662fae26bdSAlan Somers fi 14672fae26bdSAlan Somers 14682fae26bdSAlan Somers log_must $RM -rf $zdbout 14692fae26bdSAlan Somers} 14702fae26bdSAlan Somers 14712fae26bdSAlan Somers# 14722fae26bdSAlan Somers# Given a pool, and this function list all disks in the pool 14732fae26bdSAlan Somers# 14742fae26bdSAlan Somersfunction get_disklist # pool 14752fae26bdSAlan Somers{ 14762fae26bdSAlan Somers typeset disklist="" 14772fae26bdSAlan Somers 14782fae26bdSAlan Somers disklist=$($ZPOOL iostat -v $1 | $NAWK '(NR >4 ) {print $1}' | \ 14792fae26bdSAlan Somers $GREP -v "\-\-\-\-\-" | \ 14802fae26bdSAlan Somers $EGREP -v -e "^(mirror|raidz1|raidz2|spare|log|cache)$" ) 14812fae26bdSAlan Somers 14822fae26bdSAlan Somers $ECHO $disklist 14832fae26bdSAlan Somers} 14842fae26bdSAlan Somers 14852fae26bdSAlan Somers# 14862fae26bdSAlan Somers# Destroy all existing metadevices and state database 14872fae26bdSAlan Somers# 14882fae26bdSAlan Somersfunction destroy_metas 14892fae26bdSAlan Somers{ 14902fae26bdSAlan Somers typeset metad 14912fae26bdSAlan Somers 14922fae26bdSAlan Somers for metad in $($METASTAT -p | $AWK '{print $1}'); do 14932fae26bdSAlan Somers log_must $METACLEAR -rf $metad 14942fae26bdSAlan Somers done 14952fae26bdSAlan Somers 14962fae26bdSAlan Somers for metad in $($METADB | $CUT -f6 | $GREP dev | $UNIQ); do 14972fae26bdSAlan Somers log_must $METADB -fd $metad 14982fae26bdSAlan Somers done 14992fae26bdSAlan Somers} 15002fae26bdSAlan Somers 15012fae26bdSAlan Somers# /** 15022fae26bdSAlan Somers# This function kills a given list of processes after a time period. We use 15032fae26bdSAlan Somers# this in the stress tests instead of STF_TIMEOUT so that we can have processes 15042fae26bdSAlan Somers# run for a fixed amount of time, yet still pass. Tests that hit STF_TIMEOUT 15052fae26bdSAlan Somers# would be listed as FAIL, which we don't want : we're happy with stress tests 15062fae26bdSAlan Somers# running for a certain amount of time, then finishing. 15072fae26bdSAlan Somers# 15082fae26bdSAlan Somers# @param $1 the time in seconds after which we should terminate these processes 15092fae26bdSAlan Somers# @param $2..$n the processes we wish to terminate. 15102fae26bdSAlan Somers# */ 15112fae26bdSAlan Somersfunction stress_timeout 15122fae26bdSAlan Somers{ 15132fae26bdSAlan Somers typeset -i TIMEOUT=$1 15142fae26bdSAlan Somers shift 15152fae26bdSAlan Somers typeset cpids="$@" 15162fae26bdSAlan Somers 15172fae26bdSAlan Somers log_note "Waiting for child processes($cpids). " \ 15182fae26bdSAlan Somers "It could last dozens of minutes, please be patient ..." 15192fae26bdSAlan Somers log_must $SLEEP $TIMEOUT 15202fae26bdSAlan Somers 15212fae26bdSAlan Somers log_note "Killing child processes after ${TIMEOUT} stress timeout." 15222fae26bdSAlan Somers typeset pid 15232fae26bdSAlan Somers for pid in $cpids; do 15242fae26bdSAlan Somers $PS -p $pid > /dev/null 2>&1 15252fae26bdSAlan Somers if (( $? == 0 )); then 15262fae26bdSAlan Somers log_must $KILL -USR1 $pid 15272fae26bdSAlan Somers fi 15282fae26bdSAlan Somers done 15292fae26bdSAlan Somers} 15302fae26bdSAlan Somers 15312fae26bdSAlan Somers# 15322fae26bdSAlan Somers# Check whether current OS support a specified feature or not 15332fae26bdSAlan Somers# 15342fae26bdSAlan Somers# return 0 if current OS version is in unsupported list, 1 otherwise 15352fae26bdSAlan Somers# 15362fae26bdSAlan Somers# $1 unsupported target OS versions 15372fae26bdSAlan Somers# 15382fae26bdSAlan Somersfunction check_version # <OS version> 15392fae26bdSAlan Somers{ 15402fae26bdSAlan Somers typeset unsupported_vers="$@" 15412fae26bdSAlan Somers typeset ver 15422fae26bdSAlan Somers typeset cur_ver=`$UNAME -r` 15432fae26bdSAlan Somers 15442fae26bdSAlan Somers for ver in $unsupported_vers; do 15452fae26bdSAlan Somers [[ "$cur_ver" == "$ver" ]] && return 0 15462fae26bdSAlan Somers done 15472fae26bdSAlan Somers 15482fae26bdSAlan Somers return 1 15492fae26bdSAlan Somers} 15502fae26bdSAlan Somers 15512fae26bdSAlan Somers# 15522fae26bdSAlan Somers# Verify a given hotspare disk is inuse or avail 15532fae26bdSAlan Somers# 15542fae26bdSAlan Somers# Return 0 is pool/disk matches expected state, 1 otherwise 15552fae26bdSAlan Somers# 15562fae26bdSAlan Somersfunction check_hotspare_state # pool disk state{inuse,avail} 15572fae26bdSAlan Somers{ 15582fae26bdSAlan Somers typeset pool=$1 15595a2fc464SAndriy Gapon typeset disk=${2#/dev/} 15605a2fc464SAndriy Gapon disk=${disk#/dev/} 15612fae26bdSAlan Somers disk=${disk#/dev/} 15622fae26bdSAlan Somers typeset state=$3 15632fae26bdSAlan Somers 15642fae26bdSAlan Somers cur_state=$(get_device_state $pool $disk "spares") 15652fae26bdSAlan Somers 15662fae26bdSAlan Somers if [[ $state != ${cur_state} ]]; then 15672fae26bdSAlan Somers return 1 15682fae26bdSAlan Somers fi 15692fae26bdSAlan Somers return 0 15702fae26bdSAlan Somers} 15712fae26bdSAlan Somers 15722fae26bdSAlan Somers# 15732fae26bdSAlan Somers# Verify a given slog disk is inuse or avail 15742fae26bdSAlan Somers# 15752fae26bdSAlan Somers# Return 0 is pool/disk matches expected state, 1 otherwise 15762fae26bdSAlan Somers# 15772fae26bdSAlan Somersfunction check_slog_state # pool disk state{online,offline,unavail} 15782fae26bdSAlan Somers{ 15792fae26bdSAlan Somers typeset pool=$1 15805a2fc464SAndriy Gapon typeset disk=${2#/dev/} 15815a2fc464SAndriy Gapon disk=${disk#/dev/} 15822fae26bdSAlan Somers disk=${disk#/dev/} 15832fae26bdSAlan Somers typeset state=$3 15842fae26bdSAlan Somers 15852fae26bdSAlan Somers cur_state=$(get_device_state $pool $disk "logs") 15862fae26bdSAlan Somers 15872fae26bdSAlan Somers if [[ $state != ${cur_state} ]]; then 15882fae26bdSAlan Somers return 1 15892fae26bdSAlan Somers fi 15902fae26bdSAlan Somers return 0 15912fae26bdSAlan Somers} 15922fae26bdSAlan Somers 15932fae26bdSAlan Somers# 15942fae26bdSAlan Somers# Verify a given vdev disk is inuse or avail 15952fae26bdSAlan Somers# 15962fae26bdSAlan Somers# Return 0 is pool/disk matches expected state, 1 otherwise 15972fae26bdSAlan Somers# 15982fae26bdSAlan Somersfunction check_vdev_state # pool disk state{online,offline,unavail} 15992fae26bdSAlan Somers{ 16002fae26bdSAlan Somers typeset pool=$1 16015a2fc464SAndriy Gapon typeset disk=${2#/dev/} 16025a2fc464SAndriy Gapon disk=${disk#/dev/} 16032fae26bdSAlan Somers disk=${disk#/dev/} 16042fae26bdSAlan Somers typeset state=$3 16052fae26bdSAlan Somers 16062fae26bdSAlan Somers if [[ $WRAPPER == *"smi"* ]]; then 16072fae26bdSAlan Somers $ECHO $disk | $EGREP "^c[0-F]+([td][0-F]+)+$" > /dev/null 2>&1 16082fae26bdSAlan Somers if (( $? == 0 )); then 16092fae26bdSAlan Somers disk=${disk}s2 16102fae26bdSAlan Somers fi 16112fae26bdSAlan Somers fi 16122fae26bdSAlan Somers 16132fae26bdSAlan Somers cur_state=$(get_device_state $pool $disk) 16142fae26bdSAlan Somers 16152fae26bdSAlan Somers if [[ $state != ${cur_state} ]]; then 16162fae26bdSAlan Somers return 1 16172fae26bdSAlan Somers fi 16182fae26bdSAlan Somers return 0 16192fae26bdSAlan Somers} 16202fae26bdSAlan Somers 16212fae26bdSAlan Somers# 16222fae26bdSAlan Somers# Check the output of 'zpool status -v <pool>', 16232fae26bdSAlan Somers# and to see if the content of <token> contain the <keyword> specified. 16242fae26bdSAlan Somers# 16252fae26bdSAlan Somers# Return 0 is contain, 1 otherwise 16262fae26bdSAlan Somers# 16272fae26bdSAlan Somersfunction check_pool_status # pool token keyword 16282fae26bdSAlan Somers{ 16292fae26bdSAlan Somers typeset pool=$1 16302fae26bdSAlan Somers typeset token=$2 16312fae26bdSAlan Somers typeset keyword=$3 16322fae26bdSAlan Somers 16332fae26bdSAlan Somers $ZPOOL status -v "$pool" 2>/dev/null | \ 16342fae26bdSAlan Somers $NAWK -v token="$token:" '($1==token) {print $0}' | \ 16352fae26bdSAlan Somers $GREP -i "$keyword" >/dev/null 2>&1 16362fae26bdSAlan Somers 16372fae26bdSAlan Somers return $? 16382fae26bdSAlan Somers} 16392fae26bdSAlan Somers 16402fae26bdSAlan Somersfunction vdev_pool_error_count 16412fae26bdSAlan Somers{ 16422fae26bdSAlan Somers typeset errs=$1 16432fae26bdSAlan Somers if [ -z "$2" ]; then 16442fae26bdSAlan Somers test $errs -gt 0; ret=$? 16452fae26bdSAlan Somers else 16462fae26bdSAlan Somers test $errs -eq $2; ret=$? 16472fae26bdSAlan Somers fi 16482fae26bdSAlan Somers log_debug "vdev_pool_error_count: errs='$errs' \$2='$2' ret='$ret'" 16492fae26bdSAlan Somers return $ret 16502fae26bdSAlan Somers} 16512fae26bdSAlan Somers 16522fae26bdSAlan Somers# 16532fae26bdSAlan Somers# Generate a pool status error file suitable for pool_errors_from_file. 16542fae26bdSAlan Somers# If the pool is healthy, returns 0. Otherwise, the caller must handle the 16552fae26bdSAlan Somers# returned temporarily file appropriately. 16562fae26bdSAlan Somers# 16572fae26bdSAlan Somersfunction pool_error_file # <pool> 16582fae26bdSAlan Somers{ 16592fae26bdSAlan Somers typeset pool="$1" 16602fae26bdSAlan Somers 16612fae26bdSAlan Somers typeset tmpfile=$TMPDIR/pool_status.${TESTCASE_ID} 16622fae26bdSAlan Somers $ZPOOL status -x $pool > ${tmpfile} 16632fae26bdSAlan Somers echo $tmpfile 16642fae26bdSAlan Somers} 16652fae26bdSAlan Somers 16662fae26bdSAlan Somers# 16672fae26bdSAlan Somers# Evaluates <file> counting the number of errors. If vdev specified, only 16682fae26bdSAlan Somers# that vdev's errors are counted. Returns the total number. <file> will be 16692fae26bdSAlan Somers# deleted on exit. 16702fae26bdSAlan Somers# 16712fae26bdSAlan Somersfunction pool_errors_from_file # <file> [vdev] 16722fae26bdSAlan Somers{ 16732fae26bdSAlan Somers typeset file=$1 16742fae26bdSAlan Somers shift 16752fae26bdSAlan Somers typeset checkvdev="$2" 16762fae26bdSAlan Somers 16772fae26bdSAlan Somers typeset line 16782fae26bdSAlan Somers typeset -i fetchbegin=1 16792fae26bdSAlan Somers typeset -i errnum=0 16802fae26bdSAlan Somers typeset -i c_read=0 16812fae26bdSAlan Somers typeset -i c_write=0 16822fae26bdSAlan Somers typeset -i c_cksum=0 16832fae26bdSAlan Somers 16842fae26bdSAlan Somers cat ${file} | $EGREP -v "pool:" | while read line; do 16852fae26bdSAlan Somers if (( $fetchbegin != 0 )); then 16862fae26bdSAlan Somers $ECHO $line | $GREP "NAME" >/dev/null 2>&1 16872fae26bdSAlan Somers (( $? == 0 )) && (( fetchbegin = 0 )) 16882fae26bdSAlan Somers continue 16892fae26bdSAlan Somers fi 16902fae26bdSAlan Somers 16912fae26bdSAlan Somers if [[ -n $checkvdev ]]; then 16922fae26bdSAlan Somers $ECHO $line | $GREP $checkvdev >/dev/null 2>&1 16932fae26bdSAlan Somers (( $? != 0 )) && continue 16942fae26bdSAlan Somers c_read=`$ECHO $line | $AWK '{print $3}'` 16952fae26bdSAlan Somers c_write=`$ECHO $line | $AWK '{print $4}'` 16962fae26bdSAlan Somers c_cksum=`$ECHO $line | $AWK '{print $5}'` 16972fae26bdSAlan Somers if [ $c_read != 0 ] || [ $c_write != 0 ] || \ 16982fae26bdSAlan Somers [ $c_cksum != 0 ] 16992fae26bdSAlan Somers then 17002fae26bdSAlan Somers (( errnum = errnum + 1 )) 17012fae26bdSAlan Somers fi 17022fae26bdSAlan Somers break 17032fae26bdSAlan Somers fi 17042fae26bdSAlan Somers 17052fae26bdSAlan Somers c_read=`$ECHO $line | $AWK '{print $3}'` 17062fae26bdSAlan Somers c_write=`$ECHO $line | $AWK '{print $4}'` 17072fae26bdSAlan Somers c_cksum=`$ECHO $line | $AWK '{print $5}'` 17082fae26bdSAlan Somers if [ $c_read != 0 ] || [ $c_write != 0 ] || \ 17092fae26bdSAlan Somers [ $c_cksum != 0 ] 17102fae26bdSAlan Somers then 17112fae26bdSAlan Somers (( errnum = errnum + 1 )) 17122fae26bdSAlan Somers fi 17132fae26bdSAlan Somers done 17142fae26bdSAlan Somers 17152fae26bdSAlan Somers rm -f $file 17162fae26bdSAlan Somers echo $errnum 17172fae26bdSAlan Somers} 17182fae26bdSAlan Somers 17192fae26bdSAlan Somers# 17202fae26bdSAlan Somers# Returns whether the vdev has the given number of errors. 17212fae26bdSAlan Somers# If the number is unspecified, any non-zero number returns true. 17222fae26bdSAlan Somers# 17232fae26bdSAlan Somersfunction vdev_has_errors # pool vdev [errors] 17242fae26bdSAlan Somers{ 17252fae26bdSAlan Somers typeset pool=$1 17262fae26bdSAlan Somers typeset vdev=$2 17272fae26bdSAlan Somers typeset tmpfile=$(pool_error_file $pool) 17282fae26bdSAlan Somers log_note "Original pool status:" 17292fae26bdSAlan Somers cat $tmpfile 17302fae26bdSAlan Somers 17312fae26bdSAlan Somers typeset -i errs=$(pool_errors_from_file $tmpfile $vdev) 17322fae26bdSAlan Somers vdev_pool_error_count $errs $3 17332fae26bdSAlan Somers} 17342fae26bdSAlan Somers 17352fae26bdSAlan Somers# 17362fae26bdSAlan Somers# Returns whether the pool has the given number of errors. 17372fae26bdSAlan Somers# If the number is unspecified, any non-zero number returns true. 17382fae26bdSAlan Somers# 17392fae26bdSAlan Somersfunction pool_has_errors # pool [errors] 17402fae26bdSAlan Somers{ 17412fae26bdSAlan Somers typeset pool=$1 17422fae26bdSAlan Somers typeset tmpfile=$(pool_error_file $pool) 17432fae26bdSAlan Somers log_note "Original pool status:" 17442fae26bdSAlan Somers cat $tmpfile 17452fae26bdSAlan Somers 17462fae26bdSAlan Somers typeset -i errs=$(pool_errors_from_file $tmpfile) 17472fae26bdSAlan Somers vdev_pool_error_count $errs $2 17482fae26bdSAlan Somers} 17492fae26bdSAlan Somers 17502fae26bdSAlan Somers# 17512fae26bdSAlan Somers# Returns whether clearing $pool at $vdev (if given) succeeds. 17522fae26bdSAlan Somers# 17532fae26bdSAlan Somersfunction pool_clear_succeeds 17542fae26bdSAlan Somers{ 17552fae26bdSAlan Somers typeset pool="$1" 17562fae26bdSAlan Somers typeset vdev=$2 17572fae26bdSAlan Somers 17582fae26bdSAlan Somers $ZPOOL clear $pool $vdev 17592fae26bdSAlan Somers ! pool_has_errors $pool 17602fae26bdSAlan Somers} 17612fae26bdSAlan Somers 17622fae26bdSAlan Somers# 17632fae26bdSAlan Somers# Return whether the pool is healthy 17642fae26bdSAlan Somers# 17652fae26bdSAlan Somersfunction is_pool_healthy # pool 17662fae26bdSAlan Somers{ 17672fae26bdSAlan Somers typeset pool=$1 17682fae26bdSAlan Somers 17692fae26bdSAlan Somers typeset healthy_output="pool '$pool' is healthy" 17702fae26bdSAlan Somers typeset real_output=$($ZPOOL status -x $pool) 17712fae26bdSAlan Somers 17722fae26bdSAlan Somers if [[ "$real_output" == "$healthy_output" ]]; then 17732fae26bdSAlan Somers return 0 17742fae26bdSAlan Somers else 17752fae26bdSAlan Somers typeset -i ret 17762fae26bdSAlan Somers $ZPOOL status -x $pool | $GREP "state:" | \ 17772fae26bdSAlan Somers $GREP "FAULTED" >/dev/null 2>&1 17782fae26bdSAlan Somers ret=$? 17792fae26bdSAlan Somers (( $ret == 0 )) && return 1 17802fae26bdSAlan Somers typeset l_scan 17812fae26bdSAlan Somers typeset errnum 17822fae26bdSAlan Somers l_scan=$($ZPOOL status -x $pool | $GREP "scan:") 17832fae26bdSAlan Somers l_scan=${l_scan##*"with"} 17842fae26bdSAlan Somers errnum=$($ECHO $l_scan | $AWK '{print $1}') 17852fae26bdSAlan Somers if [ "$errnum" != "0" ]; then 17862fae26bdSAlan Somers return 1 17872fae26bdSAlan Somers else 17882fae26bdSAlan Somers return 0 17892fae26bdSAlan Somers fi 17902fae26bdSAlan Somers fi 17912fae26bdSAlan Somers} 17922fae26bdSAlan Somers 17932fae26bdSAlan Somers# 17942fae26bdSAlan Somers# These 5 following functions are instance of check_pool_status() 17952fae26bdSAlan Somers# is_pool_resilvering - to check if the pool is resilver in progress 17962fae26bdSAlan Somers# is_pool_resilvered - to check if the pool is resilver completed 17972fae26bdSAlan Somers# is_pool_scrubbing - to check if the pool is scrub in progress 17982fae26bdSAlan Somers# is_pool_scrubbed - to check if the pool is scrub completed 17992fae26bdSAlan Somers# is_pool_scrub_stopped - to check if the pool is scrub stopped 18002fae26bdSAlan Somers# 18012fae26bdSAlan Somersfunction is_pool_resilvering #pool 18022fae26bdSAlan Somers{ 18032fae26bdSAlan Somers check_pool_status "$1" "scan" "resilver in progress" 18042fae26bdSAlan Somers return $? 18052fae26bdSAlan Somers} 18062fae26bdSAlan Somers 18072fae26bdSAlan Somersfunction is_pool_resilvered #pool 18082fae26bdSAlan Somers{ 18092fae26bdSAlan Somers check_pool_status "$1" "scan" "resilvered" 18102fae26bdSAlan Somers return $? 18112fae26bdSAlan Somers} 18122fae26bdSAlan Somers 18132fae26bdSAlan Somersfunction resilver_happened # pool 18142fae26bdSAlan Somers{ 18152fae26bdSAlan Somers typeset pool=$1 18162fae26bdSAlan Somers is_pool_resilvering "$pool" || is_pool_resilvered "$pool" 18172fae26bdSAlan Somers} 18182fae26bdSAlan Somers 18192fae26bdSAlan Somersfunction is_pool_scrubbing #pool 18202fae26bdSAlan Somers{ 18212fae26bdSAlan Somers check_pool_status "$1" "scan" "scrub in progress" 18222fae26bdSAlan Somers return $? 18232fae26bdSAlan Somers} 18242fae26bdSAlan Somers 18252fae26bdSAlan Somersfunction is_pool_scrubbed #pool 18262fae26bdSAlan Somers{ 18272fae26bdSAlan Somers check_pool_status "$1" "scan" "scrub repaired" 18282fae26bdSAlan Somers return $? 18292fae26bdSAlan Somers} 18302fae26bdSAlan Somers 18312fae26bdSAlan Somersfunction is_pool_scrub_stopped #pool 18322fae26bdSAlan Somers{ 18332fae26bdSAlan Somers check_pool_status "$1" "scan" "scrub canceled" 18342fae26bdSAlan Somers return $? 18352fae26bdSAlan Somers} 18362fae26bdSAlan Somers 18372fae26bdSAlan Somersfunction is_pool_state # pool state 18382fae26bdSAlan Somers{ 18392fae26bdSAlan Somers check_pool_status "$1" "state" "$2" 18402fae26bdSAlan Somers return $? 18412fae26bdSAlan Somers} 18422fae26bdSAlan Somers 18432fae26bdSAlan Somers# 18442fae26bdSAlan Somers# Erase the partition tables and destroy any zfs labels 18452fae26bdSAlan Somers# 18462fae26bdSAlan Somersfunction cleanup_devices #vdevs 18472fae26bdSAlan Somers{ 18482fae26bdSAlan Somers for device in $@; do 18492fae26bdSAlan Somers # Labelclear must happen first, otherwise it may interfere 18502fae26bdSAlan Somers # with the teardown/setup of GPT labels. 18512fae26bdSAlan Somers $ZPOOL labelclear -f $device 18522fae26bdSAlan Somers # Only wipe partition tables for arguments that are disks, 18532fae26bdSAlan Somers # as opposed to slices (which are valid arguments here). 1854*11ed0a95SEric van Gyzen if geom disk list | grep -qx "Geom name: ${device#/dev/}"; then 18552fae26bdSAlan Somers wipe_partition_table $device 18562fae26bdSAlan Somers fi 18572fae26bdSAlan Somers done 18582fae26bdSAlan Somers return 0 18592fae26bdSAlan Somers} 18602fae26bdSAlan Somers 18612fae26bdSAlan Somers# 18622fae26bdSAlan Somers# Verify the rsh connectivity to each remote host in RHOSTS. 18632fae26bdSAlan Somers# 18642fae26bdSAlan Somers# Return 0 if remote host is accessible; otherwise 1. 18652fae26bdSAlan Somers# $1 remote host name 18662fae26bdSAlan Somers# $2 username 18672fae26bdSAlan Somers# 18682fae26bdSAlan Somersfunction verify_rsh_connect #rhost, username 18692fae26bdSAlan Somers{ 18702fae26bdSAlan Somers typeset rhost=$1 18712fae26bdSAlan Somers typeset username=$2 18722fae26bdSAlan Somers typeset rsh_cmd="$RSH -n" 18732fae26bdSAlan Somers typeset cur_user= 18742fae26bdSAlan Somers 18752fae26bdSAlan Somers $GETENT hosts $rhost >/dev/null 2>&1 18762fae26bdSAlan Somers if (( $? != 0 )); then 18772fae26bdSAlan Somers log_note "$rhost cannot be found from" \ 18782fae26bdSAlan Somers "administrative database." 18792fae26bdSAlan Somers return 1 18802fae26bdSAlan Somers fi 18812fae26bdSAlan Somers 18822fae26bdSAlan Somers $PING $rhost 3 >/dev/null 2>&1 18832fae26bdSAlan Somers if (( $? != 0 )); then 18842fae26bdSAlan Somers log_note "$rhost is not reachable." 18852fae26bdSAlan Somers return 1 18862fae26bdSAlan Somers fi 18872fae26bdSAlan Somers 18882fae26bdSAlan Somers if (( ${#username} != 0 )); then 18892fae26bdSAlan Somers rsh_cmd="$rsh_cmd -l $username" 18902fae26bdSAlan Somers cur_user="given user \"$username\"" 18912fae26bdSAlan Somers else 18922fae26bdSAlan Somers cur_user="current user \"`$LOGNAME`\"" 18932fae26bdSAlan Somers fi 18942fae26bdSAlan Somers 18952fae26bdSAlan Somers if ! $rsh_cmd $rhost $TRUE; then 18962fae26bdSAlan Somers log_note "$RSH to $rhost is not accessible" \ 18972fae26bdSAlan Somers "with $cur_user." 18982fae26bdSAlan Somers return 1 18992fae26bdSAlan Somers fi 19002fae26bdSAlan Somers 19012fae26bdSAlan Somers return 0 19022fae26bdSAlan Somers} 19032fae26bdSAlan Somers 19042fae26bdSAlan Somers# 19052fae26bdSAlan Somers# Verify the remote host connection via rsh after rebooting 19062fae26bdSAlan Somers# $1 remote host 19072fae26bdSAlan Somers# 19082fae26bdSAlan Somersfunction verify_remote 19092fae26bdSAlan Somers{ 19102fae26bdSAlan Somers rhost=$1 19112fae26bdSAlan Somers 19122fae26bdSAlan Somers # 19132fae26bdSAlan Somers # The following loop waits for the remote system rebooting. 19142fae26bdSAlan Somers # Each iteration will wait for 150 seconds. there are 19152fae26bdSAlan Somers # total 5 iterations, so the total timeout value will 19162fae26bdSAlan Somers # be 12.5 minutes for the system rebooting. This number 19172fae26bdSAlan Somers # is an approxiate number. 19182fae26bdSAlan Somers # 19192fae26bdSAlan Somers typeset -i count=0 19202fae26bdSAlan Somers while ! verify_rsh_connect $rhost; do 19212fae26bdSAlan Somers sleep 150 19222fae26bdSAlan Somers (( count = count + 1 )) 19232fae26bdSAlan Somers if (( count > 5 )); then 19242fae26bdSAlan Somers return 1 19252fae26bdSAlan Somers fi 19262fae26bdSAlan Somers done 19272fae26bdSAlan Somers return 0 19282fae26bdSAlan Somers} 19292fae26bdSAlan Somers 19302fae26bdSAlan Somers# 19312fae26bdSAlan Somers# Replacement function for /usr/bin/rsh. This function will include 19322fae26bdSAlan Somers# the /usr/bin/rsh and meanwhile return the execution status of the 19332fae26bdSAlan Somers# last command. 19342fae26bdSAlan Somers# 19352fae26bdSAlan Somers# $1 usrname passing down to -l option of /usr/bin/rsh 19362fae26bdSAlan Somers# $2 remote machine hostname 19372fae26bdSAlan Somers# $3... command string 19382fae26bdSAlan Somers# 19392fae26bdSAlan Somers 19402fae26bdSAlan Somersfunction rsh_status 19412fae26bdSAlan Somers{ 19422fae26bdSAlan Somers typeset ruser=$1 19432fae26bdSAlan Somers typeset rhost=$2 19442fae26bdSAlan Somers typeset -i ret=0 19452fae26bdSAlan Somers typeset cmd_str="" 19462fae26bdSAlan Somers typeset rsh_str="" 19472fae26bdSAlan Somers 19482fae26bdSAlan Somers shift; shift 19492fae26bdSAlan Somers cmd_str="$@" 19502fae26bdSAlan Somers 19512fae26bdSAlan Somers err_file=$TMPDIR/${rhost}.${TESTCASE_ID}.err 19522fae26bdSAlan Somers if (( ${#ruser} == 0 )); then 19532fae26bdSAlan Somers rsh_str="$RSH -n" 19542fae26bdSAlan Somers else 19552fae26bdSAlan Somers rsh_str="$RSH -n -l $ruser" 19562fae26bdSAlan Somers fi 19572fae26bdSAlan Somers 19582fae26bdSAlan Somers $rsh_str $rhost /usr/local/bin/ksh93 -c "'$cmd_str; \ 19592fae26bdSAlan Somers print -u 2 \"status=\$?\"'" \ 19602fae26bdSAlan Somers >/dev/null 2>$err_file 19612fae26bdSAlan Somers ret=$? 19622fae26bdSAlan Somers if (( $ret != 0 )); then 19632fae26bdSAlan Somers $CAT $err_file 19642fae26bdSAlan Somers $RM -f $std_file $err_file 19652fae26bdSAlan Somers log_fail "$RSH itself failed with exit code $ret..." 19662fae26bdSAlan Somers fi 19672fae26bdSAlan Somers 19682fae26bdSAlan Somers ret=$($GREP -v 'print -u 2' $err_file | $GREP 'status=' | \ 19692fae26bdSAlan Somers $CUT -d= -f2) 19702fae26bdSAlan Somers (( $ret != 0 )) && $CAT $err_file >&2 19712fae26bdSAlan Somers 19722fae26bdSAlan Somers $RM -f $err_file >/dev/null 2>&1 19732fae26bdSAlan Somers return $ret 19742fae26bdSAlan Somers} 19752fae26bdSAlan Somers 19762fae26bdSAlan Somers# 19772fae26bdSAlan Somers# Get the SUNWstc-fs-zfs package installation path in a remote host 19782fae26bdSAlan Somers# $1 remote host name 19792fae26bdSAlan Somers# 19802fae26bdSAlan Somersfunction get_remote_pkgpath 19812fae26bdSAlan Somers{ 19822fae26bdSAlan Somers typeset rhost=$1 19832fae26bdSAlan Somers typeset pkgpath="" 19842fae26bdSAlan Somers 19852fae26bdSAlan Somers pkgpath=$($RSH -n $rhost "$PKGINFO -l SUNWstc-fs-zfs | $GREP BASEDIR: |\ 19862fae26bdSAlan Somers $CUT -d: -f2") 19872fae26bdSAlan Somers 19882fae26bdSAlan Somers $ECHO $pkgpath 19892fae26bdSAlan Somers} 19902fae26bdSAlan Somers 19912fae26bdSAlan Somers#/** 19922fae26bdSAlan Somers# A function to find and locate free disks on a system or from given 19932fae26bdSAlan Somers# disks as the parameter. Since the conversion to ATF, this function is 19942fae26bdSAlan Somers# superfluous; it is assumed that the user will supply an accurate list of 19952fae26bdSAlan Somers# disks to use. So we just return the arguments. 19962fae26bdSAlan Somers# 19972fae26bdSAlan Somers# $@ given disks to find which are free 19982fae26bdSAlan Somers# 19992fae26bdSAlan Somers# @return a string containing the list of available disks 20002fae26bdSAlan Somers#*/ 20012fae26bdSAlan Somersfunction find_disks 20022fae26bdSAlan Somers{ 20032fae26bdSAlan Somers (( first=0 )) 20042fae26bdSAlan Somers for disk in $@; do 20052fae26bdSAlan Somers [[ $first == 1 ]] && echo -n " " 20062fae26bdSAlan Somers (( first=1 )) 20072fae26bdSAlan Somers case $disk in 20082fae26bdSAlan Somers /dev/*) echo -n "$disk" ;; 20092fae26bdSAlan Somers *) echo -n "/dev/$disk" ;; 20102fae26bdSAlan Somers esac 20112fae26bdSAlan Somers done 20122fae26bdSAlan Somers} 20132fae26bdSAlan Somers 20142fae26bdSAlan Somers# A function to set convenience variables for disks. 20152fae26bdSAlan Somersfunction set_disks 20162fae26bdSAlan Somers{ 20172fae26bdSAlan Somers set -A disk_array $(find_disks $DISKS) 20182fae26bdSAlan Somers [[ -z "$DISK_ARRAY_LIMIT" ]] && typeset -i DISK_ARRAY_LIMIT=5 20192fae26bdSAlan Somers 20202fae26bdSAlan Somers export DISK="" 20212fae26bdSAlan Somers typeset -i i=0 20222fae26bdSAlan Somers while (( i < ${#disk_array[*]} && i <= $DISK_ARRAY_LIMIT )); do 20232fae26bdSAlan Somers export DISK${i}="${disk_array[$i]}" 20242fae26bdSAlan Somers DISKSARRAY="$DISKSARRAY ${disk_array[$i]}" 20252fae26bdSAlan Somers (( i = i + 1 )) 20262fae26bdSAlan Somers done 20272fae26bdSAlan Somers export DISK_ARRAY_NUM=$i 20282fae26bdSAlan Somers export DISKSARRAY 20292fae26bdSAlan Somers export disk=$DISK0 20302fae26bdSAlan Somers} 20312fae26bdSAlan Somers 20322fae26bdSAlan Somers# 20332fae26bdSAlan Somers# Add specified user to specified group 20342fae26bdSAlan Somers# 20352fae26bdSAlan Somers# $1 group name 20362fae26bdSAlan Somers# $2 user name 20372fae26bdSAlan Somers# 20382fae26bdSAlan Somersfunction add_user #<group_name> <user_name> 20392fae26bdSAlan Somers{ 20402fae26bdSAlan Somers typeset gname=$1 20412fae26bdSAlan Somers typeset uname=$2 20422fae26bdSAlan Somers 20432fae26bdSAlan Somers if (( ${#gname} == 0 || ${#uname} == 0 )); then 20442fae26bdSAlan Somers log_fail "group name or user name are not defined." 20452fae26bdSAlan Somers fi 20462fae26bdSAlan Somers 20472fae26bdSAlan Somers # Check to see if the user exists. 20482fae26bdSAlan Somers $ID $uname > /dev/null 2>&1 && return 0 20492fae26bdSAlan Somers 20502fae26bdSAlan Somers # Assign 1000 as the base uid 20512fae26bdSAlan Somers typeset -i uid=1000 20522fae26bdSAlan Somers while true; do 20532fae26bdSAlan Somers typeset -i ret 20542fae26bdSAlan Somers $USERADD -u $uid -g $gname -d /var/tmp/$uname -m $uname 20552fae26bdSAlan Somers ret=$? 20562fae26bdSAlan Somers case $ret in 20572fae26bdSAlan Somers 0) return 0 ;; 20582fae26bdSAlan Somers # The uid is not unique 20592fae26bdSAlan Somers 65) ((uid += 1)) ;; 20602fae26bdSAlan Somers *) return 1 ;; 20612fae26bdSAlan Somers esac 20622fae26bdSAlan Somers if [[ $uid == 65000 ]]; then 20632fae26bdSAlan Somers log_fail "No user id available under 65000 for $uname" 20642fae26bdSAlan Somers fi 20652fae26bdSAlan Somers done 20662fae26bdSAlan Somers 20672fae26bdSAlan Somers return 0 20682fae26bdSAlan Somers} 20692fae26bdSAlan Somers 20702fae26bdSAlan Somers# 20712fae26bdSAlan Somers# Delete the specified user. 20722fae26bdSAlan Somers# 20732fae26bdSAlan Somers# $1 login name 20742fae26bdSAlan Somers# 20752fae26bdSAlan Somersfunction del_user #<logname> 20762fae26bdSAlan Somers{ 20772fae26bdSAlan Somers typeset user=$1 20782fae26bdSAlan Somers 20792fae26bdSAlan Somers if (( ${#user} == 0 )); then 20802fae26bdSAlan Somers log_fail "login name is necessary." 20812fae26bdSAlan Somers fi 20822fae26bdSAlan Somers 20832fae26bdSAlan Somers if $ID $user > /dev/null 2>&1; then 20842fae26bdSAlan Somers log_must $USERDEL $user 20852fae26bdSAlan Somers fi 20862fae26bdSAlan Somers 20872fae26bdSAlan Somers return 0 20882fae26bdSAlan Somers} 20892fae26bdSAlan Somers 20902fae26bdSAlan Somers# 20912fae26bdSAlan Somers# Select valid gid and create specified group. 20922fae26bdSAlan Somers# 20932fae26bdSAlan Somers# $1 group name 20942fae26bdSAlan Somers# 20952fae26bdSAlan Somersfunction add_group #<group_name> 20962fae26bdSAlan Somers{ 20972fae26bdSAlan Somers typeset group=$1 20982fae26bdSAlan Somers 20992fae26bdSAlan Somers if (( ${#group} == 0 )); then 21002fae26bdSAlan Somers log_fail "group name is necessary." 21012fae26bdSAlan Somers fi 21022fae26bdSAlan Somers 21032fae26bdSAlan Somers # See if the group already exists. 21042fae26bdSAlan Somers $GROUPSHOW $group >/dev/null 2>&1 21052fae26bdSAlan Somers [[ $? == 0 ]] && return 0 21062fae26bdSAlan Somers 21072fae26bdSAlan Somers # Assign 100 as the base gid 21082fae26bdSAlan Somers typeset -i gid=100 21092fae26bdSAlan Somers while true; do 21102fae26bdSAlan Somers $GROUPADD -g $gid $group > /dev/null 2>&1 21112fae26bdSAlan Somers typeset -i ret=$? 21122fae26bdSAlan Somers case $ret in 21132fae26bdSAlan Somers 0) return 0 ;; 21142fae26bdSAlan Somers # The gid is not unique 21152fae26bdSAlan Somers 65) ((gid += 1)) ;; 21162fae26bdSAlan Somers *) return 1 ;; 21172fae26bdSAlan Somers esac 21182fae26bdSAlan Somers if [[ $gid == 65000 ]]; then 21192fae26bdSAlan Somers log_fail "No user id available under 65000 for $group" 21202fae26bdSAlan Somers fi 21212fae26bdSAlan Somers done 21222fae26bdSAlan Somers} 21232fae26bdSAlan Somers 21242fae26bdSAlan Somers# 21252fae26bdSAlan Somers# Delete the specified group. 21262fae26bdSAlan Somers# 21272fae26bdSAlan Somers# $1 group name 21282fae26bdSAlan Somers# 21292fae26bdSAlan Somersfunction del_group #<group_name> 21302fae26bdSAlan Somers{ 21312fae26bdSAlan Somers typeset grp=$1 21322fae26bdSAlan Somers if (( ${#grp} == 0 )); then 21332fae26bdSAlan Somers log_fail "group name is necessary." 21342fae26bdSAlan Somers fi 21352fae26bdSAlan Somers 21362fae26bdSAlan Somers $GROUPDEL -n $grp > /dev/null 2>&1 21372fae26bdSAlan Somers typeset -i ret=$? 21382fae26bdSAlan Somers case $ret in 21392fae26bdSAlan Somers # Group does not exist, or was deleted successfully. 21402fae26bdSAlan Somers 0|6|65) return 0 ;; 21412fae26bdSAlan Somers # Name already exists as a group name 21422fae26bdSAlan Somers 9) log_must $GROUPDEL $grp ;; 21432fae26bdSAlan Somers *) return 1 ;; 21442fae26bdSAlan Somers esac 21452fae26bdSAlan Somers 21462fae26bdSAlan Somers return 0 21472fae26bdSAlan Somers} 21482fae26bdSAlan Somers 21492fae26bdSAlan Somers# 21502fae26bdSAlan Somers# This function will return true if it's safe to destroy the pool passed 21512fae26bdSAlan Somers# as argument 1. It checks for pools based on zvols and files, and also 21522fae26bdSAlan Somers# files contained in a pool that may have a different mountpoint. 21532fae26bdSAlan Somers# 21542fae26bdSAlan Somersfunction safe_to_destroy_pool { # $1 the pool name 21552fae26bdSAlan Somers 21562fae26bdSAlan Somers typeset pool="" 21572fae26bdSAlan Somers typeset DONT_DESTROY="" 21582fae26bdSAlan Somers 21592fae26bdSAlan Somers # We check that by deleting the $1 pool, we're not 21602fae26bdSAlan Somers # going to pull the rug out from other pools. Do this 21612fae26bdSAlan Somers # by looking at all other pools, ensuring that they 21622fae26bdSAlan Somers # aren't built from files or zvols contained in this pool. 21632fae26bdSAlan Somers 21642fae26bdSAlan Somers for pool in $($ZPOOL list -H -o name) 21652fae26bdSAlan Somers do 21662fae26bdSAlan Somers ALTMOUNTPOOL="" 21672fae26bdSAlan Somers 21682fae26bdSAlan Somers # this is a list of the top-level directories in each of the files 21692fae26bdSAlan Somers # that make up the path to the files the pool is based on 21702fae26bdSAlan Somers FILEPOOL=$($ZPOOL status -v $pool | $GREP /$1/ | \ 21712fae26bdSAlan Somers $AWK '{print $1}') 21722fae26bdSAlan Somers 21732fae26bdSAlan Somers # this is a list of the zvols that make up the pool 21745a2fc464SAndriy Gapon ZVOLPOOL=$($ZPOOL status -v $pool | $GREP "/dev/zvol/$1$" | \ 21752fae26bdSAlan Somers $AWK '{print $1}') 21762fae26bdSAlan Somers 21772fae26bdSAlan Somers # also want to determine if it's a file-based pool using an 21782fae26bdSAlan Somers # alternate mountpoint... 21792fae26bdSAlan Somers POOL_FILE_DIRS=$($ZPOOL status -v $pool | \ 21802fae26bdSAlan Somers $GREP / | $AWK '{print $1}' | \ 21812fae26bdSAlan Somers $AWK -F/ '{print $2}' | $GREP -v "dev") 21822fae26bdSAlan Somers 21832fae26bdSAlan Somers for pooldir in $POOL_FILE_DIRS 21842fae26bdSAlan Somers do 21852fae26bdSAlan Somers OUTPUT=$($ZFS list -H -r -o mountpoint $1 | \ 21862fae26bdSAlan Somers $GREP "${pooldir}$" | $AWK '{print $1}') 21872fae26bdSAlan Somers 21882fae26bdSAlan Somers ALTMOUNTPOOL="${ALTMOUNTPOOL}${OUTPUT}" 21892fae26bdSAlan Somers done 21902fae26bdSAlan Somers 21912fae26bdSAlan Somers 21922fae26bdSAlan Somers if [ ! -z "$ZVOLPOOL" ] 21932fae26bdSAlan Somers then 21942fae26bdSAlan Somers DONT_DESTROY="true" 21952fae26bdSAlan Somers log_note "Pool $pool is built from $ZVOLPOOL on $1" 21962fae26bdSAlan Somers fi 21972fae26bdSAlan Somers 21982fae26bdSAlan Somers if [ ! -z "$FILEPOOL" ] 21992fae26bdSAlan Somers then 22002fae26bdSAlan Somers DONT_DESTROY="true" 22012fae26bdSAlan Somers log_note "Pool $pool is built from $FILEPOOL on $1" 22022fae26bdSAlan Somers fi 22032fae26bdSAlan Somers 22042fae26bdSAlan Somers if [ ! -z "$ALTMOUNTPOOL" ] 22052fae26bdSAlan Somers then 22062fae26bdSAlan Somers DONT_DESTROY="true" 22072fae26bdSAlan Somers log_note "Pool $pool is built from $ALTMOUNTPOOL on $1" 22082fae26bdSAlan Somers fi 22092fae26bdSAlan Somers done 22102fae26bdSAlan Somers 22112fae26bdSAlan Somers if [ -z "${DONT_DESTROY}" ] 22122fae26bdSAlan Somers then 22132fae26bdSAlan Somers return 0 22142fae26bdSAlan Somers else 22152fae26bdSAlan Somers log_note "Warning: it is not safe to destroy $1!" 22162fae26bdSAlan Somers return 1 22172fae26bdSAlan Somers fi 22182fae26bdSAlan Somers} 22192fae26bdSAlan Somers 22202fae26bdSAlan Somers# 22212fae26bdSAlan Somers# Get IP address of hostname 22222fae26bdSAlan Somers# $1 hostname 22232fae26bdSAlan Somers# 22242fae26bdSAlan Somersfunction getipbyhost 22252fae26bdSAlan Somers{ 22262fae26bdSAlan Somers typeset ip 22272fae26bdSAlan Somers ip=`$ARP $1 2>/dev/null | $AWK -F\) '{print $1}' \ 22282fae26bdSAlan Somers | $AWK -F\( '{print $2}'` 22292fae26bdSAlan Somers $ECHO $ip 22302fae26bdSAlan Somers} 22312fae26bdSAlan Somers 22322fae26bdSAlan Somers# 22332fae26bdSAlan Somers# Setup iSCSI initiator to target 22342fae26bdSAlan Somers# $1 target hostname 22352fae26bdSAlan Somers# 22362fae26bdSAlan Somersfunction iscsi_isetup 22372fae26bdSAlan Somers{ 22382fae26bdSAlan Somers # check svc:/network/iscsi_initiator:default state, try to enable it 22392fae26bdSAlan Somers # if the state is not ON 22402fae26bdSAlan Somers typeset ISCSII_FMRI="svc:/network/iscsi_initiator:default" 22412fae26bdSAlan Somers if [[ "ON" != $($SVCS -H -o sta $ISCSII_FMRI) ]]; then 22422fae26bdSAlan Somers log_must $SVCADM enable $ISCSII_FMRI 22432fae26bdSAlan Somers 22442fae26bdSAlan Somers typeset -i retry=20 22452fae26bdSAlan Somers while [[ "ON" != $($SVCS -H -o sta $ISCSII_FMRI) && \ 22462fae26bdSAlan Somers ( $retry -ne 0 ) ]] 22472fae26bdSAlan Somers do 22482fae26bdSAlan Somers (( retry = retry - 1 )) 22492fae26bdSAlan Somers $SLEEP 1 22502fae26bdSAlan Somers done 22512fae26bdSAlan Somers 22522fae26bdSAlan Somers if [[ "ON" != $($SVCS -H -o sta $ISCSII_FMRI) ]]; then 22532fae26bdSAlan Somers log_fail "$ISCSII_FMRI service can not be enabled!" 22542fae26bdSAlan Somers fi 22552fae26bdSAlan Somers fi 22562fae26bdSAlan Somers 22572fae26bdSAlan Somers log_must $ISCSIADM add discovery-address $(getipbyhost $1) 22582fae26bdSAlan Somers log_must $ISCSIADM modify discovery --sendtargets enable 22592fae26bdSAlan Somers log_must $DEVFSADM -i iscsi 22602fae26bdSAlan Somers} 22612fae26bdSAlan Somers 22622fae26bdSAlan Somers# 22632fae26bdSAlan Somers# Check whether iscsi parameter is set as remote 22642fae26bdSAlan Somers# 22652fae26bdSAlan Somers# return 0 if iscsi is set as remote, otherwise 1 22662fae26bdSAlan Somers# 22672fae26bdSAlan Somersfunction check_iscsi_remote 22682fae26bdSAlan Somers{ 22692fae26bdSAlan Somers if [[ $iscsi == "remote" ]] ; then 22702fae26bdSAlan Somers return 0 22712fae26bdSAlan Somers else 22722fae26bdSAlan Somers return 1 22732fae26bdSAlan Somers fi 22742fae26bdSAlan Somers} 22752fae26bdSAlan Somers 22762fae26bdSAlan Somers# 22772fae26bdSAlan Somers# Check if a volume is a valide iscsi target 22782fae26bdSAlan Somers# $1 volume name 22792fae26bdSAlan Somers# return 0 if suceeds, otherwise, return 1 22802fae26bdSAlan Somers# 22812fae26bdSAlan Somersfunction is_iscsi_target 22822fae26bdSAlan Somers{ 22832fae26bdSAlan Somers typeset dataset=$1 22842fae26bdSAlan Somers typeset target targets 22852fae26bdSAlan Somers 22862fae26bdSAlan Somers [[ -z $dataset ]] && return 1 22872fae26bdSAlan Somers 22882fae26bdSAlan Somers targets=$($ISCSITADM list target | $GREP "Target:" | $AWK '{print $2}') 22892fae26bdSAlan Somers [[ -z $targets ]] && return 1 22902fae26bdSAlan Somers 22912fae26bdSAlan Somers for target in $targets; do 22922fae26bdSAlan Somers [[ $dataset == $target ]] && return 0 22932fae26bdSAlan Somers done 22942fae26bdSAlan Somers 22952fae26bdSAlan Somers return 1 22962fae26bdSAlan Somers} 22972fae26bdSAlan Somers 22982fae26bdSAlan Somers# 22992fae26bdSAlan Somers# Get the iSCSI name of a target 23002fae26bdSAlan Somers# $1 target name 23012fae26bdSAlan Somers# 23022fae26bdSAlan Somersfunction iscsi_name 23032fae26bdSAlan Somers{ 23042fae26bdSAlan Somers typeset target=$1 23052fae26bdSAlan Somers typeset name 23062fae26bdSAlan Somers 23072fae26bdSAlan Somers [[ -z $target ]] && log_fail "No parameter." 23082fae26bdSAlan Somers 23092fae26bdSAlan Somers if ! is_iscsi_target $target ; then 23102fae26bdSAlan Somers log_fail "Not a target." 23112fae26bdSAlan Somers fi 23122fae26bdSAlan Somers 23132fae26bdSAlan Somers name=$($ISCSITADM list target $target | $GREP "iSCSI Name:" \ 23142fae26bdSAlan Somers | $AWK '{print $2}') 23152fae26bdSAlan Somers 23162fae26bdSAlan Somers return $name 23172fae26bdSAlan Somers} 23182fae26bdSAlan Somers 23192fae26bdSAlan Somers# 23202fae26bdSAlan Somers# check svc:/system/iscsitgt:default state, try to enable it if the state 23212fae26bdSAlan Somers# is not ON 23222fae26bdSAlan Somers# 23232fae26bdSAlan Somersfunction iscsitgt_setup 23242fae26bdSAlan Somers{ 23252fae26bdSAlan Somers log_must $RM -f $ISCSITGTFILE 23262fae26bdSAlan Somers if [[ "ON" == $($SVCS -H -o sta $ISCSITGT_FMRI) ]]; then 23272fae26bdSAlan Somers log_note "iscsitgt is already enabled" 23282fae26bdSAlan Somers return 23292fae26bdSAlan Somers fi 23302fae26bdSAlan Somers 23312fae26bdSAlan Somers log_must $SVCADM enable -t $ISCSITGT_FMRI 23322fae26bdSAlan Somers 23332fae26bdSAlan Somers typeset -i retry=20 23342fae26bdSAlan Somers while [[ "ON" != $($SVCS -H -o sta $ISCSITGT_FMRI) && \ 23352fae26bdSAlan Somers ( $retry -ne 0 ) ]] 23362fae26bdSAlan Somers do 23372fae26bdSAlan Somers $SLEEP 1 23382fae26bdSAlan Somers (( retry = retry - 1 )) 23392fae26bdSAlan Somers done 23402fae26bdSAlan Somers 23412fae26bdSAlan Somers if [[ "ON" != $($SVCS -H -o sta $ISCSITGT_FMRI) ]]; then 23422fae26bdSAlan Somers log_fail "$ISCSITGT_FMRI service can not be enabled!" 23432fae26bdSAlan Somers fi 23442fae26bdSAlan Somers 23452fae26bdSAlan Somers log_must $TOUCH $ISCSITGTFILE 23462fae26bdSAlan Somers} 23472fae26bdSAlan Somers 23482fae26bdSAlan Somers# 23492fae26bdSAlan Somers# set DISABLED state of svc:/system/iscsitgt:default 23502fae26bdSAlan Somers# which is the most suiteable state if $ISCSITGTFILE exists 23512fae26bdSAlan Somers# 23522fae26bdSAlan Somersfunction iscsitgt_cleanup 23532fae26bdSAlan Somers{ 23542fae26bdSAlan Somers if [[ -e $ISCSITGTFILE ]]; then 23552fae26bdSAlan Somers log_must $SVCADM disable $ISCSITGT_FMRI 23562fae26bdSAlan Somers log_must $RM -f $ISCSITGTFILE 23572fae26bdSAlan Somers fi 23582fae26bdSAlan Somers} 23592fae26bdSAlan Somers 23602fae26bdSAlan Somers# 23612fae26bdSAlan Somers# Close iSCSI initiator to target 23622fae26bdSAlan Somers# $1 target hostname 23632fae26bdSAlan Somers# 23642fae26bdSAlan Somersfunction iscsi_iclose 23652fae26bdSAlan Somers{ 23662fae26bdSAlan Somers log_must $ISCSIADM modify discovery --sendtargets disable 23672fae26bdSAlan Somers log_must $ISCSIADM remove discovery-address $(getipbyhost $1) 23682fae26bdSAlan Somers $DEVFSADM -Cv 23692fae26bdSAlan Somers} 23702fae26bdSAlan Somers 23712fae26bdSAlan Somers# 23722fae26bdSAlan Somers# Get the available ZFS compression options 23732fae26bdSAlan Somers# $1 option type zfs_set|zfs_compress 23742fae26bdSAlan Somers# 23752fae26bdSAlan Somersfunction get_compress_opts 23762fae26bdSAlan Somers{ 23772fae26bdSAlan Somers typeset COMPRESS_OPTS 23782fae26bdSAlan Somers typeset GZIP_OPTS="gzip gzip-1 gzip-2 gzip-3 gzip-4 gzip-5 \ 23792fae26bdSAlan Somers gzip-6 gzip-7 gzip-8 gzip-9" 23802fae26bdSAlan Somers 23812fae26bdSAlan Somers if [[ $1 == "zfs_compress" ]] ; then 23822fae26bdSAlan Somers COMPRESS_OPTS="on lzjb" 23832fae26bdSAlan Somers elif [[ $1 == "zfs_set" ]] ; then 23842fae26bdSAlan Somers COMPRESS_OPTS="on off lzjb" 23852fae26bdSAlan Somers fi 23862fae26bdSAlan Somers typeset valid_opts="$COMPRESS_OPTS" 23872fae26bdSAlan Somers $ZFS get 2>&1 | $GREP gzip >/dev/null 2>&1 23882fae26bdSAlan Somers if [[ $? -eq 0 ]]; then 23892fae26bdSAlan Somers valid_opts="$valid_opts $GZIP_OPTS" 23902fae26bdSAlan Somers fi 23912fae26bdSAlan Somers $ECHO "$valid_opts" 23922fae26bdSAlan Somers} 23932fae26bdSAlan Somers 23942fae26bdSAlan Somers# 23952fae26bdSAlan Somers# Check the subcommand/option is supported 23962fae26bdSAlan Somers# 23972fae26bdSAlan Somersfunction check_opt_support #command, option 23982fae26bdSAlan Somers{ 23992fae26bdSAlan Somers typeset command=$1 24002fae26bdSAlan Somers typeset option=$2 24012fae26bdSAlan Somers 24022fae26bdSAlan Somers if [[ -z $command ]]; then 24032fae26bdSAlan Somers return 0 24042fae26bdSAlan Somers elif [[ -z $option ]]; then 24052fae26bdSAlan Somers eval "$ZFS 2>&1 | $GREP '$command' > /dev/null 2>&1" 24062fae26bdSAlan Somers else 24072fae26bdSAlan Somers eval "$ZFS $command 2>&1 | $GREP -- '$option' | \ 24082fae26bdSAlan Somers $GREP -v -- 'User-defined' > /dev/null 2>&1" 24092fae26bdSAlan Somers fi 24102fae26bdSAlan Somers return $? 24112fae26bdSAlan Somers} 24122fae26bdSAlan Somers 24132fae26bdSAlan Somers# 24142fae26bdSAlan Somers# Check the zpool subcommand/option is supported 24152fae26bdSAlan Somers# 24162fae26bdSAlan Somersfunction check_zpool_opt_support #command, option 24172fae26bdSAlan Somers{ 24182fae26bdSAlan Somers typeset command=$1 24192fae26bdSAlan Somers typeset option=$2 24202fae26bdSAlan Somers 24212fae26bdSAlan Somers if [[ -z $command ]]; then 24222fae26bdSAlan Somers return 0 24232fae26bdSAlan Somers elif [[ -z $option ]]; then 24242fae26bdSAlan Somers eval "$ZPOOL 2>&1 | $GREP '$command' > /dev/null 2>&1" 24252fae26bdSAlan Somers else 24262fae26bdSAlan Somers eval "$ZPOOL $command 2>&1 | $GREP -- '$option' > /dev/null 2>&1" 24272fae26bdSAlan Somers fi 24282fae26bdSAlan Somers return $? 24292fae26bdSAlan Somers} 24302fae26bdSAlan Somers 24312fae26bdSAlan Somers# 24322fae26bdSAlan Somers# Verify zfs operation with -p option work as expected 24332fae26bdSAlan Somers# $1 operation, value could be create, clone or rename 24342fae26bdSAlan Somers# $2 dataset type, value could be fs or vol 24352fae26bdSAlan Somers# $3 dataset name 24362fae26bdSAlan Somers# $4 new dataset name 24372fae26bdSAlan Somers# 24382fae26bdSAlan Somersfunction verify_opt_p_ops 24392fae26bdSAlan Somers{ 24402fae26bdSAlan Somers typeset ops=$1 24412fae26bdSAlan Somers typeset datatype=$2 24422fae26bdSAlan Somers typeset dataset=$3 24432fae26bdSAlan Somers typeset newdataset=$4 24442fae26bdSAlan Somers 24452fae26bdSAlan Somers if [[ $datatype != "fs" && $datatype != "vol" ]]; then 24462fae26bdSAlan Somers log_fail "$datatype is not supported." 24472fae26bdSAlan Somers fi 24482fae26bdSAlan Somers 24492fae26bdSAlan Somers # check parameters accordingly 24502fae26bdSAlan Somers case $ops in 24512fae26bdSAlan Somers create) 24522fae26bdSAlan Somers newdataset=$dataset 24532fae26bdSAlan Somers dataset="" 24542fae26bdSAlan Somers if [[ $datatype == "vol" ]]; then 24552fae26bdSAlan Somers ops="create -V $VOLSIZE" 24562fae26bdSAlan Somers fi 24572fae26bdSAlan Somers ;; 24582fae26bdSAlan Somers clone) 24592fae26bdSAlan Somers if [[ -z $newdataset ]]; then 24602fae26bdSAlan Somers log_fail "newdataset should not be empty" \ 24612fae26bdSAlan Somers "when ops is $ops." 24622fae26bdSAlan Somers fi 24632fae26bdSAlan Somers log_must datasetexists $dataset 24642fae26bdSAlan Somers log_must snapexists $dataset 24652fae26bdSAlan Somers ;; 24662fae26bdSAlan Somers rename) 24672fae26bdSAlan Somers if [[ -z $newdataset ]]; then 24682fae26bdSAlan Somers log_fail "newdataset should not be empty" \ 24692fae26bdSAlan Somers "when ops is $ops." 24702fae26bdSAlan Somers fi 24712fae26bdSAlan Somers log_must datasetexists $dataset 24722fae26bdSAlan Somers log_mustnot snapexists $dataset 24732fae26bdSAlan Somers ;; 24742fae26bdSAlan Somers *) 24752fae26bdSAlan Somers log_fail "$ops is not supported." 24762fae26bdSAlan Somers ;; 24772fae26bdSAlan Somers esac 24782fae26bdSAlan Somers 24792fae26bdSAlan Somers # make sure the upper level filesystem does not exist 24802fae26bdSAlan Somers if datasetexists ${newdataset%/*} ; then 24812fae26bdSAlan Somers log_must $ZFS destroy -rRf ${newdataset%/*} 24822fae26bdSAlan Somers fi 24832fae26bdSAlan Somers 24842fae26bdSAlan Somers # without -p option, operation will fail 24852fae26bdSAlan Somers log_mustnot $ZFS $ops $dataset $newdataset 24862fae26bdSAlan Somers log_mustnot datasetexists $newdataset ${newdataset%/*} 24872fae26bdSAlan Somers 24882fae26bdSAlan Somers # with -p option, operation should succeed 24892fae26bdSAlan Somers log_must $ZFS $ops -p $dataset $newdataset 24902fae26bdSAlan Somers if ! datasetexists $newdataset ; then 24912fae26bdSAlan Somers log_fail "-p option does not work for $ops" 24922fae26bdSAlan Somers fi 24932fae26bdSAlan Somers 24942fae26bdSAlan Somers # when $ops is create or clone, redo the operation still return zero 24952fae26bdSAlan Somers if [[ $ops != "rename" ]]; then 24962fae26bdSAlan Somers log_must $ZFS $ops -p $dataset $newdataset 24972fae26bdSAlan Somers fi 24982fae26bdSAlan Somers 24992fae26bdSAlan Somers return 0 25002fae26bdSAlan Somers} 25012fae26bdSAlan Somers 25022fae26bdSAlan Somersfunction get_disk_guid 25032fae26bdSAlan Somers{ 25042fae26bdSAlan Somers typeset diskname=$1 25052fae26bdSAlan Somers lastcwd=$(pwd) 25062fae26bdSAlan Somers cd /dev 25072fae26bdSAlan Somers guid=$($ZDB -l ${diskname} | ${AWK} '/^ guid:/ {print $2}' | head -1) 25082fae26bdSAlan Somers cd $lastcwd 25092fae26bdSAlan Somers echo $guid 25102fae26bdSAlan Somers} 25112fae26bdSAlan Somers 25122fae26bdSAlan Somers# 25132fae26bdSAlan Somers# Get cachefile for a pool. 25142fae26bdSAlan Somers# Prints the cache file, if there is one. 25152fae26bdSAlan Somers# Returns 0 for a default zpool.cache, 1 for an explicit one, and 2 for none. 25162fae26bdSAlan Somers# 25172fae26bdSAlan Somersfunction cachefile_for_pool 25182fae26bdSAlan Somers{ 25192fae26bdSAlan Somers typeset pool=$1 25202fae26bdSAlan Somers 25212fae26bdSAlan Somers cachefile=$(get_pool_prop cachefile $pool) 25222fae26bdSAlan Somers [[ $? != 0 ]] && return 1 25232fae26bdSAlan Somers 25242fae26bdSAlan Somers case "$cachefile" in 25252fae26bdSAlan Somers none) ret=2 ;; 25262fae26bdSAlan Somers "-") 25272fae26bdSAlan Somers ret=2 25282fae26bdSAlan Somers for dir in /boot/zfs /etc/zfs; do 25292fae26bdSAlan Somers if [[ -f "${dir}/zpool.cache" ]]; then 25302fae26bdSAlan Somers cachefile="${dir}/zpool.cache" 25312fae26bdSAlan Somers ret=0 25322fae26bdSAlan Somers break 25332fae26bdSAlan Somers fi 25342fae26bdSAlan Somers done 25352fae26bdSAlan Somers ;; 25362fae26bdSAlan Somers *) ret=1; 25372fae26bdSAlan Somers esac 25382fae26bdSAlan Somers [[ $ret -eq 0 || $ret -eq 1 ]] && print "$cachefile" 25392fae26bdSAlan Somers return $ret 25402fae26bdSAlan Somers} 25412fae26bdSAlan Somers 25422fae26bdSAlan Somers# 25432fae26bdSAlan Somers# Assert that the pool is in the appropriate cachefile. 25442fae26bdSAlan Somers# 25452fae26bdSAlan Somersfunction assert_pool_in_cachefile 25462fae26bdSAlan Somers{ 25472fae26bdSAlan Somers typeset pool=$1 25482fae26bdSAlan Somers 25492fae26bdSAlan Somers cachefile=$(cachefile_for_pool $pool) 25502fae26bdSAlan Somers [ $? -ne 0 ] && log_fail "ERROR: Cachefile not created for '$pool'?" 25512fae26bdSAlan Somers log_must test -e "${cachefile}" 25522fae26bdSAlan Somers log_must zdb -U ${cachefile} -C ${pool} 25532fae26bdSAlan Somers} 25542fae26bdSAlan Somers 25552fae26bdSAlan Somers# 25562fae26bdSAlan Somers# Get the zdb options given the cachefile state of the pool. 25572fae26bdSAlan Somers# 25582fae26bdSAlan Somersfunction zdb_cachefile_opts 25592fae26bdSAlan Somers{ 25602fae26bdSAlan Somers typeset pool=$1 25612fae26bdSAlan Somers typeset vdevdir=$2 25622fae26bdSAlan Somers typeset opts 25632fae26bdSAlan Somers 25642fae26bdSAlan Somers if poolexists "$pool"; then 25652fae26bdSAlan Somers cachefile=$(cachefile_for_pool $pool) 25662fae26bdSAlan Somers typeset -i ret=$? 25672fae26bdSAlan Somers case $ret in 25682fae26bdSAlan Somers 0) opts="-C" ;; 25692fae26bdSAlan Somers 1) opts="-U $cachefile -C" ;; 25702fae26bdSAlan Somers 2) opts="-eC" ;; 25712fae26bdSAlan Somers *) log_fail "Unknown return '$ret'" ;; 25722fae26bdSAlan Somers esac 25732fae26bdSAlan Somers else 25742fae26bdSAlan Somers opts="-eC" 25752fae26bdSAlan Somers [[ -n "$vdevdir" ]] && opts="$opts -p $vdevdir" 25762fae26bdSAlan Somers fi 25772fae26bdSAlan Somers echo "$opts" 25782fae26bdSAlan Somers} 25792fae26bdSAlan Somers 25802fae26bdSAlan Somers# 25812fae26bdSAlan Somers# Get configuration of pool 25822fae26bdSAlan Somers# $1 pool name 25832fae26bdSAlan Somers# $2 config name 25842fae26bdSAlan Somers# 25852fae26bdSAlan Somersfunction get_config 25862fae26bdSAlan Somers{ 25872fae26bdSAlan Somers typeset pool=$1 25882fae26bdSAlan Somers typeset config=$2 25892fae26bdSAlan Somers typeset vdevdir=$3 25902fae26bdSAlan Somers typeset alt_root 25912fae26bdSAlan Somers typeset zdb_opts 25922fae26bdSAlan Somers 25932fae26bdSAlan Somers zdb_opts=$(zdb_cachefile_opts $pool $vdevdir) 25942fae26bdSAlan Somers value=$($ZDB $zdb_opts $pool | $GREP "$config:" | $AWK -F: '{print $2}') 25952fae26bdSAlan Somers if [[ -n $value ]] ; then 25962fae26bdSAlan Somers value=${value#'} 25972fae26bdSAlan Somers value=${value%'} 25982fae26bdSAlan Somers else 25992fae26bdSAlan Somers return 1 26002fae26bdSAlan Somers fi 26012fae26bdSAlan Somers echo $value 26022fae26bdSAlan Somers 26032fae26bdSAlan Somers return 0 26042fae26bdSAlan Somers} 26052fae26bdSAlan Somers 26062fae26bdSAlan Somers# 26072fae26bdSAlan Somers# Privated function. Random select one of items from arguments. 26082fae26bdSAlan Somers# 26092fae26bdSAlan Somers# $1 count 26102fae26bdSAlan Somers# $2-n string 26112fae26bdSAlan Somers# 26122fae26bdSAlan Somersfunction _random_get 26132fae26bdSAlan Somers{ 26142fae26bdSAlan Somers typeset cnt=$1 26152fae26bdSAlan Somers shift 26162fae26bdSAlan Somers 26172fae26bdSAlan Somers typeset str="$@" 26182fae26bdSAlan Somers typeset -i ind 26192fae26bdSAlan Somers ((ind = RANDOM % cnt + 1)) 26202fae26bdSAlan Somers 26212fae26bdSAlan Somers typeset ret=$($ECHO "$str" | $CUT -f $ind -d ' ') 26222fae26bdSAlan Somers $ECHO $ret 26232fae26bdSAlan Somers} 26242fae26bdSAlan Somers 26252fae26bdSAlan Somers# 26262fae26bdSAlan Somers# Random select one of item from arguments which include NONE string 26272fae26bdSAlan Somers# 26282fae26bdSAlan Somersfunction random_get_with_non 26292fae26bdSAlan Somers{ 26302fae26bdSAlan Somers typeset -i cnt=$# 26312fae26bdSAlan Somers ((cnt =+ 1)) 26322fae26bdSAlan Somers 26332fae26bdSAlan Somers _random_get "$cnt" "$@" 26342fae26bdSAlan Somers} 26352fae26bdSAlan Somers 26362fae26bdSAlan Somers# 26372fae26bdSAlan Somers# Random select one of item from arguments which doesn't include NONE string 26382fae26bdSAlan Somers# 26392fae26bdSAlan Somersfunction random_get 26402fae26bdSAlan Somers{ 26412fae26bdSAlan Somers _random_get "$#" "$@" 26422fae26bdSAlan Somers} 26432fae26bdSAlan Somers 26442fae26bdSAlan Somers# 26452fae26bdSAlan Somers# The function will generate a dataset name with specific length 26462fae26bdSAlan Somers# $1, the length of the name 26472fae26bdSAlan Somers# $2, the base string to construct the name 26482fae26bdSAlan Somers# 26492fae26bdSAlan Somersfunction gen_dataset_name 26502fae26bdSAlan Somers{ 26512fae26bdSAlan Somers typeset -i len=$1 26522fae26bdSAlan Somers typeset basestr="$2" 26532fae26bdSAlan Somers typeset -i baselen=${#basestr} 26542fae26bdSAlan Somers typeset -i iter=0 26552fae26bdSAlan Somers typeset l_name="" 26562fae26bdSAlan Somers 26572fae26bdSAlan Somers if (( len % baselen == 0 )); then 26582fae26bdSAlan Somers (( iter = len / baselen )) 26592fae26bdSAlan Somers else 26602fae26bdSAlan Somers (( iter = len / baselen + 1 )) 26612fae26bdSAlan Somers fi 26622fae26bdSAlan Somers while (( iter > 0 )); do 26632fae26bdSAlan Somers l_name="${l_name}$basestr" 26642fae26bdSAlan Somers 26652fae26bdSAlan Somers (( iter -= 1 )) 26662fae26bdSAlan Somers done 26672fae26bdSAlan Somers 26682fae26bdSAlan Somers $ECHO $l_name 26692fae26bdSAlan Somers} 26702fae26bdSAlan Somers 26712fae26bdSAlan Somers# 26722fae26bdSAlan Somers# Ensure that a given path has been synced, not just ZIL committed. 26732fae26bdSAlan Somers# 2674c43f30eeSAlan Somers# XXX On FreeBSD, the sync(8) command (via $SYNC) calls zfs_sync() which just 26752fae26bdSAlan Somers# does a zil_commit(), as opposed to a txg_wait_synced(). For things that 26762fae26bdSAlan Somers# require writing to their final destination (e.g. for intentional 26772fae26bdSAlan Somers# corruption purposes), zil_commit() is not good enough. 26782fae26bdSAlan Somers# 26792fae26bdSAlan Somersfunction force_sync_path # path 26802fae26bdSAlan Somers{ 26812fae26bdSAlan Somers typeset path="$1" 26822fae26bdSAlan Somers 2683c43f30eeSAlan Somers log_must $ZPOOL export $TESTPOOL 2684c43f30eeSAlan Somers log_must $ZPOOL import -d $path $TESTPOOL 26852fae26bdSAlan Somers} 26862fae26bdSAlan Somers 26872fae26bdSAlan Somers# 26882fae26bdSAlan Somers# Get cksum tuple of dataset 26892fae26bdSAlan Somers# $1 dataset name 26902fae26bdSAlan Somers# 26912fae26bdSAlan Somers# zdb output is like below 26922fae26bdSAlan Somers# " Dataset pool/fs [ZPL], ID 978, cr_txg 2277, 19.0K, 5 objects, 26932fae26bdSAlan Somers# rootbp [L0 DMU objset] 400L/200P DVA[0]=<0:1880c00:200> 26942fae26bdSAlan Somers# DVA[1]=<0:341880c00:200> fletcher4 lzjb LE contiguous birth=2292 fill=5 26952fae26bdSAlan Somers# cksum=989930ccf:4014fe00c83:da5e388e58b4:1f7332052252ac " 26962fae26bdSAlan Somers# 26972fae26bdSAlan Somersfunction datasetcksum 26982fae26bdSAlan Somers{ 26992fae26bdSAlan Somers typeset cksum 27002fae26bdSAlan Somers $SYNC 27012fae26bdSAlan Somers cksum=$($ZDB -vvv $1 | $GREP "^Dataset $1 \[" | $GREP "cksum" \ 27022fae26bdSAlan Somers | $AWK -F= '{print $6}') 27032fae26bdSAlan Somers $ECHO $cksum 27042fae26bdSAlan Somers} 27052fae26bdSAlan Somers 27062fae26bdSAlan Somers# 27072fae26bdSAlan Somers# Get cksum of file 27082fae26bdSAlan Somers# #1 file path 27092fae26bdSAlan Somers# 27102fae26bdSAlan Somersfunction checksum 27112fae26bdSAlan Somers{ 27122fae26bdSAlan Somers typeset cksum 27132fae26bdSAlan Somers cksum=$($CKSUM $1 | $AWK '{print $1}') 27142fae26bdSAlan Somers $ECHO $cksum 27152fae26bdSAlan Somers} 27162fae26bdSAlan Somers 27172fae26bdSAlan Somers# 27182fae26bdSAlan Somers# Get the given disk/slice state from the specific field of the pool 27192fae26bdSAlan Somers# 27202fae26bdSAlan Somersfunction get_device_state #pool disk field("", "spares","logs") 27212fae26bdSAlan Somers{ 27222fae26bdSAlan Somers typeset pool=$1 27235a2fc464SAndriy Gapon typeset disk=${2#/dev/} 27245a2fc464SAndriy Gapon disk=${disk#/dev/} 27252fae26bdSAlan Somers disk=${disk#/dev/} 27262fae26bdSAlan Somers typeset field=${3:-$pool} 27272fae26bdSAlan Somers 27282fae26bdSAlan Somers state=$($ZPOOL status -v "$pool" 2>/dev/null | \ 27292fae26bdSAlan Somers $NAWK -v device=$disk -v pool=$pool -v field=$field \ 27302fae26bdSAlan Somers 'BEGIN {startconfig=0; startfield=0; } 27312fae26bdSAlan Somers /config:/ {startconfig=1} 27322fae26bdSAlan Somers (startconfig==1)&&($1==field) {startfield=1; next;} 27332fae26bdSAlan Somers (startfield==1)&&($1==device) {print $2; exit;} 27342fae26bdSAlan Somers (startfield==1)&&(NF>=3)&&($(NF-1)=="was")&&($NF==device) {print $2; exit;} 27352fae26bdSAlan Somers (startfield==1)&&($1==field || $1 ~ "^spares$" || $1 ~ "^logs$") {startfield=0}') 27362fae26bdSAlan Somers print $state 27372fae26bdSAlan Somers} 27382fae26bdSAlan Somers 27392fae26bdSAlan Somers 27402fae26bdSAlan Somers# 27412fae26bdSAlan Somers# print the given directory filesystem type 27422fae26bdSAlan Somers# 27432fae26bdSAlan Somers# $1 directory name 27442fae26bdSAlan Somers# 27452fae26bdSAlan Somersfunction get_fstype 27462fae26bdSAlan Somers{ 27472fae26bdSAlan Somers typeset dir=$1 27482fae26bdSAlan Somers 27492fae26bdSAlan Somers if [[ -z $dir ]]; then 27502fae26bdSAlan Somers log_fail "Usage: get_fstype <directory>" 27512fae26bdSAlan Somers fi 27522fae26bdSAlan Somers 27532fae26bdSAlan Somers $DF -T $dir | $AWK '{print $2}' 27542fae26bdSAlan Somers} 27552fae26bdSAlan Somers 27562fae26bdSAlan Somers# 27572fae26bdSAlan Somers# Given a disk, label it to VTOC regardless what label was on the disk 27582fae26bdSAlan Somers# $1 disk 27592fae26bdSAlan Somers# 27602fae26bdSAlan Somersfunction labelvtoc 27612fae26bdSAlan Somers{ 27622fae26bdSAlan Somers typeset disk=$1 27632fae26bdSAlan Somers if [[ -z $disk ]]; then 27642fae26bdSAlan Somers log_fail "The disk name is unspecified." 27652fae26bdSAlan Somers fi 27662fae26bdSAlan Somers typeset label_file=$TMPDIR/labelvtoc.${TESTCASE_ID} 27672fae26bdSAlan Somers typeset arch=$($UNAME -p) 27682fae26bdSAlan Somers 27692fae26bdSAlan Somers if [[ $arch == "i386" ]]; then 27702fae26bdSAlan Somers $ECHO "label" > $label_file 27712fae26bdSAlan Somers $ECHO "0" >> $label_file 27722fae26bdSAlan Somers $ECHO "" >> $label_file 27732fae26bdSAlan Somers $ECHO "q" >> $label_file 27742fae26bdSAlan Somers $ECHO "q" >> $label_file 27752fae26bdSAlan Somers 27762fae26bdSAlan Somers $FDISK -B $disk >/dev/null 2>&1 27772fae26bdSAlan Somers # wait a while for fdisk finishes 27782fae26bdSAlan Somers $SLEEP 60 27792fae26bdSAlan Somers elif [[ $arch == "sparc" ]]; then 27802fae26bdSAlan Somers $ECHO "label" > $label_file 27812fae26bdSAlan Somers $ECHO "0" >> $label_file 27822fae26bdSAlan Somers $ECHO "" >> $label_file 27832fae26bdSAlan Somers $ECHO "" >> $label_file 27842fae26bdSAlan Somers $ECHO "" >> $label_file 27852fae26bdSAlan Somers $ECHO "q" >> $label_file 27862fae26bdSAlan Somers else 27872fae26bdSAlan Somers log_fail "unknown arch type" 27882fae26bdSAlan Somers fi 27892fae26bdSAlan Somers 27902fae26bdSAlan Somers $FORMAT -e -s -d $disk -f $label_file 27912fae26bdSAlan Somers typeset -i ret_val=$? 27922fae26bdSAlan Somers $RM -f $label_file 27932fae26bdSAlan Somers # 27942fae26bdSAlan Somers # wait the format to finish 27952fae26bdSAlan Somers # 27962fae26bdSAlan Somers $SLEEP 60 27972fae26bdSAlan Somers if (( ret_val != 0 )); then 27982fae26bdSAlan Somers log_fail "unable to label $disk as VTOC." 27992fae26bdSAlan Somers fi 28002fae26bdSAlan Somers 28012fae26bdSAlan Somers return 0 28022fae26bdSAlan Somers} 28032fae26bdSAlan Somers 28042fae26bdSAlan Somers# 28052fae26bdSAlan Somers# Detect if the given filesystem property is supported in this release 28062fae26bdSAlan Somers# 28072fae26bdSAlan Somers# 0 Yes, it is supported 28082fae26bdSAlan Somers# !0 No, it is not supported 28092fae26bdSAlan Somers# 28102fae26bdSAlan Somersfunction fs_prop_exist 28112fae26bdSAlan Somers{ 28122fae26bdSAlan Somers typeset prop=$1 28132fae26bdSAlan Somers 28142fae26bdSAlan Somers if [[ -z $prop ]]; then 28152fae26bdSAlan Somers log_fail "Usage: fs_prop_exist <property>" 28162fae26bdSAlan Somers 28172fae26bdSAlan Somers return 1 28182fae26bdSAlan Somers fi 28192fae26bdSAlan Somers 28202fae26bdSAlan Somers # 28212fae26bdSAlan Somers # If the property is shortened column name, 28222fae26bdSAlan Somers # convert it to the standard name 28232fae26bdSAlan Somers # 28242fae26bdSAlan Somers case $prop in 28252fae26bdSAlan Somers avail) prop=available ;; 28262fae26bdSAlan Somers refer) prop=referenced ;; 28272fae26bdSAlan Somers volblock) prop=volblocksize ;; 28282fae26bdSAlan Somers compress) prop=compression ;; 28292fae26bdSAlan Somers rdonly) prop=readonly ;; 28302fae26bdSAlan Somers recsize) prop=recordsize ;; 28312fae26bdSAlan Somers reserv) prop=reservation ;; 28322fae26bdSAlan Somers refreserv) prop=refreservation ;; 28332fae26bdSAlan Somers esac 28342fae26bdSAlan Somers 28352fae26bdSAlan Somers # 28362fae26bdSAlan Somers # The zfs get output looks like the following 28372fae26bdSAlan Somers # 28382fae26bdSAlan Somers 28392fae26bdSAlan Somers # 28402fae26bdSAlan Somers # The following properties are supported: 28412fae26bdSAlan Somers # 28422fae26bdSAlan Somers # PROPERTY EDIT INHERIT VALUES 28432fae26bdSAlan Somers # 28442fae26bdSAlan Somers # available NO NO <size> 28452fae26bdSAlan Somers # compressratio NO NO <1.00x or higher if compressed> 28462fae26bdSAlan Somers # creation NO NO <date> 28472fae26bdSAlan Somers # ... ... 28482fae26bdSAlan Somers # zoned YES YES on | off 28492fae26bdSAlan Somers # 28502fae26bdSAlan Somers # Sizes are specified in bytes with standard units such as K, M, G, etc. 28512fae26bdSAlan Somers # 28522fae26bdSAlan Somers 28532fae26bdSAlan Somers # 28542fae26bdSAlan Somers # Start to extract property from the first blank line after 'PROPERTY' 28552fae26bdSAlan Somers # and stop at the next blank line 28562fae26bdSAlan Somers # 28572fae26bdSAlan Somers $ZFS get 2>&1 | \ 28582fae26bdSAlan Somers $AWK '/PROPERTY/ {start=1; next} 28592fae26bdSAlan Somers /Sizes/ {start=0} 28602fae26bdSAlan Somers start==1 {print $1}' | \ 28612fae26bdSAlan Somers $GREP -w "$prop" > /dev/null 2>&1 28622fae26bdSAlan Somers 28632fae26bdSAlan Somers return $? 28642fae26bdSAlan Somers} 28652fae26bdSAlan Somers 28662fae26bdSAlan Somers# 28672fae26bdSAlan Somers# Detect if the given pool property is supported in this release 28682fae26bdSAlan Somers# 28692fae26bdSAlan Somers# 0 Yes, it is supported 28702fae26bdSAlan Somers# !0 No, it is not supported 28712fae26bdSAlan Somers# 28722fae26bdSAlan Somersfunction pool_prop_exist 28732fae26bdSAlan Somers{ 28742fae26bdSAlan Somers typeset prop=$1 28752fae26bdSAlan Somers if [[ -z $prop ]]; then 28762fae26bdSAlan Somers log_fail "Usage: pool_prop_exist <property>" 28772fae26bdSAlan Somers 28782fae26bdSAlan Somers return 1 28792fae26bdSAlan Somers fi 28802fae26bdSAlan Somers # 28812fae26bdSAlan Somers # If the property is shortened column name, 28822fae26bdSAlan Somers # convert it to the standard name 28832fae26bdSAlan Somers # 28842fae26bdSAlan Somers case $prop in 28852fae26bdSAlan Somers avail) prop=available ;; 28862fae26bdSAlan Somers cap) prop=capacity ;; 28872fae26bdSAlan Somers replace) prop=autoreplace ;; 28882fae26bdSAlan Somers esac 28892fae26bdSAlan Somers 28902fae26bdSAlan Somers # 28912fae26bdSAlan Somers # The zpool get output looks like the following 28922fae26bdSAlan Somers # 28932fae26bdSAlan Somers 28942fae26bdSAlan Somers # usage: 28952fae26bdSAlan Somers # get <"all" | property[,...]> <pool> ... 28962fae26bdSAlan Somers # 28972fae26bdSAlan Somers # the following properties are supported: 28982fae26bdSAlan Somers # 28992fae26bdSAlan Somers # PROPERTY EDIT VALUES 29002fae26bdSAlan Somers # 29012fae26bdSAlan Somers # available NO <size> 29022fae26bdSAlan Somers # capacity NO <size> 29032fae26bdSAlan Somers # guid NO <guid> 29042fae26bdSAlan Somers # health NO <state> 29052fae26bdSAlan Somers # size NO <size> 29062fae26bdSAlan Somers # used NO <size> 29072fae26bdSAlan Somers # altroot YES <path> 29082fae26bdSAlan Somers # autoreplace YES on | off 29092fae26bdSAlan Somers # bootfs YES <filesystem> 29102fae26bdSAlan Somers # cachefile YES <file> | none 29112fae26bdSAlan Somers # delegation YES on | off 29122fae26bdSAlan Somers # failmode YES wait | continue | panic 29132fae26bdSAlan Somers # version YES <version> 29142fae26bdSAlan Somers 29152fae26bdSAlan Somers $ZPOOL get 2>&1 | \ 29162fae26bdSAlan Somers $AWK '/PROPERTY/ {start=1; next} 29172fae26bdSAlan Somers start==1 {print $1}' | \ 29182fae26bdSAlan Somers $GREP -w "$prop" > /dev/null 2>&1 29192fae26bdSAlan Somers 29202fae26bdSAlan Somers return $? 29212fae26bdSAlan Somers} 29222fae26bdSAlan Somers 29232fae26bdSAlan Somers# 29242fae26bdSAlan Somers# check if the system was installed as zfsroot or not 29252fae26bdSAlan Somers# return: 0 ture, otherwise false 29262fae26bdSAlan Somers# 29272fae26bdSAlan Somersfunction is_zfsroot 29282fae26bdSAlan Somers{ 29292fae26bdSAlan Somers $DF -T / | $GREP -q zfs 29302fae26bdSAlan Somers} 29312fae26bdSAlan Somers 29322fae26bdSAlan Somers# 29332fae26bdSAlan Somers# get the root filesystem name if it's zfsroot system. 29342fae26bdSAlan Somers# 29352fae26bdSAlan Somers# return: root filesystem name 29362fae26bdSAlan Somersfunction get_rootfs 29372fae26bdSAlan Somers{ 29382fae26bdSAlan Somers typeset rootfs="" 29392fae26bdSAlan Somers rootfs=$($MOUNT | $AWK '$3 == "\/" && $4~/zfs/ {print $1}') 29402fae26bdSAlan Somers if [[ -z "$rootfs" ]]; then 29412fae26bdSAlan Somers log_fail "Can not get rootfs" 29422fae26bdSAlan Somers fi 29432fae26bdSAlan Somers $ZFS list $rootfs > /dev/null 2>&1 29442fae26bdSAlan Somers if (( $? == 0 )); then 29452fae26bdSAlan Somers $ECHO $rootfs 29462fae26bdSAlan Somers else 29472fae26bdSAlan Somers log_fail "This is not a zfsroot system." 29482fae26bdSAlan Somers fi 29492fae26bdSAlan Somers} 29502fae26bdSAlan Somers 29512fae26bdSAlan Somers# 29522fae26bdSAlan Somers# get the rootfs's pool name 29532fae26bdSAlan Somers# return: 29542fae26bdSAlan Somers# rootpool name 29552fae26bdSAlan Somers# 29562fae26bdSAlan Somersfunction get_rootpool 29572fae26bdSAlan Somers{ 29582fae26bdSAlan Somers typeset rootfs="" 29592fae26bdSAlan Somers typeset rootpool="" 29602fae26bdSAlan Somers rootfs=$(get_rootfs) 29612fae26bdSAlan Somers rootpool=`$ECHO $rootfs | awk -F\/ '{print $1}'` 29622fae26bdSAlan Somers echo $rootpool 29632fae26bdSAlan Somers} 29642fae26bdSAlan Somers 29652fae26bdSAlan Somers# 29662fae26bdSAlan Somers# Get the sub string from specified source string 29672fae26bdSAlan Somers# 29682fae26bdSAlan Somers# $1 source string 29692fae26bdSAlan Somers# $2 start position. Count from 1 29702fae26bdSAlan Somers# $3 offset 29712fae26bdSAlan Somers# 29722fae26bdSAlan Somersfunction get_substr #src_str pos offset 29732fae26bdSAlan Somers{ 29742fae26bdSAlan Somers typeset pos offset 29752fae26bdSAlan Somers 29762fae26bdSAlan Somers $ECHO $1 | \ 29772fae26bdSAlan Somers $NAWK -v pos=$2 -v offset=$3 '{print substr($0, pos, offset)}' 29782fae26bdSAlan Somers} 29792fae26bdSAlan Somers 29802fae26bdSAlan Somers# 29812fae26bdSAlan Somers# Get the directory path of given device 29822fae26bdSAlan Somers# 29832fae26bdSAlan Somersfunction get_device_dir #device 29842fae26bdSAlan Somers{ 29852fae26bdSAlan Somers typeset device=$1 29862fae26bdSAlan Somers 29872fae26bdSAlan Somers $ECHO "/dev" 29882fae26bdSAlan Somers} 29892fae26bdSAlan Somers 29902fae26bdSAlan Somers# 29912fae26bdSAlan Somers# Get the package name 29922fae26bdSAlan Somers# 29932fae26bdSAlan Somersfunction get_package_name 29942fae26bdSAlan Somers{ 29952fae26bdSAlan Somers typeset dirpath=${1:-$STC_NAME} 29962fae26bdSAlan Somers 29972fae26bdSAlan Somers print "SUNWstc-${dirpath}" | /usr/bin/sed -e "s/\//-/g" 29982fae26bdSAlan Somers} 29992fae26bdSAlan Somers 30002fae26bdSAlan Somers# 30012fae26bdSAlan Somers# Get the word numbers from a string separated by white space 30022fae26bdSAlan Somers# 30032fae26bdSAlan Somersfunction get_word_count 30042fae26bdSAlan Somers{ 30052fae26bdSAlan Somers $ECHO $1 | $WC -w 30062fae26bdSAlan Somers} 30072fae26bdSAlan Somers 30082fae26bdSAlan Somers# 30092fae26bdSAlan Somers# To verify if the require numbers of disks is given 30102fae26bdSAlan Somers# 30112fae26bdSAlan Somersfunction verify_disk_count 30122fae26bdSAlan Somers{ 30132fae26bdSAlan Somers typeset -i min=${2:-1} 30142fae26bdSAlan Somers 30152fae26bdSAlan Somers typeset -i count=$(get_word_count "$1") 30162fae26bdSAlan Somers 30172fae26bdSAlan Somers if (( count < min )); then 30182fae26bdSAlan Somers atf_skip "A minimum of $min disks is required to run." \ 30192fae26bdSAlan Somers " You specified $count disk(s)" 30202fae26bdSAlan Somers fi 30212fae26bdSAlan Somers} 30222fae26bdSAlan Somers 30232fae26bdSAlan Somers# 30242fae26bdSAlan Somers# Verify that vfs.zfs.vol.recursive is set, so pools can be created using zvols 30252fae26bdSAlan Somers# as backing stores. 30262fae26bdSAlan Somers# 30272fae26bdSAlan Somersfunction verify_zvol_recursive 30282fae26bdSAlan Somers{ 30292fae26bdSAlan Somers if [ "`sysctl -n vfs.zfs.vol.recursive`" -ne 1 ]; then 30302fae26bdSAlan Somers atf_skip "Recursive ZVOLs not enabled" 30312fae26bdSAlan Somers fi 30322fae26bdSAlan Somers} 30332fae26bdSAlan Somers 30342fae26bdSAlan Somers# 30352fae26bdSAlan Somers# bsdmap disk/slice number to a device path 30362fae26bdSAlan Somers# 30372fae26bdSAlan Somersfunction bsddevmap 30382fae26bdSAlan Somers{ 30392fae26bdSAlan Somers typeset arg=$1 30402fae26bdSAlan Somers echo $arg | egrep "*s[0-9]$" > /dev/null 2>&1 30412fae26bdSAlan Somers if [ $? -eq 0 ] 30422fae26bdSAlan Somers then 30432fae26bdSAlan Somers n=`echo $arg| wc -c` 30442fae26bdSAlan Somers set -A map a b c d e f g h i j 30452fae26bdSAlan Somers s=`echo $arg | cut -c $((n-1))` 30462fae26bdSAlan Somers arg=${arg%s[0-9]}${map[$s]} 30472fae26bdSAlan Somers fi 30482fae26bdSAlan Somers echo $arg 30492fae26bdSAlan Somers} 30502fae26bdSAlan Somers 30512fae26bdSAlan Somers# 30522fae26bdSAlan Somers# Get the name of the snapshots directory. Traditionally .zfs/snapshots 30532fae26bdSAlan Somers# 30542fae26bdSAlan Somersfunction get_snapdir_name 30552fae26bdSAlan Somers{ 30562fae26bdSAlan Somers echo ".zfs/snapshot" 30572fae26bdSAlan Somers} 30582fae26bdSAlan Somers 30592fae26bdSAlan Somers# 30602fae26bdSAlan Somers# Unmount all ZFS filesystems except for those that are in the KEEP variable 30612fae26bdSAlan Somers# 30622fae26bdSAlan Somersfunction unmount_all_safe 30632fae26bdSAlan Somers{ 30642fae26bdSAlan Somers echo $(all_pools) | \ 30652fae26bdSAlan Somers $XARGS -n 1 $ZFS list -H -o name -t all -r | \ 30662fae26bdSAlan Somers $XARGS -n 1 $ZFS unmount 30672fae26bdSAlan Somers} 30682fae26bdSAlan Somers 30692fae26bdSAlan Somers# 30702fae26bdSAlan Somers# Return the highest pool version that this OS can create 30712fae26bdSAlan Somers# 30722fae26bdSAlan Somersfunction get_zpool_version 30732fae26bdSAlan Somers{ 30742fae26bdSAlan Somers # We assume output from zpool upgrade -v of the form: 30752fae26bdSAlan Somers # 30762fae26bdSAlan Somers # This system is currently running ZFS version 2. 30772fae26bdSAlan Somers # . 30782fae26bdSAlan Somers # . 30792fae26bdSAlan Somers typeset ZPOOL_VERSION=$($ZPOOL upgrade -v | $HEAD -1 | \ 30802fae26bdSAlan Somers $AWK '{print $NF}' | $SED -e 's/\.//g') 30812fae26bdSAlan Somers # Starting with version 5000, the output format changes to: 30822fae26bdSAlan Somers # This system supports ZFS pool feature flags. 30832fae26bdSAlan Somers # . 30842fae26bdSAlan Somers # . 30852fae26bdSAlan Somers if [[ $ZPOOL_VERSION = "flags" ]]; then 30862fae26bdSAlan Somers ZPOOL_VERSION=5000 30872fae26bdSAlan Somers fi 30882fae26bdSAlan Somers echo $ZPOOL_VERSION 30892fae26bdSAlan Somers} 30902fae26bdSAlan Somers 30912fae26bdSAlan Somers# Ensures that zfsd is running, starting it if necessary. Every test that 30922fae26bdSAlan Somers# interacts with zfsd must call this at startup. This is intended primarily 30932fae26bdSAlan Somers# to eliminate interference from outside the test suite. 30942fae26bdSAlan Somersfunction ensure_zfsd_running 30952fae26bdSAlan Somers{ 30962fae26bdSAlan Somers if ! service zfsd status > /dev/null 2>&1; then 30972fae26bdSAlan Somers service zfsd start || service zfsd onestart 30982fae26bdSAlan Somers service zfsd status > /dev/null 2>&1 || 30992fae26bdSAlan Somers log_unsupported "Test requires zfsd" 31002fae26bdSAlan Somers fi 31012fae26bdSAlan Somers} 31022fae26bdSAlan Somers 31032fae26bdSAlan Somers# Temporarily stops ZFSD, because it can interfere with some tests. If this 31042fae26bdSAlan Somers# function is used, then restart_zfsd _must_ be called in the cleanup routine. 31052fae26bdSAlan Somersfunction stop_zfsd 31062fae26bdSAlan Somers{ 31072fae26bdSAlan Somers $RM -f $TMPDIR/.zfsd_enabled_during_stf_zfs_tests 31082fae26bdSAlan Somers if [[ -n "$ZFSD" && -x "$ZFSD" ]]; then 31092fae26bdSAlan Somers if /etc/rc.d/zfsd status > /dev/null; then 31102fae26bdSAlan Somers log_note "Stopping zfsd" 31112fae26bdSAlan Somers $TOUCH $TMPDIR/.zfsd_enabled_during_stf_zfs_tests 31122fae26bdSAlan Somers /etc/rc.d/zfsd stop || /etc/rc.d/zfsd onestop 31132fae26bdSAlan Somers fi 31142fae26bdSAlan Somers fi 31152fae26bdSAlan Somers} 31162fae26bdSAlan Somers 31172fae26bdSAlan Somers# Restarts zfsd after it has been stopped by stop_zfsd. Intelligently restarts 31182fae26bdSAlan Somers# only iff zfsd was running at the time stop_zfsd was called. 31192fae26bdSAlan Somersfunction restart_zfsd 31202fae26bdSAlan Somers{ 31212fae26bdSAlan Somers if [[ -f $TMPDIR/.zfsd_enabled_during_stf_zfs_tests ]]; then 31222fae26bdSAlan Somers log_note "Restarting zfsd" 31232fae26bdSAlan Somers /etc/rc.d/zfsd start || /etc/rc.d/zfsd onestart 31242fae26bdSAlan Somers fi 31252fae26bdSAlan Somers $RM -f $TMPDIR/.zfsd_enabled_during_stf_zfs_tests 31262fae26bdSAlan Somers} 31272fae26bdSAlan Somers 31282fae26bdSAlan Somers# 31292fae26bdSAlan Somers# Using the given <vdev>, obtain the value of the property <propname> for 31302fae26bdSAlan Somers# the given <tvd> identified by numeric id. 31312fae26bdSAlan Somers# 31322fae26bdSAlan Somersfunction get_tvd_prop # vdev tvd propname 31332fae26bdSAlan Somers{ 31342fae26bdSAlan Somers typeset vdev=$1 31352fae26bdSAlan Somers typeset -i tvd=$2 31362fae26bdSAlan Somers typeset propname=$3 31372fae26bdSAlan Somers 31382fae26bdSAlan Somers $ZDB -l $vdev | $AWK -v tvd=$tvd -v prop="${propname}:" ' 31392fae26bdSAlan Somers BEGIN { start = 0; } 31402fae26bdSAlan Somers /^ id:/ && ($2==tvd) { start = 1; next; } 31412fae26bdSAlan Somers (start==0) { next; } 31422fae26bdSAlan Somers /^ [a-z]+/ && ($1==prop) { print $2; exit; } 31432fae26bdSAlan Somers /^ children/ { exit; } 31442fae26bdSAlan Somers ' 31452fae26bdSAlan Somers} 31462fae26bdSAlan Somers 31472fae26bdSAlan Somers# 31482fae26bdSAlan Somers# Convert a DVA into a physical block address. Prints number of blocks. 31492fae26bdSAlan Somers# This takes the usual printed form, in which offsets are left shifted so 31502fae26bdSAlan Somers# they represent bytes rather than the native sector count. 31512fae26bdSAlan Somers# 31522fae26bdSAlan Somersfunction dva_to_block_addr # dva 31532fae26bdSAlan Somers{ 31542fae26bdSAlan Somers typeset dva=$1 31552fae26bdSAlan Somers 31562fae26bdSAlan Somers typeset offcol=$(echo $dva | cut -f2 -d:) 31572fae26bdSAlan Somers typeset -i offset="0x${offcol}" 31582fae26bdSAlan Somers # First add 4MB to skip the boot blocks and first two vdev labels, 31592fae26bdSAlan Somers # then convert to 512 byte blocks (for use with dd). Note that this 31602fae26bdSAlan Somers # differs from simply adding 8192 blocks, since the input offset is 31612fae26bdSAlan Somers # given in bytes and has the actual ashift baked in. 31622fae26bdSAlan Somers (( offset += 4*1024*1024 )) 31632fae26bdSAlan Somers (( offset >>= 9 )) 31642fae26bdSAlan Somers echo "$offset" 31652fae26bdSAlan Somers} 31662fae26bdSAlan Somers 31672fae26bdSAlan Somers# 31682fae26bdSAlan Somers# Convert a RAIDZ DVA into a physical block address. This has the same 31692fae26bdSAlan Somers# output as dva_to_block_addr (number of blocks from beginning of device), but 31702fae26bdSAlan Somers# is more complicated due to RAIDZ. ashift is normally always 9, but RAIDZ 31712fae26bdSAlan Somers# uses the actual tvd ashift instead. Furthermore, the number of vdevs changes 31722fae26bdSAlan Somers# the actual block for each device. 31732fae26bdSAlan Somers# 31742fae26bdSAlan Somersfunction raidz_dva_to_block_addr # dva ncols ashift 31752fae26bdSAlan Somers{ 31762fae26bdSAlan Somers typeset dva=$1 31772fae26bdSAlan Somers typeset -i ncols=$2 31782fae26bdSAlan Somers typeset -i ashift=$3 31792fae26bdSAlan Somers 31802fae26bdSAlan Somers typeset -i offset=0x$(echo $dva | cut -f2 -d:) 31812fae26bdSAlan Somers (( offset >>= ashift )) 31822fae26bdSAlan Somers 31832fae26bdSAlan Somers typeset -i ioff=$(( (offset + ncols - 1) / ncols )) 31842fae26bdSAlan Somers 31852fae26bdSAlan Somers # Now add the front 4MB and return. 31862fae26bdSAlan Somers (( ioff += ( 4194304 >> $ashift ) )) 31872fae26bdSAlan Somers echo "$ioff" 31882fae26bdSAlan Somers} 31892fae26bdSAlan Somers 31902fae26bdSAlan Somers# 31912fae26bdSAlan Somers# Return the vdevs for the given toplevel vdev number. 31922fae26bdSAlan Somers# Child vdevs will only be included if they are ONLINE. Output format: 31932fae26bdSAlan Somers# 31942fae26bdSAlan Somers# <toplevel vdev type> <nchildren> <child1>[:<child2> ...] 31952fae26bdSAlan Somers# 31962fae26bdSAlan Somers# Valid toplevel vdev types are mirror, raidz[1-3], leaf (which can be a 31972fae26bdSAlan Somers# disk or a file). Note that 'nchildren' can be larger than the number of 31982fae26bdSAlan Somers# returned children; it represents the number of children regardless of how 31992fae26bdSAlan Somers# many are actually online. 32002fae26bdSAlan Somers# 32012fae26bdSAlan Somersfunction vdevs_for_tvd # pool tvd 32022fae26bdSAlan Somers{ 32032fae26bdSAlan Somers typeset pool=$1 32042fae26bdSAlan Somers typeset -i tvd=$2 32052fae26bdSAlan Somers 32062fae26bdSAlan Somers $ZPOOL status $pool | $AWK -v want_tvd=$tvd ' 32072fae26bdSAlan Somers BEGIN { 32082fae26bdSAlan Somers start = 0; tvd = -1; lvd = -1; 32092fae26bdSAlan Somers type = "UNKNOWN"; disks = ""; disk = ""; 32102fae26bdSAlan Somers nchildren = 0; 32112fae26bdSAlan Somers } 32122fae26bdSAlan Somers /NAME.*STATE/ { start = 1; next; } 32132fae26bdSAlan Somers (start==0) { next; } 32142fae26bdSAlan Somers 32152fae26bdSAlan Somers (tvd > want_tvd) { exit; } 32162fae26bdSAlan Somers END { print type " " nchildren " " disks; } 32172fae26bdSAlan Somers 32182fae26bdSAlan Somers length(disk) > 0 { 32192fae26bdSAlan Somers if (length(disks) > 0) { disks = disks " "; } 32202fae26bdSAlan Somers if (substr(disk, 0, 1) == "/") { 32212fae26bdSAlan Somers disks = disks disk; 32222fae26bdSAlan Somers } else { 32232fae26bdSAlan Somers disks = disks "/dev/" disk; 32242fae26bdSAlan Somers } 32252fae26bdSAlan Somers disk = ""; 32262fae26bdSAlan Somers } 32272fae26bdSAlan Somers 32282fae26bdSAlan Somers /^\t(spares|logs)/ { tvd = want_tvd + 1; next; } 32292fae26bdSAlan Somers /^\t (mirror|raidz[1-3])-[0-9]+/ { 32302fae26bdSAlan Somers tvd += 1; 32312fae26bdSAlan Somers (tvd == want_tvd) && type = substr($1, 0, 6); 32322fae26bdSAlan Somers next; 32332fae26bdSAlan Somers } 32342fae26bdSAlan Somers /^\t [\/A-Za-z]+/ { 32352fae26bdSAlan Somers tvd += 1; 32362fae26bdSAlan Somers if (tvd == want_tvd) { 32372fae26bdSAlan Somers (( nchildren += 1 )) 32382fae26bdSAlan Somers type = "leaf"; 32392fae26bdSAlan Somers ($2 == "ONLINE") && disk = $1; 32402fae26bdSAlan Somers } 32412fae26bdSAlan Somers next; 32422fae26bdSAlan Somers } 32432fae26bdSAlan Somers 32442fae26bdSAlan Somers (tvd < want_tvd) { next; } 32452fae26bdSAlan Somers 32462fae26bdSAlan Somers /^\t spare-[0-9]+/ { next; } 32472fae26bdSAlan Somers /^\t [\/A-Za-z]+/ { 32482fae26bdSAlan Somers (( nchildren += 1 )) 32492fae26bdSAlan Somers ($2 == "ONLINE") && disk = $1; 32502fae26bdSAlan Somers next; 32512fae26bdSAlan Somers } 32522fae26bdSAlan Somers 32532fae26bdSAlan Somers /^\t [\/A-Za-z]+/ { 32542fae26bdSAlan Somers (( nchildren += 1 )) 32552fae26bdSAlan Somers ($2 == "ONLINE") && disk = $1; 32562fae26bdSAlan Somers next; 32572fae26bdSAlan Somers } 32582fae26bdSAlan Somers ' 32592fae26bdSAlan Somers} 32602fae26bdSAlan Somers 32612fae26bdSAlan Somers# 32622fae26bdSAlan Somers# Get a vdev path, ashift & offset for a given pool/dataset and DVA. 32632fae26bdSAlan Somers# If desired, can also select the toplevel vdev child number. 32642fae26bdSAlan Somers# 32652fae26bdSAlan Somersfunction dva_to_vdev_ashift_off # pool/dataset dva [leaf_vdev_num] 32662fae26bdSAlan Somers{ 32672fae26bdSAlan Somers typeset poollike=$1 32682fae26bdSAlan Somers typeset dva=$2 32692fae26bdSAlan Somers typeset -i leaf_vdev_num=$3 32702fae26bdSAlan Somers 32712fae26bdSAlan Somers # vdevs are normally 0-indexed while arguments are 1-indexed. 32722fae26bdSAlan Somers (( leaf_vdev_num += 1 )) 32732fae26bdSAlan Somers 32742fae26bdSAlan Somers # Strip any child datasets or snapshots. 32752fae26bdSAlan Somers pool=$(echo $poollike | sed -e 's,[/@].*,,g') 32762fae26bdSAlan Somers tvd=$(echo $dva | cut -d: -f1) 32772fae26bdSAlan Somers 32782fae26bdSAlan Somers set -- $(vdevs_for_tvd $pool $tvd) 32792fae26bdSAlan Somers log_debug "vdevs_for_tvd: $* <EOM>" 32802fae26bdSAlan Somers tvd_type=$1; shift 32812fae26bdSAlan Somers nchildren=$1; shift 32822fae26bdSAlan Somers 32832fae26bdSAlan Somers lvd=$(eval echo \$$leaf_vdev_num) 32842fae26bdSAlan Somers log_debug "type='$tvd_type' children='$nchildren' lvd='$lvd' dva='$dva'" 32852fae26bdSAlan Somers case $tvd_type in 32862fae26bdSAlan Somers raidz*) 32872fae26bdSAlan Somers ashift=$(get_tvd_prop $lvd $tvd ashift) 32882fae26bdSAlan Somers log_debug "raidz: ashift='${ashift}'" 32892fae26bdSAlan Somers off=$(raidz_dva_to_block_addr $dva $nchildren $ashift) 32902fae26bdSAlan Somers ;; 32912fae26bdSAlan Somers *) 32922fae26bdSAlan Somers ashift=9 32932fae26bdSAlan Somers off=$(dva_to_block_addr $dva) 32942fae26bdSAlan Somers ;; 32952fae26bdSAlan Somers esac 32962fae26bdSAlan Somers echo "${lvd}:${ashift}:${off}" 32972fae26bdSAlan Somers} 32982fae26bdSAlan Somers 32992fae26bdSAlan Somers# 33002fae26bdSAlan Somers# Get the DVA for the specified dataset's given filepath. 33012fae26bdSAlan Somers# 33022fae26bdSAlan Somersfunction file_dva # dataset filepath [level] [offset] [dva_num] 33032fae26bdSAlan Somers{ 33042fae26bdSAlan Somers typeset dataset=$1 33052fae26bdSAlan Somers typeset filepath=$2 33062fae26bdSAlan Somers typeset -i level=$3 33072fae26bdSAlan Somers typeset -i offset=$4 33082fae26bdSAlan Somers typeset -i dva_num=$5 33092fae26bdSAlan Somers 33102fae26bdSAlan Somers typeset -li blksz=0 33112fae26bdSAlan Somers typeset -li blknum=0 33122fae26bdSAlan Somers typeset -li startoff 33132fae26bdSAlan Somers typeset -li inode 33142fae26bdSAlan Somers 33152fae26bdSAlan Somers eval `$STAT -s "$filepath"` 33162fae26bdSAlan Somers inode="$st_ino" 33172fae26bdSAlan Somers 33182fae26bdSAlan Somers # The inner match is for 'DVA[0]=<0:1b412600:200>', in which the 33192fae26bdSAlan Somers # text surrounding the actual DVA is a fixed size with 8 characters 33202fae26bdSAlan Somers # before it and 1 after. 3321c43f30eeSAlan Somers $ZDB -P -vvvvv "$dataset/" $inode | \ 33222fae26bdSAlan Somers $AWK -v level=${level} -v dva_num=${dva_num} ' 33232fae26bdSAlan Somers BEGIN { stage = 0; } 33242fae26bdSAlan Somers (stage == 0) && ($1=="Object") { stage = 1; next; } 33252fae26bdSAlan Somers 33262fae26bdSAlan Somers (stage == 1) { 33272fae26bdSAlan Somers print $3 " " $4; 33282fae26bdSAlan Somers stage = 2; next; 33292fae26bdSAlan Somers } 33302fae26bdSAlan Somers 33312fae26bdSAlan Somers (stage == 2) && /^Indirect blocks/ { stage=3; next; } 33322fae26bdSAlan Somers (stage < 3) { next; } 33332fae26bdSAlan Somers 33342fae26bdSAlan Somers match($2, /L[0-9]/) { 33352fae26bdSAlan Somers if (substr($2, RSTART+1, RLENGTH-1) != level) { next; } 33362fae26bdSAlan Somers } 33372fae26bdSAlan Somers match($3, /DVA\[.*>/) { 33382fae26bdSAlan Somers dva = substr($3, RSTART+8, RLENGTH-9); 33392fae26bdSAlan Somers if (substr($3, RSTART+4, 1) == dva_num) { 33402fae26bdSAlan Somers print $1 " " dva; 33412fae26bdSAlan Somers } 33422fae26bdSAlan Somers } 33432fae26bdSAlan Somers ' | \ 33442fae26bdSAlan Somers while read line; do 33452fae26bdSAlan Somers log_debug "params='$blksz/$blknum/$startoff' line='$line'" 33462fae26bdSAlan Somers if (( blksz == 0 )); then 33472fae26bdSAlan Somers typeset -i iblksz=$(echo $line | cut -d " " -f1) 33482fae26bdSAlan Somers typeset -i dblksz=$(echo $line | cut -d " " -f2) 33492fae26bdSAlan Somers 33502fae26bdSAlan Somers # Calculate the actual desired block starting offset. 33512fae26bdSAlan Somers if (( level > 0 )); then 33522fae26bdSAlan Somers typeset -i nbps_per_level 33532fae26bdSAlan Somers typeset -i indsz 33542fae26bdSAlan Somers typeset -i i=0 33552fae26bdSAlan Somers 33562fae26bdSAlan Somers (( nbps_per_level = iblksz / 128 )) 33572fae26bdSAlan Somers (( blksz = dblksz )) 33582fae26bdSAlan Somers for (( i = 0; $i < $level; i++ )); do 33592fae26bdSAlan Somers (( blksz *= nbps_per_level )) 33602fae26bdSAlan Somers done 33612fae26bdSAlan Somers else 33622fae26bdSAlan Somers blksz=$dblksz 33632fae26bdSAlan Somers fi 33642fae26bdSAlan Somers 33652fae26bdSAlan Somers (( blknum = offset / blksz )) 33662fae26bdSAlan Somers (( startoff = blknum * blksz )) 33672fae26bdSAlan Somers continue 33682fae26bdSAlan Somers fi 33692fae26bdSAlan Somers 33702fae26bdSAlan Somers typeset lineoffstr=$(echo $line | cut -d " " -f1) 33712fae26bdSAlan Somers typeset -i lineoff=$(printf "%d" "0x${lineoffstr}") 33722fae26bdSAlan Somers typeset dva="$(echo $line | cut -d " " -f2)" 33732fae26bdSAlan Somers log_debug "str='$lineoffstr' lineoff='$lineoff' dva='$dva'" 33742fae26bdSAlan Somers if [[ -n "$dva" ]] && (( lineoff == startoff )); then 33752fae26bdSAlan Somers echo $line | cut -d " " -f2 33762fae26bdSAlan Somers return 0 33772fae26bdSAlan Somers fi 33782fae26bdSAlan Somers done 33792fae26bdSAlan Somers return 1 33802fae26bdSAlan Somers} 33812fae26bdSAlan Somers 33822fae26bdSAlan Somers# 33832fae26bdSAlan Somers# Corrupt the given dataset's filepath file. This will obtain the first 33842fae26bdSAlan Somers# level 0 block's DVA and scribble random bits on it. 33852fae26bdSAlan Somers# 33862fae26bdSAlan Somersfunction corrupt_file # dataset filepath [leaf_vdev_num] 33872fae26bdSAlan Somers{ 33882fae26bdSAlan Somers typeset dataset=$1 33892fae26bdSAlan Somers typeset filepath=$2 33902fae26bdSAlan Somers typeset -i leaf_vdev_num="$3" 33912fae26bdSAlan Somers 33922fae26bdSAlan Somers dva=$(file_dva $dataset $filepath) 33932fae26bdSAlan Somers [ $? -ne 0 ] && log_fail "ERROR: Can't find file $filepath on $dataset" 33942fae26bdSAlan Somers 33952fae26bdSAlan Somers vdoff=$(dva_to_vdev_ashift_off $dataset $dva $leaf_vdev_num) 33962fae26bdSAlan Somers vdev=$(echo $vdoff | cut -d: -f1) 33972fae26bdSAlan Somers ashift=$(echo $vdoff | cut -d: -f2) 33982fae26bdSAlan Somers off=$(echo $vdoff | cut -d: -f3) 33992fae26bdSAlan Somers blocksize=$(( 1 << $ashift )) 34002fae26bdSAlan Somers 34012fae26bdSAlan Somers log_note "Corrupting ${dataset}'s $filepath on $vdev at DVA $dva with ashift $ashift" 34022fae26bdSAlan Somers log_must $DD if=/dev/urandom bs=$blocksize of=$vdev seek=$off count=1 conv=notrunc 34032fae26bdSAlan Somers} 34042fae26bdSAlan Somers 34052fae26bdSAlan Somers# 34062fae26bdSAlan Somers# Given a number of files, this function will iterate through 34072fae26bdSAlan Somers# the loop creating the specified number of files, whose names 34082fae26bdSAlan Somers# will start with <basename>. 34092fae26bdSAlan Somers# 34102fae26bdSAlan Somers# The <data> argument is special: it can be "ITER", in which case 34112fae26bdSAlan Somers# the -d argument will be the value of the current iteration. It 34122fae26bdSAlan Somers# can be 0, in which case it will always be 0. Otherwise, it will 34132fae26bdSAlan Somers# always be the given value. 34142fae26bdSAlan Somers# 34152fae26bdSAlan Somers# If <snapbase> is specified, a snapshot will be taken using the 34162fae26bdSAlan Somers# argument as the snapshot basename. 34172fae26bdSAlan Somers# 34182fae26bdSAlan Somersfunction populate_dir # basename num_files write_count blocksz data snapbase 34192fae26bdSAlan Somers{ 34202fae26bdSAlan Somers typeset basename=$1 34212fae26bdSAlan Somers typeset -i num_files=$2 34222fae26bdSAlan Somers typeset -i write_count=$3 34232fae26bdSAlan Somers typeset -i blocksz=$4 34242fae26bdSAlan Somers typeset -i i 34252fae26bdSAlan Somers typeset data=$5 34262fae26bdSAlan Somers typeset snapbase="$6" 34272fae26bdSAlan Somers 34282fae26bdSAlan Somers log_note "populate_dir: data='$data'" 34292fae26bdSAlan Somers for (( i = 0; i < num_files; i++ )); do 34302fae26bdSAlan Somers case "$data" in 34312fae26bdSAlan Somers 0) d=0 ;; 34322fae26bdSAlan Somers ITER) d=$i ;; 34332fae26bdSAlan Somers *) d=$data ;; 34342fae26bdSAlan Somers esac 34352fae26bdSAlan Somers 34362fae26bdSAlan Somers log_must $FILE_WRITE -o create -c $write_count \ 34372fae26bdSAlan Somers -f ${basename}.$i -b $blocksz -d $d 34382fae26bdSAlan Somers 34392fae26bdSAlan Somers [ -n "$snapbase" ] && log_must $ZFS snapshot ${snapbase}.${i} 34402fae26bdSAlan Somers done 34412fae26bdSAlan Somers} 34422fae26bdSAlan Somers 34432fae26bdSAlan Somers# Reap all children registered in $child_pids. 34442fae26bdSAlan Somersfunction reap_children 34452fae26bdSAlan Somers{ 34462fae26bdSAlan Somers [ -z "$child_pids" ] && return 34472fae26bdSAlan Somers for wait_pid in $child_pids; do 34482fae26bdSAlan Somers log_must $KILL $wait_pid 34492fae26bdSAlan Somers done 34502fae26bdSAlan Somers child_pids="" 34512fae26bdSAlan Somers} 34522fae26bdSAlan Somers 34532fae26bdSAlan Somers# Busy a path. Expects to be reaped via reap_children. Tries to run as 34542fae26bdSAlan Somers# long and slowly as possible. [num] is taken as a hint; if such a file 34552fae26bdSAlan Somers# already exists a different one will be chosen. 34562fae26bdSAlan Somersfunction busy_path # <path> [num] 34572fae26bdSAlan Somers{ 34582fae26bdSAlan Somers typeset busypath=$1 34592fae26bdSAlan Somers typeset -i num=$2 34602fae26bdSAlan Somers 34612fae26bdSAlan Somers while :; do 34622fae26bdSAlan Somers busyfile="$busypath/busyfile.${num}" 34632fae26bdSAlan Somers [ ! -f "$busyfile" ] && break 34642fae26bdSAlan Somers done 34652fae26bdSAlan Somers 34662fae26bdSAlan Somers cmd="$DD if=/dev/urandom of=$busyfile bs=512" 34672fae26bdSAlan Somers ( cd $busypath && $cmd ) & 34682fae26bdSAlan Somers typeset pid=$! 34692fae26bdSAlan Somers $SLEEP 1 34702fae26bdSAlan Somers log_must $PS -p $pid 34712fae26bdSAlan Somers child_pids="$child_pids $pid" 34722fae26bdSAlan Somers} 3473