5066ebce7b60fdb3c2474f67968acf2947753393
[qemu-sanity-check.git] / qemu-sanity-check.in
1 #!/bin/bash
2 # -*- shell-script -*-
3 # qemu-sanity-check
4 # Copyright (C) 2013-2020 Red Hat Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License along
17 # with this program; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20 prefix="@prefix@"
21 exec_prefix="@exec_prefix@"
22 initrd="@libdir@/qemu-sanity-check/initrd"
23
24 arch="$(uname -m)"
25 canonical_arch="$(uname -m | sed 's/i[456]86/i386/')"
26
27 verbose=no
28 timeout=10m
29 accel=kvm:tcg
30 cpu=
31 memory=768
32 machine=
33
34 # Both libguestfs and virt-manager choose cpu=host when we think that
35 # KVM is available, and default otherwise.  Although testing for KVM
36 # is hairy, I found that on aarch64 it can fail unless we choose
37 # cpu=host for KVM.
38 if test -r /dev/kvm; then
39     cpu=host
40 fi
41
42 # Default machine and CPU type depends on arch.  You can override this
43 # using -m|--machine and --cpu options.
44 case "$canonical_arch" in
45     arm*)
46         machine=virt ;;
47     aarch*)
48         if [ "$cpu" = "" ]; then cpu=cortex-a57; fi
49         machine=virt ;;
50 esac
51
52 # Handle command line parsing.
53
54 function usage {
55     echo "qemu-sanity-check [options]"
56     echo "Options:"
57     echo "  --help               Display this help"
58     echo "  --accel=[kvm|tcg]    Force KVM or software emulation"
59     echo "  --cpu=cpu            Set CPU"
60     echo "  -i|--initrd=initrd   Set location of initramfs"
61     echo "  -k|--kernel=vmlinuz  Set location of kernel"
62     echo "  -m|--machine=machine Set machine type"
63     echo "  -q|--qemu=qemu       Set location of qemu/KVM binary"
64     echo "  -t|--timeout=timeout Set the timeout"
65     echo "  -v|--verbose         Verbose output"
66     echo "  -V|--version         Display version and exit"
67     exit 0
68 }
69
70 TEMP=$(getopt \
71     -o i:k:m:q:t:vV \
72     --long help \
73     --long accel: \
74     --long cpu: \
75     --long initrd: \
76     --long kernel: \
77     --long machine: \
78     --long qemu: \
79     --long timeout: \
80     --long verbose \
81     --long version \
82     -n 'qemu-sanity-check' -- "$@")
83 if [ $? != 0 ]; then exit 2; fi
84 eval set -- "$TEMP"
85
86 while true; do
87     case "$1" in
88         --help)
89             usage
90             ;;
91         --accel)
92             accel="$2"
93             shift 2
94             ;;
95         --cpu)
96             cpu="$2"
97             shift 2
98             ;;
99         -i|--initrd)
100             initrd="$2"
101             shift 2
102             ;;
103         -k|--kernel)
104             kernel="$2"
105             shift 2
106             ;;
107         -m|--machine)
108             machine="$2"
109             shift 2
110             ;;
111         -q|--qemu)
112             qemu="$2"
113             shift 2
114             ;;
115         -t|--timeout)
116             timeout="$2"
117             shift 2
118             ;;
119         -v|--verbose)
120             verbose=yes
121             shift
122             ;;
123         -V|--version)
124             echo "@PACKAGE_NAME@ @PACKAGE_VERSION@"
125             exit 0
126             ;;
127         --)
128             shift
129             break
130             ;;
131         *)
132             echo "$0: internal error parsing options: $1"
133             exit 2
134             ;;
135     esac
136 done
137
138 # Locate initrd.
139 if [ ! -r "$initrd" ]; then
140     echo "$0: cannot find 'initrd', try using --initrd=/path/to/initrd"
141     echo "If you are running qemu-sanity-check without installing, then do:"
142     echo "    $0 --initrd=./initrd $@"
143     echo "The default path is '@libdir@/initrd'."
144     exit 2
145 fi
146
147 # Locate kernel if not specified.
148 if [ -z "$kernel" ]; then
149     kernel="$(ls -1dvr /boot/vmlinuz-*.$arch* 2>/dev/null | grep -v xen | head -1)"
150     if [ -z "$kernel" ]; then
151         echo "$0: cannot find a Linux kernel in /boot"
152         echo "Choose a kernel to test using --kernel=/path/to/vmlinuz"
153         exit 2
154     fi
155 fi
156 if [ ! -r "$kernel" ]; then
157     echo "$0: kernel $kernel is not readable"
158     exit 2
159 fi
160
161 # Locate qemu if not specified.
162 if [ -z "$qemu" ]; then
163     for q in @QEMU_LIST@; do
164         if "$q" --help >/dev/null 2>&1; then
165             qemu="$q"
166             break
167         fi
168     done
169     if [ -z "$qemu" ]; then
170         echo "$0: cannot find a qemu binary on the \$PATH"
171         echo "Choose a qemu binary to test using --qemu=/path/to/qemu"
172         exit 2
173     fi
174 fi
175
176 # Choose a temporary file for the output.
177 test_output="$(mktemp --suff=.out)"
178
179 # Generate the parameters for the qemu command.
180 declare -a argv
181 i=0
182 argv[$((i++))]="$qemu"
183 argv[$((i++))]="-display"
184 argv[$((i++))]="none"
185 argv[$((i++))]="-no-user-config"
186 argv[$((i++))]="-nodefaults"
187 argv[$((i++))]="-machine"
188 argv[$((i++))]="$machine${machine:+,}accel=$accel"
189 if [ "$cpu" != "" ]; then
190     argv[$((i++))]="-cpu"
191     argv[$((i++))]="$cpu"
192 fi
193 argv[$((i++))]="-m"
194 argv[$((i++))]="$memory"
195 argv[$((i++))]="-no-reboot"
196 argv[$((i++))]="-serial"
197 argv[$((i++))]="file:$test_output"
198 argv[$((i++))]="-kernel"
199 argv[$((i++))]="$kernel"
200 argv[$((i++))]="-initrd"
201 argv[$((i++))]="$initrd"
202 argv[$((i++))]="-append"
203 argv[$((i++))]="console=ttyS0 oops=panic panic=-1"
204
205 if [ "$verbose" = "yes" ]; then
206     echo "${argv[@]}"
207 fi
208
209 # Run the command.
210 timeout "$timeout" "${argv[@]}"
211 r="${PIPESTATUS[0]}"
212 if [ $r -eq 124 ]; then
213     cat "$test_output"
214     echo "$0: error: test $kernel on $qemu: timed out"
215     rm "$test_output"
216     exit 1
217 elif [ $r -ne 0 ]; then
218     cat "$test_output"
219     echo "$0: error: test $kernel on $qemu: failed"
220     rm "$test_output"
221     exit 1
222 fi
223
224 # Verify that userspace was reached.
225 if ! grep -sq "initrd started up OK" "$test_output"; then
226     cat "$test_output"
227     echo "$0: error: test $kernel on $qemu: init process did not start up"
228     rm "$test_output"
229     exit 1
230 fi
231
232 # Successful.
233 rm "$test_output"
234 exit 0