Skip to content

Commit 4a16de5

Browse files
committed
q-dev: fix block device removing
1 parent 5b38d7f commit 4a16de5

File tree

2 files changed

+26
-17
lines changed

2 files changed

+26
-17
lines changed

qubes/ext/block.py

+14-8
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,8 @@ async def on_domain_shutdown(self, vm, event, **_kwargs):
643643
if front_vm is None:
644644
continue
645645
dev = BlockDevice(vm, dev_id)
646-
await self._detach_and_notify(vm, dev, options=None)
646+
vm.fire_event(f"device-removed:block", port=dev.port)
647+
await self.detach_and_notify(front_vm, dev.port)
647648
continue
648649
for dev_id, front_vm in self.devices_cache[domain.name].items():
649650
if front_vm == vm:
@@ -657,14 +658,19 @@ async def on_domain_shutdown(self, vm, event, **_kwargs):
657658
new_cache[domain.name][dev_id] = front_vm
658659
self.devices_cache = new_cache.copy()
659660

660-
async def _detach_and_notify(self, vm, device, options):
661+
def ensure_detach(self, vm, port):
662+
"""
663+
Run this method if device is no longer detected.
664+
665+
If usb device which exposes block device is removed a zombie block
666+
device may remain in vm xml, so we ensure that it will be removed too.
667+
"""
668+
self.on_device_pre_detached_block(vm, "device-pre-detach:block", port)
669+
670+
async def detach_and_notify(self, vm, port):
661671
# bypass DeviceCollection logic preventing double attach
662-
self.on_device_pre_detached_block(
663-
vm, "device-pre-detach:block", device.port
664-
)
665-
await vm.fire_event_async(
666-
"device-detach:block", port=device.port, options=options
667-
)
672+
self.on_device_pre_detached_block(vm, "device-pre-detach:block", port)
673+
await vm.fire_event_async("device-detach:block", port=port)
668674

669675
@qubes.ext.handler("qubes-close", system=True)
670676
def on_qubes_close(self, app, event):

qubes/ext/utils.py

+12-9
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def device_list_change(
5252
# send events about devices detached/attached outside by themselves
5353
for port_id, front_vm in detached.items():
5454
dev = device_class(vm, port_id)
55+
ext.ensure_detach(front_vm, dev.port)
5556
asyncio.ensure_future(
5657
front_vm.fire_event_async(
5758
f"device-detach:{devclass}", port=dev.port
@@ -63,8 +64,8 @@ def device_list_change(
6364
for port_id in added:
6465
device = device_class(vm, port_id)
6566
vm.fire_event(f"device-added:{devclass}", device=device)
66-
for dev_ident, front_vm in attached.items():
67-
dev = device_class(vm, dev_ident)
67+
for port_id, front_vm in attached.items():
68+
dev = device_class(vm, port_id)
6869
# options are unknown, device already attached
6970
asyncio.ensure_future(
7071
front_vm.fire_event_async(
@@ -167,6 +168,7 @@ async def confirm_device_attachment(device, frontends) -> str:
167168
print(str(exc.__class__.__name__) + ":", str(exc), file=sys.stderr)
168169
return ""
169170

171+
170172
async def _do_confirm_device_attachment(device, frontends):
171173
socket = "device-agent.GUI"
172174

@@ -189,23 +191,24 @@ async def _do_confirm_device_attachment(device, frontends):
189191
"targets": front_names,
190192
"default_target": front_names[0] if number_of_targets == 1 else "",
191193
"icons": {
192-
dom.name
193-
if dom.klass != "DispVM" else f'@dispvm:{dom.name}':
194-
dom.icon for dom in doms.values()
194+
(
195+
dom.name if dom.klass != "DispVM" else f"@dispvm:{dom.name}"
196+
): dom.icon
197+
for dom in doms.values()
195198
},
196199
}
197200

198-
socked_call = asyncio.create_task(call_socket_service(
199-
guivm, socket, "dom0", params, SOCKET_PATH
200-
))
201+
socked_call = asyncio.create_task(
202+
call_socket_service(guivm, socket, "dom0", params, SOCKET_PATH)
203+
)
201204

202205
while not socked_call.done():
203206
await asyncio.sleep(0.1)
204207

205208
ask_response = await socked_call
206209

207210
if ask_response.startswith("allow:"):
208-
chosen = ask_response[len("allow:"):]
211+
chosen = ask_response[len("allow:") :]
209212
if chosen in front_names:
210213
return chosen
211214
return ""

0 commit comments

Comments
 (0)