libvirt: use 'host-passthrough' as default on AArch64

Nova is assuming 'host-model' for KVM/QEMU setup.

On AArch64 it results in "libvirtError: unsupported configuration: CPU
mode 'host-model' for aarch64 kvm domain on aarch64 host is not
supported by hypervisor" message.

AArch64 lacks 'host-model' support because neither libvirt nor QEMU
are able to tell what the host CPU model exactly is. And there is no
CPU description code for ARM(64) at this point.

So instead we fallback to 'host-passthrough' to get VM instances
running. This will completely break live migration, *unless* all the
Compute nodes (running libvirtd) have *identical* CPUs.

Small summary: https://marcin.juszkiewicz.com.pl/2018/01/04/today-i-was-fighting-with-nova-no-idea-who-won/

Closes-bug: #1741230

Co-authored-by: Kevin Zhao <Kevin.Zhao@arm.com>
Co-authored-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>

Change-Id: Iafb5f1790d68489db73b9f0549333108c6426a00
This commit is contained in:
Marcin Juszkiewicz 2018-01-03 17:44:27 +01:00 committed by Stephen Finucane
parent 525c90c27e
commit 8bc7b950b7
3 changed files with 62 additions and 1 deletions

View File

@ -5826,6 +5826,38 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual(conf.cpu.cores, 1)
self.assertEqual(conf.cpu.threads, 1)
def test_get_guest_cpu_config_host_passthrough_aarch64(self):
expected = {
fields.Architecture.X86_64: "host-model",
fields.Architecture.I686: "host-model",
fields.Architecture.PPC: "host-model",
fields.Architecture.PPC64: "host-model",
fields.Architecture.ARMV7: "host-model",
fields.Architecture.AARCH64: "host-passthrough",
}
for guestarch, expect_mode in expected.items():
caps = vconfig.LibvirtConfigCaps()
caps.host = vconfig.LibvirtConfigCapsHost()
caps.host.cpu = vconfig.LibvirtConfigCPU()
caps.host.cpu.arch = guestarch
with mock.patch.object(host.Host, "get_capabilities",
return_value=caps):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
if caps.host.cpu.arch == fields.Architecture.AARCH64:
drvr._has_uefi_support = mock.Mock(return_value=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)
conf = drvr._get_guest_config(instance_ref,
_fake_network_info(self, 1),
image_meta, disk_info)
self.assertIsInstance(conf.cpu,
vconfig.LibvirtConfigGuestCPU)
self.assertEqual(conf.cpu.mode, expect_mode)
def test_get_guest_cpu_config_host_model(self):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
instance_ref = objects.Instance(**self.test_instance)

View File

@ -3551,7 +3551,23 @@ class LibvirtDriver(driver.ComputeDriver):
if (CONF.libvirt.virt_type == "kvm" or
CONF.libvirt.virt_type == "qemu"):
if mode is None:
mode = "host-model"
caps = self._host.get_capabilities()
# AArch64 lacks 'host-model' support because neither libvirt
# nor QEMU are able to tell what the host CPU model exactly is.
# And there is no CPU description code for ARM(64) at this
# point.
# Also worth noting: 'host-passthrough' mode will completely
# break live migration, *unless* all the Compute nodes (running
# libvirtd) have *identical* CPUs.
if caps.host.cpu.arch == fields.Architecture.AARCH64:
mode = "host-passthrough"
LOG.info('CPU mode "host-passthrough" was chosen. Live '
'migration can break unless all compute nodes '
'have identical cpus. AArch64 does not support '
'other modes.')
else:
mode = "host-model"
if mode == "none":
return vconfig.LibvirtConfigGuestCPU()
else:

View File

@ -0,0 +1,13 @@
---
upgrade:
- |
On AArch64 architecture ``cpu_mode`` for libvirt is set to ``host-passthrough``
by default.
AArch64 currently lacks ``host-model`` support because neither libvirt nor
QEMU are able to tell what the host CPU model exactly is and there is no
CPU description code for ARM(64) at this point.
.. warning:: ``host-passthrough`` mode will completely break live
migration, *unless* all the Compute nodes (running libvirtd) have
*identical* CPUs.