Skip to content

Commit e44b1a9

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "libvirt: Add a workaround to skip compareCPU() on destination"
2 parents 61b161e + 267a406 commit e44b1a9

File tree

4 files changed

+61
-9
lines changed

4 files changed

+61
-9
lines changed

nova/conf/workarounds.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,14 @@
401401
Related options:
402402
403403
* :oslo.config:option:`quota.driver`
404+
"""),
405+
cfg.BoolOpt('skip_cpu_compare_on_dest',
406+
default=False,
407+
help="""
408+
With the libvirt driver, during live migration, skip comparing guest CPU
409+
with the destination host. When using QEMU >= 2.9 and libvirt >=
410+
4.4.0, libvirt will do the correct thing with respect to checking CPU
411+
compatibility on the destination host during live migration.
404412
"""),
405413
]
406414

nova/tests/unit/virt/libvirt/test_driver.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10915,6 +10915,25 @@ def test_check_can_live_migrate_guest_cpu_none_model(
1091510915
'serial_listen_addr': None},
1091610916
result.obj_to_primitive()['nova_object.data'])
1091710917

10918+
@mock.patch(
10919+
'nova.network.neutron.API.has_port_binding_extension',
10920+
new=mock.Mock(return_value=False))
10921+
@mock.patch.object(libvirt_driver.LibvirtDriver,
10922+
'_create_shared_storage_test_file',
10923+
return_value='fake')
10924+
@mock.patch.object(libvirt_driver.LibvirtDriver, '_compare_cpu')
10925+
def test_check_can_live_migrate_guest_cpu_none_model_skip_compare(
10926+
self, mock_cpu, mock_test_file):
10927+
self.flags(group='workarounds', skip_cpu_compare_on_dest=True)
10928+
instance_ref = objects.Instance(**self.test_instance)
10929+
instance_ref.vcpu_model = test_vcpu_model.fake_vcpumodel
10930+
instance_ref.vcpu_model.model = None
10931+
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
10932+
compute_info = {'cpu_info': 'asdf', 'disk_available_least': 1}
10933+
drvr.check_can_live_migrate_destination(
10934+
self.context, instance_ref, compute_info, compute_info)
10935+
mock_cpu.assert_not_called()
10936+
1091810937
@mock.patch(
1091910938
'nova.network.neutron.API.has_port_binding_extension',
1092010939
new=mock.Mock(return_value=False))

nova/virt/libvirt/driver.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9330,15 +9330,16 @@ def check_can_live_migrate_destination(self, context, instance,
93309330
disk_available_mb = (
93319331
(disk_available_gb * units.Ki) - CONF.reserved_host_disk_mb)
93329332

9333-
# Compare CPU
9334-
try:
9335-
if not instance.vcpu_model or not instance.vcpu_model.model:
9336-
source_cpu_info = src_compute_info['cpu_info']
9337-
self._compare_cpu(None, source_cpu_info, instance)
9338-
else:
9339-
self._compare_cpu(instance.vcpu_model, None, instance)
9340-
except exception.InvalidCPUInfo as e:
9341-
raise exception.MigrationPreCheckError(reason=e)
9333+
if not CONF.workarounds.skip_cpu_compare_on_dest:
9334+
# Compare CPU
9335+
try:
9336+
if not instance.vcpu_model or not instance.vcpu_model.model:
9337+
source_cpu_info = src_compute_info['cpu_info']
9338+
self._compare_cpu(None, source_cpu_info, instance)
9339+
else:
9340+
self._compare_cpu(instance.vcpu_model, None, instance)
9341+
except exception.InvalidCPUInfo as e:
9342+
raise exception.MigrationPreCheckError(reason=e)
93429343

93439344
# Create file on storage, to be checked on source host
93449345
filename = self._create_shared_storage_test_file(instance)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
issues:
3+
- |
4+
Nova's use of libvirt's compareCPU() API served its purpose over the
5+
years, but its design limitations break live migration in subtle
6+
ways. For example, the compareCPU() API compares against the host
7+
physical CPUID. Some of the features from this CPUID aren not
8+
exposed by KVM, and then there are some features that KVM emulates
9+
that are not in the host CPUID. The latter can cause bogus live
10+
migration failures.
11+
12+
With QEMU >=2.9 and libvirt >= 4.4.0, libvirt will do the right
13+
thing in terms of CPU compatibility checks on the destination host
14+
during live migration. Nova satisfies these minimum version
15+
requirements by a good margin. So, this workaround provides a way to
16+
skip the CPU comparison check on the destination host before
17+
migrating a guest, and let libvirt handle it correctly.
18+
19+
This workaround will be deprecated and removed once Nova replaces
20+
the older libvirt APIs with their newer counterparts. The work is
21+
being tracked via this `blueprint
22+
cpu-selection-with-hypervisor-consideration`_.
23+
24+
.. _blueprint cpu-selection-with-hypervisor-consideration: https://blueprints.launchpad.net/nova/+spec/cpu-selection-with-hypervisor-consideration

0 commit comments

Comments
 (0)