Shared Folder in QEMU Between Linux Host and Windows Guest (Shallow Thoughts)

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Wed, 23 Nov 2022

Shared Folder in QEMU Between Linux Host and Windows Guest

Unexpectedly, one of the hardest parts of Migrating a VirtualBox Windows Virtual Machine to qemu/kvm/virt-manager was finding a way to exchange files between Linux and Windows. In virtualbox, setting up a shared folder is trivial. In QEMU, not so much.

Mount the VM Image

First, it is possible to mount the .qcow image in the host Linux, a nice feature that I never figured out how to do with virtualbox. You need the libguestfs-tools package.

First, get a list of the available devices in the VM with

guestmount -a /path/to/Win10.qcow2 -m /dev/sda<something> /mnt

The "something" can be anything you like; it's a placeholder for the Windows filesystem device: guestmount will complain and show you the available devices:

% guestmount -a Win10.qcow2 -m /dev/sda99 /mnt                /ssd/QEMU
libguestfs: error: mount_options: mount_options_stub: /dev/sda99: No such file or directory
guestmount: ‘/dev/sda99’ could not be mounted.
guestmount: Did you mean to mount one of these filesystems?
guestmount: 	/dev/sda1 (ntfs)
guestmount: 	/dev/sda2 (ntfs)
zsh: exit 1     guestmount -a Win10.qcow2 -m /dev/sda99 /mnt

(Note: this may be somewhat brittle. When I first intended to post this article, I tried the above command and it gave a completely different error message that gave no clue about the available virtual partitions. But a few days later it was working again.)

In my Windows install, /dev/sda1 is boot partition stuff, while /dev/sda2 is the user partition. So the real command was:

guestmount -a Win10.qcow2 -m /dev/sda2 <i>mount-point</i>

If you're in the proper group, you can run this as your user and don't need to be root, as long as you pick a mount-point that's an empty directory that's writable by you, like ~/mnt. The exact group name you need probably varies by distro. On Debian I added myself to kvm, libvirt and libvirt-qemu, and I'm not sure which of those is the one that matters.

The mounted filesystem is only accessible to the user that ran guestmount; to allow other users, add -o allow_other To unmount, guestunmount mount-point

guestfs-tools can do other useful things too. Check out programs like virt-ls and virt-cat to examine single files from your guest OS. However, it's very slow and error prone, so most of the time you're probably better off guestmounting the filesystem and using normal Linux tools.

Mounting the VM image is a relatively easy way to pass info between the two installs, as long as you can live with not being able to copy anything while the guest is running. If you try to guestmount while the guest is running, you'll get an error message.

So that's a rudimentary way to transfer files between host and guest. But I still miss the nice, easy shared folders of VirtualBox, that let me transfer files while both OSes were running. Are there any other options?

There are — but I never got any of them to work.

Samba

Most people on the web recommend setting up samba and using SMB to transfer files over the network between the two installs. That's probably a no-brainer if you're already running a samba daemon. But I didn't want to set up samba and have it running all the time just to transfer files to and from a Windows installation that I use maybe once or twice a month.

But after struggling for three days trying to get virtio-fs working, I decided maybe having to install samba wasn't so bad. Supposedly, you can use QEMU's built-in SMB sharing, which requires installing the "samba" package (and its dependencies). but supposedly doesn't require actually running a samba daemon.

Nobody explains how to set this up, though.

These pages looked promising, but they didn't work either: the lines in the first page to create a network device didn't result in Windows being able to see a network, and the extra -net nic,model=virtio in the second page resulted in an error dialog, PCI: slot 1 function 0 not available for virtio-vga, in use by virtio-net-pci.

virtio-fs

That left two filesystems virt-manager supposedly understands. When you're editing info for your virtual machine in virt-manager, click Filesystem. The Driver field offers two options, virtiofs and virtio-9p. Virtio-9p is Plan 9 file sharing, but all the comments I found about virtio-9p when used to communicate with OSes other than Linux were very negative: it's slow, poorly supported, buggy.

Virtiofs, on the other hand, was reputed to be fast and to work well if you can manage to get it set up. That's the kicker: there's no real documentation on this process as it applies to non-linux OSes. It's easy enough to set up the virtiofs driver on the Linux side, and there's a driver, winfsp-version.msi, but I tried various ways of installing it on the Windows guest and never managed to get it to talk to virtiofs. Some pages say to go through the Windows "Add Hardware / Filesystem" window, but I never got that to work.

I also found some pages recommending a series of "sc" commands (Windows' Service Control command), such as:

C:\> sc create VirtioFsSvc binpath="(your binary location)\virtiofs.exe" start=auto depend="WinFsp.Launcher/VirtioFsDrv" DisplayName="Virtio FS Service"
    (Thank goodness CommandPrompt has autocomplete. On the other hand,
    every time it autocompletes it adds the close quote again and
    you have to delete it so you can type the next path component.)

C:\> sc start VirtioFsSvc
The dependency service does not exist or has been marked for deletion

There were various other approaches I tried, but they all ended in error messages and no communication. I'd love to hear from anyone who's managed to get virtiofs working between a Linux host and a Windows guest without needing a full-fledged samba daemon.

Tags: , ,
[ 17:37 Nov 23, 2022    More linux | permalink to this entry | ]

Comments via Disqus:

blog comments powered by Disqus