mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-03-09 08:58:27 +03:00
virtinst: cpu: Move topology elements to their own class
This is a no-op but will help with a future bug fix Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
parent
ade6c34a96
commit
34c6d1c7ea
@ -20,8 +20,8 @@
|
||||
</features>
|
||||
<clock offset="utc"/>
|
||||
<cpu mode="custom" match="exact">
|
||||
<topology cores="4" sockets="1" threads="1"/>
|
||||
<model fallback="allow">foobar</model>
|
||||
<topology sockets="1" cores="4" threads="1"/>
|
||||
<feature policy="forbid" name="x2apic"/>
|
||||
</cpu>
|
||||
<seclabel type="static" model="testSecurity">
|
||||
|
@ -33,9 +33,9 @@ class TestCapabilities(unittest.TestCase):
|
||||
|
||||
self.assertEqual(caps.host.cpu.model, "core2duo")
|
||||
self.assertEqual(caps.host.cpu.vendor, "Intel")
|
||||
self.assertEqual(caps.host.cpu.threads, 3)
|
||||
self.assertEqual(caps.host.cpu.cores, 5)
|
||||
self.assertEqual(caps.host.cpu.sockets, 7)
|
||||
self.assertEqual(caps.host.cpu.topology.threads, 3)
|
||||
self.assertEqual(caps.host.cpu.topology.cores, 5)
|
||||
self.assertEqual(caps.host.cpu.topology.sockets, 7)
|
||||
|
||||
def testCapsUtilFuncs(self):
|
||||
caps_with_kvm = self._buildCaps("test-qemu-with-kvm.xml")
|
||||
|
@ -145,25 +145,27 @@ class TestXMLMisc(unittest.TestCase):
|
||||
# Test CPU topology determining
|
||||
cpu = virtinst.DomainCpu(self.conn)
|
||||
cpu.set_topology_defaults(6)
|
||||
assert cpu.sockets is None
|
||||
assert cpu.topology.sockets is None
|
||||
|
||||
cpu.sockets = "2"
|
||||
cpu.topology.sockets = "2"
|
||||
cpu.set_topology_defaults(6)
|
||||
self.assertEqual([cpu.sockets, cpu.cores, cpu.threads], [2, 3, 1])
|
||||
def get_top(_c):
|
||||
return [_c.topology.sockets, _c.topology.cores, _c.topology.threads]
|
||||
self.assertEqual(get_top(cpu), [2, 3, 1])
|
||||
|
||||
cpu = virtinst.DomainCpu(self.conn)
|
||||
cpu.cores = "4"
|
||||
cpu.topology.cores = "4"
|
||||
cpu.set_topology_defaults(9)
|
||||
self.assertEqual([cpu.sockets, cpu.cores, cpu.threads], [2, 4, 1])
|
||||
self.assertEqual(get_top(cpu), [2, 4, 1])
|
||||
|
||||
cpu = virtinst.DomainCpu(self.conn)
|
||||
cpu.threads = "3"
|
||||
cpu.topology.threads = "3"
|
||||
cpu.set_topology_defaults(14)
|
||||
self.assertEqual([cpu.sockets, cpu.cores, cpu.threads], [4, 1, 3])
|
||||
self.assertEqual(get_top(cpu), [4, 1, 3])
|
||||
|
||||
cpu = virtinst.DomainCpu(self.conn)
|
||||
cpu.sockets = 5
|
||||
cpu.cores = 2
|
||||
cpu.topology.sockets = 5
|
||||
cpu.topology.cores = 2
|
||||
self.assertEqual(cpu.vcpus_from_topology(), 10)
|
||||
|
||||
cpu = virtinst.DomainCpu(self.conn)
|
||||
|
@ -195,10 +195,10 @@ class XMLParseTest(unittest.TestCase):
|
||||
guest.cpu.set_model(guest, "qemu64")
|
||||
check("model", "qemu64")
|
||||
check("vendor", "Intel", "qemuvendor")
|
||||
check("threads", 2, 1)
|
||||
check("cores", 5, 3)
|
||||
guest.cpu.sockets = 4.0
|
||||
check("sockets", 4)
|
||||
check("topology.threads", 2, 1)
|
||||
check("topology.cores", 5, 3)
|
||||
guest.cpu.topology.sockets = 4.0
|
||||
check("topology.sockets", 4)
|
||||
|
||||
check = self._make_checker(guest.cpu.features[0])
|
||||
check("name", "x2apic")
|
||||
@ -292,7 +292,7 @@ class XMLParseTest(unittest.TestCase):
|
||||
guest.cpu.set_model(guest, "foobar")
|
||||
check("model", "foobar")
|
||||
check("model_fallback", None, "allow")
|
||||
check("cores", None, 4)
|
||||
check("topology.cores", None, 4)
|
||||
guest.cpu.add_feature("x2apic", "forbid")
|
||||
guest.cpu.set_topology_defaults(guest.vcpus)
|
||||
self.assertTrue(guest.cpu.get_xml().startswith("<cpu"))
|
||||
|
@ -1939,13 +1939,13 @@ class vmmDetails(vmmGObjectUI):
|
||||
|
||||
def _refresh_config_cpu(self):
|
||||
# Set topology first, because it impacts vcpus values
|
||||
cpu = self.vm.get_cpu_config()
|
||||
show_top = bool(cpu.sockets or cpu.cores or cpu.threads)
|
||||
cpu = self.vm.xmlobj.cpu
|
||||
show_top = cpu.has_topology()
|
||||
self.widget("cpu-topology-enable").set_active(show_top)
|
||||
|
||||
sockets = cpu.sockets or 1
|
||||
cores = cpu.cores or 1
|
||||
threads = cpu.threads or 1
|
||||
sockets = cpu.topology.sockets or 1
|
||||
cores = cpu.topology.cores or 1
|
||||
threads = cpu.topology.threads or 1
|
||||
|
||||
self.widget("cpu-sockets").set_value(sockets)
|
||||
self.widget("cpu-cores").set_value(cores)
|
||||
|
@ -559,9 +559,9 @@ class vmmDomain(vmmLibvirtObject):
|
||||
guest.vcpu_current = int(vcpus)
|
||||
|
||||
if sockets != _SENTINEL:
|
||||
guest.cpu.sockets = sockets
|
||||
guest.cpu.cores = cores
|
||||
guest.cpu.threads = threads
|
||||
guest.cpu.topology.sockets = sockets
|
||||
guest.cpu.topology.cores = cores
|
||||
guest.cpu.topology.threads = threads
|
||||
|
||||
if secure != _SENTINEL or model != _SENTINEL:
|
||||
guest.cpu.secure = secure
|
||||
@ -1205,9 +1205,6 @@ class vmmDomain(vmmLibvirtObject):
|
||||
def get_description(self):
|
||||
return self.get_xmlobj().description
|
||||
|
||||
def get_cpu_config(self):
|
||||
return self.get_xmlobj().cpu
|
||||
|
||||
def get_boot_order(self):
|
||||
legacy = not self.can_use_device_boot_order()
|
||||
return self.xmlobj.get_boot_order(legacy=legacy)
|
||||
|
@ -2222,9 +2222,9 @@ class ParserCPU(VirtCLIParser):
|
||||
cls.add_arg("disable", None, lookup_cb=None, cb=cls.set_feature_cb)
|
||||
cls.add_arg("forbid", None, lookup_cb=None, cb=cls.set_feature_cb)
|
||||
|
||||
cls.add_arg("topology.sockets", "sockets")
|
||||
cls.add_arg("topology.cores", "cores")
|
||||
cls.add_arg("topology.threads", "threads")
|
||||
cls.add_arg("topology.sockets", "topology.sockets")
|
||||
cls.add_arg("topology.cores", "topology.cores")
|
||||
cls.add_arg("topology.threads", "topology.threads")
|
||||
|
||||
# Options for CPU.cells config
|
||||
cls.add_arg("numa.cell[0-9]*.id", "id",
|
||||
@ -2407,9 +2407,9 @@ class ParserVCPU(VirtCLIParser):
|
||||
cls.add_arg("vcpus", "vcpus", cb=cls.noset_cb)
|
||||
|
||||
# Further CPU options should be added to --cpu
|
||||
cls.add_arg("sockets", "cpu.sockets")
|
||||
cls.add_arg("cores", "cpu.cores")
|
||||
cls.add_arg("threads", "cpu.threads")
|
||||
cls.add_arg("sockets", "cpu.topology.sockets")
|
||||
cls.add_arg("cores", "cpu.topology.cores")
|
||||
cls.add_arg("threads", "cpu.topology.threads")
|
||||
|
||||
# <domain><vcpu> options
|
||||
cls.add_arg("vcpu", "vcpus")
|
||||
|
@ -57,13 +57,43 @@ class _CPUFeature(XMLBuilder):
|
||||
policy = XMLProperty("./@policy")
|
||||
|
||||
|
||||
class _CPUTopology(XMLBuilder):
|
||||
"""
|
||||
Class for generating <cpu> <topology> XML
|
||||
"""
|
||||
XML_NAME = "topology"
|
||||
_XML_PROP_ORDER = ["sockets", "cores", "threads"]
|
||||
|
||||
sockets = XMLProperty("./@sockets", is_int=True)
|
||||
cores = XMLProperty("./@cores", is_int=True)
|
||||
threads = XMLProperty("./@threads", is_int=True)
|
||||
|
||||
def set_defaults_from_vcpus(self, vcpus):
|
||||
if not self.sockets:
|
||||
if not self.cores:
|
||||
self.sockets = vcpus // self.threads
|
||||
else:
|
||||
self.sockets = vcpus // self.cores
|
||||
|
||||
if not self.cores:
|
||||
if not self.threads:
|
||||
self.cores = vcpus // self.sockets
|
||||
else:
|
||||
self.cores = vcpus // (self.sockets * self.threads)
|
||||
|
||||
if not self.threads:
|
||||
self.threads = vcpus // (self.sockets * self.cores)
|
||||
|
||||
return
|
||||
|
||||
|
||||
class DomainCpu(XMLBuilder):
|
||||
"""
|
||||
Class for generating <cpu> XML
|
||||
"""
|
||||
XML_NAME = "cpu"
|
||||
_XML_PROP_ORDER = ["mode", "match", "model", "vendor",
|
||||
"sockets", "cores", "threads", "features"]
|
||||
"topology", "features"]
|
||||
|
||||
secure = True
|
||||
|
||||
@ -207,13 +237,15 @@ class DomainCpu(XMLBuilder):
|
||||
Determine the CPU count represented by topology, or 1 if
|
||||
no topology is set
|
||||
"""
|
||||
return (self.sockets or 1) * (self.cores or 1) * (self.threads or 1)
|
||||
return ((self.topology.sockets or 1) *
|
||||
(self.topology.cores or 1) *
|
||||
(self.topology.threads or 1))
|
||||
|
||||
def has_topology(self):
|
||||
"""
|
||||
Return True if any topology info is set
|
||||
"""
|
||||
return bool(self.sockets or self.cores or self.threads)
|
||||
return bool(self.topology.get_xml())
|
||||
|
||||
def set_topology_defaults(self, vcpus):
|
||||
"""
|
||||
@ -223,29 +255,15 @@ class DomainCpu(XMLBuilder):
|
||||
"""
|
||||
if not self.has_topology():
|
||||
return
|
||||
|
||||
if not self.sockets:
|
||||
if not self.cores:
|
||||
self.sockets = vcpus // self.threads
|
||||
else:
|
||||
self.sockets = vcpus // self.cores
|
||||
|
||||
if not self.cores:
|
||||
if not self.threads:
|
||||
self.cores = vcpus // self.sockets
|
||||
else:
|
||||
self.cores = vcpus // (self.sockets * self.threads)
|
||||
|
||||
if not self.threads:
|
||||
self.threads = vcpus // (self.sockets * self.cores)
|
||||
|
||||
return
|
||||
self.topology.set_defaults_from_vcpus(vcpus)
|
||||
|
||||
|
||||
##################
|
||||
# XML properties #
|
||||
##################
|
||||
|
||||
topology = XMLChildProperty(_CPUTopology, is_single=True)
|
||||
|
||||
model = XMLProperty("./model")
|
||||
model_fallback = XMLProperty("./model/@fallback")
|
||||
|
||||
@ -253,10 +271,6 @@ class DomainCpu(XMLBuilder):
|
||||
vendor = XMLProperty("./vendor")
|
||||
mode = XMLProperty("./@mode")
|
||||
|
||||
sockets = XMLProperty("./topology/@sockets", is_int=True)
|
||||
cores = XMLProperty("./topology/@cores", is_int=True)
|
||||
threads = XMLProperty("./topology/@threads", is_int=True)
|
||||
|
||||
|
||||
##################
|
||||
# Default config #
|
||||
|
Loading…
x
Reference in New Issue
Block a user