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