Add -m/--machine option.
[qemu-sanity-check.git] / qemu-sanity-check.in
index 50b50ef..e1abafd 100644 (file)
@@ -1,7 +1,7 @@
 #!/bin/bash
 # -*- shell-script -*-
 # qemu-sanity-check
-# Copyright (C) 2013 Red Hat Inc.
+# Copyright (C) 2013-2020 Red Hat Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+initrd="@libdir@/qemu-sanity-check/initrd"
+
+arch="$(uname -m)"
+canonical_arch="$(uname -m | sed 's/i[456]86/i386/')"
+
+timeout=10m
+accel=kvm:tcg
+
+# Default machine type depends on arch.  You can override this using
+# -m|--machine option.
+case "$canonical_arch" in
+    arm*|aarch*) machine=virt ;;
+    # On non-ARM let qemu pick the default.
+    *) machine= ;;
+esac
 
 # Handle command line parsing.
 
 function usage {
     echo "qemu-sanity-check [options]"
     echo "Options:"
-    echo "  --help          Display this help"
-    echo "  --version       Display version and exit"
+    echo "  --help               Display this help"
+    echo "  --accel=[kvm|tcg]    Force KVM or software emulation"
+    echo "  -i|--initrd=initrd   Set location of initramfs"
+    echo "  -k|--kernel=vmlinuz  Set location of kernel"
+    echo "  -m|--machine=machine Set machine type"
+    echo "  -q|--qemu=qemu       Set location of qemu/KVM binary"
+    echo "  -t|--timeout=timeout Set the timeout"
+    echo "  -V|--version         Display version and exit"
     exit 0
 }
 
 TEMP=$(getopt \
-    -o v \
+    -o i:k:m:q:t:V \
     --long help \
+    --long accel: \
+    --long initrd: \
+    --long kernel: \
+    --long machine: \
+    --long qemu: \
+    --long timeout: \
     --long version \
     -n 'qemu-sanity-check' -- "$@")
-if [ $? != 0 ]; then exit 1; fi
+if [ $? != 0 ]; then exit 2; fi
 eval set -- "$TEMP"
 
 while true; do
     case "$1" in
-        --help) usage ;;
-        -v|--version) echo "@PACKAGE_NAME@ @PACKAGE_VERSION@"; exit 0 ;;
-        --) shift; break ;;
-        *) fail "internal error ($1)" ;;
+        --help)
+            usage
+            ;;
+        --accel)
+            accel="$2"
+            shift 2
+            ;;
+        -i|--initrd)
+            initrd="$2"
+            shift 2
+            ;;
+        -k|--kernel)
+            kernel="$2"
+            shift 2
+            ;;
+        -m|--machine)
+            machine="$2"
+            shift 2
+            ;;
+        -q|--qemu)
+            qemu="$2"
+            shift 2
+            ;;
+        -t|--timeout)
+            timeout="$2"
+            shift 2
+            ;;
+        -V|--version)
+            echo "@PACKAGE_NAME@ @PACKAGE_VERSION@"
+            exit 0
+            ;;
+        --)
+            shift
+            break
+            ;;
+        *)
+            echo "$0: internal error parsing options: $1"
+            exit 2
+            ;;
     esac
 done
+
+# Locate initrd.
+if [ ! -r "$initrd" ]; then
+    echo "$0: cannot find 'initrd', try using --initrd=/path/to/initrd"
+    echo "If you are running qemu-sanity-check without installing, then do:"
+    echo "    $0 --initrd=./initrd $@"
+    echo "The default path is '@libdir@/initrd'."
+    exit 2
+fi
+
+# Locate kernel if not specified.
+if [ -z "$kernel" ]; then
+    kernel="$(ls -1dvr /boot/vmlinuz-*.$arch* 2>/dev/null | grep -v xen | head -1)"
+    if [ -z "$kernel" ]; then
+        echo "$0: cannot find a Linux kernel in /boot"
+        echo "Choose a kernel to test using --kernel=/path/to/vmlinuz"
+        exit 2
+    fi
+fi
+if [ ! -r "$kernel" ]; then
+    echo "$0: kernel $kernel is not readable"
+    exit 2
+fi
+
+# Locate qemu if not specified.
+if [ -z "$qemu" ]; then
+    for q in @QEMU_LIST@; do
+        if "$q" --help >/dev/null 2>&1; then
+            qemu="$q"
+            break
+        fi
+    done
+    if [ -z "$qemu" ]; then
+        echo "$0: cannot find a qemu binary on the \$PATH"
+        echo "Choose a qemu binary to test using --qemu=/path/to/qemu"
+        exit 2
+    fi
+fi
+
+# Choose a temporary file for the output.
+test_output="$(mktemp --suff=.out)"
+
+# Generate the parameters for the qemu command.
+declare -a argv
+i=0
+argv[$((i++))]="$qemu"
+argv[$((i++))]="-display"
+argv[$((i++))]="none"
+argv[$((i++))]="-no-user-config"
+argv[$((i++))]="-nodefaults"
+argv[$((i++))]="-machine"
+argv[$((i++))]="$machine${machine:+,}accel=$accel"
+argv[$((i++))]="-no-reboot"
+argv[$((i++))]="-serial"
+argv[$((i++))]="file:$test_output"
+argv[$((i++))]="-kernel"
+argv[$((i++))]="$kernel"
+argv[$((i++))]="-initrd"
+argv[$((i++))]="$initrd"
+argv[$((i++))]="-append"
+argv[$((i++))]="console=ttyS0 oops=panic panic=-1"
+
+#echo "${argv[@]}"
+
+# Run the command.
+timeout "$timeout" "${argv[@]}"
+r="${PIPESTATUS[0]}"
+if [ $r -eq 124 ]; then
+    cat "$test_output"
+    echo "$0: error: test $kernel on $qemu: timed out"
+    rm "$test_output"
+    exit 1
+elif [ $r -ne 0 ]; then
+    cat "$test_output"
+    echo "$0: error: test $kernel on $qemu: failed"
+    rm "$test_output"
+    exit 1
+fi
+
+# Verify that userspace was reached.
+if ! grep -sq "initrd started up OK" "$test_output"; then
+    cat "$test_output"
+    echo "$0: error: test $kernel on $qemu: init process did not start up"
+    rm "$test_output"
+    exit 1
+fi
+
+# Successful.
+rm "$test_output"
+exit 0