Skip to content

Commit

Permalink
Handle disabled CPU features to fix live migration failures
Browse files Browse the repository at this point in the history
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)
(cherry picked from commit 45a4110)
  • Loading branch information
andrewbonney authored and mgariepy committed Nov 12, 2020
1 parent 29425d6 commit b6c4731
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 2 deletions.
41 changes: 41 additions & 0 deletions nova/tests/unit/virt/libvirt/test_config.py
Expand Up @@ -338,6 +338,26 @@ def test_config_simple(self):
<feature name="mtrr"/>
""")

def test_config_parse_require(self):
xml = """
<feature name="mtrr" policy="require"/>
"""
xmldoc = etree.fromstring(xml)
obj = config.LibvirtConfigCPUFeature()
obj.parse_dom(xmldoc)

self.assertEqual(obj.policy, "require")

def test_config_parse_disable(self):
xml = """
<feature name="mtrr" policy="disable"/>
"""
xmldoc = etree.fromstring(xml)
obj = config.LibvirtConfigCPUFeature()
obj.parse_dom(xmldoc)

self.assertEqual(obj.policy, "disable")


class LibvirtConfigGuestCPUFeatureTest(LibvirtConfigBaseTest):

Expand Down Expand Up @@ -436,6 +456,27 @@ def test_config_complex(self):
</cpu>
""")

def test_config_disabled_features(self):
obj = config.LibvirtConfigCPU()
obj.model = "Penryn"
obj.vendor = "Intel"
obj.arch = obj_fields.Architecture.X86_64

disabled_feature = config.LibvirtConfigCPUFeature("mtrr")
disabled_feature.policy = "disable"
obj.add_feature(disabled_feature)
obj.add_feature(config.LibvirtConfigCPUFeature("apic"))

xml = obj.to_xml()
self.assertXmlEqual(xml, """
<cpu>
<arch>x86_64</arch>
<model>Penryn</model>
<vendor>Intel</vendor>
<feature name="apic"/>
</cpu>
""")

def test_only_uniq_cpu_featues(self):
obj = config.LibvirtConfigCPU()
obj.model = "Penryn"
Expand Down
8 changes: 6 additions & 2 deletions nova/virt/libvirt/config.py
Expand Up @@ -674,11 +674,13 @@ def __init__(self, name=None, **kwargs):
**kwargs)

self.name = name
self.policy = "require"

def parse_dom(self, xmldoc):
super(LibvirtConfigCPUFeature, self).parse_dom(xmldoc)

self.name = xmldoc.get("name")
self.policy = xmldoc.get("policy", "require")

def format_dom(self):
ft = super(LibvirtConfigCPUFeature, self).format_dom()
Expand Down Expand Up @@ -730,7 +732,8 @@ def parse_dom(self, xmldoc):
elif c.tag == "feature":
f = LibvirtConfigCPUFeature()
f.parse_dom(c)
self.add_feature(f)
if f.policy != "disable":
self.add_feature(f)

def format_dom(self):
cpu = super(LibvirtConfigCPU, self).format_dom()
Expand All @@ -753,7 +756,8 @@ def format_dom(self):

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

return cpu

Expand Down

0 comments on commit b6c4731

Please sign in to comment.