mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-01-11 05:17:59 +03:00
details: Allow setting CPU topology and model
Provide a button 'Copy from host CPU', which effectively sets up the equiv of qemu -cpu host
This commit is contained in:
parent
5512e192aa
commit
ecb104dbfb
@ -279,6 +279,7 @@ class vmmDetails(vmmGObjectUI):
|
||||
|
||||
self.ignorePause = False
|
||||
self.ignoreDetails = False
|
||||
self._cpu_copy_host = False
|
||||
|
||||
self.console = vmmConsolePages(self.vm, self.window)
|
||||
|
||||
@ -345,6 +346,12 @@ class vmmDetails(vmmGObjectUI):
|
||||
"on_config_vcpus_changed": self.config_vcpus_changed,
|
||||
"on_config_vcpupin_changed": self.config_vcpus_changed,
|
||||
"on_config_vcpupin_generate_clicked": self.config_vcpupin_generate,
|
||||
"on_cpu_model_changed": self.config_enable_apply,
|
||||
"on_cpu_cores_changed": self.config_enable_apply,
|
||||
"on_cpu_sockets_changed": self.config_enable_apply,
|
||||
"on_cpu_threads_changed": self.config_enable_apply,
|
||||
"on_cpu_copy_host_clicked": self.config_cpu_copy_host,
|
||||
"on_cpu_topology_enable_toggled": self.config_cpu_topology_enable,
|
||||
|
||||
"on_config_memory_changed": self.config_memory_changed,
|
||||
"on_config_maxmem_changed": self.config_maxmem_changed,
|
||||
@ -1325,6 +1332,24 @@ class vmmDetails(vmmGObjectUI):
|
||||
|
||||
self.config_enable_apply()
|
||||
|
||||
def config_cpu_copy_host(self, src_ignore):
|
||||
# Update UI with output copied from host
|
||||
try:
|
||||
CPU = virtinst.CPU(self.vm.get_connection().vmm)
|
||||
CPU.copy_host_cpu()
|
||||
|
||||
self._refresh_cpu_config(CPU)
|
||||
self._cpu_copy_host = True
|
||||
except Exception, e:
|
||||
self.err.show_err(_("Error copying host CPU: %s") % str(e),
|
||||
"".join(traceback.format_exc()))
|
||||
return
|
||||
|
||||
def config_cpu_topology_enable(self, src):
|
||||
do_enable = src.get_active()
|
||||
self.window.get_widget("cpu-topology-table").set_sensitive(do_enable)
|
||||
self.config_enable_apply()
|
||||
|
||||
# Boot device / Autostart
|
||||
def config_bootdev_selected(self, ignore):
|
||||
boot_row = self.get_boot_selection()
|
||||
@ -1508,15 +1533,35 @@ class vmmDetails(vmmGObjectUI):
|
||||
vcpus = self.window.get_widget("config-vcpus").get_adjustment().value
|
||||
cpuset = self.window.get_widget("config-vcpupin").get_text()
|
||||
|
||||
do_top = self.window.get_widget("cpu-topology-enable").get_active()
|
||||
sockets = self.window.get_widget("cpu-sockets").get_value()
|
||||
cores = self.window.get_widget("cpu-cores").get_value()
|
||||
threads = self.window.get_widget("cpu-threads").get_value()
|
||||
model = self.window.get_widget("cpu-model").get_text() or None
|
||||
|
||||
logging.info("Setting vcpus for %s to %s, cpuset is %s" %
|
||||
(self.vm.get_name(), str(vcpus), cpuset))
|
||||
|
||||
return self._change_config_helper([self.vm.define_vcpus,
|
||||
self.vm.define_cpuset],
|
||||
[(vcpus,),
|
||||
(cpuset,)],
|
||||
self.vm.hotplug_vcpus,
|
||||
(vcpus,))
|
||||
if not do_top:
|
||||
sockets = None
|
||||
cores = None
|
||||
threads = None
|
||||
|
||||
define_funcs = [self.vm.define_vcpus,
|
||||
self.vm.define_cpuset,
|
||||
self.vm.define_cpu,
|
||||
self.vm.define_cpu_topology]
|
||||
define_args = [(vcpus,),
|
||||
(cpuset,),
|
||||
(model, self._cpu_copy_host),
|
||||
(sockets, cores, threads)]
|
||||
|
||||
ret = self._change_config_helper(define_funcs, define_args,
|
||||
self.vm.hotplug_vcpus,
|
||||
(vcpus,))
|
||||
|
||||
if ret:
|
||||
self._cpu_copy_host = False
|
||||
|
||||
def config_vcpu_pin(self, src_ignore, path, new_text):
|
||||
vcpu_list = self.window.get_widget("config-vcpu-list")
|
||||
@ -1911,16 +1956,14 @@ class vmmDetails(vmmGObjectUI):
|
||||
self.network_traffic_graph.set_property("data_array",
|
||||
self.vm.network_traffic_vector())
|
||||
|
||||
def refresh_config_cpu(self):
|
||||
def _refresh_cpu_count(self, user_changed):
|
||||
conn = self.vm.get_connection()
|
||||
host_active_count = conn.host_active_processor_count()
|
||||
cpu_max = (self.vm.is_runable() and
|
||||
conn.get_max_vcpus(self.vm.get_hv_type()) or
|
||||
self.vm.vcpu_max_count())
|
||||
curvcpus = self.vm.vcpu_count()
|
||||
vcpupin = self.vm.vcpu_pinning()
|
||||
|
||||
config_apply = self.window.get_widget("config-apply")
|
||||
vcpus_adj = self.window.get_widget("config-vcpus").get_adjustment()
|
||||
|
||||
vcpus_adj.upper = cpu_max
|
||||
@ -1928,7 +1971,8 @@ class vmmDetails(vmmGObjectUI):
|
||||
host_active_count)
|
||||
self.window.get_widget("state-vm-maxvcpus").set_text(str(cpu_max))
|
||||
|
||||
if not config_apply.get_property("sensitive"):
|
||||
# If user manually changes vcpus, don't overwrite the value
|
||||
if not user_changed:
|
||||
vcpus_adj.value = curvcpus
|
||||
|
||||
self.window.get_widget("state-vm-vcpus").set_text(str(curvcpus))
|
||||
@ -1937,6 +1981,10 @@ class vmmDetails(vmmGObjectUI):
|
||||
warn = bool(vcpus_adj.value > host_active_count)
|
||||
self.window.get_widget("config-vcpus-warn-box").set_property(
|
||||
"visible", warn)
|
||||
def _refresh_cpu_pinning(self):
|
||||
conn = self.vm.get_connection()
|
||||
host_active_count = conn.host_active_processor_count()
|
||||
vcpupin = self.vm.vcpu_pinning()
|
||||
|
||||
# Populate VCPU pinning
|
||||
self.window.get_widget("config-vcpupin").set_text(vcpupin)
|
||||
@ -1976,6 +2024,30 @@ class vmmDetails(vmmGObjectUI):
|
||||
|
||||
vcpu_model.append([vcpu, vcpucur, vcpupin])
|
||||
|
||||
def _refresh_cpu_config(self, cpu):
|
||||
model = cpu.model or ""
|
||||
|
||||
show_top = bool(cpu.sockets or cpu.cores or cpu.threads)
|
||||
sockets = cpu.sockets or 1
|
||||
cores = cpu.cores or 1
|
||||
threads = cpu.threads or 1
|
||||
|
||||
self.window.get_widget("cpu-topology-enable").set_active(show_top)
|
||||
self.window.get_widget("cpu-model").set_text(model)
|
||||
self.window.get_widget("cpu-sockets").set_value(sockets)
|
||||
self.window.get_widget("cpu-cores").set_value(cores)
|
||||
self.window.get_widget("cpu-threads").set_value(threads)
|
||||
|
||||
def refresh_config_cpu(self):
|
||||
self._cpu_copy_host = False
|
||||
config_apply = self.window.get_widget("config-apply")
|
||||
user_changed = config_apply.get_property("sensitive")
|
||||
cpu = self.vm.get_cpu_config()
|
||||
|
||||
self._refresh_cpu_count(user_changed)
|
||||
self._refresh_cpu_pinning()
|
||||
self._refresh_cpu_config(cpu)
|
||||
|
||||
def refresh_config_memory(self):
|
||||
host_mem_widget = self.window.get_widget("state-host-memory")
|
||||
vm_mem_widget = self.window.get_widget("state-vm-memory")
|
||||
|
@ -301,6 +301,20 @@ class vmmDomainBase(vmmLibvirtObject):
|
||||
guest.cpuset = cpuset
|
||||
return self._redefine_guest(change)
|
||||
|
||||
def define_cpu_topology(self, sockets, cores, threads):
|
||||
def change(guest):
|
||||
cpu = guest.cpu
|
||||
cpu.sockets = sockets
|
||||
cpu.cores = cores
|
||||
cpu.threads = threads
|
||||
return self._redefine_guest(change)
|
||||
def define_cpu(self, model, from_host):
|
||||
def change(guest):
|
||||
if from_host:
|
||||
guest.cpu.copy_host_cpu()
|
||||
guest.cpu.model = model
|
||||
return self._redefine_guest(change)
|
||||
|
||||
def define_both_mem(self, memory, maxmem):
|
||||
def change(guest):
|
||||
guest.memory = int(int(memory) / 1024)
|
||||
@ -512,6 +526,9 @@ class vmmDomainBase(vmmLibvirtObject):
|
||||
def vcpu_pinning(self):
|
||||
return self._get_guest().cpuset or ""
|
||||
|
||||
def get_cpu_config(self):
|
||||
return self._get_guest().cpu
|
||||
|
||||
def get_boot_device(self):
|
||||
return self._get_guest().installer.bootconfig.bootorder
|
||||
|
||||
|
@ -2045,6 +2045,356 @@ I/O:</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkExpander" id="expander5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment31">
|
||||
<property name="visible">True</property>
|
||||
<property name="left_padding">21</property>
|
||||
<property name="right_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox20">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkTable" id="table15">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">2</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">12</property>
|
||||
<property name="row_spacing">3</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label52">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Model:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox21">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="cpu-model">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="width_chars">15</property>
|
||||
<signal name="changed" handler="on_cpu_model_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment33">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment37">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox25">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="cpu-copy-host">
|
||||
<property name="label" translatable="yes">Copy host CPU configuration</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_cpu_copy_host_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment38">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment32">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label49">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Configuration</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkExpander" id="expander6">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment39">
|
||||
<property name="visible">True</property>
|
||||
<property name="left_padding">23</property>
|
||||
<property name="right_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox15">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">4</property>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="cpu-topology-enable">
|
||||
<property name="label" translatable="yes">Manually set CPU topology</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="active">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_cpu_topology_enable_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox26">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkTable" id="cpu-topology-table">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">3</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">12</property>
|
||||
<property name="row_spacing">4</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label59">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Threads:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label58">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Cores:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label57">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Sockets:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox27">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="cpu-threads">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="adjustment">1 1 256 1 10 0</property>
|
||||
<signal name="change_value" handler="on_cpu_threads_change_value"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment40">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox28">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="cpu-cores">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="adjustment">1 1 256 1 10 0</property>
|
||||
<signal name="changed" handler="on_cpu_cores_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment41">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox29">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="cpu-sockets">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="adjustment">1 1 256 1 10 0</property>
|
||||
<signal name="changed" handler="on_cpu_sockets_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment42">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label62">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Topology</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkExpander" id="expander3">
|
||||
<property name="visible">True</property>
|
||||
@ -2223,7 +2573,7 @@ I/O:</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label9">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>CPU Pinning</b></property>
|
||||
<property name="label" translatable="yes"><b>Pinning</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
@ -2232,7 +2582,8 @@ I/O:</property>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
|
Loading…
Reference in New Issue
Block a user