qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio
at master 231 lines 7.5 kB view raw
1# Functional test that boots a complete Linux system via a cloud image 2# 3# Copyright (c) 2018-2020 Red Hat, Inc. 4# 5# Author: 6# Cleber Rosa <crosa@redhat.com> 7# 8# This work is licensed under the terms of the GNU GPL, version 2 or 9# later. See the COPYING file in the top-level directory. 10 11import os 12 13from avocado_qemu import Test, BUILD_DIR 14 15from qemu.accel import kvm_available 16from qemu.accel import tcg_available 17 18from avocado.utils import cloudinit 19from avocado.utils import network 20from avocado.utils import vmimage 21from avocado.utils import datadrainer 22from avocado.utils.path import find_command 23 24ACCEL_NOT_AVAILABLE_FMT = "%s accelerator does not seem to be available" 25KVM_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "KVM" 26TCG_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "TCG" 27 28 29class BootLinuxBase(Test): 30 def download_boot(self): 31 self.log.debug('Looking for and selecting a qemu-img binary to be ' 32 'used to create the bootable snapshot image') 33 # If qemu-img has been built, use it, otherwise the system wide one 34 # will be used. If none is available, the test will cancel. 35 qemu_img = os.path.join(BUILD_DIR, 'qemu-img') 36 if not os.path.exists(qemu_img): 37 qemu_img = find_command('qemu-img', False) 38 if qemu_img is False: 39 self.cancel('Could not find "qemu-img", which is required to ' 40 'create the bootable image') 41 vmimage.QEMU_IMG = qemu_img 42 43 self.log.info('Downloading/preparing boot image') 44 # Fedora 31 only provides ppc64le images 45 image_arch = self.arch 46 if image_arch == 'ppc64': 47 image_arch = 'ppc64le' 48 try: 49 boot = vmimage.get( 50 'fedora', arch=image_arch, version='31', 51 checksum=self.chksum, 52 algorithm='sha256', 53 cache_dir=self.cache_dirs[0], 54 snapshot_dir=self.workdir) 55 except: 56 self.cancel('Failed to download/prepare boot image') 57 return boot.path 58 59 def download_cloudinit(self): 60 self.log.info('Preparing cloudinit image') 61 try: 62 cloudinit_iso = os.path.join(self.workdir, 'cloudinit.iso') 63 self.phone_home_port = network.find_free_port() 64 cloudinit.iso(cloudinit_iso, self.name, 65 username='root', 66 password='password', 67 # QEMU's hard coded usermode router address 68 phone_home_host='10.0.2.2', 69 phone_home_port=self.phone_home_port) 70 except Exception: 71 self.cancel('Failed to prepared cloudinit image') 72 return cloudinit_iso 73 74class BootLinux(BootLinuxBase): 75 """ 76 Boots a Linux system, checking for a successful initialization 77 """ 78 79 timeout = 900 80 chksum = None 81 82 def setUp(self): 83 super(BootLinux, self).setUp() 84 self.vm.add_args('-smp', '2') 85 self.vm.add_args('-m', '1024') 86 self.prepare_boot() 87 self.prepare_cloudinit() 88 89 def prepare_boot(self): 90 path = self.download_boot() 91 self.vm.add_args('-drive', 'file=%s' % path) 92 93 def prepare_cloudinit(self): 94 cloudinit_iso = self.download_cloudinit() 95 self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso) 96 97 def launch_and_wait(self): 98 self.vm.set_console() 99 self.vm.launch() 100 console_drainer = datadrainer.LineLogger(self.vm.console_socket.fileno(), 101 logger=self.log.getChild('console')) 102 console_drainer.start() 103 self.log.info('VM launched, waiting for boot confirmation from guest') 104 cloudinit.wait_for_phone_home(('0.0.0.0', self.phone_home_port), self.name) 105 106 107class BootLinuxX8664(BootLinux): 108 """ 109 :avocado: tags=arch:x86_64 110 """ 111 112 chksum = 'e3c1b309d9203604922d6e255c2c5d098a309c2d46215d8fc026954f3c5c27a0' 113 114 def test_pc_i440fx_tcg(self): 115 """ 116 :avocado: tags=machine:pc 117 :avocado: tags=accel:tcg 118 """ 119 if not tcg_available(self.qemu_bin): 120 self.cancel(TCG_NOT_AVAILABLE) 121 self.vm.add_args("-accel", "tcg") 122 self.launch_and_wait() 123 124 def test_pc_i440fx_kvm(self): 125 """ 126 :avocado: tags=machine:pc 127 :avocado: tags=accel:kvm 128 """ 129 if not kvm_available(self.arch, self.qemu_bin): 130 self.cancel(KVM_NOT_AVAILABLE) 131 self.vm.add_args("-accel", "kvm") 132 self.launch_and_wait() 133 134 def test_pc_q35_tcg(self): 135 """ 136 :avocado: tags=machine:q35 137 :avocado: tags=accel:tcg 138 """ 139 if not tcg_available(self.qemu_bin): 140 self.cancel(TCG_NOT_AVAILABLE) 141 self.vm.add_args("-accel", "tcg") 142 self.launch_and_wait() 143 144 def test_pc_q35_kvm(self): 145 """ 146 :avocado: tags=machine:q35 147 :avocado: tags=accel:kvm 148 """ 149 if not kvm_available(self.arch, self.qemu_bin): 150 self.cancel(KVM_NOT_AVAILABLE) 151 self.vm.add_args("-accel", "kvm") 152 self.launch_and_wait() 153 154 155class BootLinuxAarch64(BootLinux): 156 """ 157 :avocado: tags=arch:aarch64 158 :avocado: tags=machine:virt 159 :avocado: tags=machine:gic-version=2 160 """ 161 162 chksum = '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49' 163 164 def add_common_args(self): 165 self.vm.add_args('-bios', 166 os.path.join(BUILD_DIR, 'pc-bios', 167 'edk2-aarch64-code.fd')) 168 self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0') 169 self.vm.add_args('-object', 'rng-random,id=rng0,filename=/dev/urandom') 170 171 def test_virt_tcg(self): 172 """ 173 :avocado: tags=accel:tcg 174 :avocado: tags=cpu:max 175 """ 176 if not tcg_available(self.qemu_bin): 177 self.cancel(TCG_NOT_AVAILABLE) 178 self.vm.add_args("-accel", "tcg") 179 self.vm.add_args("-cpu", "max") 180 self.vm.add_args("-machine", "virt,gic-version=2") 181 self.add_common_args() 182 self.launch_and_wait() 183 184 def test_virt_kvm(self): 185 """ 186 :avocado: tags=accel:kvm 187 :avocado: tags=cpu:host 188 """ 189 if not kvm_available(self.arch, self.qemu_bin): 190 self.cancel(KVM_NOT_AVAILABLE) 191 self.vm.add_args("-accel", "kvm") 192 self.vm.add_args("-cpu", "host") 193 self.vm.add_args("-machine", "virt,gic-version=2") 194 self.add_common_args() 195 self.launch_and_wait() 196 197 198class BootLinuxPPC64(BootLinux): 199 """ 200 :avocado: tags=arch:ppc64 201 """ 202 203 chksum = '7c3528b85a3df4b2306e892199a9e1e43f991c506f2cc390dc4efa2026ad2f58' 204 205 def test_pseries_tcg(self): 206 """ 207 :avocado: tags=machine:pseries 208 :avocado: tags=accel:tcg 209 """ 210 if not tcg_available(self.qemu_bin): 211 self.cancel(TCG_NOT_AVAILABLE) 212 self.vm.add_args("-accel", "tcg") 213 self.launch_and_wait() 214 215 216class BootLinuxS390X(BootLinux): 217 """ 218 :avocado: tags=arch:s390x 219 """ 220 221 chksum = '4caaab5a434fd4d1079149a072fdc7891e354f834d355069ca982fdcaf5a122d' 222 223 def test_s390_ccw_virtio_tcg(self): 224 """ 225 :avocado: tags=machine:s390-ccw-virtio 226 :avocado: tags=accel:tcg 227 """ 228 if not tcg_available(self.qemu_bin): 229 self.cancel(TCG_NOT_AVAILABLE) 230 self.vm.add_args("-accel", "tcg") 231 self.launch_and_wait()