This commit is contained in:
Cole Robinson 2014-02-05 13:51:53 -05:00
parent 7a825d9a28
commit f5c32063e4
11 changed files with 105 additions and 80 deletions

View File

@ -229,7 +229,7 @@
<key name="cpu-default" type="s">
<default>'default'</default>
<summary>CPU setting to use for new VMs</summary>
<description>CPU setting to use for new VMs. Limited to VMs matching the host architecture. Possible values: default (virt-manager default), hv-default (qemu's default), host-cpu-model (just the model, not the additional features), host-model (libvirt's host-model setting).</description>
<description>CPU setting to use for new VMs. Limited to VMs matching the host architecture. Possible values: default (virt-manager default), hv-default (qemu's default), host-model-only (just the model, not the additional features), host-model (libvirt's host-model setting).</description>
</key>
</schema>

View File

@ -14,6 +14,9 @@
<apic/>
<pae/>
</features>
<cpu mode="custom" match="exact">
<model>core2duo</model>
</cpu>
<clock offset="localtime">
<timer name="rtc" tickpolicy="catchup"/>
<timer name="pit" tickpolicy="delay"/>
@ -71,6 +74,9 @@
<apic/>
<pae/>
</features>
<cpu mode="custom" match="exact">
<model>core2duo</model>
</cpu>
<clock offset="localtime">
<timer name="rtc" tickpolicy="catchup"/>
<timer name="pit" tickpolicy="delay"/>
@ -128,6 +134,9 @@
<apic/>
<pae/>
</features>
<cpu mode="custom" match="exact">
<model>core2duo</model>
</cpu>
<clock offset="localtime">
<timer name="rtc" tickpolicy="catchup"/>
<timer name="pit" tickpolicy="delay"/>

View File

@ -5,6 +5,9 @@
<currentMemory>65536</currentMemory>
<vcpu>1</vcpu>
<bootloader>/usr/bin/pygrub</bootloader>
<cpu mode="custom" match="exact">
<model>pentium2</model>
</cpu>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>

View File

@ -523,10 +523,10 @@ c = vinst.add_category("kvm", "--connect %(KVMURI)s --noautoconsole")
c.add_compare("--os-variant fedora20 --file %(EXISTIMG1)s --location %(TREEDIR)s --extra-args console=ttyS0 --cpu host --channel none --console none --sound none --redirdev none", "kvm-f14-url") # F14 Directory tree URL install with extra-args
c.add_compare("--os-variant fedora20 --disk %(NEWIMG1)s,size=.01 --location %(TREEDIR)s --extra-args console=ttyS0 --quiet", "quiet-url") # Quiet URL install should make no noise
c.add_compare("--cdrom %(EXISTIMG2)s --file %(EXISTIMG1)s --os-variant win2k3 --wait 0 --sound --controller usb", "kvm-win2k3-cdrom") # HVM windows install with disk
c.add_compare("--os-variant fedora20 --nodisks --boot hd --paravirt", "kvm-xenner") # xenner
c.add_compare("--os-variant fedora20 --nodisks --boot hd --paravirt --cpu pentium2", "kvm-xenner") # xenner
c.add_compare("--os-variant fedora20 --nodisks --boot cdrom --virt-type qemu --cpu Penryn", "qemu-plain") # plain qemu
c.add_compare("--os-variant fedora20 --nodisks --boot network --nographics --arch i686", "qemu-32-on-64") # 32 on 64
c.add_compare("--os-variant fedora20 --nodisks --boot fd --graphics spice --machine pc", "kvm-machine") # kvm machine type 'pc'
c.add_compare("--os-variant fedora20 --nodisks --boot fd --graphics spice --machine pc --cpu none", "kvm-machine") # kvm machine type 'pc'
c.add_compare("--os-variant fedora20 --nodisks --boot fd --graphics sdl --arch sparc --machine SS-20", "qemu-sparc") # exotic arch + machine type
c.add_compare("--arch armv7l --machine vexpress-a9 --boot kernel=/f19-arm.kernel,initrd=/f19-arm.initrd,dtb=/f19-arm.dtb,extra_args=\"console=ttyAMA0 rw root=/dev/mmcblk0p3\" --disk %(EXISTIMG1)s --nographics", "arm-vexpress-plain", skip_check=support.SUPPORT_CONN_DISK_SD)
c.add_compare("--arch armv7l --machine vexpress-a15 --boot kernel=/f19-arm.kernel,initrd=/f19-arm.initrd,dtb=/f19-arm.dtb,kernel_args=\"console=ttyAMA0 rw root=/dev/vda3\",extra_args=foo --disk %(EXISTIMG1)s --nographics --os-variant fedora19", "arm-vexpress-f19", skip_check=support.SUPPORT_CONN_VIRTIO_MMIO)

View File

