[Xen-devel] PCI passthrough test script

Simon Horman
Mon, 01 Jun 2009 01:39:24 -0000

Hi,

I am kind of hoping that others have something a bit better that
they are sitting on, but the following rough and ready script
has helped me to test for PCI pass-through problems and
reduce regrssions in my recent patches.

#!/bin/sh

set -e

RETRY=5
TIMEOUT=15

try_quiet ()
{
	"$@"
	status=$?

	if [ $status != 0 ]; then
		echo "failed:   non-zero status" >&2
		echo "status:   $status" >&2
		exit 1
	fi

	return 0
}

try ()
{
	echo "# $@"
	try_quiet "$@"
}

log_value ()
{
	key="$1"; shift
	val="$1"; shift

	if [ $(echo -n "$val" | wc -l ) -gt 1 ]; then
		echo "--- begin $key ---"
		echo "$val"
		echo "--- end $key ---"
	else
		echo "$key: \"$val\""
	fi
}

expect ()
{
	expect="$1"; shift

	echo "# $@"
	result=$(try_quiet "$@")

	if [ "$expect" != "$result" ]; then
		echo "failed: output missmatch" >&2
		log_value "expected" "$expect" >&2
		log_value "received" "$result" >&2
		exit 1
	fi

	#if [ "$result" != "" ]; then
	#    echo "$result"
	#fi
	return 0
}

#sudo xm list | fgrep Domain-0 | cut -c 64-69

domain_exists ()
{
	domain="$1"

	text=$(sudo xm list | fgrep "$domain" || true)
	if [ -z "$text" ]; then
		return 1
	fi

	return 0
}

domain_booted ()
{
	domain="$1"

	text=$(sudo xm list | fgrep "$domain" || true)
	if [ -z "$text" ]; then
		return 1
	fi
	state=$(echo "$text" | cut -c 64-69)
	if [ "$state" != "-b----" ]; then
		return 1
	fi

	return 0
}

xm_destroy ()
{
	domain="$1"

	if ! domain_exists "$domain"; then
		return 0
	fi

	try sudo xm destroy "$domain"
}

xm_delete ()
{
	domain="$1"

	if ! domain_exists "$domain"; then
		return 0
	fi

	try sudo xm delete "$domain"
}

xm_delete ()
{
	domain="$1"

	if ! domain_exists "$domain"; then
		return 0
	fi

	try sudo xm delete "$domain"
}

xm_create ()
{
	domain="$1"; shift
	conf="$1"; shift
	timeout="$1"; shift

	echo -n "# sudo xm create $conf"
	try_quiet sudo xm create "$conf" > /dev/null

	while [ $timeout -gt 0 ]; do
		if domain_booted "$domain"; then
			echo
			return 0
		fi
		timeout=$(( $timeout - 1 ))
		echo -n "."
		sleep 1
	done

	echo "timeout" >&2
	return 1

}

xm_start ()
{
	domain="$1"; shift
	timeout="$1"; shift

	echo -n "# sudo xm start $domain"
	try_quiet sudo xm start "$domain"

	while [ $timeout -gt 0 ]; do
		if domain_booted "$domain"; then
			echo
			return 0
		fi
		timeout=$(( $timeout - 1 ))
		echo -n "."
		sleep 1
	done

	echo "timeout" >&2
	return 1

}

xm_new ()
{
	conf="$1"; shift

	echo "# sudo xm new $conf"
	try_quiet sudo xm new "$conf" > /dev/null
}

CONF="/home/horms/projects/xen/xen-config/x86_64/hvm/conf/debian-unstable-hvm-1.conf"
TEST=0

#############################################################################

TEST=$(($TEST + 1));
ATTEMPT=0
STATUS="fail"
for i in $(seq $RETRY); do
	ATTEMPT=$(($ATTEMPT + 1));
	echo "Test $TEST, Attempt $ATTEMPT"

	xm_destroy debian
	xm_delete debian

	xm_create "debian" "$CONF" "$TIMEOUT" || continue
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x05 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0 b
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x0b 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm destroy debian

	STATUS="ok"
	break
done

if [ "$STATUS" != "ok" ]; then
	exit 1
fi

#############################################################################

TEST=$(($TEST + 1))
ATTEMPT=0
STATUS="fail"
for i in $(seq $RETRY); do
        ATTEMPT=$(($ATTEMPT + 1));
        echo "Test $TEST, Attempt $ATTEMPT"

	xm_destroy debian
	xm_delete debian

	xm_new "$CONF"
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
-    0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0 b
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x0b 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	xm_delete debian

	STATUS="ok"
	break
