This is all tested on windows 10 running wsl equipped with nix.
The vm doesn't boot w/o problems, so I decided to boot just the generated iso in qemu first (admin account bc I wanna use host usb later):
& $(scoop which qemu-system-x86_64.exe) -monitor tcp:localhost:55555,server,nowait -net nic,netdev=user.0,model=virtio -netdev user,id=user.0,hostfwd=tcp::2221-:22 -m 512 -device qemu-xhci,id=xhci -cdrom c:/temp/nixos.iso -boot d,menu=on -M pc
Regarding the monitor option read the excellent https://unix.stackexchange.com/questions/426652/connect-to-running-qemu-instance-with-qemu-monitor as well as https://wiki.ubuntu.com/QemuDiskHotplug I will add the usb devices using the monitor session. First run (normal user) a nix-shell equipped with the nc command:
wsl bash --login --init-file ~/.nix-profile/etc/profile.d/nix.sh -c "bash"
nix-shell -p netcat -I nixpkgs=channel:nixos-19.09
And now for the disk image file lying on your windows host somewhere just:
echo drive_add\ 0\ if=none,id=usbdisk1,file=C:/temp/8GB.vhd |nc -N localhost 55555
echo device_add\ usb-storage,id=usbdisk1,drive=usbdisk1 |nc -N localhost 55555
echo info\ usb |nc -N localhost 55555
Observe that for the windows qemu port (https://qemu.weilnetz.de/doc/qemu-doc.html#pcsys_005fmonitor) the windows filename syntax works. Also tres cool is that adding host devices (passthrough) even works in the non-elevated user's account, example:
echo drive_add\ 0\ if=none,id=realusbstick1,file=//./PhysicalDrive1 |nc -N localhost 55555
echo device_add\ usb-storage,id=realusbstick1,drive=realusbstick1 |nc -N localhost 55555
Can do basically all things imaginable now:
mount /dev/sda1 /mnt/usbimage
scp -o "StrictHostKeyChecking=no" -i ~/.ssh/id_rsa -P 2221 /mnt/c/temp/nixos.iso root@localhost:/mnt/usbimage/
# or even better
rsync -avz --no-perms --no-owner --no-group -e "ssh -i ~/.ssh/id_rsa -p 2221 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --progress /mnt/c/temp/nixos.iso root@localhost:/mnt/usbimage/
dd if=/mnt/usbimage/nixos.iso of=/dev/sdb status=progress
Booting the usbstick testwise in qemu (again admin account) is possible pretending it is a cdrom:
& $(scoop which qemu-system-x86_64.exe) -monitor tcp:localhost:55555,server,nowait -net nic,netdev=user.0,model=virtio -netdev user,id=user.0,hostfwd=tcp::2221-:22 -m 512 -device qemu-xhci,id=xhci -cdrom //./PhysicalDrive1 -boot d,menu=on -M pc
Also working:
& $(scoop which qemu-system-x86_64.exe) -monitor tcp:localhost:55555,server,nowait -net nic,netdev=user.0,model=virtio -netdev user,id=user.0,hostfwd=tcp::2221-:22 -m 512 -device qemu-xhci,id=xhci -drive file=//./PhysicalDrive1,if=none,id=bootstick -device usb-storage,drive=bootstick -boot d,menu=on -M pc
Use case:
Access usb devices via nixos-shell
:
Starting nixos-shell with
hardware.sane.enable = true;
hardware.sane.extraBackends = [ pkgs.sane-airscan ];
virtualisation.qemu.options = [
"-usb" "-device usb-host,productid=0x04A9,vendorid=0x220E"
];
settings accordingly you'd get:
/nix/store/xzdf0wav4ijr8m00jw3mg1ir32hfw3yp-nixos-vm qemu-system-x86_64: -device usb-host,productid=0x04A9,vendorid=0x220E: failed to init libusb
You could try the whole thing as Windows Administrator user but the above setup should do everything needed (in netcat equipped nix-shell):
virtualisation.qemu.options = [
"-monitor tcp:localhost:55555,server,nowait"
];
(https://unix.stackexchange.com/questions/426652/connect-to-running-qemu-instance-with-qemu-monitor)
echo device_add\ usb-host,vendorid=0x220E,productid=0x04A9 |nc -N localhost 55555
with the nc available via scoop (in elevated powershell session):
echo "device_add usb-host,vendorid=0x220E,productid=0x04A9" |nc localhost 55555
But get as well (maybe we just need admin perms as well):
QEMU 5.2.0 monitor - type 'help' for more information (qemu) device_add usb-host,vendorid=0x220E,productid=0x04A9 Error: failed to init libusb (qemu)
Would sure involve setting up nix in the windows elevated account (https://github.com/gerardog/gsudo as well as wsl2).
https://qemu.readthedocs.io/en/latest/system/usb.html
q=qemu+passthrough+windows+host+failed+to+init+libusb
TODO Had that sort of issue solved using libvirt documented somewhere. discourse.nixos.org ?
requires Hyper-V
but: When Cisco-VPN is running, DNS won't work, probably also QEMU won't work as before (EDIT: qemu in wsl1 still works, in wsl2 not (yet)). So either disable VPN (temporarily) or try https://docs.microsoft.com/en-us/windows/wsl/troubleshooting#bash-loses-network-connectivity-once-connected-to-a-vpn (via microsoft/WSL#6457 (comment)):
- VPN adapter is the one which has (german) "Beschreibung. . . . . . . . . . . : Cisco AnyConnect Secure Mobility Client Virtual Miniport Adapter for Windows x64": Doesn't work either, just temp. disable vpn
To initially install a WSL distribution at all you'll probably need the graphical login with your elevated account, setting up things via gsudo and powershell cmdlets didn't work for me (i. e. https://xuad.net/artikel/wsl-auf-version-2-heben).
https://github.com/Trundle/NixOS-WSL describes very well how the process is, best case you have a nix installation already, use:
NIX_PATH=nixpkgs=http://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz nix-build -A system -A config.system.build.tarball ./nixos.nix
with the checked out repo and copy the archive somewhere to import via wsl. Latter is possible via gsudo again once wsl2 is set up correctly.
q=wsl2+cisco+vpn+ping+fails (this microsoft/WSL#5821 (comment) could work)
Scanner still not detected even after getting lsusb (qemu monitor device_add) to work in a wsl session via elevated user. at least there is no libusb error message.
https://github.com/NixOS/nixpkgs/tree/master/pkgs/os-specific/linux/usbip
via https://gist.github.com/danvy/9486bf730371436131cb888ff4c2ceb6: https://www.heise.de/select/ix/2016/2/1454730392228766 (https://github.com/cezanne/usbip-win/releases/tag/v0.3.3-dev)
more on wsl2 dns maybe here https://superuser.com/questions/1533291/how-do-i-change-the-dns-settings-for-wsl2 (via q=wsl2+systemd-resolved)
or here microsoft/WSL#4285
Seems to work (promising): microsoft/WSL#4277 (comment) (also here https://gist.github.com/pyther/b7c03579a5ea55fe431561b502ec1ba8)
In pwsh with VPN active:
Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Hyper-V.*#2"}
Get-DnsClientServerAddress -AddressFamily ipv4 | Select-Object -ExpandProperty ServerAddresses