diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 77b1073ce7..57496a7b7e 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -8420,6 +8420,21 @@ class LibvirtConnTestCase(test.NoDBTestCase, else: self.fail('Did not find a USB host controller') + # while PPC64 should always get a USB controller, regardless of config + self.mock_get_arch.return_value = fields.Architecture.PPC64 + image_meta = objects.ImageMeta.from_dict(self.test_image_meta) + disk_info = blockinfo.get_disk_info( + CONF.libvirt.virt_type, instance_ref, image_meta) + + cfg = drvr._get_guest_config(instance_ref, [], image_meta, disk_info) + for device in cfg.devices: + if isinstance(device, vconfig.LibvirtConfigGuestUSBHostController): + # the model property should be unset, meaning auto-configured + self.assertIsNone(device.model) + break + else: + self.fail('Did not find a USB host controller') + @mock.patch.object(libvirt_driver, 'LOG') @mock.patch.object( fakelibvirt, 'VIR_PERF_PARAM_CPU_CLOCK', 'cpu_clock', create=True) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 6accf1ef14..5b933eb5df 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -5738,6 +5738,10 @@ class LibvirtDriver(driver.ComputeDriver): s390x_archs = (fields.Architecture.S390, fields.Architecture.S390X) return libvirt_utils.get_arch(image_meta) in s390x_archs + def _is_ppc64_guest(self, image_meta): + archs = (fields.Architecture.PPC64, fields.Architecture.PPC64LE) + return libvirt_utils.get_arch(image_meta) in archs + def _create_consoles_qemu_kvm(self, guest_cfg, instance, flavor, image_meta): char_dev_cls = vconfig.LibvirtConfigGuestSerial @@ -5875,8 +5879,12 @@ class LibvirtDriver(driver.ComputeDriver): cpu_config.features.add(xf) return cpu_config - def _guest_needs_usb(self, guest): + def _guest_needs_usb(self, guest, image_meta): """Evaluate devices currently attached to the guest.""" + if self._is_ppc64_guest(image_meta): + # PPC64 guests get a USB keyboard and mouse automatically + return True + for dev in guest.devices: if isinstance(dev, vconfig.LibvirtConfigGuestDisk): if dev.target_bus == 'usb': @@ -5888,7 +5896,7 @@ class LibvirtDriver(driver.ComputeDriver): return False - def _guest_add_usb_root_controller(self, guest): + def _guest_add_usb_root_controller(self, guest, image_meta): """Add USB root controller, if necessary. Note that these are added by default on x86-64. We add the controller @@ -5899,7 +5907,9 @@ class LibvirtDriver(driver.ComputeDriver): usbhost.index = 0 # an unset model means autodetect, while 'none' means don't add a # controller (x86 gets one by default) - usbhost.model = None if self._guest_needs_usb(guest) else 'none' + usbhost.model = None + if not self._guest_needs_usb(guest, image_meta): + usbhost.model = 'none' guest.add_device(usbhost) def _guest_add_pcie_root_ports(self, guest): @@ -6087,7 +6097,7 @@ class LibvirtDriver(driver.ComputeDriver): if self._guest_needs_pcie(guest, caps): self._guest_add_pcie_root_ports(guest) - self._guest_add_usb_root_controller(guest) + self._guest_add_usb_root_controller(guest, image_meta) self._guest_add_pci_devices(guest, instance)