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:
@@ -353,6 +353,16 @@ Related options:
|
|||||||
* :oslo.config:option:`DEFAULT.instances_path`
|
* :oslo.config:option:`DEFAULT.instances_path`
|
||||||
* :oslo.config:option:`image_cache.subdirectory_name`
|
* :oslo.config:option:`image_cache.subdirectory_name`
|
||||||
* :oslo.config:option:`update_resources_interval`
|
* :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.
|
||||||
"""),
|
"""),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@@ -4917,6 +4917,37 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
self.assertTrue(cfg.features[2].vapic)
|
self.assertTrue(cfg.features[2].vapic)
|
||||||
self.assertEqual(hvid_hidden, cfg.features[2].vendorid_spoof)
|
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):
|
def test_get_guest_config_windows_hyperv_feature2(self):
|
||||||
self._test_get_guest_config_windows_hyperv()
|
self._test_get_guest_config_windows_hyperv()
|
||||||
|
|
||||||
|
@@ -5859,7 +5859,8 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||||||
|
|
||||||
if CONF.libvirt.virt_type in ('qemu', 'kvm'):
|
if CONF.libvirt.virt_type in ('qemu', 'kvm'):
|
||||||
guest.features.append(vconfig.LibvirtConfigGuestFeatureACPI())
|
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':
|
if CONF.libvirt.virt_type in ('qemu', 'kvm') and os_type == 'windows':
|
||||||
hv = vconfig.LibvirtConfigGuestFeatureHyperV()
|
hv = vconfig.LibvirtConfigGuestFeatureHyperV()
|
||||||
|
@@ -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.
|
Reference in New Issue
Block a user