Skip to content

Commit 7374fee

Browse files
committed
Cache block devices
1 parent b81f632 commit 7374fee

1 file changed

Lines changed: 40 additions & 7 deletions

File tree

qubes/ext/block.py

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,8 @@ def _is_attached_to(self, vm):
233233

234234
for disk in xml_desc.findall("devices/disk[source][@type='block']"):
235235
backend_domain, port_id = _try_get_block_device_info(vm.app, disk)
236-
237236
if backend_domain.name != self.backend_domain.name:
238237
continue
239-
240238
if self.port_id == port_id:
241239
return True
242240
return False
@@ -307,6 +305,11 @@ def _try_get_block_device_info(app, disk):
307305

308306
class BlockDeviceExtension(qubes.ext.Extension):
309307

308+
def __init__(self):
309+
super().__init__()
310+
self._attachments = {}
311+
self._attachments_with_options = {}
312+
310313
@qubes.ext.handler("domain-init", "domain-load")
311314
def on_domain_init_load(self, vm, event):
312315
"""Initialize watching for changes"""
@@ -327,6 +330,26 @@ def on_domain_init_load(self, vm, event):
327330
else:
328331
self.devices_cache[vm.name] = {}
329332

333+
@qubes.ext.handler("device-attach:block")
334+
def on_device_block_attach(self, vm, event, device, options):
335+
# pylint: disable=unused-argument
336+
self._attachments[device.port_id] = device.backend_domain
337+
338+
@qubes.ext.handler("device-detach:block")
339+
def on_device_block_detach(self, vm, event, port):
340+
# pylint: disable=unused-argument
341+
if port in self._attachments:
342+
self._attachments.pop(port)
343+
if vm not in self._attachments_with_options:
344+
return
345+
if port not in self._attachments_with_options[vm]:
346+
return
347+
for index, (device, options) in enumerate(
348+
self._attachments_with_options[vm]
349+
):
350+
if device.port_id == port:
351+
self._attachments_with_options[vm].pop(device)
352+
330353
@qubes.ext.handler("domain-qdb-change:/qubes-block-devices")
331354
def on_qdb_change(self, vm, event, path):
332355
"""A change in QubesDB means a change in a device list."""
@@ -338,8 +361,7 @@ def on_qdb_change(self, vm, event, path):
338361
)
339362
utils.device_list_change(self, current_devices, vm, path, BlockDevice)
340363

341-
@staticmethod
342-
def get_device_attachments(vm_):
364+
def get_device_attachments(self, vm_):
343365
result = {}
344366
for vm in vm_.app.domains:
345367
if not vm.is_running() or isinstance(vm, RemoteVM):
@@ -348,7 +370,10 @@ def get_device_attachments(vm_):
348370
if vm.app.vmm.offline_mode:
349371
return result
350372

351-
# TODO: ben: cache
373+
if vm in self._attachments:
374+
result = self._attachments[vm]
375+
continue
376+
352377
xml_desc = lxml.etree.fromstring(vm.libvirt_domain.XMLDesc())
353378

354379
for disk in xml_desc.findall("devices/disk[source][@type='block']"):
@@ -359,6 +384,7 @@ def get_device_attachments(vm_):
359384
continue
360385

361386
result[port_id] = vm
387+
self._attachments[vm] = result
362388
return result
363389

364390
@staticmethod
@@ -422,10 +448,14 @@ def on_device_list_attached(self, vm, event, **kwargs):
422448
if not vm.is_running():
423449
return
424450

451+
if vm in self._attachments_with_options:
452+
yield from self._attachments_with_options[vm]
453+
return
454+
self._attachments_with_options[vm] = []
455+
425456
system_disks = SYSTEM_DISKS
426457
if getattr(vm, "kernel", None):
427458
system_disks = SYSTEM_DISKS_DOM0_KERNEL
428-
# TODO: ben: cache
429459
xml_desc = lxml.etree.fromstring(vm.libvirt_domain.XMLDesc())
430460

431461
for disk in xml_desc.findall(
@@ -450,7 +480,10 @@ def on_device_list_attached(self, vm, event, **kwargs):
450480
if devtype != "disk":
451481
options["devtype"] = devtype
452482

453-
yield BlockDevice(Port(backend_domain, port_id, "block")), options
483+
dev = BlockDevice(Port(backend_domain, port_id, "block")), options
484+
yield dev
485+
self._attachments_with_options[vm].append(dev)
486+
454487

455488
@staticmethod
456489
def _is_block(vm, block: str) -> bool:

0 commit comments

Comments
 (0)