diff --git a/nova/tests/unit/virt/libvirt/test_migration.py b/nova/tests/unit/virt/libvirt/test_migration.py
index 39321b912502..b849170230ca 100644
--- a/nova/tests/unit/virt/libvirt/test_migration.py
+++ b/nova/tests/unit/virt/libvirt/test_migration.py
@@ -181,42 +181,49 @@ class UtilityMigrationTestCase(test.NoDBTestCase):
self.assertXmlEqual(res, new_xml)
def test_update_numa_xml(self):
- xml = textwrap.dedent("""
+ doc = etree.fromstring("""
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
""")
- doc = etree.fromstring(xml)
data = objects.LibvirtLiveMigrateData(
dst_numa_info=objects.LibvirtLiveMigrateNUMAInfo(
- cpu_pins={'0': set([10, 11]),
- '1': set([12, 13])},
- cell_pins={'2': set([14, 15]),
- '3': set([16, 17])},
+ cpu_pins={'0': set([10, 11]), '1': set([12, 13])},
+ cell_pins={'2': set([14, 15]), '3': set([16, 17])},
emulator_pins=set([18, 19]),
sched_vcpus=set([20, 21]),
sched_priority=22))
- res = etree.tostring(migration._update_numa_xml(copy.deepcopy(doc),
- data),
- encoding='unicode')
- doc.find('./cputune/vcpupin/[@vcpu="0"]').set('cpuset', '10-11')
- doc.find('./cputune/vcpupin/[@vcpu="1"]').set('cpuset', '12-13')
- doc.find('./cputune/emulatorpin').set('cpuset', '18-19')
- doc.find('./cputune/vcpusched').set('vcpus', '20-21')
- doc.find('./cputune/vcpusched').set('priority', '22')
- doc.find('./numatune/memory').set('nodeset', '14-17')
- doc.find('./numatune/memnode/[@cellid="2"]').set('nodeset', '14-15')
- doc.find('./numatune/memnode/[@cellid="3"]').set('nodeset', '16-17')
- self.assertXmlEqual(res, etree.tostring(doc, encoding='unicode'))
+
+ result = etree.tostring(
+ migration._update_numa_xml(copy.deepcopy(doc), data),
+ encoding='unicode')
+
+ expected = textwrap.dedent("""
+
+
+
+
+
+
+
+
+
+
+
+
+ """)
+
+ self.assertXmlEqual(expected, result)
def test_update_numa_xml_no_updates(self):
xml = textwrap.dedent("""
diff --git a/nova/virt/libvirt/migration.py b/nova/virt/libvirt/migration.py
index 4143261ad038..a3bc92c527df 100644
--- a/nova/virt/libvirt/migration.py
+++ b/nova/virt/libvirt/migration.py
@@ -150,9 +150,23 @@ def _update_numa_xml(xml_doc, migrate_data):
memory.set('nodeset', hardware.format_cpu_spec(set(all_cells)))
if 'sched_vcpus' and 'sched_priority' in info:
- vcpusched = xml_doc.find('./cputune/vcpusched')
- vcpusched.set('vcpus', hardware.format_cpu_spec(info.sched_vcpus))
- vcpusched.set('priority', str(info.sched_priority))
+ cputune = xml_doc.find('./cputune')
+
+ # delete the old variant(s)
+ for elem in cputune.findall('./vcpusched'):
+ elem.getparent().remove(elem)
+
+ # ...and create a new, shiny one
+ vcpusched = vconfig.LibvirtConfigGuestCPUTuneVCPUSched()
+ vcpusched.vcpus = info.sched_vcpus
+ vcpusched.priority = info.sched_priority
+ # TODO(stephenfin): Stop assuming scheduler type. We currently only
+ # create these elements for real-time instances and 'fifo' is the only
+ # scheduler policy we currently support so this is reasonably safe to
+ # assume, but it's still unnecessary
+ vcpusched.scheduler = 'fifo'
+
+ cputune.append(vcpusched.format_dom())
LOG.debug('_update_numa_xml output xml=%s',
etree.tostring(xml_doc, encoding='unicode', pretty_print=True))