Previously I wrote an article about configuring NFS and autofs for use with a VM on Linux. The premise of that article is that you want to run a local VM, and you want to share files between the VM and the host machine. I described a mechanism for doing this by setting up an NFS server on the guest VM, and then using autofs on the host to automatically mount the guest filesystem as necessary. This does work, but I've since learned that it's not at all the best way to configure things.
First, I've realized that it's better to have the host OS also be the host for the filesystem. That is, the VM should mount the host filesystem, not the other way around. There are two reasons this is better:
- The host will have access to all of the files, even when the guest VM is shutdown.
- You probably want to run your text editor on the host OS, and this way the files will be regular local files. This means you won't run into situations where the files lock up or become unavailable due to some virtualization error or quirk.
The other thing I learned is that there's this thing called 9p filesystem passthrough, which allows you to "directly" expose the host filesystem to the guest. I put "directly" in quotes here because the filesystem still needs to be mounted using a non-local driver, in this case using the 9p protocol. The difference here, compared to NFS, is that on Linux 9p has a native virtio driver which means that all of the filesystem operations are directly virtualized by the hypervisor. This means that everything is fast and there's no weird network protocols (like NFS): everything is directly exposed by the kernel from the host to the guest.
Setting Up 9p Passthrough On Fedora
There are already a bunch of guides for configuring 9p passthrough on Linux, and
I found that they all work except one step on Fedora, which is why I'm writing
this post. The short version is that using virt-manager
you expose a
"filesystem" device and for the "source path" you point it at the directory on
the host you want to share, and then for the "target path" you set up a unique
tag like shared
that you will be the name of the share. Then on the guest you
mount the filesystem using the 9p
mount type and using the options -o trans=virtio,version=9p2000.L,rw
. I found
this illustrated guide
to be helpful; it even has pictures! If you don't want to use virt-manager
,
just Googling "qemu 9p passthrough" should yield plenty of results explaining
the relevant qemu command-line options.
Now once you do all of this, on Fedora you'll run into a problem. If you did
everything correctly you'll find that while the guest can read files, it won't
be able to write to them, regardless of what fsdev security model you use. In
other words, the mount will act like a read-only mount, even if you have it
mounted read-write and have the right user ids and directory permissions and
whatnot. More concretely, any system calls that open files for writing will
fail with an EPERM
error.
After a lot of head scratching I found
this virt-users mailing list email about the issue.
The issue is that by default on Fedora libvirt will arrange for the QEMU process
to be run as a special, unprivileged user: the qemu
user. The problem is that
if you're trying to mount files in your home directory, the qemu
user won't
have the correct permissions to access those files. What you want, instead, is
for the QEMU process to run as your own user id. This is easy to set up. Edit
the file /etc/libvirt/qemu.conf
and find the commented out lines for user
and group
, and make them look something like this:
user = "YOUR_USERNAME_HERE"
group = "YOUR_USERNAME_HERE"
Of course, the actual user and group on your system will probably be different
(unless your Unix login happens to be YOUR_USERNAME_HERE
).
After you make this change you'll have to restart any active QEMU processes,
e.g. by restarting any guests you have in virt-manager
. Then confirm that in
the process listing the QEMU process is running as the expected user id, e.g. by
examining ps -ef | grep qemu
. If that looks OK, you should be able to log into
the guest and write to files!
I hope this article helps save a fellow Fedora user some time, since it took me quite a while to hunt this down.