~ubuntu-branches/ubuntu/precise/virtinst/precise-updates

« back to all changes in this revision

Viewing changes to virtinst/CPU.py

  • Committer: Bazaar Package Importer
  • Author(s): Marc Deslauriers
  • Date: 2011-02-01 15:40:11 UTC
  • mfrom: (1.3.16 experimental)
  • Revision ID: james.westby@ubuntu.com-20110201154011-op0nusgc240xajvb
Tags: 0.500.5-1ubuntu1
* Merge from debian experimental. Remaining changes:
  - debian/patches/9001_Ubuntu.patch:
     + Updated to add maverick and natty to OS list and enable virtio
       for them.
  - debian/patches/9003-fix-path-to-hvmloader-in-testsuite.patch: adjust
    testsuite for 0001-fix-path-to-hvmloader.patch and
    0002-Fix-path-to-pygrub.patch. (refreshed)
  - debian/control: added acl package to depends.
  - Demote virt-viewer to Suggests, as it's in universe.
  - Recommends libvirt-bin
* Removed patches:
  - debian/patches/9002-libvirt_disk_format.patch: Upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# Copyright 2010  Red Hat, Inc.
 
3
# Cole Robinson <crobinso@redhat.com>
 
4
#
 
5
# This program is free software; you can redistribute it and/or modify
 
6
# it under the terms of the GNU General Public License as published by
 
7
# the Free  Software Foundation; either version 2 of the License, or
 
8
# (at your option)  any later version.
 
9
#
 
10
# This program is distributed in the hope that it will be useful,
 
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
# GNU General Public License for more details.
 
14
#
 
15
# You should have received a copy of the GNU General Public License
 
16
# along with this program; if not, write to the Free Software
 
17
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
18
# MA 02110-1301 USA.
 
19
 
 
20
import XMLBuilderDomain
 
21
from XMLBuilderDomain import _xml_property
 
22
 
 
23
import libxml2
 
24
 
 
25
def _int_or_none(val):
 
26
    return val and int(val) or val
 
27
 
 
28
class CPUFeature(XMLBuilderDomain.XMLBuilderDomain):
 
29
    """
 
30
    Class for generating <cpu> child <feature> XML
 
31
    """
 
32
 
 
33
    POLICIES = ["force", "require", "optional", "disable", "forbid"]
 
34
 
 
35
    def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None):
 
36
        XMLBuilderDomain.XMLBuilderDomain.__init__(self, conn, parsexml,
 
37
                                                   parsexmlnode, caps)
 
38
 
 
39
        self._name = None
 
40
        self._policy = None
 
41
 
 
42
        if self._is_parse():
 
43
            return
 
44
 
 
45
    def _get_name(self):
 
46
        return self._name
 
47
    def _set_name(self, val):
 
48
        self._name = val
 
49
    name = _xml_property(_get_name, _set_name,
 
50
                         xpath="./@name")
 
51
 
 
52
    def _get_policy(self):
 
53
        return self._policy
 
54
    def _set_policy(self, val):
 
55
        self._policy = val
 
56
    policy = _xml_property(_get_policy, _set_policy,
 
57
                           xpath="./@policy")
 
58
 
 
59
    def _get_xml_config(self):
 
60
        if not self.name:
 
61
            return ""
 
62
 
 
63
        xml = "    <feature"
 
64
        if self.policy:
 
65
            xml += " policy='%s'" % self.policy
 
66
        xml += " name='%s'/>" % self.name
 
67
 
 
68
        return xml
 
69
 
 
70
 
 
71
class CPU(XMLBuilderDomain.XMLBuilderDomain):
 
72
    """
 
73
    Class for generating <cpu> XML
 
74
    """
 
75
 
 
76
    _dumpxml_xpath = "/domain/cpu"
 
77
 
 
78
    MATCHS = ["minimum", "exact", "strict"]
 
79
 
 
80
    def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None):
 
81
        self._model = None
 
82
        self._match = None
 
83
        self._vendor = None
 
84
        self._features = []
 
85
 
 
86
        self._sockets = None
 
87
        self._cores = None
 
88
        self._threads = None
 
89
 
 
90
        XMLBuilderDomain.XMLBuilderDomain.__init__(self, conn, parsexml,
 
91
                                                   parsexmlnode, caps)
 
92
        if self._is_parse():
 
93
            return
 
94
 
 
95
    def _parsexml(self, xml, node):
 
96
        XMLBuilderDomain.XMLBuilderDomain._parsexml(self, xml, node)
 
97
 
 
98
        for node in self._xml_node.children:
 
99
            if node.name != "feature":
 
100
                continue
 
101
            feature = CPUFeature(self.conn, parsexmlnode=node)
 
102
            self._features.append(feature)
 
103
 
 
104
    def _get_features(self):
 
105
        return self._features[:]
 
106
    features = _xml_property(_get_features)
 
107
 
 
108
    def add_feature(self, name, policy="require"):
 
109
        feature = CPUFeature(self.conn)
 
110
        feature.name = name
 
111
        feature.policy = policy
 
112
 
 
113
        if self._is_parse():
 
114
            xml = feature.get_xml_config()
 
115
            node = libxml2.parseDoc(xml).children
 
116
            feature.set_xml_node(node)
 
117
            self._add_child_node("./cpu", node)
 
118
 
 
119
        self._features.append(feature)
 
120
 
 
121
    def remove_feature(self, feature):
 
122
        if self._is_parse() and feature in self._features:
 
123
            xpath = feature.get_xml_node_path()
 
124
            if xpath:
 
125
                self._remove_child_xpath(xpath)
 
126
 
 
127
        self._features.remove(feature)
 
128
 
 
129
 
 
130
    def _get_model(self):
 
131
        return self._model
 
132
    def _set_model(self, val):
 
