workarounds: Add libvirt_disable_apic

This change adds a new workaround config option to allow disabling the
guest apic.

Co-authored-by: Lee Yarwood <lyarwood@redhat.com>
Related-Bug: #1939108
Change-Id: I2da867f2734b590a884b1fe1200c402cbf7e9e1c
This commit is contained in:
Sean Mooney 2020-12-08 16:42:52 +00:00 committed by Lee Yarwood
parent c2b965b793
commit ec48e1523d
4 changed files with 56 additions and 1 deletions

View File

@ -353,6 +353,16 @@ Related options:
* :oslo.config:option:`DEFAULT.instances_path`
* :oslo.config:option:`image_cache.subdirectory_name`
* :oslo.config:option:`update_resources_interval`
"""),
cfg.BoolOpt('libvirt_disable_apic',
default=False,
help="""
With some kernels initializing the guest apic can result in a kernel hang that
renders the guest unusable. This happens as a result of a kernel bug. In most
cases the correct fix it to update the guest image kernel to one that is
patched however in some cases this is not possible. This workaround allows the
emulation of an apic to be disabled per host however it is not recommended to
use outside of a CI or developer cloud.
"""),
]

View File

@ -4917,6 +4917,37 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertTrue(cfg.features[2].vapic)
self.assertEqual(hvid_hidden, cfg.features[2].vendorid_spoof)
@mock.patch.object(host.Host, 'has_min_version',
new=mock.Mock(return_value=True))
def test_get_guest_config_apic_workaround(self):
self.flags(virt_type='qemu', group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
instance_ref = objects.Instance(**self.test_instance)
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, _fake_network_info(self), image_meta, disk_info)
self.assertEqual(3, len(cfg.features))
self.assertIsInstance(
cfg.features[0], vconfig.LibvirtConfigGuestFeatureACPI)
self.assertIsInstance(
cfg.features[1], vconfig.LibvirtConfigGuestFeatureAPIC)
self.assertIsInstance(
cfg.features[2], vconfig.LibvirtConfigGuestFeatureVMCoreInfo)
self.flags(libvirt_disable_apic=True, group='workarounds')
cfg = drvr._get_guest_config(
instance_ref, _fake_network_info(self), image_meta, disk_info)
self.assertEqual(2, len(cfg.features))
self.assertIsInstance(
cfg.features[0], vconfig.LibvirtConfigGuestFeatureACPI)
self.assertIsInstance(
cfg.features[1], vconfig.LibvirtConfigGuestFeatureVMCoreInfo)
def test_get_guest_config_windows_hyperv_feature2(self):
self._test_get_guest_config_windows_hyperv()

View File

@ -5859,7 +5859,8 @@ class LibvirtDriver(driver.ComputeDriver):
if CONF.libvirt.virt_type in ('qemu', 'kvm'):
guest.features.append(vconfig.LibvirtConfigGuestFeatureACPI())
guest.features.append(vconfig.LibvirtConfigGuestFeatureAPIC())
if not CONF.workarounds.libvirt_disable_apic:
guest.features.append(vconfig.LibvirtConfigGuestFeatureAPIC())
if CONF.libvirt.virt_type in ('qemu', 'kvm') and os_type == 'windows':
hv = vconfig.LibvirtConfigGuestFeatureHyperV()

View File

@ -0,0 +1,13 @@
---
issues:
- |
Linux guest images that have known kernel bugs related to virtualized apic
initialization previously would sporadically hang. For images where the
kernel cannot be upgraded, a ``[workarounds]`` config option has been
introduced:
``[workarounds]libvirt_disable_apic``
This option is primarily intended for CI and development clouds as a bridge
for operators to mitigate the issue while they work with their upstream
image vendors.