Merge "Support BuildFlags: nocumulaterpms" into devel
[tools/build.git] / build-vm-kvm
1 #
2 # kvm/qemu specific functions
3 #
4 ################################################################
5 #
6 # Copyright (c) 1995-2014 SUSE Linux Products GmbH
7 #
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License version 2 or 3 as
10 # published by the Free Software Foundation.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program (see the file COPYING); if not, write to the
19 # Free Software Foundation, Inc.,
20 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21 #
22 ################################################################
23
24 kvm_bin=/usr/bin/qemu-kvm
25 test ! -x $kvm_bin  -a -x /usr/bin/kvm && kvm_bin=/usr/bin/kvm
26 kvm_console=ttyS0
27
28 # assume virtio support by default
29 kvm_device=virtio-blk-pci
30 kvm_serial_device=
31 kvm_rng_device=virtio-rng-pci
32 kvm_options=
33
34 function complain()
35 {
36     local ex=$1; shift
37     printf "Error: %s\n" "$@" >&2
38     cleanup_and_exit $ex
39 }
40
41 kvm_check_ppc970() {
42     if ! grep -q -E '(kvm_rma_count.*kvm_hpt_count)|(kvm_hpt_count.*kvm_rma_count)' /proc/cmdline ; then 
43         echo "put kvm_rma_count=<VM number> or kvm_hpt_count=<> to your boot options"
44         cleanup_and_exit 3
45     fi
46 }
47
48 kvm_check_hugetlb() {
49     if ! grep -q "$HUGETLBFSPATH" /proc/mounts ; then
50         echo "hugetlbfs is not mounted to $HUGETLBFSPATH"
51         cleanup_and_exit 3
52     fi
53     local HUGETLBBLKSIZE=$(stat -f -c "%S" "$HUGETLBFSPATH")
54     HUGETLBBLKSIZE=$(( ${HUGETLBBLKSIZE:-0} / 1024 ))
55     if test "$HUGETLBBLKSIZE" -lt 1 -o ! -e  "/sys/kernel/mm/hugepages/hugepages-${HUGETLBBLKSIZE}kB" ; then
56         echo "could not determine hugetlbfs block size"
57         cleanup_and_exit 3
58     fi
59     local PAGES_FREE=$(cat /sys/kernel/mm/hugepages/hugepages-${HUGETLBBLKSIZE}kB/free_hugepages)
60     local PAGES_REQ=$(( ${VM_MEMSIZE:-64} * 1024 / $HUGETLBBLKSIZE ))
61     if test "$PAGES_FREE" -lt "$PAGES_REQ" ; then
62         echo "expected $PAGES_REQ to be available (have $PAGES_FREE)"
63         echo "please adjust nr_hugepages"
64         cleanup_and_exit 3
65     fi
66 }
67
68 vm_verify_options_kvm() {
69     vm_kernel=
70     vm_initrd=
71     
72     # overwrite some options for specific host architectures
73     case `uname -m` in
74         armv7l)
75             kvm_bin="/usr/bin/qemu-system-arm"
76             kvm_console=ttyAMA0
77             kvm_options="-enable-kvm -M virt -cpu host"
78             vm_kernel=/boot/zImage
79             vm_initrd=/boot/initrd
80             # prefer the guest kernel/initrd
81             test -e /boot/zImage.guest && vm_kernel=/boot/zImage.guest
82             test -e /boot/initrd.guest && vm_initrd=/boot/initrd.guest
83             kvm_device=virtio-blk-device
84             kvm_rng_device=virtio-rng-device
85             ;;
86         armv8l|aarch64)
87             kvm_bin="/usr/bin/qemu-system-aarch64"
88             kvm_console=ttyAMA0
89             vm_kernel=/boot/Image
90             vm_initrd=/boot/initrd
91             if test "${BUILD_ARCH#aarch}" != "$BUILD_ARCH" -o "${BUILD_ARCH#armv8}" != "$BUILD_ARCH"; then
92                 kvm_options="-enable-kvm -cpu host "
93                 test -e /boot/Image.guest && vm_kernel=/boot/Image.guest
94                 test -e /boot/initrd.guest && vm_initrd=/boot/initrd.guest
95             else
96                 # Running an armv7 kernel on aarch64
97                 kvm_options="-enable-kvm -cpu host,aarch64=off "
98                 # prefer the guest kernel/initrd
99                 test -e /boot/Image.guest32 && vm_kernel=/boot/Image.guest32
100                 test -e /boot/initrd.guest32 && vm_initrd=/boot/initrd.guest32
101             fi
102             # This option only exists with QEMU 2.5 or newer
103             if $kvm_bin -machine 'virt,?' 2>&1 | grep -q gic-version ; then
104                 # We want to use the host gic version in order to make use
105                 # of all available features (e.g. more than 8 CPUs) and avoid
106                 # the emulation overhead of vGICv2 on a GICv3 host.
107                 kvm_options+="-M virt,gic-version=host"
108             else
109                 kvm_options+="-M virt"
110             fi
111             kvm_device=virtio-blk-device
112             ;;
113         ppc|ppcle|ppc64|ppc64le)
114             kvm_bin="/usr/bin/qemu-system-ppc64"
115             kvm_console=hvc0
116             kvm_options="-enable-kvm -M pseries"
117             grep -q PPC970MP /proc/cpuinfo && kvm_check_ppc970
118             vm_kernel=/boot/vmlinux
119             vm_initrd=/boot/initrd
120             if test "$BUILD_ARCH" = ppc64le -a -e /boot/vmlinuxle ; then
121                 vm_kernel=/boot/vmlinuxle
122                 vm_initrd=/boot/initrdle
123             fi
124             grep -q "pSeries" /proc/cpuinfo && kvm_device=scsi-hd       # no virtio on pSeries
125             grep -q "PowerNV" /proc/cpuinfo || kvm_device=scsi-hd       # no virtio on ppc != power7 yet
126             ;;
127         s390|s390x)
128             kvm_bin="/usr/bin/qemu-system-s390x"
129             kvm_options="-enable-kvm"
130             kvm_console=hvc0
131             vm_kernel=/boot/image
132             vm_initrd=/boot/initrd
133             kvm_device=virtio-blk-ccw
134             kvm_serial_device=virtio-serial-ccw
135             kvm_rng_device=virtio-rng-ccw
136             ;;
137     esac
138
139     # check if we can run kvm
140     if ! test -r /dev/kvm -a -x "$kvm_bin" ; then
141         echo "host does not support kvm"
142         echo "either the kvm kernel-module is not loaded or kvm is not installed or hardware virtualization is deactivated in the BIOS."
143         cleanup_and_exit 3
144     fi
145
146     # check hugepages
147     test -n "$HUGETLBFSPATH" -a "$VM_TYPE" = kvm && kvm_check_hugetlb
148
149     # set kernel
150     test -n "$VM_KERNEL" && vm_kernel="$VM_KERNEL"
151     test -z "$vm_kernel" && vm_kernel=/boot/vmlinuz
152
153     # set initrd
154     test -n "$VM_INITRD" && vm_initrd="$VM_INITRD"
155     if test -z "$vm_initrd" ; then
156         # find a nice default
157         if test -e "/boot/initrd-build" ; then
158             vm_initrd="/boot/initrd-build"
159         elif test -e "/boot/initrd-virtio" ; then
160             vm_initrd="/boot/initrd-virtio"
161         else
162             vm_initrd="/boot/initrd"
163             kvm_device=ide-hd
164             # use /etc/sysconfig/kernel as indication if we have virtio
165             if test -e /etc/sysconfig/kernel ; then
166                 local im=$(INITRD_MODULES=; . /etc/sysconfig/kernel; echo "$INITRD_MODULES")
167                 if test "$im" != "${im/virtio/}" ; then
168                     kvm_device=virtio-blk-pci
169                 fi
170             fi
171         fi
172     fi
173
174     case $kvm_device in
175         virtio*)
176             qemu_rootdev=/dev/disk/by-id/virtio-0
177             VM_SWAPDEV=/dev/disk/by-id/virtio-1
178             ;;
179         *)
180             qemu_rootdev=/dev/sda
181             VM_SWAPDEV=/dev/sdb
182             ;;
183     esac
184
185     if test -n "$VM_NETOPT" -o -n "$VM_NETDEVOPT" ; then
186         if test -n "$VM_NETOPT" ; then
187            for item in "${VM_NETOPT[@]}" ; do
188               kvm_options="$kvm_options -net $item"
189            done
190         fi
191         if test -n "$VM_NETDEVOPT" ; then
192            for item in "${VM_NETDEVOPT[@]}" ; do
193               kvm_options="$kvm_options -netdev $item"
194            done
195         fi
196     fi
197
198     if test -n "$VM_DEVICEOPT" ; then
199         for item in "${VM_DEVICEOPT[@]}" ; do
200             kvm_options="$kvm_options -device $item"
201         done
202     fi
203
204     if test -n "$kvm_rng_device" ; then
205         if test -c /dev/hwrng &&
206             test -f /sys/class/misc/hw_random/rng_current &&
207             test "$(cat /sys/class/misc/hw_random/rng_current)" != none; then
208             rng_dev="/dev/hwrng"
209         else
210             rng_dev="/dev/random"
211         fi
212         kvm_options="$kvm_options -object rng-random,filename=$rng_dev,id=rng0 -device $kvm_rng_device,rng=rng0"
213     fi
214 }
215
216 vm_startup_kvm() {
217     qemu_bin="$kvm_bin"
218     qemu_args=(-drive file="$VM_IMAGE",format=raw,if=none,id=disk,cache=unsafe -device "$kvm_device",drive=disk,serial=0)
219     if [ -n "$VM_USER" ] ; then
220         getent passwd "$VM_USER" > /dev/null || complain 22 "cannot find KVM user '$VM_USER'"
221     else
222         # use qemu user by default if available
223         getent passwd qemu >/dev/null && VM_USER=qemu
224     fi
225     [ -n "$VM_USER" ] && kvm_options="$kvm_options -runas $VM_USER"
226     if test -n "$VM_SWAP" ; then
227         qemu_args=("${qemu_args[@]}" -drive file="$VM_SWAP",format=raw,if=none,id=swap,cache=unsafe -device "$kvm_device",drive=swap,serial=1)
228     fi
229     # the serial console device needs to be compiled into the target kernel
230     # which is why we can not use virtio-serial on other platforms
231     if test -n "$kvm_serial_device" ; then
232         qemu_args=("${qemu_args[@]}" -device "$kvm_serial_device" -device virtconsole,chardev=virtiocon0 -chardev stdio,id=virtiocon0)
233     elif test -n "$VM_CONSOLE_INPUT" ; then
234         qemu_args=("${qemu_args[@]}" -serial mon:stdio)
235     else
236         qemu_args=("${qemu_args[@]}" -serial stdio)
237     fi
238
239     if test -n "$BUILD_JOBS" -a "$icecream" = 0 -a -z "$BUILD_THREADS" ; then
240         qemu_args=("${qemu_args[@]}" "-smp" "$BUILD_JOBS")
241     elif test -n "$BUILD_JOBS" -a -n "$BUILD_THREADS" ; then
242         qemu_args=("${qemu_args[@]}" "-smp" "$BUILD_JOBS,threads=$BUILD_THREADS")
243     fi
244     if test "$VM_TYPE" = kvm ; then
245         test "$kvm_console" != ttyAMA0 && kvm_options="$kvm_options -cpu host"
246         test -n "$HUGETLBFSPATH" && kvm_options="$kvm_options -mem-prealloc -mem-path $HUGETLBFSPATH"
247     fi
248     qemu_rootfstype=""
249     if test -n "$VMDISK_FILESYSTEM" ; then
250         qemu_rootfstype="rootfstype=$VMDISK_FILESYSTEM"
251     fi
252     qemu_rootflags=""
253     if test -n "$VMDISK_MOUNT_OPTIONS" ; then
254         qemu_rootflags="rootflags=${VMDISK_MOUNT_OPTIONS#-o }"
255     fi
256     if test -z "$VM_NETOPT" -a -z "$VM_NETDEVOPT"; then
257         kvm_options="$kvm_options -net none"
258     fi
259     if test -n "$VM_TELNET"; then
260         kvm_options="$kvm_options -netdev user,id=telnet,hostfwd=tcp:127.0.0.1:$VM_TELNET-:23 -device e1000,netdev=telnet"
261     fi
262     set -- $qemu_bin -nodefaults -no-reboot -nographic -vga none $kvm_options \
263         -kernel $vm_kernel \
264         -initrd $vm_initrd \
265         -append "root=$qemu_rootdev $qemu_rootfstype $qemu_rootflags panic=1 quiet no-kvmclock nmi_watchdog=0 rw rd.driver.pre=binfmt_misc elevator=noop console=$kvm_console init=$vm_init_script" \
266         ${VM_MEMSIZE:+-m $VM_MEMSIZE} \
267         "${qemu_args[@]}"
268
269     if test "$PERSONALITY" != 0 ; then
270         # have to switch back to PER_LINUX to make qemu work
271         set -- linux64 "$@"
272     fi
273     export QEMU_AUDIO_DRV=none          # we do not want to have sound inside the VMs
274     echo "$@"
275     "$@"
276 }
277
278 vm_kill_kvm() {
279     if ! fuser -k -TERM "$VM_IMAGE" ; then
280         echo "could not kill build in $VM_IMAGE"
281         cleanup_and_exit 1
282     fi
283 }
284
285 vm_fixup_kvm() {
286     # check if we will use a kernel from the build root, in this case
287     # we assume the kernel does virtio
288     if test -z "$VM_KERNEL" -a -e "$BUILD_ROOT/.build.kernel.$VM_TYPE" ; then
289         # ide-hd is the non-virtio default
290         if test "$kvm_device" = ide-hd ; then
291             kvm_device=virtio-blk-pci
292             qemu_rootdev=/dev/disk/by-id/virtio-0
293             VM_SWAPDEV=/dev/disk/by-id/virtio-1
294         fi
295     fi
296 }
297
298 vm_attach_root_kvm() {
299     :
300 }
301
302 vm_attach_swap_kvm() {
303     :
304 }
305
306 vm_detach_root_kvm() {
307     :
308 }
309
310 vm_detach_swap_kvm() {
311     :
312 }
313
314 vm_cleanup_kvm() {
315     :
316 }
317