Skip to content

Commit 9275e6f

Browse files
committed
qui-devices: Improve partition handling
At device_attached() function: When a partition is attached, the parent device’s entry is immediately removed from the QubesDB, the sub-device’s infomation is changed, and an device-attach event is triggered. However, due to concurrency issues, the API may not return information about the attached device. In that case, let’s query the backend domain to get the proper device information. At device_removed() function: If the parent device has sub-devices, updates their internal information. Fixes: QubesOS/qubes-issues#10828 Fixes: QubesOS/qubes-issues#10732
1 parent 3134d0c commit 9275e6f

1 file changed

Lines changed: 41 additions & 0 deletions

File tree

qui/devices/device_widget.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,36 @@ def device_removed(self, vm, _event, port):
338338
self.cameras_to_hide.remove(dev.parent)
339339
del self.devices[dev_id]
340340

341+
# If the removed device has sub-devices, update their states
342+
if dev.has_children:
343+
to_update = {}
344+
to_delete = []
345+
parent_dev = dev
346+
for dev_id, device in self.devices.items():
347+
if device.parent == parent_dev.port:
348+
vm.devices[parent_dev.device_class].clear_cache()
349+
for dev in (
350+
vm.devices[parent_dev.device_class]
351+
.get_exposed_devices()
352+
):
353+
if str(dev.port) == device.port:
354+
to_update[dev] = [
355+
attachment
356+
for attachment in device.attachments
357+
if device.attachments
358+
]
359+
if dev_id != backend.Device.id_from_device(dev):
360+
to_delete.append(device._full_id)
361+
362+
for dev, attachments in to_update.items():
363+
dev_id = backend.Device.id_from_device(dev)
364+
self.devices[dev_id] = backend.Device(dev, self)
365+
if attachments:
366+
for attachment in attachments:
367+
self.devices[dev_id].attachments.add(attachment)
368+
for dev_id in to_delete:
369+
del self.devices[dev_id]
370+
341371
def initialize_dev_data(self):
342372
# list all devices
343373
for domain in self.qapp.domains:
@@ -606,6 +636,17 @@ def device_attached(self, vm, _event, device, **_kwargs):
606636
# we don't have access to VM state
607637
return
608638

639+
if not isinstance(device, qubesadmin.device_protocol.DeviceInfo):
640+
device.backend_domain.devices[device.devclass].clear_cache()
641+
devices = (
642+
device.backend_domain
643+
.devices[device.devclass]
644+
.get_exposed_devices()
645+
)
646+
for dev in devices:
647+
if dev.port_id == device.port_id:
648+
device = dev
649+
609650
dev_id = backend.Device.id_from_device(device)
610651
if dev_id not in self.devices:
611652
self.devices[dev_id] = backend.Device(device, self)

0 commit comments

Comments
 (0)