1############################################################################## 2# run_qemu translates the ambiguous exit status in Table1 to that in Table2. 3# Table3 simply documents the complete status table. 4# 5# Table1: Before fixup 6# -------------------- 7# 0 - Unexpected exit from QEMU (possible signal), or the unittest did 8# not use debug-exit 9# 1 - most likely unittest succeeded, or QEMU failed 10# 11# Table2: After fixup 12# ------------------- 13# 0 - Everything succeeded 14# 1 - most likely QEMU failed 15# 16# Table3: Complete table 17# ---------------------- 18# 0 - SUCCESS 19# 1 - most likely QEMU failed 20# 2 - most likely a run script failed 21# 3 - most likely the unittest failed 22# 124 - most likely the unittest timed out 23# 127 - most likely the unittest called abort() 24# 1..127 - FAILURE (could be QEMU, a run script, or the unittest) 25# >= 128 - Signal (signum = status - 128) 26############################################################################## 27run_qemu () 28{ 29 local stdout errors ret sig 30 31 # stdout to {stdout}, stderr to $errors and stderr 32 exec {stdout}>&1 33 errors=$("${@}" </dev/null 2> >(tee /dev/stderr) > /dev/fd/$stdout) 34 ret=$? 35 exec {stdout}>&- 36 37 [ $ret -eq 134 ] && echo "QEMU Aborted" >&2 38 39 if [ "$errors" ]; then 40 sig=$(grep 'terminating on signal' <<<"$errors") 41 if [ "$sig" ]; then 42 sig=$(sed 's/.*terminating on signal \([0-9][0-9]*\).*/\1/' <<<"$sig") 43 fi 44 fi 45 46 if [ $ret -eq 0 ]; then 47 # Some signals result in a zero return status, but the 48 # error log tells the truth. 49 if [ "$sig" ]; then 50 ((ret=sig+128)) 51 else 52 # Exiting with zero (non-debugexit) is an error 53 ret=1 54 fi 55 elif [ $ret -eq 1 ]; then 56 # Even when ret==1 (unittest success) if we also got stderr 57 # logs, then we assume a QEMU failure. Otherwise we translate 58 # status of 1 to 0 (SUCCESS) 59 if [ -z "$(echo "$errors" | grep -vi warning)" ]; then 60 ret=0 61 fi 62 fi 63 64 return $ret 65} 66 67timeout_cmd () 68{ 69 if [ "$TIMEOUT" ] && [ "$TIMEOUT" != "0" ]; then 70 echo "timeout -k 1s --foreground $TIMEOUT" 71 fi 72} 73 74qmp () 75{ 76 echo '{ "execute": "qmp_capabilities" }{ "execute":' "$2" '}' | nc -U $1 77} 78 79run_migration () 80{ 81 if ! command -v nc >/dev/null 2>&1; then 82 echo "$FUNCNAME needs nc (netcat)" >&2 83 exit 2 84 fi 85 86 qemu=$1 87 shift 88 89 migsock=`mktemp -u -t mig-helper-socket.XXXXXXXXXX` 90 migout1=`mktemp -t mig-helper-stdout1.XXXXXXXXXX` 91 qmp1=`mktemp -u -t mig-helper-qmp1.XXXXXXXXXX` 92 qmp2=`mktemp -u -t mig-helper-qmp2.XXXXXXXXXX` 93 qmpout1=/dev/null 94 qmpout2=/dev/null 95 96 trap 'rm -f ${migout1} ${migsock} ${qmp1} ${qmp2}' EXIT 97 98 $qemu "$@" -chardev socket,id=mon1,path=${qmp1},server,nowait \ 99 -mon chardev=mon1,mode=control | tee ${migout1} & 100 101 $qemu "$@" -chardev socket,id=mon2,path=${qmp2},server,nowait \ 102 -mon chardev=mon2,mode=control -incoming unix:${migsock} & 103 104 # The test must prompt the user to migrate, so wait for the "migrate" keyword 105 while ! grep -q -i "migrate" < ${migout1} ; do 106 sleep 1 107 done 108 109 qmp ${qmp1} '"migrate", "arguments": { "uri": "unix:'${migsock}'" }' > ${qmpout1} 110 111 # Wait for the migration to complete 112 migstatus=`qmp ${qmp1} '"query-migrate"' | grep return` 113 while ! grep -q '"completed"' <<<"$migstatus" ; do 114 sleep 1 115 migstatus=`qmp ${qmp1} '"query-migrate"' | grep return` 116 if grep -q '"failed"' <<<"$migstatus" ; then 117 echo "ERROR: Migration failed." >&2 118 qmp ${qmp1} '"quit"'> ${qmpout1} 2>/dev/null 119 qmp ${qmp2} '"quit"'> ${qmpout2} 2>/dev/null 120 exit 2 121 fi 122 done 123 qmp ${qmp1} '"quit"'> ${qmpout1} 2>/dev/null 124 125 qmp ${qmp2} '"inject-nmi"'> ${qmpout2} 126 127 wait 128} 129 130migration_cmd () 131{ 132 if [ "$MIGRATION" = "yes" ]; then 133 echo "run_migration" 134 fi 135} 136 137search_qemu_binary () 138{ 139 local save_path=$PATH 140 local qemucmd qemu 141 142 export PATH=$PATH:/usr/libexec 143 for qemucmd in ${QEMU:-qemu-system-$ARCH_NAME qemu-kvm}; do 144 if $qemucmd --help 2>/dev/null | grep -q 'QEMU'; then 145 qemu="$qemucmd" 146 break 147 fi 148 done 149 150 if [ -z "$qemu" ]; then 151 echo "A QEMU binary was not found." 152 echo "You can set a custom location by using the QEMU=<path> environment variable." 153 exit 2 154 fi 155 command -v $qemu 156 export PATH=$save_path 157} 158 159initrd_create () 160{ 161 unset INITRD 162 [ -f "$ENV" ] && INITRD="-initrd $ENV" 163} 164