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{ 9715a12650SAndrew Jones local s 9815a12650SAndrew Jones 99fd149358SAndrew Jones if [ "$TIMEOUT" ] && [ "$TIMEOUT" != "0" ]; then 10015a12650SAndrew Jones if [ "$CONFIG_EFI" = 'y' ]; then 10115a12650SAndrew Jones s=${TIMEOUT: -1} 10215a12650SAndrew Jones if [ "$s" = 's' ]; then 10315a12650SAndrew Jones TIMEOUT=${TIMEOUT:0:-1} 10415a12650SAndrew Jones ((TIMEOUT += 10)) # Add 10 seconds for booting UEFI 10515a12650SAndrew Jones TIMEOUT="${TIMEOUT}s" 10615a12650SAndrew Jones fi 10715a12650SAndrew 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 132af3484fcSNicholas Piggin trap 'trap - TERM ; kill 0 ; exit 2' INT TERM 133*659557c0SNicholas Piggin trap 'rm -f ${migout1} ${migout_fifo1} ${migsock} ${qmp1} ${qmp2} ${fifo}' RETURN EXIT 134af3484fcSNicholas Piggin 1358d26c42cSThomas Huth migsock=$(mktemp -u -t mig-helper-socket.XXXXXXXXXX) 1368d26c42cSThomas Huth migout1=$(mktemp -t mig-helper-stdout1.XXXXXXXXXX) 137*659557c0SNicholas Piggin migout_fifo1=$(mktemp -u -t mig-helper-fifo-stdout1.XXXXXXXXXX) 1388d26c42cSThomas Huth qmp1=$(mktemp -u -t mig-helper-qmp1.XXXXXXXXXX) 1398d26c42cSThomas Huth qmp2=$(mktemp -u -t mig-helper-qmp2.XXXXXXXXXX) 1408d26c42cSThomas Huth fifo=$(mktemp -u -t mig-helper-fifo.XXXXXXXXXX) 14137abdda9SThomas Huth qmpout1=/dev/null 14237abdda9SThomas Huth qmpout2=/dev/null 14337abdda9SThomas Huth 144*659557c0SNicholas Piggin mkfifo ${migout_fifo1} 14548d779b0SAlex Bennée eval "$@" -chardev socket,id=mon1,path=${qmp1},server=on,wait=off \ 146*659557c0SNicholas Piggin -mon chardev=mon1,mode=control > ${migout_fifo1} & 147*659557c0SNicholas Piggin live_pid=$! 148*659557c0SNicholas Piggin cat ${migout_fifo1} | tee ${migout1} & 14937abdda9SThomas Huth 150ffd9da55SAndrew Jones # We have to use cat to open the named FIFO, because named FIFO's, unlike 151ffd9da55SAndrew Jones # pipes, will block on open() until the other end is also opened, and that 152ffd9da55SAndrew Jones # totally breaks QEMU... 153ffd9da55SAndrew Jones mkfifo ${fifo} 15448d779b0SAlex Bennée eval "$@" -chardev socket,id=mon2,path=${qmp2},server=on,wait=off \ 155ffd9da55SAndrew Jones -mon chardev=mon2,mode=control -incoming unix:${migsock} < <(cat ${fifo}) & 156*659557c0SNicholas Piggin incoming_pid=$! 15737abdda9SThomas Huth 15837abdda9SThomas Huth # The test must prompt the user to migrate, so wait for the "migrate" keyword 159bfe5d7d0SNicholas Piggin while ! grep -q -i "Now migrate the VM" < ${migout1} ; do 160bfe5d7d0SNicholas Piggin if ! ps -p ${live_pid} > /dev/null ; then 161bfe5d7d0SNicholas Piggin echo "ERROR: Test exit before migration point." >&2 162bfe5d7d0SNicholas Piggin echo > ${fifo} 163bfe5d7d0SNicholas Piggin qmp ${qmp1} '"quit"'> ${qmpout1} 2>/dev/null 164bfe5d7d0SNicholas Piggin qmp ${qmp2} '"quit"'> ${qmpout2} 2>/dev/null 165bfe5d7d0SNicholas Piggin return 3 166bfe5d7d0SNicholas Piggin fi 16737abdda9SThomas Huth sleep 1 16837abdda9SThomas Huth done 16937abdda9SThomas Huth 170*659557c0SNicholas Piggin # Wait until the destination has created the incoming and qmp sockets 171*659557c0SNicholas Piggin while ! [ -S ${migsock} ] ; do sleep 0.1 ; done 172*659557c0SNicholas Piggin while ! [ -S ${qmp2} ] ; do sleep 0.1 ; done 173*659557c0SNicholas Piggin 17437abdda9SThomas Huth qmp ${qmp1} '"migrate", "arguments": { "uri": "unix:'${migsock}'" }' > ${qmpout1} 17537abdda9SThomas Huth 17637abdda9SThomas Huth # Wait for the migration to complete 17737abdda9SThomas Huth migstatus=`qmp ${qmp1} '"query-migrate"' | grep return` 17837abdda9SThomas Huth while ! grep -q '"completed"' <<<"$migstatus" ; do 17937abdda9SThomas Huth sleep 1 18009e8c119SNico Boehr if ! migstatus=`qmp ${qmp1} '"query-migrate"'`; then 18109e8c119SNico Boehr echo "ERROR: Querying migration state failed." >&2 18209e8c119SNico Boehr echo > ${fifo} 18309e8c119SNico Boehr qmp ${qmp2} '"quit"'> ${qmpout2} 2>/dev/null 18409e8c119SNico Boehr return 2 18509e8c119SNico Boehr fi 18609e8c119SNico Boehr migstatus=`grep return <<<"$migstatus"` 18737abdda9SThomas Huth if grep -q '"failed"' <<<"$migstatus"; then 18837abdda9SThomas Huth echo "ERROR: Migration failed." >&2 189a710a84cSNicholas Piggin echo > ${fifo} 19037abdda9SThomas Huth qmp ${qmp1} '"quit"'> ${qmpout1} 2>/dev/null 19137abdda9SThomas Huth qmp ${qmp2} '"quit"'> ${qmpout2} 2>/dev/null 1929806f62dSAndrew Jones return 2 19337abdda9SThomas Huth fi 19437abdda9SThomas Huth done 19537abdda9SThomas Huth qmp ${qmp1} '"quit"'> ${qmpout1} 2>/dev/null 196ffd9da55SAndrew Jones echo > ${fifo} 1979806f62dSAndrew Jones wait $incoming_pid 1989806f62dSAndrew Jones ret=$? 199394d1421SAndrew Jones 200394d1421SAndrew Jones while (( $(jobs -r | wc -l) > 0 )); do 201394d1421SAndrew Jones sleep 0.5 202394d1421SAndrew Jones done 203394d1421SAndrew Jones 2049806f62dSAndrew Jones return $ret 20537abdda9SThomas Huth} 20637abdda9SThomas Huth 2075f65d6f4SNico Boehrrun_panic () 2085f65d6f4SNico Boehr{ 2095f65d6f4SNico Boehr if ! command -v ncat >/dev/null 2>&1; then 2105f65d6f4SNico Boehr echo "${FUNCNAME[0]} needs ncat (netcat)" >&2 2115f65d6f4SNico Boehr return 77 2125f65d6f4SNico Boehr fi 2135f65d6f4SNico Boehr 2145f65d6f4SNico Boehr if ! command -v jq >/dev/null 2>&1; then 2155f65d6f4SNico Boehr echo "${FUNCNAME[0]} needs jq" >&2 2165f65d6f4SNico Boehr return 77 2175f65d6f4SNico Boehr fi 2185f65d6f4SNico Boehr 219af3484fcSNicholas Piggin trap 'trap - TERM ; kill 0 ; exit 2' INT TERM 2205f65d6f4SNico Boehr trap 'rm -f ${qmp}' RETURN EXIT 2215f65d6f4SNico Boehr 222af3484fcSNicholas Piggin qmp=$(mktemp -u -t panic-qmp.XXXXXXXXXX) 223af3484fcSNicholas Piggin 2245f65d6f4SNico Boehr # start VM stopped so we don't miss any events 2255f65d6f4SNico Boehr eval "$@" -chardev socket,id=mon1,path=${qmp},server=on,wait=off \ 2265f65d6f4SNico Boehr -mon chardev=mon1,mode=control -S & 2275f65d6f4SNico Boehr 2285f65d6f4SNico Boehr panic_event_count=$(qmp_events ${qmp} | jq -c 'select(.event == "GUEST_PANICKED")' | wc -l) 2295f65d6f4SNico Boehr if [ "$panic_event_count" -lt 1 ]; then 2305f65d6f4SNico Boehr echo "FAIL: guest did not panic" 2315f65d6f4SNico Boehr ret=3 2325f65d6f4SNico Boehr else 2335f65d6f4SNico Boehr # some QEMU versions report multiple panic events 2345f65d6f4SNico Boehr echo "PASS: guest panicked" 2355f65d6f4SNico Boehr ret=1 2365f65d6f4SNico Boehr fi 2375f65d6f4SNico Boehr 2385f65d6f4SNico Boehr return $ret 2395f65d6f4SNico Boehr} 2405f65d6f4SNico Boehr 24137abdda9SThomas Huthmigration_cmd () 24237abdda9SThomas Huth{ 24337abdda9SThomas Huth if [ "$MIGRATION" = "yes" ]; then 24437abdda9SThomas Huth echo "run_migration" 24537abdda9SThomas Huth fi 24637abdda9SThomas Huth} 247531326aeSBalamuruhan S 2485f65d6f4SNico Boehrpanic_cmd () 2495f65d6f4SNico Boehr{ 2505f65d6f4SNico Boehr if [ "$PANIC" = "yes" ]; then 2515f65d6f4SNico Boehr echo "run_panic" 2525f65d6f4SNico Boehr fi 2535f65d6f4SNico Boehr} 2545f65d6f4SNico Boehr 255531326aeSBalamuruhan Ssearch_qemu_binary () 256531326aeSBalamuruhan S{ 257531326aeSBalamuruhan S local save_path=$PATH 258232f404aSAndrew Jones local qemucmd qemu 259232f404aSAndrew Jones 260ee5a8a1aSAndrew Jones : "${QEMU_ARCH:=$ARCH_NAME}" 261ee5a8a1aSAndrew Jones 262531326aeSBalamuruhan S export PATH=$PATH:/usr/libexec 263ee5a8a1aSAndrew Jones for qemucmd in ${QEMU:-qemu-system-$QEMU_ARCH qemu-kvm}; do 264232f404aSAndrew Jones if $qemucmd --help 2>/dev/null | grep -q 'QEMU'; then 265232f404aSAndrew Jones qemu="$qemucmd" 266531326aeSBalamuruhan S break 267531326aeSBalamuruhan S fi 268531326aeSBalamuruhan S done 269531326aeSBalamuruhan S 270232f404aSAndrew Jones if [ -z "$qemu" ]; then 271fcf4e0d9SRadim Krčmář echo "A QEMU binary was not found." >&2 272fcf4e0d9SRadim Krčmář echo "You can set a custom location by using the QEMU=<path> environment variable." >&2 273fcf4e0d9SRadim Krčmář return 2 274531326aeSBalamuruhan S fi 275232f404aSAndrew Jones command -v $qemu 276531326aeSBalamuruhan S export PATH=$save_path 277531326aeSBalamuruhan S} 2784da0bc9aSAndrew Jones 279c8764266SNicholas Piggininitrd_cleanup () 280c8764266SNicholas Piggin{ 281c8764266SNicholas Piggin rm -f $KVM_UNIT_TESTS_ENV 282c8764266SNicholas Piggin if [ "$KVM_UNIT_TESTS_ENV_OLD" ]; then 283c8764266SNicholas Piggin export KVM_UNIT_TESTS_ENV="$KVM_UNIT_TESTS_ENV_OLD" 284c8764266SNicholas Piggin else 285c8764266SNicholas Piggin unset KVM_UNIT_TESTS_ENV 286c8764266SNicholas Piggin fi 287c8764266SNicholas Piggin unset KVM_UNIT_TESTS_ENV_OLD 288c8764266SNicholas Piggin} 289c8764266SNicholas Piggin 2904da0bc9aSAndrew Jonesinitrd_create () 2914da0bc9aSAndrew Jones{ 292b16df9eeSAndrew Jones if [ "$ENVIRON_DEFAULT" = "yes" ]; then 293c8764266SNicholas Piggin trap_exit_push 'initrd_cleanup' 294b16df9eeSAndrew Jones [ -f "$KVM_UNIT_TESTS_ENV" ] && export KVM_UNIT_TESTS_ENV_OLD="$KVM_UNIT_TESTS_ENV" 295b16df9eeSAndrew Jones export KVM_UNIT_TESTS_ENV=$(mktemp) 296b16df9eeSAndrew Jones env_params 297b16df9eeSAndrew Jones env_file 298b16df9eeSAndrew Jones env_errata || return $? 299b16df9eeSAndrew Jones fi 3008b13a5b5SRadim Krčmář 3014da0bc9aSAndrew Jones unset INITRD 30263dd93ecSAndrew Jones [ -f "$KVM_UNIT_TESTS_ENV" ] && INITRD="-initrd $KVM_UNIT_TESTS_ENV" 3038b13a5b5SRadim Krčmář 304b16df9eeSAndrew Jones return 0 3054da0bc9aSAndrew Jones} 3068ec99569SAndrew Jones 307b16df9eeSAndrew Jonesenv_add_params () 3088ec99569SAndrew Jones{ 309b16df9eeSAndrew Jones local p 3108ec99569SAndrew Jones 311b16df9eeSAndrew Jones for p in "$@"; do 312b16df9eeSAndrew Jones if eval test -v $p; then 313b16df9eeSAndrew Jones eval export "$p" 314b16df9eeSAndrew Jones else 315b16df9eeSAndrew Jones eval export "$p=" 316b16df9eeSAndrew Jones fi 317b16df9eeSAndrew Jones grep "^$p=" <(env) >>$KVM_UNIT_TESTS_ENV 3188ec99569SAndrew Jones done 319b16df9eeSAndrew Jones} 320b16df9eeSAndrew Jones 321b16df9eeSAndrew Jonesenv_params () 322b16df9eeSAndrew Jones{ 323b16df9eeSAndrew Jones local qemu have_qemu 324b16df9eeSAndrew Jones local _ rest 325b16df9eeSAndrew Jones 326b16df9eeSAndrew Jones qemu=$(search_qemu_binary) && have_qemu=1 327b16df9eeSAndrew Jones 328b16df9eeSAndrew Jones if [ "$have_qemu" ]; then 329b16df9eeSAndrew Jones if [ -n "$ACCEL" ] || [ -n "$QEMU_ACCEL" ]; then 330b16df9eeSAndrew Jones [ -n "$ACCEL" ] && QEMU_ACCEL=$ACCEL 331b16df9eeSAndrew Jones fi 332b16df9eeSAndrew Jones QEMU_VERSION_STRING="$($qemu -h | head -1)" 333b16df9eeSAndrew Jones IFS='[ .]' read -r _ _ _ QEMU_MAJOR QEMU_MINOR QEMU_MICRO rest <<<"$QEMU_VERSION_STRING" 334b16df9eeSAndrew Jones fi 335b16df9eeSAndrew Jones env_add_params QEMU_ACCEL QEMU_VERSION_STRING QEMU_MAJOR QEMU_MINOR QEMU_MICRO 336b16df9eeSAndrew Jones 337b16df9eeSAndrew Jones KERNEL_VERSION_STRING=$(uname -r) 338b16df9eeSAndrew Jones IFS=. read -r KERNEL_VERSION KERNEL_PATCHLEVEL rest <<<"$KERNEL_VERSION_STRING" 339b16df9eeSAndrew Jones IFS=- read -r KERNEL_SUBLEVEL KERNEL_EXTRAVERSION <<<"$rest" 340b16df9eeSAndrew Jones KERNEL_SUBLEVEL=${KERNEL_SUBLEVEL%%[!0-9]*} 341b16df9eeSAndrew Jones KERNEL_EXTRAVERSION=${KERNEL_EXTRAVERSION%%[!0-9]*} 342b16df9eeSAndrew Jones ! [[ $KERNEL_SUBLEVEL =~ ^[0-9]+$ ]] && unset $KERNEL_SUBLEVEL 343b16df9eeSAndrew Jones ! [[ $KERNEL_EXTRAVERSION =~ ^[0-9]+$ ]] && unset $KERNEL_EXTRAVERSION 344b16df9eeSAndrew Jones env_add_params KERNEL_VERSION_STRING KERNEL_VERSION KERNEL_PATCHLEVEL KERNEL_SUBLEVEL KERNEL_EXTRAVERSION 345b16df9eeSAndrew Jones} 346b16df9eeSAndrew Jones 347b16df9eeSAndrew Jonesenv_file () 348b16df9eeSAndrew Jones{ 349b16df9eeSAndrew Jones local line var 350b16df9eeSAndrew Jones 351b16df9eeSAndrew Jones [ ! -f "$KVM_UNIT_TESTS_ENV_OLD" ] && return 352b16df9eeSAndrew Jones 353b16df9eeSAndrew Jones for line in $(grep -E '^[[:blank:]]*[[:alpha:]_][[:alnum:]_]*=' "$KVM_UNIT_TESTS_ENV_OLD"); do 354b16df9eeSAndrew Jones var=${line%%=*} 355b16df9eeSAndrew Jones if ! grep -q "^$var=" $KVM_UNIT_TESTS_ENV; then 356b16df9eeSAndrew Jones eval export "$line" 357b16df9eeSAndrew Jones grep "^$var=" <(env) >>$KVM_UNIT_TESTS_ENV 358b16df9eeSAndrew Jones fi 359b16df9eeSAndrew Jones done 360b16df9eeSAndrew Jones} 361b16df9eeSAndrew Jones 362b16df9eeSAndrew Jonesenv_errata () 363b16df9eeSAndrew Jones{ 364ec2f5147SAlex Bennée if [ "$ACCEL" = "tcg" ]; then 365ec2f5147SAlex Bennée export "ERRATA_FORCE=y" 366ec2f5147SAlex Bennée elif [ "$ERRATATXT" ] && [ ! -f "$ERRATATXT" ]; then 367b16df9eeSAndrew Jones echo "$ERRATATXT not found. (ERRATATXT=$ERRATATXT)" >&2 368b16df9eeSAndrew Jones return 2 369b16df9eeSAndrew Jones elif [ "$ERRATATXT" ]; then 37070fcb64bSAndrew Jones env_generate_errata 3718ec99569SAndrew Jones fi 372b16df9eeSAndrew Jones sort <(env | grep '^ERRATA_') <(grep '^ERRATA_' $KVM_UNIT_TESTS_ENV) | uniq -u >>$KVM_UNIT_TESTS_ENV 3738ec99569SAndrew Jones} 3748ec99569SAndrew Jones 37570fcb64bSAndrew Jonesenv_generate_errata () 37670fcb64bSAndrew Jones{ 37712a4328eSAndrew Jones local line commit minver errata rest v p s x have 37870fcb64bSAndrew Jones 3791ea4709cSAndrew Jones for line in $(grep -v '^#' "$ERRATATXT" | tr -d '[:blank:]' | cut -d: -f1,2); do 38070fcb64bSAndrew Jones commit=${line%:*} 38170fcb64bSAndrew Jones minver=${line#*:} 38270fcb64bSAndrew Jones 383171aa3a2SPeter Shier test -z "$commit" && continue 38470fcb64bSAndrew Jones errata="ERRATA_$commit" 385d1bc9395SAndrew Jones [ -n "${!errata}" ] && continue 38670fcb64bSAndrew Jones 387d38b111bSJim Mattson IFS=. read -r v p rest <<<"$minver" 388d38b111bSJim Mattson IFS=- read -r s x <<<"$rest" 38970fcb64bSAndrew Jones s=${s%%[!0-9]*} 39012a4328eSAndrew Jones x=${x%%[!0-9]*} 39112a4328eSAndrew Jones 39212a4328eSAndrew Jones if ! [[ $v =~ ^[0-9]+$ ]] || ! [[ $p =~ ^[0-9]+$ ]]; then 39312a4328eSAndrew Jones echo "Bad minimum kernel version in $ERRATATXT, $minver" 3949806f62dSAndrew Jones return 2 39512a4328eSAndrew Jones fi 39612a4328eSAndrew Jones ! [[ $s =~ ^[0-9]+$ ]] && unset $s 39712a4328eSAndrew Jones ! [[ $x =~ ^[0-9]+$ ]] && unset $x 39870fcb64bSAndrew Jones 399b16df9eeSAndrew Jones if (( $KERNEL_VERSION > $v || 400b16df9eeSAndrew Jones ($KERNEL_VERSION == $v && $KERNEL_PATCHLEVEL > $p) )); then 40170fcb64bSAndrew Jones have=y 402b16df9eeSAndrew Jones elif (( $KERNEL_VERSION == $v && $KERNEL_PATCHLEVEL == $p )); then 403b16df9eeSAndrew Jones if [ "$KERNEL_SUBLEVEL" ] && [ "$s" ]; then 404b16df9eeSAndrew Jones if (( $KERNEL_SUBLEVEL > $s )); then 40570fcb64bSAndrew Jones have=y 406b16df9eeSAndrew Jones elif (( $KERNEL_SUBLEVEL == $s )); then 407b16df9eeSAndrew Jones if [ "$KERNEL_EXTRAVERSION" ] && [ "$x" ]; then 408b16df9eeSAndrew Jones if (( $KERNEL_EXTRAVERSION >= $x )); then 40912a4328eSAndrew Jones have=y 41012a4328eSAndrew Jones else 41112a4328eSAndrew Jones have=n 41212a4328eSAndrew Jones fi 41312a4328eSAndrew Jones elif [ "$x" ] && (( $x != 0 )); then 41412a4328eSAndrew Jones have=n 41512a4328eSAndrew Jones else 41612a4328eSAndrew Jones have=y 41712a4328eSAndrew Jones fi 41870fcb64bSAndrew Jones else 41970fcb64bSAndrew Jones have=n 42070fcb64bSAndrew Jones fi 42170fcb64bSAndrew Jones elif [ "$s" ] && (( $s != 0 )); then 42270fcb64bSAndrew Jones have=n 42370fcb64bSAndrew Jones else 42470fcb64bSAndrew Jones have=y 42570fcb64bSAndrew Jones fi 42670fcb64bSAndrew Jones else 42770fcb64bSAndrew Jones have=n 42870fcb64bSAndrew Jones fi 42970fcb64bSAndrew Jones eval export "$errata=$have" 43070fcb64bSAndrew Jones done 43170fcb64bSAndrew Jones} 43270fcb64bSAndrew Jones 4338ec99569SAndrew Jonestrap_exit_push () 4348ec99569SAndrew Jones{ 4358ec99569SAndrew Jones local old_exit=$(trap -p EXIT | sed "s/^[^']*'//;s/'[^']*$//") 4368ec99569SAndrew Jones trap -- "$1; $old_exit" EXIT 4378ec99569SAndrew Jones} 438f4d99928SRadim Krčmář 439f4d99928SRadim Krčmářkvm_available () 440f4d99928SRadim Krčmář{ 441f4d99928SRadim Krčmář [ -c /dev/kvm ] || 442f4d99928SRadim Krčmář return 1 443f4d99928SRadim Krčmář 444f4d99928SRadim Krčmář [ "$HOST" = "$ARCH_NAME" ] || 445d76bf076SAndrew Jones ( [ "$HOST" = aarch64 ] && [ "$ARCH" = arm ] ) || 446d76bf076SAndrew Jones ( [ "$HOST" = x86_64 ] && [ "$ARCH" = i386 ] ) 447f4d99928SRadim Krčmář} 448f4d99928SRadim Krčmář 4497edd698eSRoman Bolshakovhvf_available () 4507edd698eSRoman Bolshakov{ 4517edd698eSRoman Bolshakov [ "$(sysctl -n kern.hv_support 2>/dev/null)" = "1" ] || return 1 4527edd698eSRoman Bolshakov [ "$HOST" = "$ARCH_NAME" ] || 4537edd698eSRoman Bolshakov ( [ "$HOST" = x86_64 ] && [ "$ARCH" = i386 ] ) 4547edd698eSRoman Bolshakov} 4557edd698eSRoman Bolshakov 45601e047d0SGavin Shanset_qemu_accelerator () 457f4d99928SRadim Krčmář{ 45801e047d0SGavin Shan ACCEL_PROPS=${ACCEL#"${ACCEL%%,*}"} 45901e047d0SGavin Shan ACCEL=${ACCEL%%,*} 46001e047d0SGavin Shan 461f4d99928SRadim Krčmář if [ "$ACCEL" = "kvm" ] && ! kvm_available; then 462f4d99928SRadim Krčmář echo "KVM is needed, but not available on this host" >&2 463f4d99928SRadim Krčmář return 2 464f4d99928SRadim Krčmář fi 4657edd698eSRoman Bolshakov if [ "$ACCEL" = "hvf" ] && ! hvf_available; then 4667edd698eSRoman Bolshakov echo "HVF is needed, but not available on this host" >&2 4677edd698eSRoman Bolshakov return 2 4687edd698eSRoman Bolshakov fi 469f4d99928SRadim Krčmář 47001e047d0SGavin Shan if [ -z "$ACCEL" ]; then 47101e047d0SGavin Shan if kvm_available; then 47201e047d0SGavin Shan ACCEL="kvm" 4737edd698eSRoman Bolshakov elif hvf_available; then 47401e047d0SGavin Shan ACCEL="hvf" 475f4d99928SRadim Krčmář else 47601e047d0SGavin Shan ACCEL="tcg" 477f4d99928SRadim Krčmář fi 47801e047d0SGavin Shan fi 47901e047d0SGavin Shan 48001e047d0SGavin Shan return 0 481f4d99928SRadim Krčmář} 482