- bsc#1086038 - VM guests cannot be properly installed with

virt-install
  d15b78ab-virtinst-read-CPU-model-from-domain-capabilities.patch
  fd6a8154-virtinst-compare-host-and-domain-cpu-models.patch
- Drop virtinst-dont-set-cpu-model-when-caps-mismatch.patch in
  favor of upstream versions.

OBS-URL: https://build.opensuse.org/package/show/Virtualization/virt-manager?expand=0&rev=421
This commit is contained in:
Charles Arnold 2018-04-03 21:20:28 +00:00 committed by Git OBS Bridge
parent 10990f582a
commit a51105234f
8 changed files with 298 additions and 143 deletions

View File

@ -0,0 +1,193 @@
Subject: virtinst: read CPU model from domain capabilities
From: Charles Arnold carnold@suse.com Wed Mar 28 13:45:29 2018 -0600
Date: Tue Apr 3 10:57:15 2018 -0400:
Git: d15b78ab0d7b9e73261a19fafc841a4ee206d413
Add functionality to acquire the CPU model from the
libvirt domain capabilities. This is used to compare
with the host CPU model.
(crobinso: add test coverage, rework domcaps layout a bit)
Index: virt-manager-1.5.0/tests/capabilities-xml/kvm-x86_64-domcaps.xml
===================================================================
--- virt-manager-1.5.0.orig/tests/capabilities-xml/kvm-x86_64-domcaps.xml
+++ virt-manager-1.5.0/tests/capabilities-xml/kvm-x86_64-domcaps.xml
@@ -18,6 +18,68 @@
</enum>
</loader>
</os>
+ <cpu>
+ <mode name='host-passthrough' supported='yes'/>
+ <mode name='host-model' supported='yes'>
+ <model fallback='forbid'>Broadwell</model>
+ <vendor>Intel</vendor>
+ <feature policy='require' name='vme'/>
+ <feature policy='require' name='ss'/>
+ <feature policy='require' name='f16c'/>
+ <feature policy='require' name='rdrand'/>
+ <feature policy='require' name='hypervisor'/>
+ <feature policy='require' name='arat'/>
+ <feature policy='require' name='tsc_adjust'/>
+ <feature policy='require' name='xsaveopt'/>
+ <feature policy='require' name='pdpe1gb'/>
+ <feature policy='require' name='abm'/>
+ <feature policy='require' name='invtsc'/>
+ </mode>
+ <mode name='custom' supported='yes'>
+ <model usable='yes'>qemu64</model>
+ <model usable='yes'>qemu32</model>
+ <model usable='no'>phenom</model>
+ <model usable='yes'>pentium3</model>
+ <model usable='yes'>pentium2</model>
+ <model usable='yes'>pentium</model>
+ <model usable='yes'>n270</model>
+ <model usable='yes'>kvm64</model>
+ <model usable='yes'>kvm32</model>
+ <model usable='yes'>coreduo</model>
+ <model usable='yes'>core2duo</model>
+ <model usable='no'>athlon</model>
+ <model usable='yes'>Westmere</model>
+ <model usable='no'>Westmere-IBRS</model>
+ <model usable='no'>Skylake-Server</model>
+ <model usable='no'>Skylake-Server-IBRS</model>
+ <model usable='no'>Skylake-Client</model>
+ <model usable='no'>Skylake-Client-IBRS</model>
+ <model usable='yes'>SandyBridge</model>
+ <model usable='no'>SandyBridge-IBRS</model>
+ <model usable='yes'>Penryn</model>
+ <model usable='no'>Opteron_G5</model>
+ <model usable='yes'>Opteron_G4</model>
+ <model usable='no'>Opteron_G3</model>
+ <model usable='yes'>Opteron_G2</model>
+ <model usable='yes'>Opteron_G1</model>
+ <model usable='yes'>Nehalem</model>
+ <model usable='no'>Nehalem-IBRS</model>
+ <model usable='yes'>IvyBridge</model>
+ <model usable='no'>IvyBridge-IBRS</model>
+ <model usable='yes'>Haswell</model>
+ <model usable='yes'>Haswell-noTSX</model>
+ <model usable='no'>Haswell-noTSX-IBRS</model>
+ <model usable='no'>Haswell-IBRS</model>
+ <model usable='no'>EPYC</model>
+ <model usable='no'>EPYC-IBPB</model>
+ <model usable='yes'>Conroe</model>
+ <model usable='yes'>Broadwell</model>
+ <model usable='yes'>Broadwell-noTSX</model>
+ <model usable='no'>Broadwell-noTSX-IBRS</model>
+ <model usable='no'>Broadwell-IBRS</model>
+ <model usable='yes'>486</model>
+ </mode>
+ </cpu>
<devices>
<disk supported='yes'>
<enum name='diskDevice'>
@@ -32,8 +94,25 @@
<value>scsi</value>
<value>virtio</value>
<value>usb</value>
+ <value>sata</value>
</enum>
</disk>
+ <graphics supported='yes'>
+ <enum name='type'>
+ <value>sdl</value>
+ <value>vnc</value>
+ <value>spice</value>
+ </enum>
+ </graphics>
+ <video supported='yes'>
+ <enum name='modelType'>
+ <value>vga</value>
+ <value>cirrus</value>
+ <value>vmvga</value>
+ <value>qxl</value>
+ <value>virtio</value>
+ </enum>
+ </video>
<hostdev supported='yes'>
<enum name='mode'>
<value>subsystem</value>
@@ -50,11 +129,10 @@
<value>scsi</value>
</enum>
<enum name='capsType'/>
- <enum name='pciBackend'>
- <value>default</value>
- <value>kvm</value>
- <value>vfio</value>
- </enum>
+ <enum name='pciBackend'/>
</hostdev>
</devices>
+ <features>
+ <gic supported='no'/>
+ </features>
</domainCapabilities>
Index: virt-manager-1.5.0/tests/capabilities.py
===================================================================
--- virt-manager-1.5.0.orig/tests/capabilities.py
+++ virt-manager-1.5.0/tests/capabilities.py
@@ -131,6 +131,16 @@ class TestCapabilities(unittest.TestCase
self.assertEqual(caps.os.loader.get_enum("type").get_values(),
["rom", "pflash"])
+ def testDomainCapabilitiesx86(self):
+ xml = open("tests/capabilities-xml/kvm-x86_64-domcaps.xml").read()
+ caps = DomainCapabilities(utils.URIs.open_testdriver_cached(), xml)
+
+ custom_mode = caps.cpu.get_mode("custom")
+ self.assertTrue(bool(custom_mode))
+ cpu_model = custom_mode.get_model("Opteron_G4")
+ self.assertTrue(bool(cpu_model))
+ self.assertTrue(cpu_model.usable)
+
if __name__ == "__main__":
unittest.main()
Index: virt-manager-1.5.0/virtinst/domcapabilities.py
===================================================================
--- virt-manager-1.5.0.orig/virtinst/domcapabilities.py
+++ virt-manager-1.5.0/virtinst/domcapabilities.py
@@ -76,6 +76,33 @@ class _Features(_CapsBlock):
gic = XMLChildProperty(_make_capsblock("gic"), is_single=True)
+
+class _CPUModel(XMLBuilder):
+ _XML_ROOT_NAME = "model"
+ model = XMLProperty(".")
+ usable = XMLProperty("./@usable", is_yesno=True)
+
+
+class _CPUMode(XMLBuilder):
+ _XML_ROOT_NAME = "mode"
+ name = XMLProperty("./@name")
+ models = XMLChildProperty(_CPUModel)
+
+ def get_model(self, name):
+ for model in self.models:
+ if model.model == name:
+ return model
+
+class _CPU(XMLBuilder):
+ _XML_ROOT_NAME = "cpu"
+ modes = XMLChildProperty(_CPUMode)
+
+ def get_mode(self, name):
+ for mode in self.modes:
+ if mode.name == name:
+ return mode
+
+
class DomainCapabilities(XMLBuilder):
@staticmethod
def build_from_params(conn, emulator, arch, machine, hvtype):
@@ -163,6 +190,7 @@ class DomainCapabilities(XMLBuilder):
_XML_ROOT_NAME = "domainCapabilities"
os = XMLChildProperty(_OS, is_single=True)
+ cpu = XMLChildProperty(_CPU, is_single=True)
devices = XMLChildProperty(_Devices, is_single=True)
arch = XMLProperty("./arch")

View File

@ -0,0 +1,81 @@
Subject: virtinst: compare host and domain cpu models
From: Charles Arnold carnold@suse.com Wed Mar 28 13:45:30 2018 -0600
Date: Tue Apr 3 10:57:49 2018 -0400:
Git: fd6a8154408fb462e5437dc920afe4d80da3c1f8
Lookup the domain capabilities CPU model and compare with
the host capabilities CPU model and if they are not equal
set the guest's CPU model to None.
(crobinso: compare against 'custom' list not 'host-model', move
to separate function)
Index: virt-manager-1.5.0/tests/cli-test-xml/compare/virt-install-boot-uefi.xml
===================================================================
--- virt-manager-1.5.0.orig/tests/cli-test-xml/compare/virt-install-boot-uefi.xml
+++ virt-manager-1.5.0/tests/cli-test-xml/compare/virt-install-boot-uefi.xml
@@ -15,9 +15,7 @@
<smm state="on"/>
<vmport state="off"/>
</features>
- <cpu mode="custom" match="exact">
- <model>Opteron_G4</model>
- </cpu>
+ <cpu mode="custom" match="exact"/>
<clock offset="utc">
<timer name="rtc" tickpolicy="catchup"/>
<timer name="pit" tickpolicy="delay"/>
Index: virt-manager-1.5.0/virtinst/guest.py
===================================================================
--- virt-manager-1.5.0.orig/virtinst/guest.py
+++ virt-manager-1.5.0/virtinst/guest.py
@@ -880,6 +880,33 @@ class Guest(XMLBuilder):
else:
self.emulator = "/usr/lib/xen/bin/qemu-dm"
+ def _set_cpu_x86_kvm_default(self):
+ if self.os.arch != self.conn.caps.host.cpu.arch:
+ return
+
+ self.cpu.set_special_mode(self.x86_cpu_default)
+ if self.x86_cpu_default != self.cpu.SPECIAL_MODE_HOST_MODEL_ONLY:
+ return
+ if not self.cpu.model:
+ return
+
+ # It's possible that the value HOST_MODEL_ONLY gets from
+ # <capabilities> is not actually supported by qemu/kvm
+ # combo which will be reported in <domainCapabilities>
+ domcaps = DomainCapabilities.build_from_guest(self)
+ domcaps_mode = domcaps.cpu.get_mode("custom")
+ if not domcaps_mode:
+ return
+
+ cpu_model = domcaps_mode.get_model(self.cpu.model)
+ if cpu_model and cpu_model.usable:
+ return
+
+ logging.debug("Host capabilities CPU '%s' is not supported "
+ "according to domain capabilities. Unsetting CPU model",
+ self.cpu.model)
+ self.cpu.model = None
+
def _set_cpu_defaults(self):
self.cpu.set_topology_defaults(self.vcpus)
@@ -898,14 +925,11 @@ class Guest(XMLBuilder):
self.cpu.model = "cortex-a57"
elif self.os.is_x86() and self.type == "kvm":
- if self.os.arch != self.conn.caps.host.cpu.arch:
- return
+ self._set_cpu_x86_kvm_default()
- self.cpu.set_special_mode(self.x86_cpu_default)
if self._os_object.broken_x2apic():
self.cpu.add_feature("x2apic", policy="disable")
-
def _hyperv_supported(self):
if (self.os.loader_type == "pflash" and
self.os_variant in ("win2k8r2", "win7")):

View File

@ -1,3 +1,13 @@
-------------------------------------------------------------------
Tue Apr 3 09:21:41 MDT 2018 - carnold@suse.com
- bsc#1086038 - VM guests cannot be properly installed with
virt-install
d15b78ab-virtinst-read-CPU-model-from-domain-capabilities.patch
fd6a8154-virtinst-compare-host-and-domain-cpu-models.patch
- Drop virtinst-dont-set-cpu-model-when-caps-mismatch.patch in
favor of upstream versions.
-------------------------------------------------------------------
Thu Mar 29 09:06:00 MDT 2018 - carnold@suse.com

View File

@ -40,6 +40,8 @@ Source3: virt-manager-supportconfig
# Upstream Patches
Patch0: 4c7c4590-manager-Fix-mem-disk-net-stats-graphs.patch
Patch1: 27d4b167-virtinst-update-location-for-opensuse.patch
Patch2: d15b78ab-virtinst-read-CPU-model-from-domain-capabilities.patch
Patch3: fd6a8154-virtinst-compare-host-and-domain-cpu-models.patch
# SUSE Only
Patch70: virtman-desktop.patch
Patch71: virtman-kvm.patch
@ -84,8 +86,7 @@ Patch168: virtinst-add-sle15-detection-support.patch
Patch169: virtinst-keep-install-iso-attached.patch
Patch170: virtinst-osdict-get_supported.patch
Patch171: virtinst-dont-use-special-copy-cpu-features.patch
Patch172: virtinst-dont-set-cpu-model-when-caps-mismatch.patch
Patch173: virtinst-use-latest-opensuse-version-when-unknown-media.patch
Patch172: virtinst-use-latest-opensuse-version-when-unknown-media.patch
# Python2 to Python3 patches
Patch200: virtmisc-python2-to-python3-conversion.patch
Patch201: virtcli-python2-to-python3-conversion.patch
@ -183,6 +184,8 @@ machine).
# Upstream Patches
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
# SUSE Only
%patch70 -p1
%patch71 -p1
@ -228,7 +231,6 @@ machine).
%patch170 -p1
%patch171 -p1
%patch172 -p1
%patch173 -p1
# Python2 to Python3 patches
%patch200 -p1
%patch201 -p1

