使用 virt-manager 启动虚拟机时在主机中运行脚本

使用 virt-manager 启动虚拟机时在主机中运行脚本

这与我在 Ask Ubuntu 上的问题有关:在virt-manager中为QEMU/KVM虚拟机添加物理分区(如果需要,请参阅末尾处的“更新”)。

每次从 virt-manager 启动虚拟机时,是否有一种好方法可以在主机上运行任意脚本?

原因是我想自动卸载ESP分区/dev/sda1(作为 挂载在主机中/boot/efi),并在虚拟机断电时重新挂载它。

[更新]我正在使用的脚本可以在这里找到

答案1

libvirt:用于特定系统管理的挂钩

脚本名称

目前可以调用的hook脚本有5个:

  • /etc/libvirt/hooks/daemon
    当 libvirt 守护进程启动、停止或重新加载其配置时执行

  • /etc/libvirt/hooks/qemu
    当 QEMU guest 启动、停止或迁移时执行

(...)

脚本参数

钩子脚本是使用特定的命令行参数调用的,具体取决于脚本和正在执行的操作。

(...)

命令行参数采用这种方法:

  1. 第一个参数是名称目的参与操作,如果没有则为“-”。
    例如,正在启动的客人的姓名。

  2. 第二个参数是名称手术正在执行。
    例如,如果正在启动来宾,则为“启动”。

(...)

/etc/libvirt/hooks/qemu

  • 在启动 QEMU guest 之前,会在三个位置调用 qemu 挂钩脚本:如果任何位置失败,则来宾系统不会启动。从 0.9.0 开始,第一个位置是在 libvirt 执行任何资源标记之前,并且该钩子可以分配不受 libvirt 管理的资源,例如 DRBD 或丢失的桥接器。这被称为:
    /etc/libvirt/hooks/qemu guest_name prepare begin -

    第二个位置自 0.8.0 起可用,发生在 libvirt 完成标记所有资源但尚未启动 guest 虚拟机之后,称为:
    /etc/libvirt/hooks/qemu guest_name start begin -

    第三个位置 0.9.13 出现在 QEMU 进程成功启动之后:
    /etc/libvirt/hooks/qemu guest_name started begin -

(...)


所以,在实践中,这样:

/etc/libvirt/hooks/qemu(无扩展名)

#!/bin/bash

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

当然,编辑<domain name>,实现挂载/卸载逻辑,然后重新启动libvirtd.service

另外不要忘记:chmod +x /etc/libvirt/hooks/qemu

我正在提供完整的解决方案https://gitlab.com/ranolfi/rvirtep


一个附录fstab:对于这个特定的用例,您可能会发现使用选项设置文件很有用noauto ,也许还可以使用x-systemd.automount 和。看 x-systemd.device-timeout=<seconds>文件系统表(5)和 systemd.automount(5)

答案2

您的脚本的一个较短的变体。把这个放进去/etc/libvirt/hooks/qemu

#!/bin/bash

case $1:$2 in
win11:start)
    umount /boot/efi
    ;;
win11:stopped)
    mount /boot/efi
    ;;
esac

并使其可执行。这win11是客人姓名。

PS:这实际上是一条评论。由于格式问题,我将其作为答案。

相关内容