workarounds: Add libvirt_disable_apic

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

NOTE(lyarwood): Conflict caused by I66a8e94f6d04cc89785646aa9c3e138f22a51f60
not being present in stable/wallaby (test_driver.py), and
Ie904d1513b5cf76d6d5f6877545e8eb378dd5499 merged in different order in
different branches (workarounds.py).

Conflicts:
    nova/tests/unit/virt/libvirt/test_driver.py
    nova/conf/workarounds.py

Co-authored-by: Lee Yarwood <lyarwood@redhat.com>
Related-Bug: #1939108
Change-Id: I2da867f2734b590a884b1fe1200c402cbf7e9e1c
(cherry picked from commit ec48e1523d)
This commit is contained in:
Sean Mooney 2020-12-08 16:42:52 +00:00 committed by Elod Illes
parent a7d086618c
commit 80572cef67
4 changed files with 52 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.
"""),
cfg.ListOpt('wait_for_vif_plugged_event_during_hard_reboot',
item_type=cfg.types.String(

View File

@ -4909,6 +4909,33 @@ 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(2, len(cfg.features))
self.assertIsInstance(
cfg.features[0], vconfig.LibvirtConfigGuestFeatureACPI)
self.assertIsInstance(
cfg.features[1], vconfig.LibvirtConfigGuestFeatureAPIC)
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(1, len(cfg.features))
self.assertIsInstance(
cfg.features[0], vconfig.LibvirtConfigGuestFeatureACPI)
def test_get_guest_config_windows_hyperv_feature2(self):
self._test_get_guest_config_windows_hyperv()

View File

@ -5867,7 +5867,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.