@ -26,6 +26,7 @@ from gi.repository import GLib
from gi.repository import Gtk
# pylint: enable=E0611
from virtinst import CPU
from virtManager.keyring import vmmKeyring, vmmSecret
running_config = None
@ -455,14 +456,24 @@ class vmmConfig(object):
def set_storage_format(self, typ):
self.conf.set("/new-vm/storage-format", typ.lower())
def get_default_cpu_setting(self, raw=False):
def get_default_cpu_setting(self, raw=False, for_cpu=False):
ret = self.conf.get("/new-vm/cpu-default")
whitelist = ["default", "hv-default", "host-cpu-model", "host-model"]
whitelist = [CPU.SPECIAL_MODE_HOST_MODEL_ONLY,
CPU.SPECIAL_MODE_HOST_MODEL,
CPU.SPECIAL_MODE_HV_DEFAULT]
if ret not in whitelist:
ret = "default"
if ret == "default" and not raw:
ret = self.cpu_default_from_config
if ret not in whitelist:
ret = whitelist[0]
if for_cpu and ret == CPU.SPECIAL_MODE_HOST_MODEL:
# host-model has known issues, so use our 'copy cpu'
# behavior until host-model does what we need
ret = CPU.SPECIAL_MODE_HOST_COPY
return ret
def set_default_cpu_setting(self, val):
self.conf.set("/new-vm/cpu-default", val.lower())

View File

@ -1391,6 +1391,8 @@ class vmmCreate(vmmGObjectUI):
guest.skip_default_usbredir = (
self.config.get_add_spice_usbredir() == "no")
guest.x86_cpu_default = self.config.get_default_cpu_setting(
for_cpu=True)
guest.add_default_video_device()
guest.add_default_input_device()
@ -1398,24 +1400,6 @@ class vmmCreate(vmmGObjectUI):
guest.add_default_usb_controller()
guest.add_default_channels()
if (((guest.conn.is_qemu() and guest.type == "kvm") or
guest.conn.is_test()) and
guest.os.is_x86() and
guest.os.arch == guest.conn.caps.host.cpu.arch):
cpu_type = self.config.get_default_cpu_setting()
if cpu_type == "hv-default":
pass
elif cpu_type == "host-cpu-model":
if guest.conn.caps.host.cpu.model:
guest.cpu.model = guest.conn.caps.host.cpu.model
elif cpu_type == "host-model":
# host-model has known issues, so use our 'copy cpu'
# behavior until host-model does what we need
guest.cpu.copy_host_cpu()
else:
raise RuntimeError("Unknown cpu default '%s'" % cpu_type)
if self.conn.check_support(self.conn.SUPPORT_CONN_PM_DISABLE):
guest.pm.suspend_to_mem = False
guest.pm.suspend_to_disk = False

View File

@ -874,8 +874,10 @@ class vmmDetails(vmmGObjectUI):
cpu_model.set_row_separator_func(sep_func, None)
model.set_sort_column_id(1, Gtk.SortType.ASCENDING)
model.append([_("Application Default"), "1", "appdefault", False])
model.append([_("Hypervisor Default"), "2", "hypdefault", False])
model.append([_("Clear CPU configuration"), "3", "clearcpu", False])
model.append([_("Hypervisor Default"), "2",
virtinst.CPU.SPECIAL_MODE_HV_DEFAULT, False])
model.append([_("Clear CPU configuration"), "3",
virtinst.CPU.SPECIAL_MODE_CLEAR, False])
model.append([None, None, None, True])
for name in [c.model for c in cpu_values.cpus]:
model.append([name, name, name, False])
@ -1426,43 +1428,22 @@ class vmmDetails(vmmGObjectUI):
def get_config_cpu_model(self):
cpu_list = self.widget("cpu-model")
text = cpu_list.get_child().get_text()
model = None
mode = None
copy_host = bool(self.widget("cpu-copy-host").get_active())
key = None
row = None
for r in cpu_list.get_model():
if text == r[0]:
row = r
if self.widget("cpu-copy-host").get_active():
return virtinst.CPU.SPECIAL_MODE_HOST_COPY
key = None
for row in cpu_list.get_model():
if text == row[0]:
key = row[2]
break
if row:
key = row[2]
elif text == "host-model" or text == "host-passthrough":
mode = text
else:
model = text
if not key:
return text
if key == "hypdefault" or key == "clearcpu":
# Clear the whole CPU
pass
elif key == "appdefault":
cpu_type = self.config.get_default_cpu_setting()
if cpu_type == "hv-default":
pass
elif cpu_type == "host-cpu-model":
if self.vm.conn.caps.host.cpu.model:
model = self.vm.conn.caps.host.cpu.model
elif cpu_type == "host-model":
copy_host = True
else:
raise RuntimeError("Unknown cpu default '%s'" % cpu_type)
elif key:
model = key
return model, mode, copy_host
if key == "appdefault":
return self.config.get_default_cpu_setting(for_cpu=True)
return key
##############################
@ -1875,9 +1856,8 @@ class vmmDetails(vmmGObjectUI):
add_define(self.vm.define_cpuset, cpuset)
if self.edited(EDIT_CPU):
model, mode, copy_host = self.get_config_cpu_model()
add_define(self.vm.define_cpu,
model, mode, copy_host)
val = self.get_config_cpu_model()
add_define(self.vm.define_cpu, val)
if self.edited(EDIT_TOPOLOGY):
do_top = self.widget("cpu-topology-enable").get_active()
@ -2461,7 +2441,8 @@ class vmmDetails(vmmGObjectUI):
self.widget("cpu-model").get_child().set_text(model)
else:
uiutil.set_combo_entry(
self.widget("cpu-model"), "hypdefault", 2)
self.widget("cpu-model"),
virtinst.CPU.SPECIAL_MODE_HV_DEFAULT, 2)
# Determine if CPU definition is just the host copy
hostcpu = self.conn.caps.host.cpu

