Added 'configure no strict reset for PCI devices' button

The button is in 'devices' tab of VM settings; it allows the user to
select which devices should have 'no-strict-reset' enabled and tells
the user not to change this setting if there are no errors.

fixes QubesOS/qubes-issues#3205
This commit is contained in:
Marta Marczykowska-Górecka 2018-01-12 23:56:48 +01:00
parent f4fae54057
commit 801014f2e5
No known key found for this signature in database
GPG Key ID: 9A752C30B26FD04B
3 changed files with 163 additions and 17 deletions

View File

@ -22,12 +22,13 @@ from PyQt4 import QtGui, QtCore # pylint: disable=import-error
class PCIDeviceListWindow(ui_devicelist.Ui_Dialog, QtGui.QDialog):
def __init__(self, vm, qapp, dev_list, parent=None):
def __init__(self, vm, qapp, dev_list, no_strict_reset_list, parent=None):
super(PCIDeviceListWindow, self).__init__(parent)
self.vm = vm
self.qapp = qapp
self.dev_list = dev_list
self.no_strict_reset_list = no_strict_reset_list
self.setupUi(self)
@ -36,26 +37,26 @@ class PCIDeviceListWindow(ui_devicelist.Ui_Dialog, QtGui.QDialog):
self.connect(
self.buttonBox, QtCore.SIGNAL("rejected()"), self.reject)
self.ident_list = {}
self.fill_device_list()
def fill_device_list(self):
self.device_list.clear()
pci_devices = [ass.ident.replace('_', ':')
for ass in self.vm.devices['pci'].assignments()]
for i in range(self.dev_list.selected_list.count()):
text = self.dev_list.selected_list.item(i).text()
ident = self.dev_list.selected_list.item(i).ident
if ident in pci_devices:
self.device_list.addItem(text)
self.device_list.addItem(text)
self.ident_list[text] = ident
if ident in self.no_strict_reset_list:
self.device_list.setItemSelected(
self.device_list.item(i), True)
def reject(self):
self.done(0)
def save_and_apply(self):
self.no_strict_reset_list.clear()
self.no_strict_reset_list.extend([self.ident_list[item.text()] for item
in self.device_list.selectedItems()])
self.done(0)
def show(self):
super(PCIDeviceListWindow, self).show()
self.fill_device_list()

View File

@ -126,6 +126,9 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
self.devices_selection_changed)
self.no_strict_reset_button.clicked.connect(
self.strict_reset_button_pressed)
self.current_strict_reset_list = []
self.new_strict_reset_list = []
self.define_strict_reset_devices()
####### services tab
self.__init_services_tab__()
@ -664,6 +667,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
if self.vm.is_running():
self.dev_list.setEnabled(False)
self.turn_off_vm_to_modify_devs.setVisible(True)
self.no_strict_reset_button.setEnabled(False)
else:
self.dev_list.setEnabled(True)
self.turn_off_vm_to_modify_devs.setVisible(False)
@ -671,8 +675,6 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
def __apply_devices_tab__(self):
msg = []
no_strict_reset = self.no_pci_strict_reset.isChecked()
try:
old = [ass.ident.replace('_', ':')
for ass in self.vm.devices['pci'].persistent()]
@ -682,13 +684,35 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
for ident in new:
if ident not in old:
options = {}
if no_strict_reset:
if ident in self.new_strict_reset_list:
options['no-strict-reset'] = True
ass = devices.DeviceAssignment(
self.vm.app.domains['dom0'],
ident.replace(':', '_'),
persistent=True, options=options)
self.vm.devices['pci'].attach(ass)
elif (ident in self.current_strict_reset_list) != \
(ident in self.new_strict_reset_list):
current_assignment = None
for assignment in self.vm.devices['pci'].assignments(
persistent=True):
if assignment.ident.replace("_", ":") == ident:
current_assignment = assignment
break
if current_assignment is None:
# it would be very weird if this happened
break
self.vm.devices['pci'].detach(current_assignment)
options = {}
if ident in self.new_strict_reset_list:
options['no-strict-reset'] = True
new_assignment = devices.DeviceAssignment(
self.vm.app.domains['dom0'],
ident.replace(':', '_'),
persistent=True, options=options)
self.vm.devices['pci'].attach(new_assignment)
for ass in self.vm.devices['pci'].assignments(persistent=True):
if ass.ident.replace('_', ':') not in new:
self.vm.devices['pci'].detach(ass)
@ -725,12 +749,18 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
self.dmm_warning_adv.hide()
self.dmm_warning_dev.hide()
def define_strict_reset_devices(self):
for assignment in self.vm.devices['pci'].assignments():
if 'no-strict-reset' in assignment.options and \
assignment.options['no-strict-reset']:
self.current_strict_reset_list.append(
assignment.ident.replace('_', ':'))
self.new_strict_reset_list = self.current_strict_reset_list.copy()
def strict_reset_button_pressed(self):
device_list_window = device_list.PCIDeviceListWindow(
self.vm, self.qapp, self.dev_list, self)
device_list_window.show()
pass
self.vm, self.qapp, self.dev_list, self.new_strict_reset_list, self)
device_list_window.exec()
######## applications tab

115
ui/devicelist.ui Normal file
View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Select devices</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>10</x>
<y>260</y>
<width>391</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QListWidget" name="device_list">
<property name="geometry">
<rect>
<x>0</x>
<y>40</y>
<width>391</width>
<height>171</height>
</rect>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>391</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Which PCI devices should use the no strict reset option?</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>0</x>
<y>220</y>
<width>391</width>
<height>41</height>
</rect>
</property>
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Note: use this option only if &quot;unable to reset PCI device&quot; error occurs. </string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>