16f793812SPavel Zakharov#!/usr/bin/ksh
26f793812SPavel Zakharov
36f793812SPavel Zakharov#
46f793812SPavel Zakharov# This file and its contents are supplied under the terms of the
56f793812SPavel Zakharov# Common Development and Distribution License ("CDDL"), version 1.0.
66f793812SPavel Zakharov# You may only use this file in accordance with the terms of version
76f793812SPavel Zakharov# 1.0 of the CDDL.
86f793812SPavel Zakharov#
96f793812SPavel Zakharov# A full copy of the text of the CDDL should have accompanied this
106f793812SPavel Zakharov# source.  A copy of the CDDL is also available via the Internet at
116f793812SPavel Zakharov# http://www.illumos.org/license/CDDL.
126f793812SPavel Zakharov#
136f793812SPavel Zakharov
146f793812SPavel Zakharov#
156f793812SPavel Zakharov# Copyright (c) 2016 by Delphix. All rights reserved.
166f793812SPavel Zakharov#
176f793812SPavel Zakharov
186f793812SPavel Zakharov. $STF_SUITE/include/libtest.shlib
196f793812SPavel Zakharov. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.cfg
206f793812SPavel Zakharov
216f793812SPavel Zakharov#
226f793812SPavel Zakharov# Prototype cleanup function for zpool_import tests.
236f793812SPavel Zakharov#
246f793812SPavel Zakharovfunction cleanup
256f793812SPavel Zakharov{
26c4de6c3cSPavel Zakharov	# clear any remaining zinjections
27c4de6c3cSPavel Zakharov	log_must zinject -c all > /dev/null
28c4de6c3cSPavel Zakharov
296f793812SPavel Zakharov	destroy_pool $TESTPOOL1
306f793812SPavel Zakharov
316f793812SPavel Zakharov	log_must rm -f $CPATH $CPATHBKP $CPATHBKP2 $MD5FILE $MD5FILE2
326f793812SPavel Zakharov
336f793812SPavel Zakharov	log_must rm -rf $DEVICE_DIR/*
346f793812SPavel Zakharov	typeset i=0
356f793812SPavel Zakharov	while (( i < $MAX_NUM )); do
366f793812SPavel Zakharov		log_must mkfile $FILE_SIZE ${DEVICE_DIR}/${DEVICE_FILE}$i
376f793812SPavel Zakharov		((i += 1))
386f793812SPavel Zakharov	done
396f793812SPavel Zakharov}
406f793812SPavel Zakharov
416f793812SPavel Zakharov#
426f793812SPavel Zakharov# Write a bit of data and sync several times.
436f793812SPavel Zakharov# This function is intended to be used by zpool rewind tests.
446f793812SPavel Zakharov#
456f793812SPavel Zakharovfunction sync_some_data_a_few_times
466f793812SPavel Zakharov{
476f793812SPavel Zakharov	typeset pool=$1
486f793812SPavel Zakharov	typeset -i a_few_times=${2:-10}
496f793812SPavel Zakharov
506f793812SPavel Zakharov	typeset file="/$pool/tmpfile"
516f793812SPavel Zakharov	for i in {0..$a_few_times}; do
526f793812SPavel Zakharov		dd if=/dev/urandom of=${file}_$i bs=128k count=10
536f793812SPavel Zakharov		sync
546f793812SPavel Zakharov	done
556f793812SPavel Zakharov
566f793812SPavel Zakharov	return 0
576f793812SPavel Zakharov}
586f793812SPavel Zakharov
596f793812SPavel Zakharov#
606f793812SPavel Zakharov# Just write a moderate amount of data to the pool.
616f793812SPavel Zakharov#
626f793812SPavel Zakharovfunction write_some_data
636f793812SPavel Zakharov{
646f793812SPavel Zakharov	typeset pool=$1
656f793812SPavel Zakharov	typeset files10mb=${2:-10}
666f793812SPavel Zakharov
676f793812SPavel Zakharov	typeset ds="$pool/fillerds"
686f793812SPavel Zakharov	zfs create $ds
696f793812SPavel Zakharov	[[ $? -ne 0 ]] && return 1
706f793812SPavel Zakharov
716f793812SPavel Zakharov	# Create 100 MB of data
726f793812SPavel Zakharov	typeset file="/$ds/fillerfile"
736f793812SPavel Zakharov	for i in {1..$files10mb}; do
746f793812SPavel Zakharov		dd if=/dev/urandom of=$file.$i bs=128k count=80
756f793812SPavel Zakharov		[[ $? -ne 0 ]] && return 1
766f793812SPavel Zakharov	done
776f793812SPavel Zakharov
786f793812SPavel Zakharov	return 0
796f793812SPavel Zakharov}
806f793812SPavel Zakharov
816f793812SPavel Zakharov#
826f793812SPavel Zakharov# Create/overwrite a few datasets with files.
836f793812SPavel Zakharov# Apply md5sum on all the files and store checksums in a file.
846f793812SPavel Zakharov#
856f793812SPavel Zakharov# newdata: overwrite existing files if false.
866f793812SPavel Zakharov# md5file: file where to store md5sums
876f793812SPavel Zakharov# datasetname: base name for datasets
886f793812SPavel Zakharov#
896f793812SPavel Zakharovfunction _generate_data_common
906f793812SPavel Zakharov{
916f793812SPavel Zakharov	typeset pool=$1
926f793812SPavel Zakharov	typeset newdata=$2
936f793812SPavel Zakharov	typeset md5file=$3
946f793812SPavel Zakharov	typeset datasetname=$4
956f793812SPavel Zakharov
966f793812SPavel Zakharov	typeset -i datasets=3
976f793812SPavel Zakharov	typeset -i files=5
986f793812SPavel Zakharov	typeset -i blocks=10
996f793812SPavel Zakharov
1006f793812SPavel Zakharov	[[ -n $md5file ]] && rm -f $md5file
1016f793812SPavel Zakharov	for i in {1..$datasets}; do
1026f793812SPavel Zakharov		( $newdata ) && log_must zfs create "$pool/$datasetname$i"
1036f793812SPavel Zakharov		for j in {1..$files}; do
1046f793812SPavel Zakharov			typeset file="/$pool/$datasetname$i/file$j"
1056f793812SPavel Zakharov			dd if=/dev/urandom of=$file bs=128k count=$blocks > /dev/null
1066f793812SPavel Zakharov			[[ -n $md5file ]] && md5sum $file >> $md5file
1076f793812SPavel Zakharov		done
1086f793812SPavel Zakharov		( $newdata ) && sync
1096f793812SPavel Zakharov	done
1106f793812SPavel Zakharov
1116f793812SPavel Zakharov	return 0
1126f793812SPavel Zakharov}
1136f793812SPavel Zakharov
1146f793812SPavel Zakharovfunction generate_data
1156f793812SPavel Zakharov{
1166f793812SPavel Zakharov	typeset pool=$1
1176f793812SPavel Zakharov	typeset md5file="$2"
1186f793812SPavel Zakharov	typeset datasetname=${3:-ds}
1196f793812SPavel Zakharov
1206f793812SPavel Zakharov	_generate_data_common $pool true "$md5file" $datasetname
1216f793812SPavel Zakharov}
1226f793812SPavel Zakharov
1236f793812SPavel Zakharovfunction overwrite_data
1246f793812SPavel Zakharov{
1256f793812SPavel Zakharov	typeset pool=$1
1266f793812SPavel Zakharov	typeset md5file="$2"
1276f793812SPavel Zakharov	typeset datasetname=${3:-ds}
1286f793812SPavel Zakharov
1296f793812SPavel Zakharov	_generate_data_common $1 false "$md5file" $datasetname
1306f793812SPavel Zakharov}
1316f793812SPavel Zakharov
1326f793812SPavel Zakharov#
1336f793812SPavel Zakharov# Verify md5sums of every file in md5sum file $1.
1346f793812SPavel Zakharov#
1356f793812SPavel Zakharovfunction verify_data_md5sums
1366f793812SPavel Zakharov{
1376f793812SPavel Zakharov	typeset md5file=$1
1386f793812SPavel Zakharov
1396f793812SPavel Zakharov	if [[ ! -f $md5file ]]; then
1406f793812SPavel Zakharov		log_note "md5 sums file '$md5file' doesn't exist"
1416f793812SPavel Zakharov		return 1
1426f793812SPavel Zakharov	fi
1436f793812SPavel Zakharov
1446f793812SPavel Zakharov	md5sum -c --quiet $md5file
1456f793812SPavel Zakharov	return $?
1466f793812SPavel Zakharov}
1476f793812SPavel Zakharov
1486f793812SPavel Zakharov#
1496f793812SPavel Zakharov# Set devices size in DEVICE_DIR to $1.
1506f793812SPavel Zakharov#
1516f793812SPavel Zakharovfunction increase_device_sizes
1526f793812SPavel Zakharov{
1536f793812SPavel Zakharov	typeset newfilesize=$1
1546f793812SPavel Zakharov
1556f793812SPavel Zakharov	typeset -i i=0
1566f793812SPavel Zakharov	while (( i < $MAX_NUM )); do
1576f793812SPavel Zakharov		log_must mkfile $newfilesize ${DEVICE_DIR}/${DEVICE_FILE}$i
1586f793812SPavel Zakharov		((i += 1))
1596f793812SPavel Zakharov	done
1606f793812SPavel Zakharov}
1616f793812SPavel Zakharov
1626f793812SPavel Zakharov#
1636f793812SPavel Zakharov# Translate vdev names returned by zpool status into more generic names.
1646f793812SPavel Zakharov#
1656f793812SPavel Zakharov# eg: mirror-2 --> mirror
1666f793812SPavel Zakharov#
1676f793812SPavel Zakharovfunction _translate_vdev
1686f793812SPavel Zakharov{
1696f793812SPavel Zakharov	typeset vdev=$1
1706f793812SPavel Zakharov
1716f793812SPavel Zakharov	typeset keywords="mirror replacing raidz1 raidz2 raidz3 indirect"
1726f793812SPavel Zakharov	for word in $keywords; do
1736f793812SPavel Zakharov		echo $vdev | egrep "^${word}-[0-9]+\$" > /dev/null
1746f793812SPavel Zakharov		if [[ $? -eq 0 ]]; then
1756f793812SPavel Zakharov			vdev=$word
1766f793812SPavel Zakharov			break
1776f793812SPavel Zakharov		fi
1786f793812SPavel Zakharov	done
1796f793812SPavel Zakharov
1806f793812SPavel Zakharov	[[ $vdev == "logs" ]] && echo "log" && return 0
1816f793812SPavel Zakharov	[[ $vdev == "raidz1" ]] && echo "raidz" && return 0
1826f793812SPavel Zakharov
1836f793812SPavel Zakharov	echo $vdev
1846f793812SPavel Zakharov	return 0
1856f793812SPavel Zakharov}
1866f793812SPavel Zakharov
1876f793812SPavel Zakharov#
1886f793812SPavel Zakharov# Check that pool configuration returned by zpool status matches expected
1896f793812SPavel Zakharov# configuration. Format for the check string is same as the vdev arguments for
1906f793812SPavel Zakharov# creating a pool
1916f793812SPavel Zakharov# Add -q for quiet mode.
1926f793812SPavel Zakharov#
1936f793812SPavel Zakharov# eg: check_pool_config pool1 "mirror c0t0d0s0 c0t1d0s0 log c1t1d0s0"
1946f793812SPavel Zakharov#
1956f793812SPavel Zakharovfunction check_pool_config
1966f793812SPavel Zakharov{
1976f793812SPavel Zakharov	typeset logfailure=true
1986f793812SPavel Zakharov	if [[ $1 == '-q' ]]; then
1996f793812SPavel Zakharov		logfailure=false
2006f793812SPavel Zakharov		shift
2016f793812SPavel Zakharov	fi
2026f793812SPavel Zakharov
2036f793812SPavel Zakharov	typeset poolname=$1
2046f793812SPavel Zakharov	typeset expected=$2
2056f793812SPavel Zakharov
2066f793812SPavel Zakharov	typeset status
2076f793812SPavel Zakharov	status=$(zpool status $poolname 2>&1)
2086f793812SPavel Zakharov	if [[ $? -ne 0 ]]; then
2096f793812SPavel Zakharov		if ( $logfailure ); then
2106f793812SPavel Zakharov			log_note "zpool status $poolname failed: $status"
2116f793812SPavel Zakharov		fi
2126f793812SPavel Zakharov		return 1
2136f793812SPavel Zakharov	fi
2146f793812SPavel Zakharov
2156f793812SPavel Zakharov	typeset actual=""
2166f793812SPavel Zakharov	typeset began=false
2176f793812SPavel Zakharov	printf "$status\n" | while read line; do
2186f793812SPavel Zakharov		typeset vdev=$(echo "$line" | awk '{printf $1}')
2196f793812SPavel Zakharov		if ( ! $began ) && [[ $vdev == NAME ]]; then
2206f793812SPavel Zakharov			began=true
2216f793812SPavel Zakharov			continue
2226f793812SPavel Zakharov		fi
2236f793812SPavel Zakharov		( $began ) && [[ -z $vdev ]] && break;
2246f793812SPavel Zakharov
2256f793812SPavel Zakharov		if ( $began ); then
2266f793812SPavel Zakharov			[[ -z $actual ]] && actual="$vdev" && continue
2276f793812SPavel Zakharov			vdev=$(_translate_vdev $vdev)
2286f793812SPavel Zakharov			actual="$actual $vdev"
2296f793812SPavel Zakharov		fi
2306f793812SPavel Zakharov	done
2316f793812SPavel Zakharov
2326f793812SPavel Zakharov	expected="$poolname $expected"
2336f793812SPavel Zakharov
2346f793812SPavel Zakharov	if [[ "$actual" != "$expected" ]]; then
2356f793812SPavel Zakharov		if ( $logfailure ); then
2366f793812SPavel Zakharov			log_note "expected pool vdevs:"
2376f793812SPavel Zakharov			log_note "> '$expected'"
2386f793812SPavel Zakharov			log_note "actual pool vdevs:"
2396f793812SPavel Zakharov			log_note "> '$actual'"
2406f793812SPavel Zakharov		fi
2416f793812SPavel Zakharov		return 1
2426f793812SPavel Zakharov	fi
2436f793812SPavel Zakharov
2446f793812SPavel Zakharov	return 0
2456f793812SPavel Zakharov}
2466f793812SPavel Zakharov
2476f793812SPavel Zakharov#
2486f793812SPavel Zakharov# Check that pool configuration returned by zpool status matches expected
2496f793812SPavel Zakharov# configuration within a given timeout in seconds. See check_pool_config().
2506f793812SPavel Zakharov#
2516f793812SPavel Zakharov# eg: wait_for_pool_config pool1 "mirror c0t0d0s0 c0t1d0s0" 60
2526f793812SPavel Zakharov#
2536f793812SPavel Zakharovfunction wait_for_pool_config
2546f793812SPavel Zakharov{
2556f793812SPavel Zakharov	typeset poolname=$1
2566f793812SPavel Zakharov	typeset expectedconfig="$2"
2576f793812SPavel Zakharov	typeset -i timeout=${3:-60}
2586f793812SPavel Zakharov
2596f793812SPavel Zakharov	timeout=$(( $timeout + $(date +%s) ))
2606f793812SPavel Zakharov
2616f793812SPavel Zakharov	while  (( $(date +%s) < $timeout )); do
2626f793812SPavel Zakharov		check_pool_config -q $poolname "$expectedconfig"
2636f793812SPavel Zakharov		[[ $? -eq 0 ]] && return 0
2646f793812SPavel Zakharov		sleep 3
2656f793812SPavel Zakharov	done
2666f793812SPavel Zakharov
2676f793812SPavel Zakharov	check_pool_config $poolname "$expectedconfig"
2686f793812SPavel Zakharov	return $?
2696f793812SPavel Zakharov}
2706f793812SPavel Zakharov
2716f793812SPavel Zakharov#
2726f793812SPavel Zakharov# Check that pool status is ONLINE
2736f793812SPavel Zakharov#
2746f793812SPavel Zakharovfunction check_pool_healthy
2756f793812SPavel Zakharov{
2766f793812SPavel Zakharov	typeset pool=$1
2776f793812SPavel Zakharov
2786f793812SPavel Zakharov	typeset status
2796f793812SPavel Zakharov	status=$(zpool status $pool 2>&1)
2806f793812SPavel Zakharov	if [[ $? -ne 0 ]]; then
2816f793812SPavel Zakharov		log_note "zpool status $pool failed: $status"
2826f793812SPavel Zakharov		return 1
2836f793812SPavel Zakharov	fi
2846f793812SPavel Zakharov
2856f793812SPavel Zakharov	status=$(echo "$status" | grep "$pool" | grep -v "pool:" | \
2866f793812SPavel Zakharov	    awk '{print $2}')
2876f793812SPavel Zakharov
2886f793812SPavel Zakharov	if [[ $status != "ONLINE" ]]; then
2896f793812SPavel Zakharov		log_note "Invalid zpool status for '$pool': '$status'" \
2906f793812SPavel Zakharov		    "!= 'ONLINE'"
2916f793812SPavel Zakharov		return 1
2926f793812SPavel Zakharov	fi
2936f793812SPavel Zakharov
2946f793812SPavel Zakharov	return 0
2956f793812SPavel Zakharov}
2966f793812SPavel Zakharov
2976f793812SPavel Zakharov#
2986f793812SPavel Zakharov# Return 0 if a device is currently being replaced in the pool.
2996f793812SPavel Zakharov#
3006f793812SPavel Zakharovfunction pool_is_replacing
3016f793812SPavel Zakharov{
3026f793812SPavel Zakharov	typeset pool=$1
3036f793812SPavel Zakharov
3046f793812SPavel Zakharov	zpool status $pool | grep "replacing" | grep "ONLINE" > /dev/null
3056f793812SPavel Zakharov
3066f793812SPavel Zakharov	return $?
3076f793812SPavel Zakharov}
3086f793812SPavel Zakharov
3096f793812SPavel Zakharovfunction set_vdev_validate_skip
3106f793812SPavel Zakharov{
3116f793812SPavel Zakharov	mdb_set_uint32 "vdev_validate_skip" "$1"
3126f793812SPavel Zakharov}
3136f793812SPavel Zakharov
3146f793812SPavel Zakharovfunction get_zfs_txg_timeout
3156f793812SPavel Zakharov{
3166f793812SPavel Zakharov	echo $(mdb_get_uint32 "zfs_txg_timeout")
3176f793812SPavel Zakharov}
3186f793812SPavel Zakharov
3196f793812SPavel Zakharovfunction set_zfs_txg_timeout
3206f793812SPavel Zakharov{
3216f793812SPavel Zakharov	mdb_set_uint32 "zfs_txg_timeout" "$1"
3226f793812SPavel Zakharov}
3236f793812SPavel Zakharov
3246f793812SPavel Zakharovfunction set_spa_load_verify_metadata
3256f793812SPavel Zakharov{
3266f793812SPavel Zakharov	mdb_set_uint32 "spa_load_verify_metadata" "$1"
3276f793812SPavel Zakharov}
3286f793812SPavel Zakharov
3296f793812SPavel Zakharovfunction set_spa_load_verify_data
3306f793812SPavel Zakharov{
3316f793812SPavel Zakharov	mdb_set_uint32 "spa_load_verify_data" "$1"
3326f793812SPavel Zakharov}
3336f793812SPavel Zakharov
3346f793812SPavel Zakharovfunction set_zfs_max_missing_tvds
3356f793812SPavel Zakharov{
3366f793812SPavel Zakharov	mdb_set_uint32 "zfs_max_missing_tvds" "$1"
3376f793812SPavel Zakharov}
3386f793812SPavel Zakharov
3396f793812SPavel Zakharov#
3406f793812SPavel Zakharov# Use mdb to find the last txg that was synced in an active pool.
3416f793812SPavel Zakharov#
3426f793812SPavel Zakharovfunction get_last_txg_synced
3436f793812SPavel Zakharov{
3446f793812SPavel Zakharov	typeset pool=$1
3456f793812SPavel Zakharov
346*dd50e0ccSTony Hutter	if is_linux; then
347*dd50e0ccSTony Hutter		txg=$(tail "/proc/spl/kstat/zfs/$pool/txgs" |
348*dd50e0ccSTony Hutter		    awk '$3=="C" {print $1}' | tail -1)
349*dd50e0ccSTony Hutter		[[ "$txg" ]] || txg=0
350*dd50e0ccSTony Hutter		echo $txg
351*dd50e0ccSTony Hutter		return 0
352*dd50e0ccSTony Hutter	fi
353*dd50e0ccSTony Hutter
3546f793812SPavel Zakharov	typeset spas
3556f793812SPavel Zakharov	spas=$(mdb -k -e "::spa")
3566f793812SPavel Zakharov	[[ $? -ne 0 ]] && return 1
3576f793812SPavel Zakharov
3586f793812SPavel Zakharov	typeset spa=""
3596f793812SPavel Zakharov	print "$spas\n" | while read line; do
3606f793812SPavel Zakharov		typeset poolname=$(echo "$line" | awk '{print $3}')
3616f793812SPavel Zakharov		typeset addr=$(echo "$line" | awk '{print $1}')
3626f793812SPavel Zakharov		if [[ $poolname == $pool ]]; then
3636f793812SPavel Zakharov			spa=$addr
3646f793812SPavel Zakharov			break
3656f793812SPavel Zakharov		fi
3666f793812SPavel Zakharov	done
3676f793812SPavel Zakharov	if [[ -z $spa ]]; then
3686f793812SPavel Zakharov		log_fail "Couldn't find pool '$pool'"
3696f793812SPavel Zakharov		return 1
3706f793812SPavel Zakharov	fi
3716f793812SPavel Zakharov	typeset mdbcmd="$spa::print spa_t spa_ubsync.ub_txg | ::eval '.=E'"
3726f793812SPavel Zakharov	typeset -i txg
3736f793812SPavel Zakharov	txg=$(mdb -k -e "$mdbcmd")
3746f793812SPavel Zakharov	[[ $? -ne 0 ]] && return 1
3756f793812SPavel Zakharov
3766f793812SPavel Zakharov	echo $txg
3776f793812SPavel Zakharov	return 0
3786f793812SPavel Zakharov}
379