details: Allow setting individual CPU features
This commit is contained in:
parent
a9617507e3
commit
c63282b9cb
|
@ -691,18 +691,50 @@ class vmmDetails(vmmGObjectUI):
|
|||
|
||||
no_default = not self.is_customize_dialog
|
||||
|
||||
# CPU model combo
|
||||
# CPU features
|
||||
caps = self.vm.get_connection().get_capabilities()
|
||||
cpu_values = None
|
||||
cpu_names = []
|
||||
all_features = []
|
||||
|
||||
try:
|
||||
cpu_values = caps.get_cpu_values(self.vm.get_arch())
|
||||
cpu_names = sorted(map(lambda c: c.model, cpu_values.cpus),
|
||||
key=str.lower)
|
||||
all_features = cpu_values.features
|
||||
except:
|
||||
logging.exception("Error populating CPU model list")
|
||||
|
||||
# [ feature name, enabled? ]
|
||||
feat_list = self.window.get_widget("cpu-features")
|
||||
feat_model = gtk.ListStore(str, bool)
|
||||
feat_list.set_model(feat_model)
|
||||
|
||||
nameCol = gtk.TreeViewColumn()
|
||||
chkCol = gtk.TreeViewColumn()
|
||||
|
||||
feat_list.append_column(nameCol)
|
||||
feat_list.append_column(chkCol)
|
||||
|
||||
name_text = gtk.CellRendererText()
|
||||
nameCol.pack_start(name_text, True)
|
||||
nameCol.add_attribute(name_text, 'text', 0)
|
||||
nameCol.set_sort_column_id(0)
|
||||
|
||||
feat_toggle = gtk.CellRendererToggle()
|
||||
chkCol.pack_start(feat_toggle, True)
|
||||
chkCol.add_attribute(feat_toggle, 'active', 1)
|
||||
chkCol.set_sort_column_id(1)
|
||||
|
||||
def feature_changed(src, index, model):
|
||||
model[index][1] = not src.get_active()
|
||||
self.config_enable_apply()
|
||||
|
||||
feat_toggle.connect("toggled", feature_changed, feat_model)
|
||||
for name in all_features:
|
||||
feat_model.append([name, False])
|
||||
|
||||
# CPU model combo
|
||||
cpu_model = self.window.get_widget("cpu-model")
|
||||
|
||||
model = gtk.ListStore(str, object)
|
||||
|
@ -1318,6 +1350,16 @@ class vmmDetails(vmmGObjectUI):
|
|||
|
||||
return model, None
|
||||
|
||||
def get_config_cpu_features(self):
|
||||
feature_list = self.window.get_widget("cpu-features")
|
||||
ret = []
|
||||
|
||||
for row in feature_list.get_model():
|
||||
if row[1]:
|
||||
ret.append(row[0])
|
||||
|
||||
return ret
|
||||
|
||||
##############################
|
||||
# Details/Hardware listeners #
|
||||
##############################
|
||||
|
@ -1611,6 +1653,7 @@ class vmmDetails(vmmGObjectUI):
|
|||
cores = self.window.get_widget("cpu-cores").get_value()
|
||||
threads = self.window.get_widget("cpu-threads").get_value()
|
||||
model, vendor = self.get_config_cpu_model()
|
||||
features = self.get_config_cpu_features()
|
||||
|
||||
logging.info("Setting vcpus for %s to %s, cpuset is %s" %
|
||||
(self.vm.get_name(), str(vcpus), cpuset))
|
||||
|
@ -1626,7 +1669,7 @@ class vmmDetails(vmmGObjectUI):
|
|||
self.vm.define_cpu_topology]
|
||||
define_args = [(vcpus, maxv),
|
||||
(cpuset,),
|
||||
(model, vendor, self._cpu_copy_host),
|
||||
(model, vendor, self._cpu_copy_host, features),
|
||||
(sockets, cores, threads)]
|
||||
|
||||
ret = self._change_config_helper(define_funcs, define_args,
|
||||
|
@ -2121,6 +2164,7 @@ class vmmDetails(vmmGObjectUI):
|
|||
vcpu_model.append([vcpu, vcpucur, vcpupin])
|
||||
|
||||
def _refresh_cpu_config(self, cpu):
|
||||
feature_ui = self.window.get_widget("cpu-features")
|
||||
model = cpu.model or ""
|
||||
|
||||
show_top = bool(cpu.sockets or cpu.cores or cpu.threads)
|
||||
|
@ -2134,6 +2178,15 @@ class vmmDetails(vmmGObjectUI):
|
|||
self.window.get_widget("cpu-cores").set_value(cores)
|
||||
self.window.get_widget("cpu-threads").set_value(threads)
|
||||
|
||||
def has_feature(name):
|
||||
for f in cpu.features:
|
||||
if f.name == name:
|
||||
return True
|
||||
return False
|
||||
|
||||
for row in feature_ui.get_model():
|
||||
row[1] = has_feature(row[0])
|
||||
|
||||
def refresh_config_cpu(self):
|
||||
self._cpu_copy_host = False
|
||||
cpu = self.vm.get_cpu_config()
|
||||
|
|
|
@ -309,7 +309,7 @@ class vmmDomainBase(vmmLibvirtObject):
|
|||
cpu.cores = cores
|
||||
cpu.threads = threads
|
||||
return self._redefine_guest(change)
|
||||
def define_cpu(self, model, vendor, from_host):
|
||||
def define_cpu(self, model, vendor, from_host, featurelist):
|
||||
def change(guest):
|
||||
if from_host:
|
||||
guest.cpu.copy_host_cpu()
|
||||
|
@ -318,6 +318,17 @@ class vmmDomainBase(vmmLibvirtObject):
|
|||
# caps value
|
||||
guest.cpu.vendor = vendor
|
||||
guest.cpu.model = model or None
|
||||
|
||||
# Sync feature lists
|
||||
origfeatures = guest.cpu.features
|
||||
for f in origfeatures:
|
||||
if f.name not in featurelist:
|
||||
guest.cpu.remove_feature(f)
|
||||
else:
|
||||
featurelist.remove(f.name)
|
||||
for f in featurelist:
|
||||
guest.cpu.add_feature(f)
|
||||
|
||||
return self._redefine_guest(change)
|
||||
|
||||
def define_both_mem(self, memory, maxmem):
|
||||
|
|
|
@ -2032,8 +2032,9 @@ I/O:</property>
|
|||
<property name="left_padding">21</property>
|
||||
<property name="right_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox20">
|
||||
<widget class="GtkVBox" id="vbox220">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<widget class="GtkTable" id="table15">
|
||||
<property name="visible">True</property>
|
||||
|
@ -2135,10 +2136,62 @@ I/O:</property>
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment32">
|
||||
<widget class="GtkExpander" id="cpu-features-expander">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
<widget class="GtkAlignment" id="alignment29">
|
||||
<property name="visible">True</property>
|
||||
<property name="left_padding">21</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox19">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow4">
|
||||
<property name="height_request">150</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<property name="shadow_type">etched-in</property>
|
||||
<child>
|
||||
<widget class="GtkTreeView" id="cpu-features">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">False</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<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="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>CPU Features</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
|
|
Loading…
Reference in New Issue