diff --git a/nova/virt/libvirt/config.py b/nova/virt/libvirt/config.py index 2a1e703d31..936eb4052e 100644 --- a/nova/virt/libvirt/config.py +++ b/nova/virt/libvirt/config.py @@ -2136,6 +2136,23 @@ class LibvirtConfigGuestVideo(LibvirtConfigGuestDevice): return dev +#RABSER +class LibvirtConfigCommandLine(LibvirtConfigObject): + def __init__(self, **kwargs): + super(LibvirtConfigCommandLine, self).__init__( + root_name='commandline', + ns_uri = "http://libvirt.org/schemas/domain/qemu/1.0", + **kwargs) + self.memsize = None + + def format_dom(self): + cmdline = super(LibvirtConfigCommandLine, self).format_dom() + + cmdline.append(etree.Element('arg', value='-fw_cfg')) + cmdline.append(etree.Element('arg', value='opt/ovmf/X-PciMmio64Mb,string='+str(self.memsize))) + return cmdline +#RABSER END + class LibvirtConfigMemoryBalloon(LibvirtConfigGuestDevice): def __init__(self, **kwargs): @@ -2945,6 +2962,9 @@ class LibvirtConfigGuest(LibvirtConfigObject): self.idmaps = [] self.perf_events = [] self.launch_security = None + #RABSER + self.cmdline = None + #RABSER END def _format_basic_props(self, root): root.append(self._text_node("uuid", self.uuid)) @@ -3041,6 +3061,12 @@ class LibvirtConfigGuest(LibvirtConfigObject): features.append(feat.format_dom()) root.append(features) + #RABSER + def _format_cmdline(self, root): + if self.cmdline is not None : + root.append(self.cmdline.format_dom()) + #RABSER END + def _format_devices(self, root): if len(self.devices) == 0: return diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 863ac60af0..d6d773f80f 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -36,6 +36,9 @@ import grp import itertools import operator import os +#RABSER +import re +#RABSER END import pwd import random import shutil @@ -7131,6 +7134,30 @@ class LibvirtDriver(driver.ComputeDriver): self._guest_add_memory_balloon(guest) + #RABSER PATCH for UEFI/PCI support + if guest.os_loader == DEFAULT_UEFI_LOADER_PATH[caps.host.cpu.arch]: + memsize = 0 + for device in guest.devices: + if device.root_name == 'hostdev' and device.type == 'pci': + pcibasepath='/sys/bus/pci/devices/' + resource_regex = re.compile('resource[0-9]+$') + + dev_dir=pcibasepath+device.domain+':'+device.bus+':'+device.slot+'.'+device.function + for path in os.scandir(dev_dir): + if path.is_file(): + if resource_regex.match(path.name): + file_stats=os.stat(dev_dir+'/'+path.name) + memsize += int(file_stats.st_size/1024/1024) + if os.path.isfile('/usr/share/OVMF/MEMFD.fd'): + if memsize > 0: + LOG.warning("adding custom X-PciMmio64Mb argument to domain") + self._guest_add_commandline(guest,memsize) + else: + LOG.warning("BEWARE: your OVMF firmware seems too old and does not supports X-PciMmio64Mb argument") + LOG.warning("Anyway, you can build the firmware by yourself following the instruction here: https://github.com/tianocore/edk2.g +it and put the *.fd files newly built in /usr/share/OVMF overwriting the old ones") + #RABSER END + if mdevs: self._guest_add_mdevs(guest, mdevs) @@ -7276,6 +7303,14 @@ class LibvirtDriver(driver.ComputeDriver): channel.target_name = "com.redhat.spice.0" guest.add_device(channel) + #RABSER add a commandline section to domain xml for UEFI/PCI support + @staticmethod + def _guest_add_commandline(guest,memsize): + cmdline = vconfig.LibvirtConfigCommandLine() + cmdline.memsize = memsize + guest.cmdline = cmdline + #RABSER END + @staticmethod def _guest_add_memory_balloon(guest): # Memory balloon device only support 'qemu/kvm' hypervisor