79372eda296dc79556cb28d5e4e59e9ef21030ca
[qemu-sanity-check.git] / src / 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 console=ttyS0
33 machine=
34
35 # Both libguestfs and virt-manager choose cpu=host when we think that
36 # KVM is available, and default otherwise.  Although testing for KVM
37 # is hairy, I found that on aarch64 it can fail unless we choose
38 # cpu=host for KVM.
39 if test -r /dev/kvm; then
40     cpu=host
41 fi
42
43 # Default machine and CPU type depends on arch.  You can override this
44 # using -m|--machine and --cpu options.
45 case "$canonical_arch" in
46     arm*)
47         console=ttyAMA0
48         machine=virt ;;
49     aarch*)
50         console=ttyAMA0
51         if [ "$cpu" = "" ]; then cpu=cortex-a57; fi
52         machine=virt ;;
53     s390*)
54         console=ttysclp0 ;;
55 esac
56
57 # Handle command line parsing.
58
59 function usage {
60     echo "qemu-sanity-check [options]"
61     echo "Options:"
62     echo "  --help               Display this help"
63     echo "  --accel=[kvm|tcg]    Force KVM or software emulation"
64     echo "  --cpu=cpu            Set CPU"
65     echo "  -i|--initrd=initrd   Set location of initramfs"
66     echo "  -k|--kernel=vmlinuz  Set location of kernel"
67     echo "  -m|--machine=machine Set machine type"
68     echo "  -q|--qemu=qemu       Set location of qemu/KVM binary"
69     echo "  -t|--timeout=timeout Set the timeout"
70     echo "  -v|--verbose         Verbose output"
71     echo "  -V|--version         Display version and exit"
72     exit 0
73 }
74
75 TEMP=$(getopt \
76     -o i:k:m:q:t:vV \
77     --long help \
78     --long accel: \
79     --long cpu: \
80     --long initrd: \
81     --long kernel: \
82     --long machine: \
83     --long qemu: \
84     --long timeout: \
85     --long verbose \
86     --long version \
87     -n 'qemu-sanity-check' -- "$@")
88 if [ $? != 0 ]; then exit 2; fi
89 eval set -- "$TEMP"
90
91 while true; do
92     case "$1" in
93         --help)
94             usage
95             ;;
96         --accel)
97             accel="$2"
98             shift 2
99             ;;
100         --cpu)
101             cpu="$2"
102             shift 2
103             ;;
104         -i|--initrd)
105             initrd="$2"
106             shift 2
107             ;;
108         -k|--kernel)
109             kernel="$2"
110             shift 2
111             ;;
112         -m|--machine)
113             machine="$2"
114             shift 2
115             ;;
116         -q|--qemu)
117             qemu="$2"
118             shift 2
119             ;;
120         -t|--timeout)
121             timeout="$2"
122             shift 2
123             ;;
124         -v|--verbose)
125             verbose=yes
126             shift
127             ;;
128         -V|--version)
129             echo "@PACKAGE_NAME@ @PACKAGE_VERSION@"
130             exit 0
131             ;;
132         --)
133             shift
134             break
135             ;;
136         *)
137             echo "$0: internal error parsing options: $1"
138             exit 2
139             ;;
140     esac
141 done
142
143 # Locate initrd.
144 if [ ! -r "$initrd" ]; then
145     echo "$0: cannot find 'initrd', try using --initrd=/path/to/initrd"
146     echo "If you are running qemu-sanity-check without installing, then do:"
147     echo "    $0 --initrd=./initrd $@"
148     echo "The default path is '@libdir@/initrd'."
149     exit 2
150 fi
151
152 # Locate kernel if not specified.
153 if [ -z "$kernel" ]; then
154     kernel="$(ls -1dvr /boot/vmlinuz-*.$arch* 2>/dev/null | grep -v xen | head -1)"
155     if [ -z "$kernel" ]; then
156         echo "$0: cannot find a Linux kernel in /boot"
157         echo "Choose a kernel to test using --kernel=/path/to/vmlinuz"
158         exit 2
159     fi
160 fi
161 if [ ! -r "$kernel" ]; then
162     echo "$0: kernel $kernel is not readable"
163     exit 2
164 fi
165
166 # Locate qemu if not specified.
167 if [ -z "$qemu" ]; then
168     for q in @QEMU_LIST@; do
169         if "$q" --help >/dev/null 2>&1; then
170             qemu="$q"
171             break
172         fi
173     done
174     if [ -z "$qemu" ]; then
175         echo "$0: cannot find a qemu binary on the \$PATH"
176         echo "Choose a qemu binary to test using --qemu=/path/to/qemu"
177         exit 2
178     fi
179 fi
180
181 # Choose a temporary file for the output.
182 test_output="$(mktemp --suff=.out)"
183
184 # Generate the parameters for the qemu command.
185 declare -a argv
186 i=0
187 argv[$((i++))]="$qemu"
188 argv[$((i++))]="-display"
189 argv[$((i++))]="none"
190 argv[$((i++))]="-no-user-config"
191 argv[$((i++))]="-nodefaults"
192 argv[$((i++))]="-machine"
193 argv[$((i++))]="$machine${machine:+,}accel=$accel"
194 if [ "$cpu" != "" ]; then
195     argv[$((i++))]="-cpu"
196     argv[$((i++))]="$cpu"
197 fi
198 argv[$((i++))]="-m"
199 argv[$((i++))]="$memory"
200 argv[$((i++))]="-no-reboot"
201 argv[$((i++))]="-serial"
202 argv[$((i++))]="file:$test_output"
203 argv[$((i++))]="-kernel"
204 argv[$((i++))]="$kernel"
205 argv[$((i++))]="-initrd"
206 argv[$((i++))]="$initrd"
207 argv[$((i++))]="-append"
208 argv[$((i++))]="console=$console oops=panic panic=-1"
209
210 if [ "$verbose" = "yes" ]; then
211     echo "${argv[@]}"
212 fi
213
214 # Run the command.
215 timeout "$timeout" "${argv[@]}"
216 r="${PIPESTATUS[0]}"
217 if [ $r -eq 124 ]; then
218     cat "$test_output"
219     echo "$0: error: test $kernel on $qemu: timed out"
220     rm "$test_output"
221     exit 1
222 elif [ $r -ne 0 ]; then
223     cat "$test_output"
224     echo "$0: error: test $kernel on $qemu: failed"
225     rm "$test_output"
226     exit 1
227 fi
228
229 # Verify that userspace was reached.
230 if ! grep -sq "initrd started up OK" "$test_output"; then
231     cat "$test_output"
232     echo "$0: error: test $kernel on $qemu: init process did not start up"
233     rm "$test_output"
234     exit 1
235 fi
236
237 # Successful.
238 rm "$test_output"
239 exit 0