Repository navigation
libusb: stop UTM freezing when a USB 3 drive is disconnected - #8131
Merged
Merged
Conversation
Disconnecting a USB drive that the guest uses through USB Attached SCSI (most USB 3 drives and SSD enclosures) froze UTM: the USB menu and every other part of the app stopped answering, and after UTM was ended the drive did not come back to macOS until it was replugged. When a device is released, usbredirhost cancels its transfers and waits for them to complete. libusb on macOS refused to cancel bulk stream transfers (LIBUSB_ERROR_INVALID_PARAM), and USB Attached SCSI always has one pending on its status pipe, so the wait never ended while it held the lock the main thread needs. Pick up c1c01e6593 from the UTM libusb fork (utmapp/libusb#1), which cancels bulk stream transfers the way plain bulk transfers are. The change is by giovariot, who included it in utmapp#7928. Assisted-by: Claude:claude-fable-5-2
UTMapp-bot
force-pushed
the
fix/usb-disconnect-freeze
branch
from
November 11, 2026 06:19
4bc879e to
3353ebf
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Disconnecting a USB drive from a running VM froze UTM when the guest was using the drive through USB Attached SCSI, which most USB 3 drives and SSD enclosures do. The USB menu and the rest of the app stopped answering. After UTM was ended, the drive did not come back to macOS until it was unplugged and plugged in again.
When a device is released,
usbredirhost_clear_device()cancels its transfers and waits for them to complete. libusb on macOS refused to cancel bulk stream transfers (darwin_cancel_transfer()returnedLIBUSB_ERROR_INVALID_PARAMforLIBUSB_TRANSFER_TYPE_BULK_STREAM), and USB Attached SCSI always has one pending on its status pipe. The wait never ended, and it holds the lock that UTM's main thread takes inspice_usb_device_manager_is_device_connected().This picks up c1c01e6593 from the UTM libusb fork (utmapp/libusb#1), which sends bulk stream transfers to
darwin_abort_transfers(); that function already aborts a stream withAbortStreamsPipe(). The change is by @giovariot, who included it in #7928; this is that change on its own, with them as the patch's author. Upstream libusb'smasterhas the same gap.Resolves #5851
Related: #7530
Testing
Tested by an AI agent on a MacBook Pro M2 Max, macOS 27.2 (26B123), with a Seagate Backup Plus 500 GB drive (0bc2:ab24) on a USB 3 port (5 Gb/s link). Guest: Ubuntu 26.04 arm64 (Linux 7.0), USB 3.0 controller, the drive attached with the scripting
connectcommand. In the guest the drive isDriver=uas, 5000M. Only reads were done on the drive.disconnectnever returns ("AppleEvent timed out"), and every later scripting command times out too; a click on the USB menu in the VM window freezes the window. Asampleof UTM shows a worker thread inspice_usb_backend_channel_detach→usbredirhost_set_device→usbredirhost_clear_device, and the main thread waiting inspice_usb_device_manager_is_device_connected→g_mutex_lock. After ending UTM,diskutil listdid not show the drive again until it was replugged.mainwith libusb rebuilt from the patched source in its sysroot):disconnectreturns within a second, twice in a row, and the disk is gone from the guest each time.connectbrings it back, and 200 MiB reads run at 102 MB/s.disconnectwhileddwas reading from the drive returns within a second and UTM keeps answering. The drive connects again afterwards.diskutil listwithout a replug.The patch file applies to a fresh extract of
libusb-1.0.25.tar.bz2with no fuzz or rejects. The tests above ran before the change was merged in the fork; the code line is the same.Not tested: iOS, other drives, a drive using the older bulk-only protocol (its transfers were already cancelled), and a full dependency build (left to CI).