View File

@ -537,18 +537,12 @@ class vmmDomain(vmmLibvirtObject):
cpu.cores = cores
cpu.threads = threads
return self._redefine(change)
def define_cpu(self, model, mode, copy_host):
def define_cpu(self, val):
def change(guest):
if copy_host:
guest.cpu.copy_host_cpu()
elif mode:
guest.cpu.clear()
guest.cpu.mode = mode
elif model:
guest.cpu.model = model
guest.cpu.vendor = None
if val in guest.cpu.SPECIAL_MODES:
guest.cpu.set_special_mode(val)
else:
guest.cpu.clear()
guest.cpu.model = val
return self._redefine(change)
# Mem define methods

View File

@ -1236,13 +1236,12 @@ class ParserCPU(VirtCLIParser):
ignore = opts
ignore = cliname
if val == "host":
inst.cpu.copy_host_cpu()
elif (val == "host-model-only" and
self.guest.conn.caps.host.cpu.model):
inst.cpu.model = self.guest.conn.caps.host.cpu.model
elif val == "host-model" or val == "host-passthrough":
inst.cpu.model = None
inst.cpu.mode = val
val = inst.cpu.SPECIAL_MODE_HOST_COPY
if val == "none":
val = inst.cpu.SPECIAL_MODE_CLEAR
if val in inst.cpu.SPECIAL_MODES:
inst.cpu.set_special_mode(val)
else:
inst.cpu.model = val

View File

@ -38,13 +38,42 @@ class CPU(XMLBuilder):
"""
Class for generating <cpu> XML
"""
MATCHS = ["minimum", "exact", "strict"]
_XML_ROOT_NAME = "cpu"
_XML_PROP_ORDER = ["mode", "match", "model", "vendor",
"sockets", "cores", "threads", "features"]
special_mode_was_set = False
# These values are exposed on the command line, so are stable API
SPECIAL_MODE_HOST_MODEL_ONLY = "host-model-only"
SPECIAL_MODE_HV_DEFAULT = "hv-default"
SPECIAL_MODE_HOST_COPY = "host-copy"
SPECIAL_MODE_HOST_MODEL = "host-model"
SPECIAL_MODE_HOST_PASSTHROUGH = "host-passthrough"
SPECIAL_MODE_CLEAR = "clear"
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):
if (val == self.SPECIAL_MODE_HOST_MODEL or
val == self.SPECIAL_MODE_HOST_PASSTHROUGH):
self.model = None
self.mode = val
elif val == self.SPECIAL_MODE_HOST_COPY:
self.copy_host_cpu()
elif (val == self.SPECIAL_MODE_HV_DEFAULT or
val == self.SPECIAL_MODE_CLEAR):
self.clear()
elif val == self.SPECIAL_MODE_HOST_MODEL_ONLY:
if self.conn.caps.host.cpu.model:
self.model = self.conn.caps.host.cpu.model
else:
raise RuntimeError("programming error: unknown "
"special cpu mode '%s'" % val)
self.special_mode_was_set = True
def add_feature(self, name, policy="require"):
feature = CPUFeature(self.conn)
feature.name = name

View File

@ -108,6 +108,7 @@ class Guest(XMLBuilder):
self.skip_default_channel = False
self.skip_default_sound = False
self.skip_default_usbredir = False
self.x86_cpu_default = self.cpu.SPECIAL_MODE_HOST_MODEL_ONLY
self._os_variant = None
self._random_uuid = None
@ -693,6 +694,20 @@ class Guest(XMLBuilder):
def _set_cpu_defaults(self):
self.cpu.set_topology_defaults(self.vcpus)
if (not self.conn.is_test() and not
(self.conn.is_qemu() and self.type == "kvm")):
return
if not self.os.is_x86():
return
if self.os.arch != self.conn.caps.host.cpu.arch:
return
if self.cpu.special_mode_was_set:
return
if self.cpu.get_xml_config().strip():
return
self.cpu.set_special_mode(self.x86_cpu_default)
def _set_feature_defaults(self):
if self.os.is_container():
self.features.acpi = None