When working with KVM virtualization, there are multiple ways to expose physical storage devices to guest VMs. While most documentation focuses on creating storage pools or virtual disk images, direct device mapping is less commonly documented but equally powerful for specific use cases.
Before proceeding, ensure:
1. The USB device is properly connected and recognized by the host (check with lsblk)
2. You have appropriate permissions (typically root/sudo access)
3. The device isn't currently mounted on the host
4. Libvirt and KVM are properly installed
The most reliable approach is to define the device in your VM's XML configuration. Here's a complete example:
<disk type='block' device='disk'>
<driver name='qemu' type='raw'/>
<source dev='/dev/sdc1'/>
<target dev='vdb' bus='virtio'/>
</disk>
Key elements explained:
type='block'
: Specifies we're using a physical block devicedevice='disk'
: Treats it as a regular disk (not CDROM etc.)driver type='raw'
: Essential for direct device accesssource dev
: Points to the actual device path
For temporary access without VM restart, use virsh attach-device:
virsh attach-device myvm usb_device.xml --persistent
Where usb_device.xml contains:
<hostdev mode='subsystem' type='usb'>
<source>
<vendor id='0x1234'/>
<product id='0x5678'/>
</source>
</hostdev>
Permission Errors: Ensure the libvirt-qemu user has access to the device:
chown root:libvirt /dev/sdc1
chmod 660 /dev/sdc1
Device Busy: Unmount the device first:
umount /dev/sdc1
Remember that direct device access:
- Bypasses host filesystem permissions
- May expose the host to malicious guest actions
- Should be used cautiously in multi-tenant environments
When working with KVM virtualization, directly mapping USB storage devices to VMs requires careful configuration. Unlike file-based storage backends, USB passthrough involves device-level access which presents unique challenges.
The most straightforward approach is defining the USB device as a disk in your domain XML:
<disk type='block' device='disk'>
<driver name='qemu' type='raw'/>
<source dev='/dev/sdX'/>
<target dev='vdb' bus='virtio'/>
</disk>
Key considerations:
- Replace /dev/sdX with your actual device (e.g., /dev/sdc1)
- Use
lsblk
to identify the correct device path - The VM must have permissions to access the raw device
For persistent USB device mapping, create a storage pool definition:
<pool type='disk'>
<name>usb_pool</name>
<source>
<device path='/dev/sdX'/>
</source>
<target>
<path>/dev</path>
</target>
</pool>
Then define the volume in your domain XML:
<disk type='volume' device='disk'>
<driver name='qemu' type='raw'/>
<source pool='usb_pool' volume='sdc1'/>
<target dev='vdb' bus='virtio'/>
</disk>
For advanced scenarios where you need the entire USB controller:
<hostdev mode='subsystem' type='usb'>
<source>
<vendor id='0x1234'/>
<product id='0x5678'/>
</source>
</hostdev>
Find your USB device IDs with:
lsusb
Permission problems: Ensure the libvirt-qemu user has read/write access to the device:
chown root:libvirt-qemu /dev/sdX
chmod 660 /dev/sdX
Device in use errors: Unmount the device before attaching:
umount /dev/sdX1
Hotplug limitations: Most USB passthrough requires VM restart for changes.
For best performance with USB 3.0 devices:
- Use virtio-scsi instead of virtio-blk
- Consider enabling write caching in the guest OS
- Monitor I/O performance with
iostat -x 1