zfs/tests/zfs-tests/tests/functional/mmp/mmp.kshlib

241 lines
5.1 KiB
Plaintext

#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2017 by Lawrence Livermore National Security, LLC.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/mmp/mmp.cfg
function check_pool_import # pool opts token keyword
{
typeset pool=${1:-$MMP_POOL}
typeset opts=$2
typeset token=$3
typeset keyword=$4
zpool import $opts 2>&1 | \
nawk -v token="$token:" '($1==token) {print $0}' | \
grep -i "$keyword" > /dev/null 2>&1
return $?
}
function is_pool_imported # pool opts
{
typeset pool=${1:-$MMP_POOL}
typeset opts=$2
check_pool_import "$pool" "$opts" "status" \
"The pool is currently imported"
return $?
}
function wait_pool_imported # pool opts
{
typeset pool=${1:-$MMP_POOL}
typeset opts=$2
while is_pool_imported "$pool" "$opts"; do
log_must sleep 5
done
return 0
}
function try_pool_import # pool opts message
{
typeset pool=${1:-$MMP_POOL}
typeset opts=$2
typeset msg=$3
zpool import $opts $pool 2>&1 | grep -i "$msg"
return $?
}
function mmp_set_hostid
{
typeset hostid=$1
zgenhostid $1
if [ $(hostid) != "$hostid" ]; then
return 1
fi
return 0
}
function mmp_clear_hostid
{
rm -f $HOSTID_FILE
}
function mmp_pool_create_simple # pool dir
{
typeset pool=${1:-$MMP_POOL}
typeset dir=${2:-$MMP_DIR}
log_must mkdir -p $dir
log_must rm -f $dir/*
log_must truncate -s $MINVDEVSIZE $dir/vdev1 $dir/vdev2
log_must mmp_clear_hostid
log_must mmp_set_hostid $HOSTID1
log_must zpool create -f -o cachefile=$MMP_CACHE $pool \
mirror $dir/vdev1 $dir/vdev2
log_must zpool set multihost=on $pool
}
function mmp_pool_create # pool dir
{
typeset pool=${1:-$MMP_POOL}
typeset dir=${2:-$MMP_DIR}
typeset opts="-VVVVV -T120 -M -k0 -f $dir -E -p $pool"
mmp_pool_create_simple $pool $dir
log_must mv $MMP_CACHE ${MMP_CACHE}.stale
log_must zpool export $pool
log_must mmp_clear_hostid
log_must mmp_set_hostid $HOSTID2
log_note "Starting ztest in the background as hostid $HOSTID1"
log_must eval "ZFS_HOSTID=$HOSTID1 ztest $opts >$MMP_ZTEST_LOG 2>&1 &"
while ! is_pool_imported "$pool" "-d $dir"; do
log_must pgrep ztest
log_must sleep 5
done
}
function mmp_pool_destroy # pool dir
{
typeset pool=${1:-$MMP_POOL}
typeset dir=${2:-$MMP_DIR}
ZTESTPID=$(pgrep ztest)
if [ -n "$ZTESTPID" ]; then
log_must kill $ZTESTPID
wait $ZTESTPID
fi
if poolexists $pool; then
destroy_pool $pool
fi
log_must rm -f $dir/*
mmp_clear_hostid
}
function mmp_pool_set_hostid # pool hostid
{
typeset pool=$1
typeset hostid=$2
log_must mmp_clear_hostid
log_must mmp_set_hostid $hostid
log_must zpool export $pool
log_must zpool import $pool
return 0
}
# Return the number of seconds the activity check portion of the import process
# will take. Does not include the time to find devices and assemble the
# preliminary pool configuration passed into the kernel.
function seconds_mmp_waits_for_activity
{
typeset import_intervals=$(get_tunable zfs_multihost_import_intervals)
typeset interval=$(get_tunable zfs_multihost_interval)
typeset seconds=$((interval*import_intervals/1000))
echo $seconds
}
function import_no_activity_check # pool opts
{
typeset pool=$1
typeset opts=$2
typeset max_duration=$(seconds_mmp_waits_for_activity)
SECONDS=0
zpool import $opts $pool
typeset rc=$?
if [[ $SECONDS -gt $max_duration ]]; then
log_fail "unexpected activity check (${SECONDS}s gt \
$max_duration)"
fi
return $rc
}
function import_activity_check # pool opts
{
typeset pool=$1
typeset opts=$2
typeset min_duration=$(seconds_mmp_waits_for_activity)
SECONDS=0
zpool import $opts $pool
typeset rc=$?
if [[ $SECONDS -le $min_duration ]]; then
log_fail "expected activity check (${SECONDS}s le \
$min_duration)"
fi
return $rc
}
function clear_mmp_history
{
log_must set_tunable64 zfs_multihost_history $MMP_HISTORY_OFF
log_must set_tunable64 zfs_multihost_history $MMP_HISTORY
}
function count_skipped_mmp_writes # pool duration
{
typeset pool=$1
typeset -i duration=$2
typeset hist_path="/proc/spl/kstat/zfs/$pool/multihost"
sleep $duration
awk 'BEGIN {count=0}; $NF == "-" {count++}; END {print count};' "$hist_path"
}
function count_mmp_writes # pool duration
{
typeset pool=$1
typeset -i duration=$2
typeset hist_path="/proc/spl/kstat/zfs/$pool/multihost"
sleep $duration
awk 'BEGIN {count=0}; $NF != "-" {count++}; END {print count};' "$hist_path"
}