A quick story to get the context

My gaming setup involves a libvirt VM with some passthrough, mainly the GPU, but also sound and USB devices for example.

Another device that is passed through to the VM is my dedicated SSD, formatted in Btrfs.
Why Btrfs? Because it’s both natively supported by the Linux kernel, and by the WinBtrfs project that brings its support to Windows. That means I can easily share the same disk for casual gaming that just works™ on the Windows VM, casual gaming that just works™ on the Linux host with native games, and for Wine/Proton experiments with the same data I use on Windows without duplicating everything.

That’s a setup I’ve use for years without problem, but a recent adventure proved me I needed to be more careful something to prevent accidents from happening again. Imagine that for some reason it’s the week-end, and you make some experiments with Lutris and your GOG library, then a bit later a friend asks you to come have some fun, and the proposed game is a popular one that is known not to work with Wine/Proton. Then you’ll just fire up the VM, play the game for the rest of the evening, then shut down everything and go to bed.

But on the next day, when you just thought everything was fine and you could go play some more games again, you realize that nothing works anymore, and that the Btrfs filesystem is completely corrupted because it was mounted two times in parallel, by two autonomous systems that thought had authority on it. The problem is not that serious, because nothing on that disk was really important, and to fix it you simply mkfs.btrfs again, and re-install everything. But when re-installing everything involves re-downloading half a Terabyte, you also realize that a simple safe-guard would probably not be too much luxury to avoid further accidents, and that’s what this article is about!

libvirt hooks

Fortunately, someone in the libvirt team thought one day that it would be great to run custom scripts when some events occurred in the VM lifetime, and the hooks were developed.

Long story short, to prevent the story above from happening again, I just put the script below in the following executable file: /etc/libvirt/hooks/qemu

#!/bin/bash

if [ "$2" = "prepare" ]; then
    if findmnt /data; then
        umount /data
    fi
fi

Now, I can completely forget to unmount my shared disk, it will automatically be unmounted before being passed through to the VM, and I won’t have to re-download my game library ever again… famous last words