View File

@ -1,131 +0,0 @@
References: bsc#1086038
The issue is when the host has been updated with microcode for Spectre v2
but qemu has not been updated. In this scenario (as an example),
'virsh capabilities' shows the host cpu model as IvyBridge-IBRS, which is
correct. However, 'virsh domcapabilities' shows IvyBridge as the host-model
and does not show any of the '-IBRS' flavors available under the custom model,
which is also correct since the qemu does not have Spectre patches. Setting
the model to the 'IBRS' version in the installation XML will cause qemu to
fail because of an unknown CPU model.
When the capabilities CPU does not match the domcapabilities CPU,
leave the model unset in the cpu mode XML.
Index: virt-manager-1.5.0/virtinst/domcapabilities.py
===================================================================
--- virt-manager-1.5.0.orig/virtinst/domcapabilities.py
+++ virt-manager-1.5.0/virtinst/domcapabilities.py
@@ -41,9 +41,27 @@ class _Enum(_HasValues):
name = XMLProperty("./@name")
+class _Model(XMLBuilder):
+ _XML_ROOT_NAME = "model"
+ model = XMLProperty(".")
+
+
+class _HasModels(XMLBuilder):
+ models = XMLChildProperty(_Model)
+
+ def get_models(self):
+ return [m.model for m in self.models]
+
+
+class _CPUMode(_HasModels):
+ _XML_ROOT_NAME = "mode"
+ name = XMLProperty("./@name")
+
+
class _CapsBlock(_HasValues):
supported = XMLProperty("./@supported", is_yesno=True)
enums = XMLChildProperty(_Enum)
+ modes = XMLChildProperty(_CPUMode)
def enum_names(self):
return [e.name for e in self.enums]
@@ -52,6 +70,12 @@ class _CapsBlock(_HasValues):
d = dict((e.name, e) for e in self.enums)
return d[name]
+ def mode_names(self):
+ return [m.name for m in self.modes]
+
+ def get_mode(self, name):
+ d = dict((m.name, m) for m in self.modes)
+ return d[name]
def _make_capsblock(xml_root_name):
class TmpClass(_CapsBlock):
@@ -65,6 +89,11 @@ class _OS(_CapsBlock):
loader = XMLChildProperty(_make_capsblock("loader"), is_single=True)
+class _CPU(_CapsBlock):
+ _XML_ROOT_NAME = "cpu"
+ mode = XMLChildProperty(_make_capsblock("mode"), is_single=True)
+
+
class _Devices(_CapsBlock):
_XML_ROOT_NAME = "devices"
hostdev = XMLChildProperty(_make_capsblock("hostdev"), is_single=True)
@@ -163,6 +192,7 @@ class DomainCapabilities(XMLBuilder):
_XML_ROOT_NAME = "domainCapabilities"
os = XMLChildProperty(_OS, is_single=True)
+ cpu = XMLChildProperty(_CPU, is_single=True)
devices = XMLChildProperty(_Devices, is_single=True)
arch = XMLProperty("./arch")
Index: virt-manager-1.5.0/virtinst/cpu.py
===================================================================
--- virt-manager-1.5.0.orig/virtinst/cpu.py
+++ virt-manager-1.5.0/virtinst/cpu.py
@@ -17,7 +17,9 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
+from .domcapabilities import DomainCapabilities
from .xmlbuilder import XMLBuilder, XMLProperty, XMLChildProperty
+import logging
class _CPUCellSibling(XMLBuilder):
@@ -96,7 +98,7 @@ class CPU(XMLBuilder):
SPECIAL_MODES = [SPECIAL_MODE_HOST_MODEL_ONLY, SPECIAL_MODE_HV_DEFAULT,
SPECIAL_MODE_HOST_COPY, SPECIAL_MODE_HOST_MODEL,
SPECIAL_MODE_HOST_PASSTHROUGH, SPECIAL_MODE_CLEAR]
- def set_special_mode(self, val):
+ def set_special_mode(self, val, guest=None):
if (val == self.SPECIAL_MODE_HOST_MODEL or
val == self.SPECIAL_MODE_HOST_PASSTHROUGH or
val == self.SPECIAL_MODE_HOST_COPY):
@@ -118,6 +120,15 @@ class CPU(XMLBuilder):
if self.conn.caps.host.cpu.model:
self.clear()
self.model = self.conn.caps.host.cpu.model
+ if guest:
+ domcaps = DomainCapabilities.build_from_guest(guest)
+ domcaps_model = domcaps.cpu.get_mode("host-model").get_models()
+ if (isinstance(domcaps_model, list) and len(domcaps_model) and
+ domcaps_model[0] != self.conn.caps.host.cpu.model):
+ logging.debug("Host capabilities CPU '%s' does not match "
+ "domain capabilities CPU '%s'. Leaving CPU model unset.",
+ self.conn.caps.host.cpu.model, domcaps_model[0])
+ self.model = None
else:
raise RuntimeError("programming error: unknown "
"special cpu mode '%s'" % val)
Index: virt-manager-1.5.0/virtinst/guest.py
===================================================================
--- virt-manager-1.5.0.orig/virtinst/guest.py
+++ virt-manager-1.5.0/virtinst/guest.py
@@ -930,7 +930,7 @@ class Guest(XMLBuilder):
if self.os.arch != self.conn.caps.host.cpu.arch:
return
- self.cpu.set_special_mode(self.x86_cpu_default)
+ self.cpu.set_special_mode(self.x86_cpu_default, self)
if self._os_object.broken_x2apic():
self.cpu.add_feature("x2apic", policy="disable")

