Skip to content

Commit 45a4110

Browse files
andrewbonneystephenfin
authored andcommitted
Handle disabled CPU features to fix live migration failures
When performing a live migration between hypervisors running libvirt, where one or more CPU features are disabled, nova does not take account of these. This results in migration failures as none of the available hypervisor targets appear compatible. This patch ensures that the libvirt 'disable' poicy is taken account of, at least in a basic sense, by explicitly ignoring items flagged in this way when enumerating CPU features. Closes-Bug: #1898715 Change-Id: Iaf14ca97cfac99dd280d1114123f2d4bb6292b63 (cherry picked from commit eeeca4c)
1 parent f1e4f6b commit 45a4110

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,26 @@ def test_config_simple(self):
339339
<feature name="mtrr"/>
340340
""")
341341

342+
def test_config_parse_require(self):
343+
xml = """
344+
<feature name="mtrr" policy="require"/>
345+
"""
346+
xmldoc = etree.fromstring(xml)
347+
obj = config.LibvirtConfigCPUFeature()
348+
obj.parse_dom(xmldoc)
349+
350+
self.assertEqual(obj.policy, "require")
351+
352+
def test_config_parse_disable(self):
353+
xml = """
354+
<feature name="mtrr" policy="disable"/>
355+
"""
356+
xmldoc = etree.fromstring(xml)
357+
obj = config.LibvirtConfigCPUFeature()
358+
obj.parse_dom(xmldoc)
359+
360+
self.assertEqual(obj.policy, "disable")
361+
342362

343363
class LibvirtConfigGuestCPUFeatureTest(LibvirtConfigBaseTest):
344364

@@ -437,6 +457,27 @@ def test_config_complex(self):
437457
</cpu>
438458
""")
439459

460+
def test_config_disabled_features(self):
461+
obj = config.LibvirtConfigCPU()
462+
obj.model = "Penryn"
463+
obj.vendor = "Intel"
464+
obj.arch = obj_fields.Architecture.X86_64
465+
466+
disabled_feature = config.LibvirtConfigCPUFeature("mtrr")
467+
disabled_feature.policy = "disable"
468+
obj.add_feature(disabled_feature)
469+
obj.add_feature(config.LibvirtConfigCPUFeature("apic"))
470+
471+
xml = obj.to_xml()
472+
self.assertXmlEqual(xml, """
473+
<cpu>
474+
<arch>x86_64</arch>
475+
<model>Penryn</model>
476+
<vendor>Intel</vendor>
477+
<feature name="apic"/>
478+
</cpu>
479+
""")
480+
440481
def test_only_uniq_cpu_featues(self):
441482
obj = config.LibvirtConfigCPU()
442483
obj.model = "Penryn"

nova/virt/libvirt/config.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -674,11 +674,13 @@ def __init__(self, name=None, **kwargs):
674674
**kwargs)
675675

676676
self.name = name
677+
self.policy = "require"
677678

678679
def parse_dom(self, xmldoc):
679680
super(LibvirtConfigCPUFeature, self).parse_dom(xmldoc)
680681

681682
self.name = xmldoc.get("name")
683+
self.policy = xmldoc.get("policy", "require")
682684

683685
def format_dom(self):
684686
ft = super(LibvirtConfigCPUFeature, self).format_dom()
@@ -730,7 +732,8 @@ def parse_dom(self, xmldoc):
730732
elif c.tag == "feature":
731733
f = LibvirtConfigCPUFeature()
732734
f.parse_dom(c)
733-
self.add_feature(f)
735+
if f.policy != "disable":
736+
self.add_feature(f)
734737

735738
def format_dom(self):
736739
cpu = super(LibvirtConfigCPU, self).format_dom()
@@ -753,7 +756,8 @@ def format_dom(self):
753756

754757
# sorting the features to allow more predictable tests
755758
for f in sorted(self.features, key=lambda x: x.name):
756-
cpu.append(f.format_dom())
759+
if f.policy != "disable":
760+
cpu.append(f.format_dom())
757761

758762
return cpu
759763

0 commit comments

Comments
 (0)