Update libvirt cpu map before starting nova
We are trying to get a working 64bit qemu cpu model in the gate for nova live migration testing. It appears that we need to make this change prior to nova starting. Make the change in configure_libvirt() to handle this along with the other libvirt config updates. This allows us to restart the libvirt service once. This function calls a python tool which parses and updates the XML if necessary. Change-Id: I00667713bfba67ab8cedbcb1660ff94d4f4bcc07
This commit is contained in:
parent
e57a1e04d5
commit
edd6048168
@ -110,10 +110,18 @@ EOF
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Update the libvirt cpu map with a gate64 cpu model. This enables nova
|
||||||
|
# live migration for 64bit guest OSes on heterogenous cloud "hardware".
|
||||||
|
if [[ -f /usr/share/libvirt/cpu_map.xml ]] ; then
|
||||||
|
sudo $TOP_DIR/tools/cpu_map_update.py /usr/share/libvirt/cpu_map.xml
|
||||||
|
fi
|
||||||
|
|
||||||
# libvirt detects various settings on startup, as we potentially changed
|
# libvirt detects various settings on startup, as we potentially changed
|
||||||
# the system configuration (modules, filesystems), we need to restart
|
# the system configuration (modules, filesystems), we need to restart
|
||||||
# libvirt to detect those changes.
|
# libvirt to detect those changes. Use a stop start as otherwise the new
|
||||||
restart_service $LIBVIRT_DAEMON
|
# cpu_map is not loaded properly on some systems (Ubuntu).
|
||||||
|
stop_service $LIBVIRT_DAEMON
|
||||||
|
start_service $LIBVIRT_DAEMON
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
89
tools/cpu_map_update.py
Executable file
89
tools/cpu_map_update.py
Executable file
@ -0,0 +1,89 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
# This small script updates the libvirt CPU map to add a gate64 cpu model
|
||||||
|
# that can be used to enable a common 64bit capable feature set across
|
||||||
|
# devstack nodes so that features like nova live migration work.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
from xml.dom import minidom
|
||||||
|
|
||||||
|
|
||||||
|
def update_cpu_map(tree):
|
||||||
|
root = tree.getroot()
|
||||||
|
cpus = root#.find("cpus")
|
||||||
|
x86 = None
|
||||||
|
for arch in cpus.findall("arch"):
|
||||||
|
if arch.get("name") == "x86":
|
||||||
|
x86 = arch
|
||||||
|
break
|
||||||
|
if x86 is not None:
|
||||||
|
# Create a gate64 cpu model that is core2duo less monitor and pse36
|
||||||
|
gate64 = ET.SubElement(x86, "model")
|
||||||
|
gate64.set("name", "gate64")
|
||||||
|
ET.SubElement(gate64, "vendor").set("name", "Intel")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "fpu")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "de")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "pse")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "tsc")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "msr")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "pae")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "mce")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "cx8")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "apic")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "sep")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "pge")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "cmov")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "pat")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "mmx")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "fxsr")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "sse")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "sse2")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "vme")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "mtrr")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "mca")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "clflush")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "pni")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "nx")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "ssse3")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "syscall")
|
||||||
|
ET.SubElement(gate64, "feature").set("name", "lm")
|
||||||
|
|
||||||
|
|
||||||
|
def format_xml(root):
|
||||||
|
# Adapted from http://pymotw.com/2/xml/etree/ElementTree/create.html
|
||||||
|
# thank you dhellmann
|
||||||
|
rough_string = ET.tostring(root, encoding="UTF-8")
|
||||||
|
dom_parsed = minidom.parseString(rough_string)
|
||||||
|
return dom_parsed.toprettyxml(" ", encoding="UTF-8")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
raise Exception("Must pass path to cpu_map.xml to update")
|
||||||
|
cpu_map = sys.argv[1]
|
||||||
|
tree = ET.parse(cpu_map)
|
||||||
|
for model in tree.getroot().iter("model"):
|
||||||
|
if model.get("name") == "gate64":
|
||||||
|
# gate64 model is already present
|
||||||
|
return
|
||||||
|
update_cpu_map(tree)
|
||||||
|
pretty_xml = format_xml(tree.getroot())
|
||||||
|
with open(cpu_map, 'w') as f:
|
||||||
|
f.write(pretty_xml)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in New Issue
Block a user