QEMU SCSI Tape passthrough

Posted on February 21, 2019 with tags tech.

Just a note to myself since I searched the internet for a long time to make this work…

I needed to test a really trivial change to the scsi tape driver code, but didn’t want to reboot an actual machine that has a tape drive. So I thought, maybe QEMU can pass-through an arbitrary device?

Indeed it can, but all the examples one finds are either

  • referring to libvirt or openstack or another random virtualisation tool, and their xml config files;
  • and most likely referring to disks/block devices, for which there are simpler ways to do things.

After many fruitless searches, finally found a reddit comment that shows how it is done for, well, (cdrom) disks again, but in a generic way. A bit of massaging results in:

$ qemu … \
-drive id=footape,if=none,format=raw,readonly=off,file=/dev/sgX \
-device virtio-scsi-pci,id=scsi0 \
-device scsi-generic,bus=scsi0.0,drive=footape

Note 1: The special note is that tapes shouldn’t be addressed by their regular devices (stX/nstX), since that would actually open the tape and hangs without a tape. You need to find the scsi generic device for it (via sg_map), and use that as the file argument to the drive parameter.

Note 2: Of course, if running qemu unprivileged, don’t forget permissions on the ‘sg’ device.

After that, all good. Almost, that is: while mt status and mt eject work, at least for my tape drive, mt tell said (in the virtual machine):

# mt tell
/dev/nst0: Input/output error
# dmesg
…
[  128.799466] st 1:0:0:0: [st0] Sense Key : Illegal Request [current] 
[  128.800172] st 1:0:0:0: [st0] Add. Sense: Invalid field in cdb

Well, even with that, it was good enough for me, so thought to write this down. And yes, I ejected the tape from the VM.