Skip to content

Commit

Permalink
[microTVM][RVM] Skip USB device attach if device is already attached (#…
Browse files Browse the repository at this point in the history
…8737)

* [microTVM][RVM] Skip USB device attach if device is already attached

Currently, when the VirtualBox provider is selected, if base-box-tool.py
'test' command is used and a VM is already running with the USB device
necessary to perform the tests already attached to it the command fails
because it tries to blindly attach again the USB device without checking
if device is already attached.

The failure can be reproduced by first running a VM for testing (the
tests need to fail and leave the VM running):

$ ./base-box-tool.py --provider virtualbox test --microtvm-board=stm32f746g_disco

then one tries to re-run the tests without building the whole VM again:

$ ./base-box-tool.py --provider virtualbox test --skip-build zephyr --microtvm-board=stm32f746g_disco

This commit fixes that error by checking and properly skipping the USB
device attach if it's already attached to the VirtualBox VM.

Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>

* areusch review: Use --machinereadable for the output

Use 'showvminfo --machinereadable' output to parse for more robustness
to updates in VBoxManage.
  • Loading branch information
gromero authored Feb 28, 2022
1 parent b56770b commit b55997d
Showing 1 changed file with 25 additions and 4 deletions.
29 changes: 25 additions & 4 deletions apps/microtvm/reference-vm/base-box-tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,26 @@ def parse_virtualbox_devices():
return devices


VIRTUALBOX_USB_DEVICE_RE = (
"USBAttachVendorId[0-9]+=0x([0-9a-z]{4})\n" +
"USBAttachProductId[0-9]+=0x([0-9a-z]{4})"
)


def parse_virtualbox_attached_usb_devices(vm_uuid):
output = subprocess.check_output(["VBoxManage", "showvminfo", "--machinereadable", vm_uuid], encoding="utf-8")

r = re.compile(VIRTUALBOX_USB_DEVICE_RE)
attached_usb_devices = r.findall(output, re.MULTILINE)

# List of couples (VendorId, ProductId) for all attached USB devices
return attached_usb_devices


VIRTUALBOX_VID_PID_RE = re.compile(r"0x([0-9A-Fa-f]{4}).*")


def attach_virtualbox(uuid, vid_hex=None, pid_hex=None, serial=None):
def attach_virtualbox(vm_uuid, vid_hex=None, pid_hex=None, serial=None):
usb_devices = parse_virtualbox_devices()
for dev in usb_devices:
m = VIRTUALBOX_VID_PID_RE.match(dev["VendorId"])
Expand All @@ -122,6 +138,12 @@ def attach_virtualbox(uuid, vid_hex=None, pid_hex=None, serial=None):
and pid_hex == dev_pid_hex
and (serial is None or serial == dev["SerialNumber"])
):
attached_devices = parse_virtualbox_attached_usb_devices(vm_uuid)
for vid, pid in parse_virtualbox_attached_usb_devices(vm_uuid):
if vid_hex == vid and pid_hex == pid:
print(f"USB dev {vid_hex}:{pid_hex} already attached. Skipping attach.")
return

rule_args = [
"VBoxManage",
"usbfilter",
Expand All @@ -132,7 +154,7 @@ def attach_virtualbox(uuid, vid_hex=None, pid_hex=None, serial=None):
"--name",
"test device",
"--target",
uuid,
vm_uuid,
"--vendorid",
vid_hex,
"--productid",
Expand All @@ -141,8 +163,7 @@ def attach_virtualbox(uuid, vid_hex=None, pid_hex=None, serial=None):
if serial is not None:
rule_args.extend(["--serialnumber", serial])
subprocess.check_call(rule_args)
# TODO(mehrdadh): skip usb attach if it's already attached
subprocess.check_call(["VBoxManage", "controlvm", uuid, "usbattach", dev["UUID"]])
subprocess.check_call(["VBoxManage", "controlvm", vm_uuid, "usbattach", dev["UUID"]])
return

raise Exception(
Expand Down

0 comments on commit b55997d

Please sign in to comment.