# virtio-gpu tests # # This work is licensed under the terms of the GNU GPL, version 2 or # later. See the COPYING file in the top-level directory. from avocado_qemu import Test from avocado_qemu import BUILD_DIR from avocado_qemu import wait_for_console_pattern from avocado_qemu import exec_command_and_wait_for_pattern from avocado_qemu import is_readable_executable_file from qemu.utils import kvm_available import os import socket import subprocess ACCEL_NOT_AVAILABLE_FMT = "%s accelerator does not seem to be available" KVM_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "KVM" def pick_default_vug_bin(): relative_path = "./contrib/vhost-user-gpu/vhost-user-gpu" if is_readable_executable_file(relative_path): return relative_path bld_dir_path = os.path.join(BUILD_DIR, relative_path) if is_readable_executable_file(bld_dir_path): return bld_dir_path class VirtioGPUx86(Test): """ :avocado: tags=virtio-gpu """ KERNEL_COMMON_COMMAND_LINE = "printk.time=0 " KERNEL_URL = ( "https://archives.fedoraproject.org/pub/fedora" "/linux/releases/33/Everything/x86_64/os/images" "/pxeboot/vmlinuz" ) INITRD_URL = ( "https://archives.fedoraproject.org/pub/fedora" "/linux/releases/33/Everything/x86_64/os/images" "/pxeboot/initrd.img" ) def wait_for_console_pattern(self, success_message, vm=None): wait_for_console_pattern( self, success_message, failure_message="Kernel panic - not syncing", vm=vm, ) def test_virtio_vga_virgl(self): """ :avocado: tags=arch:x86_64 :avocado: tags=device:virtio-vga """ kernel_command_line = ( self.KERNEL_COMMON_COMMAND_LINE + "console=ttyS0 rdinit=/bin/bash" ) # FIXME: should check presence of virtio, virgl etc if not kvm_available(self.arch, self.qemu_bin): self.cancel(KVM_NOT_AVAILABLE) kernel_path = self.fetch_asset(self.KERNEL_URL) initrd_path = self.fetch_asset(self.INITRD_URL) self.vm.set_console() self.vm.add_args("-cpu", "host") self.vm.add_args("-m", "2G") self.vm.add_args("-machine", "pc,accel=kvm") self.vm.add_args("-device", "virtio-vga,virgl=on") self.vm.add_args("-display", "egl-headless") self.vm.add_args( "-kernel", kernel_path, "-initrd", initrd_path, "-append", kernel_command_line, ) try: self.vm.launch() except: # TODO: probably fails because we are missing the VirGL features self.cancel("VirGL not enabled?") self.wait_for_console_pattern("as init process") exec_command_and_wait_for_pattern( self, "/usr/sbin/modprobe virtio_gpu", "" ) self.wait_for_console_pattern("features: +virgl +edid") def test_vhost_user_vga_virgl(self): """ :avocado: tags=arch:x86_64 :avocado: tags=device:vhost-user-vga """ kernel_command_line = ( self.KERNEL_COMMON_COMMAND_LINE + "console=ttyS0 rdinit=/bin/bash" ) # FIXME: should check presence of vhost-user-gpu, virgl, memfd etc if not kvm_available(self.arch, self.qemu_bin): self.cancel(KVM_NOT_AVAILABLE) vug = pick_default_vug_bin() if not vug: self.cancel("Could not find vhost-user-gpu") kernel_path = self.fetch_asset(self.KERNEL_URL) initrd_path = self.fetch_asset(self.INITRD_URL) # Create socketpair to connect proxy and remote processes qemu_sock, vug_sock = socket.socketpair( socket.AF_UNIX, socket.SOCK_STREAM ) os.set_inheritable(qemu_sock.fileno(), True) os.set_inheritable(vug_sock.fileno(), True) self._vug_log_path = os.path.join( self.logdir, "vhost-user-gpu.log" ) self._vug_log_file = open(self._vug_log_path, "wb") self.log.info('Complete vhost-user-gpu.log file can be ' 'found at %s', self._vug_log_path) vugp = subprocess.Popen( [vug, "--virgl", "--fd=%d" % vug_sock.fileno()], stdin=subprocess.DEVNULL, stdout=self._vug_log_file, stderr=subprocess.STDOUT, shell=False, close_fds=False, ) self.vm.set_console() self.vm.add_args("-cpu", "host") self.vm.add_args("-m", "2G") self.vm.add_args("-object", "memory-backend-memfd,id=mem,size=2G") self.vm.add_args("-machine", "pc,memory-backend=mem,accel=kvm") self.vm.add_args("-chardev", "socket,id=vug,fd=%d" % qemu_sock.fileno()) self.vm.add_args("-device", "vhost-user-vga,chardev=vug") self.vm.add_args("-display", "egl-headless") self.vm.add_args( "-kernel", kernel_path, "-initrd", initrd_path, "-append", kernel_command_line, ) self.vm.launch() self.wait_for_console_pattern("as init process") exec_command_and_wait_for_pattern( self, "/usr/sbin/modprobe virtio_gpu", "" ) self.wait_for_console_pattern("features: +virgl -edid") self.vm.shutdown() qemu_sock.close() vugp.terminate() vugp.wait()