Browse code

Merge "Update libvirt cpu map before starting nova"

Jenkins authored on 2015/04/04 05:21:20
Showing 2 changed files
... ...
@@ -115,10 +115,18 @@ EOF
115 115
         fi
116 116
     fi
117 117
 
118
+    # Update the libvirt cpu map with a gate64 cpu model. This enables nova
119
+    # live migration for 64bit guest OSes on heterogenous cloud "hardware".
120
+    if [[ -f /usr/share/libvirt/cpu_map.xml ]] ; then
121
+        sudo $TOP_DIR/tools/cpu_map_update.py /usr/share/libvirt/cpu_map.xml
122
+    fi
123
+
118 124
     # libvirt detects various settings on startup, as we potentially changed
119 125
     # the system configuration (modules, filesystems), we need to restart
120
-    # libvirt to detect those changes.
121
-    restart_service $LIBVIRT_DAEMON
126
+    # libvirt to detect those changes. Use a stop start as otherwise the new
127
+    # cpu_map is not loaded properly on some systems (Ubuntu).
128
+    stop_service $LIBVIRT_DAEMON
129
+    start_service $LIBVIRT_DAEMON
122 130
 }
123 131
 
124 132
 
125 133
new file mode 100755
... ...
@@ -0,0 +1,89 @@
0
+#!/usr/bin/env python
1
+#
2
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
3
+# not use this file except in compliance with the License. You may obtain
4
+# a copy of the License at
5
+#
6
+#      http://www.apache.org/licenses/LICENSE-2.0
7
+#
8
+# Unless required by applicable law or agreed to in writing, software
9
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11
+# License for the specific language governing permissions and limitations
12
+# under the License.
13
+
14
+# This small script updates the libvirt CPU map to add a gate64 cpu model
15
+# that can be used to enable a common 64bit capable feature set across
16
+# devstack nodes so that features like nova live migration work.
17
+
18
+import sys
19
+import xml.etree.ElementTree as ET
20
+from xml.dom import minidom
21
+
22
+
23
+def update_cpu_map(tree):
24
+    root = tree.getroot()
25
+    cpus = root#.find("cpus")
26
+    x86 = None
27
+    for arch in cpus.findall("arch"):
28
+        if arch.get("name") == "x86":
29
+            x86 = arch
30
+            break
31
+    if x86 is not None:
32
+        # Create a gate64 cpu model that is core2duo less monitor and pse36
33
+        gate64 = ET.SubElement(x86, "model")
34
+        gate64.set("name", "gate64")
35
+        ET.SubElement(gate64, "vendor").set("name", "Intel")
36
+        ET.SubElement(gate64, "feature").set("name", "fpu")
37
+        ET.SubElement(gate64, "feature").set("name", "de")
38
+        ET.SubElement(gate64, "feature").set("name", "pse")
39
+        ET.SubElement(gate64, "feature").set("name", "tsc")
40
+        ET.SubElement(gate64, "feature").set("name", "msr")
41
+        ET.SubElement(gate64, "feature").set("name", "pae")
42
+        ET.SubElement(gate64, "feature").set("name", "mce")
43
+        ET.SubElement(gate64, "feature").set("name", "cx8")
44
+        ET.SubElement(gate64, "feature").set("name", "apic")
45
+        ET.SubElement(gate64, "feature").set("name", "sep")
46
+        ET.SubElement(gate64, "feature").set("name", "pge")
47
+        ET.SubElement(gate64, "feature").set("name", "cmov")
48
+        ET.SubElement(gate64, "feature").set("name", "pat")
49
+        ET.SubElement(gate64, "feature").set("name", "mmx")
50
+        ET.SubElement(gate64, "feature").set("name", "fxsr")
51
+        ET.SubElement(gate64, "feature").set("name", "sse")
52
+        ET.SubElement(gate64, "feature").set("name", "sse2")
53
+        ET.SubElement(gate64, "feature").set("name", "vme")
54
+        ET.SubElement(gate64, "feature").set("name", "mtrr")
55
+        ET.SubElement(gate64, "feature").set("name", "mca")
56
+        ET.SubElement(gate64, "feature").set("name", "clflush")
57
+        ET.SubElement(gate64, "feature").set("name", "pni")
58
+        ET.SubElement(gate64, "feature").set("name", "nx")
59
+        ET.SubElement(gate64, "feature").set("name", "ssse3")
60
+        ET.SubElement(gate64, "feature").set("name", "syscall")
61
+        ET.SubElement(gate64, "feature").set("name", "lm")
62
+
63
+
64
+def format_xml(root):
65
+    # Adapted from http://pymotw.com/2/xml/etree/ElementTree/create.html
66
+    # thank you dhellmann
67
+    rough_string = ET.tostring(root, encoding="UTF-8")
68
+    dom_parsed = minidom.parseString(rough_string)
69
+    return dom_parsed.toprettyxml("  ", encoding="UTF-8")
70
+
71
+
72
+def main():
73
+    if len(sys.argv) != 2:
74
+        raise Exception("Must pass path to cpu_map.xml to update")
75
+    cpu_map = sys.argv[1]
76
+    tree = ET.parse(cpu_map)
77
+    for model in tree.getroot().iter("model"):
78
+        if model.get("name") == "gate64":
79
+            # gate64 model is already present
80
+            return
81
+    update_cpu_map(tree)
82
+    pretty_xml = format_xml(tree.getroot())
83
+    with open(cpu_map, 'w') as f:
84
+        f.write(pretty_xml)
85
+
86
+
87
+if __name__ == "__main__":
88
+    main()