133
        if val and not self.match:
 
134
            self.match = "exact"
 
135
        self._model = val
 
136
    model = _xml_property(_get_model, _set_model,
 
137
                          xpath="./cpu/model")
 
138
 
 
139
    def _get_match(self):
 
140
        return self._match
 
141
    def _set_match(self, val):
 
142
        self._match = val
 
143
    match = _xml_property(_get_match, _set_match,
 
144
                          xpath="./cpu/@match")
 
145
 
 
146
    def _get_vendor(self):
 
147
        return self._vendor
 
148
    def _set_vendor(self, val):
 
149
        self._vendor = val
 
150
    vendor = _xml_property(_get_vendor, _set_vendor,
 
151
                           xpath="./cpu/vendor")
 
152
 
 
153
    # Topology properties
 
154
    def _get_sockets(self):
 
155
        return self._sockets
 
156
    def _set_sockets(self, val):
 
157
        self._sockets = _int_or_none(val)
 
158
    sockets = _xml_property(_get_sockets, _set_sockets,
 
159
                            get_converter=lambda s, x: _int_or_none(x),
 
160
                            xpath="./cpu/topology/@sockets")
 
161
 
 
162
    def _get_cores(self):
 
163
        return self._cores
 
164
    def _set_cores(self, val):
 
165
        self._cores = _int_or_none(val)
 
166
    cores = _xml_property(_get_cores, _set_cores,
 
167
                          get_converter=lambda s, x: _int_or_none(x),
 
168
                          xpath="./cpu/topology/@cores")
 
169
 
 
170
    def _get_threads(self):
 
171
        return self._threads
 
172
    def _set_threads(self, val):
 
173
        self._threads = _int_or_none(val)
 
174
    threads = _xml_property(_get_threads, _set_threads,
 
175
                            get_converter=lambda s, x: _int_or_none(x),
 
176
                            xpath="./cpu/topology/@threads")
 
177
 
 
178
    def copy_host_cpu(self):
 
179
        """
 
180
        Enact the equivalent of qemu -cpu host, pulling all info
 
181
        from capabilities about the host CPU
 
182
        """
 
183
        cpu = self._get_caps().host.cpu
 
184
        if not cpu.model:
 
185
            raise ValueError(_("No host CPU reported in capabilities"))
 
186
 
 
187
        self.match = "exact"
 
188
        self.model = cpu.model
 
189
        self.vendor = cpu.vendor
 
190
 
 
191
        for feature in self.features:
 
192
            self.remove_feature(feature)
 
193
        for name in cpu.features.names():
 
194
            self.add_feature(name)
 
195
 
 
196
    def vcpus_from_topology(self):
 
197
        """
 
198
        Determine the CPU count represented by topology, or 1 if
 
199
        no topology is set
 
200
        """
 
201
        self.set_topology_defaults()
 
202
        if self.sockets:
 
203
            return self.sockets * self.cores * self.threads
 
204
        return 1
 
205
 
 
206
    def set_topology_defaults(self, vcpus=None):
 
207
        """
 
208
        Fill in unset topology values, using the passed vcpus count if
 
209
        required
 
210
        """
 
211
        if (self.sockets is None and
 
212
            self.cores is None and
 
213
            self.threads is None):
 
214
            return
 
215
 
 
216
        if vcpus is None:
 
217
            if self.sockets is None:
 
218
                self.sockets = 1
 
219
            if self.threads is None:
 
220
                self.threads = 1
 
221
            if self.cores is None:
 
222
                self.cores = 1
 
223
 
 
224
        vcpus = int(vcpus or 0)
 
225
        if not self.sockets:
 
226
            if not self.cores:
 
227
                self.sockets = vcpus / self.threads
 
228
            else:
 
229
                self.sockets = vcpus / self.cores
 
230
 
 
231
        if not self.cores:
 
232
            if not self.threads:
 
233
                self.cores = vcpus / self.sockets
 
234
            else:
 
235
                self.cores = vcpus / (self.sockets * self.threads)
 
236
 
 
237
        if not self.threads:
 
238
            self.threads = vcpus / (self.sockets * self.cores)
 
239
 
 
240
        return
 
241
 
 
242
    def _get_topology_xml(self):
 
243
        xml = ""
 
244
        if self.sockets:
 
245
            xml += " sockets='%s'" % self.sockets
 
246
        if self.cores:
 
247
            xml += " cores='%s'" % self.cores
 
248
        if self.threads:
 
249
            xml += " threads='%s'" % self.threads
 
250
 
 
251
        if not xml:
 
252
            return ""
 
253
        return "    <topology%s/>\n" % xml
 
254
 
 
255
    def _get_feature_xml(self):
 
256
        xml = ""
 
257
        for feature in self._features:
 
258
            xml += feature.get_xml_config() + "\n"
 
259
        return xml
 
260
 
 
261
    def _get_xml_config(self):
 
262
        top_xml = self._get_topology_xml()
 
263
        feature_xml = self._get_feature_xml()
 
264
        match_xml = ""
 
265
        if self.match:
 
266
            match_xml = " match='%s'" % self.match
 
267
        xml = ""
 
268
 
 
269
        if not (self.model or top_xml or feature_xml):
 
270
            return ""
 
271
 
 
272
        # Simple topology XML mode
 
273
        xml += "  <cpu%s>\n" % match_xml
 
274
        if self.model:
 
275
            xml += "    <model>%s</model>\n" % self.model
 
276
        if self.vendor:
 
277
            xml += "    <vendor>%s</vendor>\n" % self.vendor
 
278
        if top_xml:
 
279
            xml += top_xml
 
280
        if feature_xml:
 
281
            xml += feature_xml
 
282
 
 
283
        xml += "  </cpu>"
 
284
        return xml