done

if [ "$STATUS" != "ok" ]; then
        exit 1
fi

############################################################################

TEST=$(($TEST + 1))
ATTEMPT=0
STATUS="fail"
for i in $(seq $RETRY); do
        ATTEMPT=$(($ATTEMPT + 1));
        echo "Test $TEST, Attempt $ATTEMPT"

	xm_destroy debian
	xm_delete debian

	xm_new "$CONF"
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
-    0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	xm_start debian "$TIMEOUT" || continue
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x05 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0 b
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x0b 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	xm_destroy debian
	xm_delete debian

	STATUS="ok"
	break
done

if [ "$STATUS" != "ok" ]; then
        exit 1
fi

#############################################################################

TEST=$(($TEST + 1))
ATTEMPT=0
STATUS="fail"
for i in $(seq $RETRY); do
	ATTEMPT=$(($ATTEMPT + 1));
	echo "Test $TEST, Attempt $ATTEMPT"

	xm_destroy debian
	xm_delete debian

	xm_new "$CONF"
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
-    0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	xm_start debian "$TIMEOUT" || continue
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0 b
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x0b 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	xm_destroy debian
	xm_delete debian

	STATUS="ok"
	break
done

if [ "$STATUS" != "ok" ]; then
        exit 1
fi

#############################################################################

TEST=$(($TEST + 1))
ATTEMPT=0
STATUS="fail"
for i in $(seq $RETRY); do
        ATTEMPT=$(($ATTEMPT + 1));
	echo "Test $TEST, Attempt $ATTEMPT"

	xm_destroy debian
	xm_delete debian

	xm_new "$CONF"
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
-    0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0 b
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x0b 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	xm_start debian "$TIMEOUT" || continue
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x0b 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	xm_destroy debian
	xm_delete debian

        STATUS="ok"
        break
done

if [ "$STATUS" != "ok" ]; then
        exit 1
fi

#############################################################################

TEST=$(($TEST + 1))
ATTEMPT=0
STATUS="fail"
for i in $(seq $RETRY); do
        ATTEMPT=$(($ATTEMPT + 1));
	echo "Test $TEST, Attempt $ATTEMPT"

	xm_destroy debian
	xm_delete debian

	xm_new "$CONF"
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
-    0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0 b
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x0b 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	xm_start debian "$TIMEOUT" || continue
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	xm_destroy debian
	xm_delete debian

        STATUS="ok"
        break
done

if [ "$STATUS" != "ok" ]; then
        exit 1
fi

#############################################################################

TEST=$(($TEST + 1))
ATTEMPT=0
STATUS="fail"
for i in $(seq $RETRY); do
        ATTEMPT=$(($ATTEMPT + 1));
	echo "Test $TEST, Attempt $ATTEMPT"

	xm_destroy debian
	xm_delete debian

	xm_new "$CONF"
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
-    0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	xm_start debian "$TIMEOUT" || continue
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x05 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	xm_destroy debian
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x05 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
-    0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	xm_start debian "$TIMEOUT" || continue
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x05 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	xm_destroy debian
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x05 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	xm_destroy debian
	xm_delete debian

        STATUS="ok"
        break
done

if [ "$STATUS" != "ok" ]; then
        exit 1
fi

#############################################################################

TEST=$(($TEST + 1))
ATTEMPT=0
STATUS="fail"
for i in $(seq $RETRY); do
        ATTEMPT=$(($ATTEMPT + 1));
	echo "Test $TEST, Attempt $ATTEMPT"

	xm_destroy debian
	xm_delete debian

	xm_new "$CONF"
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0
	expect "VSlt domain bus  slot func
-    0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
-    0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	xm_start debian "$TIMEOUT" || continue
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x05 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	xm_destroy debian
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	expect "" sudo xm pci-attach debian 00:1d.0 b
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x0b 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	xm_start debian "$TIMEOUT" || continue
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1
0x0b 0x0000 0x00 0x1d 0x0" sudo xm pci-list debian

	expect "" sudo xm pci-detach debian 00:1d.0
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	xm_destroy debian
	expect "VSlt domain bus  slot func
0x04 0x0000 0x01 0x00 0x0
0x07 0x0000 0x01 0x00 0x1" sudo xm pci-list debian

	xm_destroy debian
	xm_delete debian

        STATUS="ok"
        break
done

if [ "$STATUS" != "ok" ]; then
        exit 1
fi

#############################################################################

echo OK\!

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com