View File

@ -114,7 +114,7 @@ Index: virt-manager-1.5.0/virtinst/guest.py
if install_xml and install_xml != final_xml:
domain = self.conn.defineXML(final_xml)
@@ -1075,7 +1075,7 @@ class Guest(XMLBuilder):
@@ -1099,7 +1099,7 @@ class Guest(XMLBuilder):
(str(d), str(addresses[addrstr][addr.function])))
addresses[addrstr][addr.function] = d
@ -294,7 +294,7 @@ Index: virt-manager-1.5.0/virtinst/domcapabilities.py
===================================================================
--- virt-manager-1.5.0.orig/virtinst/domcapabilities.py
+++ virt-manager-1.5.0/virtinst/domcapabilities.py
@@ -168,7 +168,7 @@ class DomainCapabilities(XMLBuilder):
@@ -166,7 +166,7 @@ class DomainCapabilities(XMLBuilder):
return _("BIOS")
return _("None")
@ -303,7 +303,7 @@ Index: virt-manager-1.5.0/virtinst/domcapabilities.py
for pattern in patterns:
if re.match(pattern, path):
return (_("UEFI %(arch)s: %(path)s") %
@@ -180,7 +180,7 @@ class DomainCapabilities(XMLBuilder):
@@ -178,7 +178,7 @@ class DomainCapabilities(XMLBuilder):
"""
Return True if we know how to setup UEFI for the passed arch
"""

View File

@ -43,7 +43,7 @@ Index: virt-manager-1.5.0/virtinst/guest.py
return
self.add_device(VirtualGraphics(self.conn))
@@ -1086,7 +1091,7 @@ class Guest(XMLBuilder):
@@ -1110,7 +1115,7 @@ class Guest(XMLBuilder):
if not os_support:
return False

View File

@ -1,10 +1,10 @@
Use the correct qemu emulator based on the architecture.
We want to get away from using the old qemu-dm emulator
for Xen HVM guests so default to qemu-system-i386.
Index: virt-manager-1.4.3/virtinst/guest.py
Index: virt-manager-1.5.0/virtinst/guest.py
===================================================================
--- virt-manager-1.4.3.orig/virtinst/guest.py
+++ virt-manager-1.4.3/virtinst/guest.py
--- virt-manager-1.5.0.orig/virtinst/guest.py
+++ virt-manager-1.5.0/virtinst/guest.py
@@ -897,14 +897,11 @@ class Guest(XMLBuilder):
self.emulator = None
return
@ -22,5 +22,5 @@ Index: virt-manager-1.4.3/virtinst/guest.py
+ if not self.conn.is_remote() or not self.emulator:
+ self.emulator = "/usr/lib/xen/bin/qemu-system-i386"
def _set_cpu_defaults(self):
self.cpu.set_topology_defaults(self.vcpus)
def _set_cpu_x86_kvm_default(self):
if self.os.arch != self.conn.caps.host.cpu.arch: