CPU Pinning support

Virt-manager doesn't consider CPU pinning settings in the Processor tab yet so
this is the patch to provide CPU pinning support for virt-manager. It's using
only CPU definition for libvirt itself and it doesn't support CPU pinning for
domains that are currently in running state since this feature will be rarely
used for already running domains in my opinion.
This commit is contained in:
Michal Novotny 2009-07-27 22:55:11 -04:00
parent 499964c584
commit 7277d28c46
3 changed files with 253 additions and 127 deletions

View File

@ -763,6 +763,7 @@ class vmmDetails(gobject.GObject):
ro = vm.is_read_only()
self.window.get_widget("config-vcpus").set_sensitive(not ro)
self.window.get_widget("config-vcpupin").set_sensitive(not ro)
self.window.get_widget("config-memory").set_sensitive(not ro)
self.window.get_widget("config-maxmem").set_sensitive(not ro)
self.window.get_widget("details-menu-migrate").set_sensitive(not ro)
@ -950,6 +951,7 @@ class vmmDetails(gobject.GObject):
if not(self.window.get_widget("config-apply").get_property("sensitive")):
self.window.get_widget("config-vcpus").get_adjustment().value = self.vm.vcpu_count()
self.window.get_widget("state-vm-vcpus").set_text("%d" % (self.vm.vcpu_count()))
self.window.get_widget("config-vcpupin").set_text("%s" % self.vm.vcpu_pinning() )
def refresh_config_memory(self):
self.window.get_widget("state-host-memory").set_text("%d MB" % (int(round(self.vm.get_connection().host_memory_size()/1024))))
@ -1575,8 +1577,21 @@ class vmmDetails(gobject.GObject):
def config_vcpus_apply(self):
vcpus = self.window.get_widget("config-vcpus").get_adjustment().value
logging.info("Setting vcpus for %s to %s" % (self.vm.get_name(),
str(vcpus)))
cpuset = self.window.get_widget("config-vcpupin").get_text()
try:
self.vm.get_cpuset_syntax_error(cpuset)
except Exception, e:
self.err.show_err(_("Error setting CPU pinning: %s") % str(e),
"".join(traceback.format_exc()))
return False
# Since for cpuset we require None for define_vcpus, we'll change this now
if len(cpuset) == 0:
cpuset = None
logging.info("Setting vcpus for %s to %s, cpuset is %s" %
(self.vm.get_name(), str(vcpus), cpuset))
hotplug_err = False
try:
@ -1588,7 +1603,7 @@ class vmmDetails(gobject.GObject):
# Change persistent config
try:
self.vm.define_vcpus(vcpus)
self.vm.define_vcpus(vcpus, cpuset)
except Exception, e:
self.err.show_err(_("Error changing vcpu value: %s" % str(e)),
"".join(traceback.format_exc()))

View File

@ -24,9 +24,11 @@ import os
import logging
import time
import difflib
import re
from virtManager import util
import virtinst.util as vutil
import virtinst.Guest as vguest
def safeint(val, fmt="%.3d"):
try:
@ -554,6 +556,13 @@ class vmmDomain(gobject.GObject):
return 0
return self.record[0]["vcpuCount"]
def vcpu_pinning(self):
cpuset = vutil.get_xml_path(self.get_xml(), "/domain/vcpu/@cpuset")
# We need to set it to empty string not to show None in the entry
if cpuset is None:
cpuset = ""
return cpuset
def vcpu_max_count(self):
cpus = vutil.get_xml_path(self.get_xml(), "/domain/vcpu")
return int(cpus)
@ -1329,22 +1338,39 @@ class vmmDomain(gobject.GObject):
if vcpus != self.vcpu_count():
self.vm.setVcpus(vcpus)
def define_vcpus(self, vcpus):
def get_cpuset_syntax_error(self, val):
# We need to allow None value and empty string so we can't get
# rid of this function
if len(val) == 0:
return None
guest = vguest(connection = self.get_connection().vmm)
guest.cpuset = val
def define_vcpus(self, vcpus, cpuset=None):
vcpus = int(vcpus)
def set_node(doc, ctx, val, xpath):
def set_node(doc, ctx, vcpus, cpumask, xpath):
node = ctx.xpathEval(xpath)
node = (node and node[0] or None)
if node:
node.setContent(str(val))
node.setContent(str(vcpus))
# If cpuset mask is not valid, don't change it
# If cpuset mask is None, we don't want to use cpuset
if cpumask is None or (cpumask is not None
and len(cpumask) == 0):
node.unsetProp("cpuset")
elif not self.get_cpuset_syntax_error(cpumask):
node.setProp("cpuset", cpumask)
return doc.serialize()
def change_vcpu_xml(xml, vcpus):
return util.xml_parse_wrapper(xml, set_node, vcpus,
def change_vcpu_xml(xml, vcpus, cpuset):
return util.xml_parse_wrapper(xml, set_node, vcpus, cpuset,
"/domain/vcpu[1]")
self.redefine(change_vcpu_xml, vcpus)
self.redefine(change_vcpu_xml, vcpus, cpuset)
def hotplug_memory(self, memory):
if memory != self.get_memory():

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.5 on Thu Jul 9 10:48:48 2009 -->
<!--Generated with glade3 3.4.5 on Mon Jul 27 22:54:20 2009 -->
<glade-interface>
<widget class="GtkWindow" id="vmm-details">
<property name="title" translatable="yes">Virtual Machine</property>
@ -1543,127 +1543,212 @@ I/O:</property>
</packing>
</child>
<child>
<widget class="GtkTable" id="table30">
<widget class="GtkAlignment" id="alignment11">
<property name="visible">True</property>
<property name="border_width">3</property>
<property name="n_rows">4</property>
<property name="n_columns">2</property>
<property name="column_spacing">3</property>
<property name="row_spacing">3</property>
<property name="left_padding">12</property>
<child>
<widget class="GtkLabel" id="label347">
<widget class="GtkTable" id="table30">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Current allocation:</property>
<property name="border_width">3</property>
<property name="n_rows">5</property>
<property name="n_columns">3</property>
<property name="column_spacing">12</property>
<property name="row_spacing">6</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<widget class="GtkHBox" id="hbox4">
<property name="visible">True</property>
<child>
<widget class="GtkEntry" id="config-vcpupin">
<property name="visible">True</property>
<property name="can_focus">True</property>
<accessibility>
<atkproperty name="AtkObject::accessible_name" translatable="yes">Virtual CPU Affinity Select</atkproperty>
</accessibility>
<signal name="changed" handler="on_config_vcpus_changed"/>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment14">
<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">3</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="state-vm-maxvcpus">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label">8</property>
</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>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="state-vm-vcpus">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label">2</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="state-host-cpus">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label">8</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label334">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Host CPUs:</property>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label335">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Maximum allocation:</property>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label347">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Current allocation:</property>
</widget>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label336">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Physical CPU pinning:</property>
</widget>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label333">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Change allocation:</property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox5">
<property name="visible">True</property>
<child>
<widget class="GtkSpinButton" id="config-vcpus">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">2 1 32 1 2 0</property>
<property name="climb_rate">1</property>
<property name="numeric">True</property>
<property name="update_policy">GTK_UPDATE_IF_VALID</property>
<accessibility>
<atkproperty name="AtkObject::accessible_name" translatable="yes">Virtual CPU Select</atkproperty>
</accessibility>
<signal name="changed" handler="on_config_vcpus_changed"/>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment12">
<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>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
</widget>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label333">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Change allocation:</property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label335">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Maximum allocation:</property>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label334">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Total CPUs on host machine:</property>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="state-vm-maxvcpus">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label">8</property>
</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>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="state-host-cpus">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label">8</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="state-vm-vcpus">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label">2</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="config-vcpus">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">2 1 32 1 2 0</property>
<property name="climb_rate">1</property>
<property name="numeric">True</property>
<property name="update_policy">GTK_UPDATE_IF_VALID</property>
<accessibility>
<atkproperty name="AtkObject::accessible_name" translatable="yes">Virtual CPU Select</atkproperty>
</accessibility>
<signal name="changed" handler="on_config_vcpus_changed"/>
</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>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
<packing>