This is related to my question on Ask Ubuntu: Add physical partition to QEMU/KVM virtual machine in virt-manager (see "Updates" near the end, if needed).

Is there a nice way to run any arbitrary script on the host every time a VM is started from virt-manager?

The reason is that I want to automagically unmount the ESP partition /dev/sda1 (mounted in the host as /boot/efi), and remount it when the VM is powered off.

[update] The script I was using can be found here.

2 Answers 2


From libvirt: Hooks for specific system management:

Script names

At present, there are five hook scripts that can be called:

  • /etc/libvirt/hooks/daemon
    Executed when the libvirt daemon is started, stopped, or reloads its configuration

  • /etc/libvirt/hooks/qemu
    Executed when a QEMU guest is started, stopped, or migrated


Script arguments

The hook scripts are called with specific command line arguments, depending upon the script, and the operation being performed.


The command line arguments take this approach:

  1. The first argument is the name of the object involved in the operation, or '-' if there is none.
    For example, the name of a guest being started.

  2. The second argument is the name of the operation being performed.
    For example, "start" if a guest is being started.



  • Before a QEMU guest is started, the qemu hook script is called in three locations; if any location fails, the guest is not started. The first location, since 0.9.0, is before libvirt performs any resource labeling, and the hook can allocate resources not managed by libvirt such as DRBD or missing bridges. This is called as:
    /etc/libvirt/hooks/qemu guest_name prepare begin -

    The second location, available Since 0.8.0, occurs after libvirt has finished labeling all resources, but has not yet started the guest, called as:
    /etc/libvirt/hooks/qemu guest_name start begin -

    The third location, 0.9.13, occurs after the QEMU process has successfully started up:
    /etc/libvirt/hooks/qemu guest_name started begin -


So, in practice, this:

/etc/libvirt/hooks/qemu (without extension)


if [[ $1 == "<domain_name>" ]] && [[ $2 == "start" || $2 == "stopped" ]]
  if [[ $2 == "start" ]]
    # unmount logic here
    # mount logic here

Of course, edit <domain name>, implement the mount/unmount logic, and then restart libvirtd.service.

Also don't forget to: chmod +x /etc/libvirt/hooks/qemu

I'm making my full solution available at https://gitlab.com/ranolfi/rvirtesp.

An addendum: for this particular use case, you may find it useful to set up your fstab file with the option noauto and maybe also x-systemd.automount and x-systemd.device-timeout=<seconds>.  See fstab(5) and systemd.automount(5).

  • Thanks for sharing this, but I think the scripts are a bit complicated. This line is wrong: if [[ $1 == "rwin10" ]] && [[ $2 == "start" ]] || [[ $2 == "stopped" ]] It's executed on any VM stop, the correct line is if [[ $1 == "rwin10" && ( $2 == "start" || $2 == "stopped" ) ]]
    – Alek
    Aug 10, 2023 at 19:17

A little shorter variant of your scripts. Put this in /etc/libvirt/hooks/qemu:


case $1:$2 in
    umount /boot/efi
    mount /boot/efi

and make it executable. Here win11 is the guest name.

PS: It's actually a comment. I put it as an answer because of formatting.

  • Thanks a lot. I hope to revisit this soon, with your improvements and due credit.
    – Marc.2377
    Aug 12, 2023 at 16:45
  • You are welcome
    – Alek
    Aug 15, 2023 at 17:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .