xref: /kvm-unit-tests/scripts/arch-run.bash (revision 15a12650ada87e59848c7bf4daeb36fc04ba312d)
1b2a2aa5dSAndrew Jones##############################################################################
2b2a2aa5dSAndrew Jones# run_qemu translates the ambiguous exit status in Table1 to that in Table2.
3b2a2aa5dSAndrew Jones# Table3 simply documents the complete status table.
4b2a2aa5dSAndrew Jones#
5b2a2aa5dSAndrew Jones# Table1: Before fixup
6b2a2aa5dSAndrew Jones# --------------------
7b2a2aa5dSAndrew Jones# 0      - Unexpected exit from QEMU (possible signal), or the unittest did
8b2a2aa5dSAndrew Jones#          not use debug-exit
9b2a2aa5dSAndrew Jones# 1      - most likely unittest succeeded, or QEMU failed
10b2a2aa5dSAndrew Jones#
11b2a2aa5dSAndrew Jones# Table2: After fixup
12b2a2aa5dSAndrew Jones# -------------------
13b2a2aa5dSAndrew Jones# 0      - Everything succeeded
14b2a2aa5dSAndrew Jones# 1      - most likely QEMU failed
15b2a2aa5dSAndrew Jones#
16b2a2aa5dSAndrew Jones# Table3: Complete table
17b2a2aa5dSAndrew Jones# ----------------------
18b2a2aa5dSAndrew Jones# 0      - SUCCESS
19b2a2aa5dSAndrew Jones# 1      - most likely QEMU failed
20b2a2aa5dSAndrew Jones# 2      - most likely a run script failed
21b2a2aa5dSAndrew Jones# 3      - most likely the unittest failed
22fd149358SAndrew Jones# 124    - most likely the unittest timed out
23b2a2aa5dSAndrew Jones# 127    - most likely the unittest called abort()
24b2a2aa5dSAndrew Jones# 1..127 - FAILURE (could be QEMU, a run script, or the unittest)
25b2a2aa5dSAndrew Jones# >= 128 - Signal (signum = status - 128)
26b2a2aa5dSAndrew Jones##############################################################################
27b2a2aa5dSAndrew Jonesrun_qemu ()
28b2a2aa5dSAndrew Jones{
298c3f0d96SAndrew Jones	local stdout errors ret sig
30b2a2aa5dSAndrew Jones
31b16df9eeSAndrew Jones	initrd_create || return $?
32d76bf076SAndrew Jones	echo -n "$@"
33b16df9eeSAndrew Jones	[ "$ENVIRON_DEFAULT" = "yes" ] && echo -n " #"
348b13a5b5SRadim Krčmář	echo " $INITRD"
358b13a5b5SRadim Krčmář
36f0ca153cSRadim Krčmář	# stdout to {stdout}, stderr to $errors and stderr
37b2a2aa5dSAndrew Jones	exec {stdout}>&1
388b13a5b5SRadim Krčmář	errors=$("${@}" $INITRD </dev/null 2> >(tee /dev/stderr) > /dev/fd/$stdout)
39b2a2aa5dSAndrew Jones	ret=$?
40b2a2aa5dSAndrew Jones	exec {stdout}>&-
418727c886SAndrew Jones
428727c886SAndrew Jones	[ $ret -eq 134 ] && echo "QEMU Aborted" >&2
43b2a2aa5dSAndrew Jones
44b2a2aa5dSAndrew Jones	if [ "$errors" ]; then
45b2a2aa5dSAndrew Jones		sig=$(grep 'terminating on signal' <<<"$errors")
46b2a2aa5dSAndrew Jones		if [ "$sig" ]; then
47b2a2aa5dSAndrew Jones			sig=$(sed 's/.*terminating on signal \([0-9][0-9]*\).*/\1/' <<<"$sig")
48b2a2aa5dSAndrew Jones		fi
49b2a2aa5dSAndrew Jones	fi
50b2a2aa5dSAndrew Jones
51b2a2aa5dSAndrew Jones	if [ $ret -eq 0 ]; then
52b2a2aa5dSAndrew Jones		# Some signals result in a zero return status, but the
53b2a2aa5dSAndrew Jones		# error log tells the truth.
54b2a2aa5dSAndrew Jones		if [ "$sig" ]; then
55b2a2aa5dSAndrew Jones			((ret=sig+128))
56b2a2aa5dSAndrew Jones		else
57b2a2aa5dSAndrew Jones			# Exiting with zero (non-debugexit) is an error
58b2a2aa5dSAndrew Jones			ret=1
59b2a2aa5dSAndrew Jones		fi
60b2a2aa5dSAndrew Jones	elif [ $ret -eq 1 ]; then
61b2a2aa5dSAndrew Jones		# Even when ret==1 (unittest success) if we also got stderr
62b2a2aa5dSAndrew Jones		# logs, then we assume a QEMU failure. Otherwise we translate
63b2a2aa5dSAndrew Jones		# status of 1 to 0 (SUCCESS)
64a51bab13SRadim Krčmář		if [ -z "$(echo "$errors" | grep -vi warning)" ]; then
65b2a2aa5dSAndrew Jones			ret=0
66b2a2aa5dSAndrew Jones		fi
67b2a2aa5dSAndrew Jones	fi
68b2a2aa5dSAndrew Jones
69b2a2aa5dSAndrew Jones	return $ret
70b2a2aa5dSAndrew Jones}
71fd149358SAndrew Jones
72e0a8391eSRadim Krčmářrun_qemu_status ()
73e0a8391eSRadim Krčmář{
74e0a8391eSRadim Krčmář	local stdout ret
75e0a8391eSRadim Krčmář
76e0a8391eSRadim Krčmář	exec {stdout}>&1
77e0a8391eSRadim Krčmář	lines=$(run_qemu "$@" > >(tee /dev/fd/$stdout))
78e0a8391eSRadim Krčmář	ret=$?
79e0a8391eSRadim Krčmář	exec {stdout}>&-
80e0a8391eSRadim Krčmář
81e0a8391eSRadim Krčmář	if [ $ret -eq 1 ]; then
82e0a8391eSRadim Krčmář		testret=$(grep '^EXIT: ' <<<"$lines" | sed 's/.*STATUS=\([0-9][0-9]*\).*/\1/')
83e0a8391eSRadim Krčmář		if [ "$testret" ]; then
84e0a8391eSRadim Krčmář			if [ $testret -eq 1 ]; then
85e0a8391eSRadim Krčmář				ret=0
86e0a8391eSRadim Krčmář			else
87e0a8391eSRadim Krčmář				ret=$testret
88e0a8391eSRadim Krčmář			fi
89e0a8391eSRadim Krčmář		fi
90e0a8391eSRadim Krčmář	fi
91e0a8391eSRadim Krčmář
92e0a8391eSRadim Krčmář	return $ret
93e0a8391eSRadim Krčmář}
94e0a8391eSRadim Krčmář
95fd149358SAndrew Jonestimeout_cmd ()
96fd149358SAndrew Jones{
97*15a12650SAndrew Jones	local s
98*15a12650SAndrew Jones
99fd149358SAndrew Jones	if [ "$TIMEOUT" ] && [ "$TIMEOUT" != "0" ]; then
100*15a12650SAndrew Jones		if [ "$CONFIG_EFI" = 'y' ]; then
101*15a12650SAndrew Jones			s=${TIMEOUT: -1}
102*15a12650SAndrew Jones			if [ "$s" = 's' ]; then
103*15a12650SAndrew Jones				TIMEOUT=${TIMEOUT:0:-1}
104*15a12650SAndrew Jones				((TIMEOUT += 10)) # Add 10 seconds for booting UEFI
105*15a12650SAndrew Jones				TIMEOUT="${TIMEOUT}s"
106*15a12650SAndrew Jones			fi
107*15a12650SAndrew Jones		fi
108fd149358SAndrew Jones		echo "timeout -k 1s --foreground $TIMEOUT"
109fd149358SAndrew Jones	fi
110fd149358SAndrew Jones}
11137abdda9SThomas Huth
11237abdda9SThomas Huthqmp ()
11337abdda9SThomas Huth{
114b508e114SJamie Iles	echo '{ "execute": "qmp_capabilities" }{ "execute":' "$2" '}' | ncat -U $1
11537abdda9SThomas Huth}
11637abdda9SThomas Huth
1175f65d6f4SNico Boehrqmp_events ()
1185f65d6f4SNico Boehr{
1195f65d6f4SNico Boehr	while ! test -S "$1"; do sleep 0.1; done
1205f65d6f4SNico Boehr	echo '{ "execute": "qmp_capabilities" }{ "execute": "cont" }' |
1215f65d6f4SNico Boehr		ncat --no-shutdown -U $1 |
1225f65d6f4SNico Boehr		jq -c 'select(has("event"))'
1235f65d6f4SNico Boehr}
1245f65d6f4SNico Boehr
12537abdda9SThomas Huthrun_migration ()
12637abdda9SThomas Huth{
127b508e114SJamie Iles	if ! command -v ncat >/dev/null 2>&1; then
128b508e114SJamie Iles		echo "${FUNCNAME[0]} needs ncat (netcat)" >&2
1292176d963SThomas Huth		return 77
13037abdda9SThomas Huth	fi
13137abdda9SThomas Huth
1328d26c42cSThomas Huth	migsock=$(mktemp -u -t mig-helper-socket.XXXXXXXXXX)
1338d26c42cSThomas Huth	migout1=$(mktemp -t mig-helper-stdout1.XXXXXXXXXX)
1348d26c42cSThomas Huth	qmp1=$(mktemp -u -t mig-helper-qmp1.XXXXXXXXXX)
1358d26c42cSThomas Huth	qmp2=$(mktemp -u -t mig-helper-qmp2.XXXXXXXXXX)
1368d26c42cSThomas Huth	fifo=$(mktemp -u -t mig-helper-fifo.XXXXXXXXXX)
13737abdda9SThomas Huth	qmpout1=/dev/null
13837abdda9SThomas Huth	qmpout2=/dev/null
13937abdda9SThomas Huth
1409806f62dSAndrew Jones	trap 'kill 0; exit 2' INT TERM
141ffd9da55SAndrew Jones	trap 'rm -f ${migout1} ${migsock} ${qmp1} ${qmp2} ${fifo}' RETURN EXIT
14237abdda9SThomas Huth
14348d779b0SAlex Bennée	eval "$@" -chardev socket,id=mon1,path=${qmp1},server=on,wait=off \
14437abdda9SThomas Huth		-mon chardev=mon1,mode=control | tee ${migout1} &
14537abdda9SThomas Huth
146ffd9da55SAndrew Jones	# We have to use cat to open the named FIFO, because named FIFO's, unlike
147ffd9da55SAndrew Jones	# pipes, will block on open() until the other end is also opened, and that
148ffd9da55SAndrew Jones	# totally breaks QEMU...
149ffd9da55SAndrew Jones	mkfifo ${fifo}
15048d779b0SAlex Bennée	eval "$@" -chardev socket,id=mon2,path=${qmp2},server=on,wait=off \
151ffd9da55SAndrew Jones		-mon chardev=mon2,mode=control -incoming unix:${migsock} < <(cat ${fifo}) &
1529806f62dSAndrew Jones	incoming_pid=`jobs -l %+ | awk '{print$2}'`
15337abdda9SThomas Huth
15437abdda9SThomas Huth	# The test must prompt the user to migrate, so wait for the "migrate" keyword
15537abdda9SThomas Huth	while ! grep -q -i "migrate" < ${migout1} ; do
15637abdda9SThomas Huth		sleep 1
15737abdda9SThomas Huth	done
15837abdda9SThomas Huth
15937abdda9SThomas Huth	qmp ${qmp1} '"migrate", "arguments": { "uri": "unix:'${migsock}'" }' > ${qmpout1}
16037abdda9SThomas Huth
16137abdda9SThomas Huth	# Wait for the migration to complete
16237abdda9SThomas Huth	migstatus=`qmp ${qmp1} '"query-migrate"' | grep return`
16337abdda9SThomas Huth	while ! grep -q '"completed"' <<<"$migstatus" ; do
16437abdda9SThomas Huth		sleep 1
16537abdda9SThomas Huth		migstatus=`qmp ${qmp1} '"query-migrate"' | grep return`
16637abdda9SThomas Huth		if grep -q '"failed"' <<<"$migstatus" ; then
16737abdda9SThomas Huth			echo "ERROR: Migration failed." >&2
16837abdda9SThomas Huth			qmp ${qmp1} '"quit"'> ${qmpout1} 2>/dev/null
16937abdda9SThomas Huth			qmp ${qmp2} '"quit"'> ${qmpout2} 2>/dev/null
1709806f62dSAndrew Jones			return 2
17137abdda9SThomas Huth		fi
17237abdda9SThomas Huth	done
17337abdda9SThomas Huth	qmp ${qmp1} '"quit"'> ${qmpout1} 2>/dev/null
174ffd9da55SAndrew Jones	echo > ${fifo}
1759806f62dSAndrew Jones	wait $incoming_pid
1769806f62dSAndrew Jones	ret=$?
177394d1421SAndrew Jones
178394d1421SAndrew Jones	while (( $(jobs -r | wc -l) > 0 )); do
179394d1421SAndrew Jones		sleep 0.5
180394d1421SAndrew Jones	done
181394d1421SAndrew Jones
1829806f62dSAndrew Jones	return $ret
18337abdda9SThomas Huth}
18437abdda9SThomas Huth
1855f65d6f4SNico Boehrrun_panic ()
1865f65d6f4SNico Boehr{
1875f65d6f4SNico Boehr	if ! command -v ncat >/dev/null 2>&1; then
1885f65d6f4SNico Boehr		echo "${FUNCNAME[0]} needs ncat (netcat)" >&2
1895f65d6f4SNico Boehr		return 77
1905f65d6f4SNico Boehr	fi
1915f65d6f4SNico Boehr
1925f65d6f4SNico Boehr	if ! command -v jq >/dev/null 2>&1; then
1935f65d6f4SNico Boehr		echo "${FUNCNAME[0]} needs jq" >&2
1945f65d6f4SNico Boehr		return 77
1955f65d6f4SNico Boehr	fi
1965f65d6f4SNico Boehr
1975f65d6f4SNico Boehr	qmp=$(mktemp -u -t panic-qmp.XXXXXXXXXX)
1985f65d6f4SNico Boehr
1995f65d6f4SNico Boehr	trap 'kill 0; exit 2' INT TERM
2005f65d6f4SNico Boehr	trap 'rm -f ${qmp}' RETURN EXIT
2015f65d6f4SNico Boehr
2025f65d6f4SNico Boehr	# start VM stopped so we don't miss any events
2035f65d6f4SNico Boehr	eval "$@" -chardev socket,id=mon1,path=${qmp},server=on,wait=off \
2045f65d6f4SNico Boehr		-mon chardev=mon1,mode=control -S &
2055f65d6f4SNico Boehr
2065f65d6f4SNico Boehr	panic_event_count=$(qmp_events ${qmp} | jq -c 'select(.event == "GUEST_PANICKED")' | wc -l)
2075f65d6f4SNico Boehr	if [ "$panic_event_count" -lt 1 ]; then
2085f65d6f4SNico Boehr		echo "FAIL: guest did not panic"
2095f65d6f4SNico Boehr		ret=3
2105f65d6f4SNico Boehr	else
2115f65d6f4SNico Boehr		# some QEMU versions report multiple panic events
2125f65d6f4SNico Boehr		echo "PASS: guest panicked"
2135f65d6f4SNico Boehr		ret=1
2145f65d6f4SNico Boehr	fi
2155f65d6f4SNico Boehr
2165f65d6f4SNico Boehr	return $ret
2175f65d6f4SNico Boehr}
2185f65d6f4SNico Boehr
21937abdda9SThomas Huthmigration_cmd ()
22037abdda9SThomas Huth{
22137abdda9SThomas Huth	if [ "$MIGRATION" = "yes" ]; then
22237abdda9SThomas Huth		echo "run_migration"
22337abdda9SThomas Huth	fi
22437abdda9SThomas Huth}
225531326aeSBalamuruhan S
2265f65d6f4SNico Boehrpanic_cmd ()
2275f65d6f4SNico Boehr{
2285f65d6f4SNico Boehr	if [ "$PANIC" = "yes" ]; then
2295f65d6f4SNico Boehr		echo "run_panic"
2305f65d6f4SNico Boehr	fi
2315f65d6f4SNico Boehr}
2325f65d6f4SNico Boehr
233531326aeSBalamuruhan Ssearch_qemu_binary ()
234531326aeSBalamuruhan S{
235531326aeSBalamuruhan S	local save_path=$PATH
236232f404aSAndrew Jones	local qemucmd qemu
237232f404aSAndrew Jones
238ee5a8a1aSAndrew Jones	: "${QEMU_ARCH:=$ARCH_NAME}"
239ee5a8a1aSAndrew Jones
240531326aeSBalamuruhan S	export PATH=$PATH:/usr/libexec
241ee5a8a1aSAndrew Jones	for qemucmd in ${QEMU:-qemu-system-$QEMU_ARCH qemu-kvm}; do
242232f404aSAndrew Jones		if $qemucmd --help 2>/dev/null | grep -q 'QEMU'; then
243232f404aSAndrew Jones			qemu="$qemucmd"
244531326aeSBalamuruhan S			break
245531326aeSBalamuruhan S		fi
246531326aeSBalamuruhan S	done
247531326aeSBalamuruhan S
248232f404aSAndrew Jones	if [ -z "$qemu" ]; then
249fcf4e0d9SRadim Krčmář		echo "A QEMU binary was not found." >&2
250fcf4e0d9SRadim Krčmář		echo "You can set a custom location by using the QEMU=<path> environment variable." >&2
251fcf4e0d9SRadim Krčmář		return 2
252531326aeSBalamuruhan S	fi
253232f404aSAndrew Jones	command -v $qemu
254531326aeSBalamuruhan S	export PATH=$save_path
255531326aeSBalamuruhan S}
2564da0bc9aSAndrew Jones
2574da0bc9aSAndrew Jonesinitrd_create ()
2584da0bc9aSAndrew Jones{
259b16df9eeSAndrew Jones	if [ "$ENVIRON_DEFAULT" = "yes" ]; then
260b16df9eeSAndrew Jones		trap_exit_push 'rm -f $KVM_UNIT_TESTS_ENV; [ "$KVM_UNIT_TESTS_ENV_OLD" ] && export KVM_UNIT_TESTS_ENV="$KVM_UNIT_TESTS_ENV_OLD" || unset KVM_UNIT_TESTS_ENV; unset KVM_UNIT_TESTS_ENV_OLD'
261b16df9eeSAndrew Jones		[ -f "$KVM_UNIT_TESTS_ENV" ] && export KVM_UNIT_TESTS_ENV_OLD="$KVM_UNIT_TESTS_ENV"
262b16df9eeSAndrew Jones		export KVM_UNIT_TESTS_ENV=$(mktemp)
263b16df9eeSAndrew Jones		env_params
264b16df9eeSAndrew Jones		env_file
265b16df9eeSAndrew Jones		env_errata || return $?
266b16df9eeSAndrew Jones	fi
2678b13a5b5SRadim Krčmář
2684da0bc9aSAndrew Jones	unset INITRD
26963dd93ecSAndrew Jones	[ -f "$KVM_UNIT_TESTS_ENV" ] && INITRD="-initrd $KVM_UNIT_TESTS_ENV"
2708b13a5b5SRadim Krčmář
271b16df9eeSAndrew Jones	return 0
2724da0bc9aSAndrew Jones}
2738ec99569SAndrew Jones
274b16df9eeSAndrew Jonesenv_add_params ()
2758ec99569SAndrew Jones{
276b16df9eeSAndrew Jones	local p
2778ec99569SAndrew Jones
278b16df9eeSAndrew Jones	for p in "$@"; do
279b16df9eeSAndrew Jones		if eval test -v $p; then
280b16df9eeSAndrew Jones			eval export "$p"
281b16df9eeSAndrew Jones		else
282b16df9eeSAndrew Jones			eval export "$p="
283b16df9eeSAndrew Jones		fi
284b16df9eeSAndrew Jones		grep "^$p=" <(env) >>$KVM_UNIT_TESTS_ENV
2858ec99569SAndrew Jones	done
286b16df9eeSAndrew Jones}
287b16df9eeSAndrew Jones
288b16df9eeSAndrew Jonesenv_params ()
289b16df9eeSAndrew Jones{
290b16df9eeSAndrew Jones	local qemu have_qemu
291b16df9eeSAndrew Jones	local _ rest
292b16df9eeSAndrew Jones
293b16df9eeSAndrew Jones	qemu=$(search_qemu_binary) && have_qemu=1
294b16df9eeSAndrew Jones
295b16df9eeSAndrew Jones	if [ "$have_qemu" ]; then
296b16df9eeSAndrew Jones		if [ -n "$ACCEL" ] || [ -n "$QEMU_ACCEL" ]; then
297b16df9eeSAndrew Jones			[ -n "$ACCEL" ] && QEMU_ACCEL=$ACCEL
298b16df9eeSAndrew Jones		fi
299b16df9eeSAndrew Jones		QEMU_VERSION_STRING="$($qemu -h | head -1)"
300b16df9eeSAndrew Jones		IFS='[ .]' read -r _ _ _ QEMU_MAJOR QEMU_MINOR QEMU_MICRO rest <<<"$QEMU_VERSION_STRING"
301b16df9eeSAndrew Jones	fi
302b16df9eeSAndrew Jones	env_add_params QEMU_ACCEL QEMU_VERSION_STRING QEMU_MAJOR QEMU_MINOR QEMU_MICRO
303b16df9eeSAndrew Jones
304b16df9eeSAndrew Jones	KERNEL_VERSION_STRING=$(uname -r)
305b16df9eeSAndrew Jones	IFS=. read -r KERNEL_VERSION KERNEL_PATCHLEVEL rest <<<"$KERNEL_VERSION_STRING"
306b16df9eeSAndrew Jones	IFS=- read -r KERNEL_SUBLEVEL KERNEL_EXTRAVERSION <<<"$rest"
307b16df9eeSAndrew Jones	KERNEL_SUBLEVEL=${KERNEL_SUBLEVEL%%[!0-9]*}
308b16df9eeSAndrew Jones	KERNEL_EXTRAVERSION=${KERNEL_EXTRAVERSION%%[!0-9]*}
309b16df9eeSAndrew Jones	! [[ $KERNEL_SUBLEVEL =~ ^[0-9]+$ ]] && unset $KERNEL_SUBLEVEL
310b16df9eeSAndrew Jones	! [[ $KERNEL_EXTRAVERSION =~ ^[0-9]+$ ]] && unset $KERNEL_EXTRAVERSION
311b16df9eeSAndrew Jones	env_add_params KERNEL_VERSION_STRING KERNEL_VERSION KERNEL_PATCHLEVEL KERNEL_SUBLEVEL KERNEL_EXTRAVERSION
312b16df9eeSAndrew Jones}
313b16df9eeSAndrew Jones
314b16df9eeSAndrew Jonesenv_file ()
315b16df9eeSAndrew Jones{
316b16df9eeSAndrew Jones	local line var
317b16df9eeSAndrew Jones
318b16df9eeSAndrew Jones	[ ! -f "$KVM_UNIT_TESTS_ENV_OLD" ] && return
319b16df9eeSAndrew Jones
320b16df9eeSAndrew Jones	for line in $(grep -E '^[[:blank:]]*[[:alpha:]_][[:alnum:]_]*=' "$KVM_UNIT_TESTS_ENV_OLD"); do
321b16df9eeSAndrew Jones		var=${line%%=*}
322b16df9eeSAndrew Jones		if ! grep -q "^$var=" $KVM_UNIT_TESTS_ENV; then
323b16df9eeSAndrew Jones			eval export "$line"
324b16df9eeSAndrew Jones			grep "^$var=" <(env) >>$KVM_UNIT_TESTS_ENV
325b16df9eeSAndrew Jones		fi
326b16df9eeSAndrew Jones	done
327b16df9eeSAndrew Jones}
328b16df9eeSAndrew Jones
329b16df9eeSAndrew Jonesenv_errata ()
330b16df9eeSAndrew Jones{
331ec2f5147SAlex Bennée	if [ "$ACCEL" = "tcg" ]; then
332ec2f5147SAlex Bennée		export "ERRATA_FORCE=y"
333ec2f5147SAlex Bennée	elif [ "$ERRATATXT" ] && [ ! -f "$ERRATATXT" ]; then
334b16df9eeSAndrew Jones		echo "$ERRATATXT not found. (ERRATATXT=$ERRATATXT)" >&2
335b16df9eeSAndrew Jones		return 2
336b16df9eeSAndrew Jones	elif [ "$ERRATATXT" ]; then
33770fcb64bSAndrew Jones		env_generate_errata
3388ec99569SAndrew Jones	fi
339b16df9eeSAndrew Jones	sort <(env | grep '^ERRATA_') <(grep '^ERRATA_' $KVM_UNIT_TESTS_ENV) | uniq -u >>$KVM_UNIT_TESTS_ENV
3408ec99569SAndrew Jones}
3418ec99569SAndrew Jones
34270fcb64bSAndrew Jonesenv_generate_errata ()
34370fcb64bSAndrew Jones{
34412a4328eSAndrew Jones	local line commit minver errata rest v p s x have
34570fcb64bSAndrew Jones
3461ea4709cSAndrew Jones	for line in $(grep -v '^#' "$ERRATATXT" | tr -d '[:blank:]' | cut -d: -f1,2); do
34770fcb64bSAndrew Jones		commit=${line%:*}
34870fcb64bSAndrew Jones		minver=${line#*:}
34970fcb64bSAndrew Jones
350171aa3a2SPeter Shier		test -z "$commit" && continue
35170fcb64bSAndrew Jones		errata="ERRATA_$commit"
352d1bc9395SAndrew Jones		[ -n "${!errata}" ] && continue
35370fcb64bSAndrew Jones
354d38b111bSJim Mattson		IFS=. read -r v p rest <<<"$minver"
355d38b111bSJim Mattson		IFS=- read -r s x <<<"$rest"
35670fcb64bSAndrew Jones		s=${s%%[!0-9]*}
35712a4328eSAndrew Jones		x=${x%%[!0-9]*}
35812a4328eSAndrew Jones
35912a4328eSAndrew Jones		if ! [[ $v =~ ^[0-9]+$ ]] || ! [[ $p =~ ^[0-9]+$ ]]; then
36012a4328eSAndrew Jones			echo "Bad minimum kernel version in $ERRATATXT, $minver"
3619806f62dSAndrew Jones			return 2
36212a4328eSAndrew Jones		fi
36312a4328eSAndrew Jones		! [[ $s =~ ^[0-9]+$ ]] && unset $s
36412a4328eSAndrew Jones		! [[ $x =~ ^[0-9]+$ ]] && unset $x
36570fcb64bSAndrew Jones
366b16df9eeSAndrew Jones		if (( $KERNEL_VERSION > $v ||
367b16df9eeSAndrew Jones		      ($KERNEL_VERSION == $v && $KERNEL_PATCHLEVEL > $p) )); then
36870fcb64bSAndrew Jones			have=y
369b16df9eeSAndrew Jones		elif (( $KERNEL_VERSION == $v && $KERNEL_PATCHLEVEL == $p )); then
370b16df9eeSAndrew Jones			if [ "$KERNEL_SUBLEVEL" ] && [ "$s" ]; then
371b16df9eeSAndrew Jones				if (( $KERNEL_SUBLEVEL > $s )); then
37270fcb64bSAndrew Jones					have=y
373b16df9eeSAndrew Jones				elif (( $KERNEL_SUBLEVEL == $s )); then
374b16df9eeSAndrew Jones					if [ "$KERNEL_EXTRAVERSION" ] && [ "$x" ]; then
375b16df9eeSAndrew Jones						if (( $KERNEL_EXTRAVERSION >= $x )); then
37612a4328eSAndrew Jones							have=y
37712a4328eSAndrew Jones						else
37812a4328eSAndrew Jones							have=n
37912a4328eSAndrew Jones						fi
38012a4328eSAndrew Jones					elif [ "$x" ] && (( $x != 0 )); then
38112a4328eSAndrew Jones						have=n
38212a4328eSAndrew Jones					else
38312a4328eSAndrew Jones						have=y
38412a4328eSAndrew Jones					fi
38570fcb64bSAndrew Jones				else
38670fcb64bSAndrew Jones					have=n
38770fcb64bSAndrew Jones				fi
38870fcb64bSAndrew Jones			elif [ "$s" ] && (( $s != 0 )); then
38970fcb64bSAndrew Jones				have=n
39070fcb64bSAndrew Jones			else
39170fcb64bSAndrew Jones				have=y
39270fcb64bSAndrew Jones			fi
39370fcb64bSAndrew Jones		else
39470fcb64bSAndrew Jones			have=n
39570fcb64bSAndrew Jones		fi
39670fcb64bSAndrew Jones		eval export "$errata=$have"
39770fcb64bSAndrew Jones	done
39870fcb64bSAndrew Jones}
39970fcb64bSAndrew Jones
4008ec99569SAndrew Jonestrap_exit_push ()
4018ec99569SAndrew Jones{
4028ec99569SAndrew Jones	local old_exit=$(trap -p EXIT | sed "s/^[^']*'//;s/'[^']*$//")
4038ec99569SAndrew Jones	trap -- "$1; $old_exit" EXIT
4048ec99569SAndrew Jones}
405f4d99928SRadim Krčmář
406f4d99928SRadim Krčmářkvm_available ()
407f4d99928SRadim Krčmář{
408f4d99928SRadim Krčmář	[ -c /dev/kvm ] ||
409f4d99928SRadim Krčmář		return 1
410f4d99928SRadim Krčmář
411f4d99928SRadim Krčmář	[ "$HOST" = "$ARCH_NAME" ] ||
412d76bf076SAndrew Jones		( [ "$HOST" = aarch64 ] && [ "$ARCH" = arm ] ) ||
413d76bf076SAndrew Jones		( [ "$HOST" = x86_64 ] && [ "$ARCH" = i386 ] )
414f4d99928SRadim Krčmář}
415f4d99928SRadim Krčmář
4167edd698eSRoman Bolshakovhvf_available ()
4177edd698eSRoman Bolshakov{
4187edd698eSRoman Bolshakov	[ "$(sysctl -n kern.hv_support 2>/dev/null)" = "1" ] || return 1
4197edd698eSRoman Bolshakov	[ "$HOST" = "$ARCH_NAME" ] ||
4207edd698eSRoman Bolshakov		( [ "$HOST" = x86_64 ] && [ "$ARCH" = i386 ] )
4217edd698eSRoman Bolshakov}
4227edd698eSRoman Bolshakov
423f4d99928SRadim Krčmářget_qemu_accelerator ()
424f4d99928SRadim Krčmář{
425f4d99928SRadim Krčmář	if [ "$ACCEL" = "kvm" ] && ! kvm_available; then
426f4d99928SRadim Krčmář		echo "KVM is needed, but not available on this host" >&2
427f4d99928SRadim Krčmář		return 2
428f4d99928SRadim Krčmář	fi
4297edd698eSRoman Bolshakov	if [ "$ACCEL" = "hvf" ] && ! hvf_available; then
4307edd698eSRoman Bolshakov		echo "HVF is needed, but not available on this host" >&2
4317edd698eSRoman Bolshakov		return 2
4327edd698eSRoman Bolshakov	fi
433f4d99928SRadim Krčmář
434f4d99928SRadim Krčmář	if [ "$ACCEL" ]; then
435f4d99928SRadim Krčmář		echo $ACCEL
436f4d99928SRadim Krčmář	elif kvm_available; then
437f4d99928SRadim Krčmář		echo kvm
4387edd698eSRoman Bolshakov	elif hvf_available; then
4397edd698eSRoman Bolshakov		echo hvf
440f4d99928SRadim Krčmář	else
441f4d99928SRadim Krčmář		echo tcg
442f4d99928SRadim Krčmář	fi
443f4d99928SRadim Krčmář}
444