Skip to content

Commit db0f754

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "libvirt: At start-up rework compareCPU() usage with a workaround" into stable/zed
2 parents d4e156e + 1e1e404 commit db0f754

File tree

3 files changed

+46
-30
lines changed

3 files changed

+46
-30
lines changed

nova/conf/workarounds.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,13 @@
410410
4.4.0, libvirt will do the correct thing with respect to checking CPU
411411
compatibility on the destination host during live migration.
412412
"""),
413+
cfg.BoolOpt('skip_cpu_compare_at_startup',
414+
default=False,
415+
help="""
416+
This will skip the CPU comparison call at the startup of Compute
417+
service and lets libvirt handle it.
418+
"""),
419+
413420
cfg.BoolOpt(
414421
'skip_hypervisor_version_check_on_lm',
415422
default=False,

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

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,22 @@ def test__check_cpu_compatibility_advance_model(self, mocked_compare):
13311331
self.assertRaises(exception.InvalidCPUInfo,
13321332
drvr.init_host, "dummyhost")
13331333

1334+
@mock.patch.object(libvirt_driver.LibvirtDriver,
1335+
'_register_all_undefined_instance_details',
1336+
new=mock.Mock())
1337+
@mock.patch('nova.virt.libvirt.host.libvirt.Connection.compareCPU')
1338+
def test__check_cpu_compatibility_skip_compare_at_init(
1339+
self, mocked_compare
1340+
):
1341+
self.flags(group='workarounds', skip_cpu_compare_at_startup=True)
1342+
self.flags(cpu_mode="custom",
1343+
cpu_models=["Icelake-Server-noTSX"],
1344+
cpu_model_extra_flags = ["-mpx"],
1345+
group="libvirt")
1346+
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
1347+
drvr.init_host("dummyhost")
1348+
mocked_compare.assert_not_called()
1349+
13341350
@mock.patch.object(libvirt_driver.LibvirtDriver,
13351351
'_register_all_undefined_instance_details',
13361352
new=mock.Mock())
@@ -1344,7 +1360,7 @@ def test__check_cpu_compatibility_with_flag(self):
13441360

13451361
@mock.patch('nova.virt.libvirt.host.libvirt.Connection.compareCPU')
13461362
def test__check_cpu_compatibility_advance_flag(self, mocked_compare):
1347-
mocked_compare.side_effect = (2, 0)
1363+
mocked_compare.side_effect = (-1, 0)
13481364
self.flags(cpu_mode="custom",
13491365
cpu_models=["qemu64"],
13501366
cpu_model_extra_flags = ["avx", "avx2"],
@@ -1357,7 +1373,7 @@ def test__check_cpu_compatibility_advance_flag(self, mocked_compare):
13571373
def test__check_cpu_compatibility_wrong_flag(self, mocked_compare):
13581374
# here, and in the surrounding similar tests, the non-zero error
13591375
# code in the compareCPU() side effect indicates error
1360-
mocked_compare.side_effect = (2, 0)
1376+
mocked_compare.side_effect = (-1, 0)
13611377
self.flags(cpu_mode="custom",
13621378
cpu_models=["Broadwell-noTSX"],
13631379
cpu_model_extra_flags = ["a v x"],
@@ -1370,7 +1386,7 @@ def test__check_cpu_compatibility_wrong_flag(self, mocked_compare):
13701386
def test__check_cpu_compatibility_enabled_and_disabled_flags(
13711387
self, mocked_compare
13721388
):
1373-
mocked_compare.side_effect = (2, 0)
1389+
mocked_compare.side_effect = (-1, 0)
13741390
self.flags(
13751391
cpu_mode="custom",
13761392
cpu_models=["Cascadelake-Server"],

nova/virt/libvirt/driver.py

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -984,33 +984,26 @@ def _check_cpu_compatibility(self):
984984
msg = _("The cpu_models option is required when cpu_mode=custom")
985985
raise exception.Invalid(msg)
986986

987-
cpu = vconfig.LibvirtConfigGuestCPU()
988-
for model in models:
989-
cpu.model = self._get_cpu_model_mapping(model)
990-
try:
991-
self._compare_cpu(cpu, self._get_cpu_info(), None)
992-
except exception.InvalidCPUInfo as e:
993-
msg = (_("Configured CPU model: %(model)s is not "
994-
"compatible with host CPU. Please correct your "
995-
"config and try again. %(e)s") % {
996-
'model': model, 'e': e})
997-
raise exception.InvalidCPUInfo(msg)
998-
999-
# Use guest CPU model to check the compatibility between guest CPU and
1000-
# configured extra_flags
1001-
cpu = vconfig.LibvirtConfigGuestCPU()
1002-
cpu.model = self._host.get_capabilities().host.cpu.model
1003-
for flag in set(x.lower() for x in CONF.libvirt.cpu_model_extra_flags):
1004-
cpu_feature = self._prepare_cpu_flag(flag)
1005-
cpu.add_feature(cpu_feature)
1006-
try:
1007-
self._compare_cpu(cpu, self._get_cpu_info(), None)
1008-
except exception.InvalidCPUInfo as e:
1009-
msg = (_("Configured extra flag: %(flag)s it not correct, or "
1010-
"the host CPU does not support this flag. Please "
1011-
"correct the config and try again. %(e)s") % {
1012-
'flag': flag, 'e': e})
1013-
raise exception.InvalidCPUInfo(msg)
987+
if not CONF.workarounds.skip_cpu_compare_at_startup:
988+
# Use guest CPU model to check the compatibility between
989+
# guest CPU and configured extra_flags
990+
for model in models:
991+
cpu = vconfig.LibvirtConfigGuestCPU()
992+
cpu.model = self._get_cpu_model_mapping(model)
993+
for flag in set(x.lower() for
994+
x in CONF.libvirt.cpu_model_extra_flags):
995+
cpu_feature = self._prepare_cpu_flag(flag)
996+
cpu.add_feature(cpu_feature)
997+
try:
998+
self._compare_cpu(cpu, self._get_cpu_info(), None)
999+
except exception.InvalidCPUInfo as e:
1000+
msg = (_("Configured CPU model: %(model)s "
1001+
"and CPU Flags %(flags)s ar not "
1002+
"compatible with host CPU. Please correct your "
1003+
"config and try again. %(e)s") % {
1004+
'model': model, 'e': e,
1005+
'flags': CONF.libvirt.cpu_model_extra_flags})
1006+
raise exception.InvalidCPUInfo(msg)
10141007

10151008
def _check_vtpm_support(self) -> None:
10161009
# TODO(efried): A key manager must be configured to create/retrieve

0 commit comments

Comments
 (0)