Skip to content

Commit

Permalink
q-dev: async confirmation
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrbartman committed Oct 15, 2024
1 parent 1db8f8f commit 1267f3f
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
9 changes: 6 additions & 3 deletions qubes/ext/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import qubes.device_protocol
import qubes.devices
import qubes.ext
from qubes.ext.utils import device_list_change, confirm_device_attachment
from qubes.ext import utils
from qubes.storage import Storage

name_re = re.compile(r"\A[a-z0-9-]{1,12}\Z")
Expand Down Expand Up @@ -324,7 +324,7 @@ def on_qdb_change(self, vm, event, path):
current_devices = dict(
(dev.port_id, device_attachments.get(dev.port_id, None))
for dev in self.on_device_list_block(vm, None))
device_list_change(self, current_devices, vm, path, BlockDevice)
utils.device_list_change(self, current_devices, vm, path, BlockDevice)

@staticmethod
def get_device_attachments(vm_):
Expand Down Expand Up @@ -569,7 +569,10 @@ async def attach_and_notify(self, vm, assignment):
# bypass DeviceCollection logic preventing double attach
device = assignment.device
if assignment.mode.value == "ask-to-attach":
if vm.name != confirm_device_attachment(device, {vm: assignment}):
allowed = await utils.confirm_device_attachment(
device, {vm: assignment})
allowed = allowed.strip()
if vm.name != allowed:
return
self.on_device_pre_attached_block(
vm, 'device-pre-attach:block', device, assignment.options)
Expand Down
23 changes: 14 additions & 9 deletions qubes/ext/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ def device_list_change(
if len(frontends) > 1:
# unique
device = tuple(frontends.values())[0].device
target_name = confirm_device_attachment(device, frontends)
target_name = asyncio.ensure_future(
confirm_device_attachment(device, frontends)).result()
for front in frontends:
if front.name == target_name:
target = front
Expand Down Expand Up @@ -140,17 +141,21 @@ def compare_device_cache(vm, devices_cache, current_devices):
return added, attached, detached, removed


def confirm_device_attachment(device, frontends) -> str:
async def confirm_device_attachment(device, frontends) -> str:
try:
front_names = [f.name for f in frontends.keys()]
# pylint: disable=consider-using-with
proc = subprocess.Popen(
["attach-confirm", device.backend_domain.name,
device.port_id, device.description,
*[f.name for f in frontends.keys()]],
stdout=subprocess.PIPE, stderr=subprocess.PIPE
# vm names are safe to just join by spaces
proc = await asyncio.create_subprocess_shell(
" ".join(["attach-confirm", device.backend_domain.name,
device.port_id, "'" + device.description + "'", *front_names]),
stdout=asyncio.subprocess.PIPE
)
(target_name, _) = proc.communicate()
return target_name.decode()
(target_name, _) = await proc.communicate()
target_name = target_name.decode()
if target_name in front_names:
return target_name
return ""
except Exception as exc:
print("attach-confirm", exc, file=sys.stderr)
return ""

0 comments on commit 1267f3f

Please sign in to comment.