这与我在 Ask Ubuntu 上的问题有关:在virt-manager中为QEMU/KVM虚拟机添加物理分区(如果需要,请参阅末尾处的“更新”)。
每次从 virt-manager 启动虚拟机时,是否有一种好方法可以在主机上运行任意脚本?
原因是我想自动卸载ESP分区/dev/sda1
(作为 挂载在主机中/boot/efi
),并在虚拟机断电时重新挂载它。
[更新]我正在使用的脚本可以在这里找到。
答案1
脚本名称
目前可以调用的hook脚本有5个:
/etc/libvirt/hooks/daemon
当 libvirt 守护进程启动、停止或重新加载其配置时执行
/etc/libvirt/hooks/qemu
当 QEMU guest 启动、停止或迁移时执行(...)
脚本参数
钩子脚本是使用特定的命令行参数调用的,具体取决于脚本和正在执行的操作。
(...)
命令行参数采用这种方法:
第一个参数是名称目的参与操作,如果没有则为“-”。
例如,正在启动的客人的姓名。第二个参数是名称手术正在执行。
例如,如果正在启动来宾,则为“启动”。(...)
/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:这实际上是一条评论。由于格式问题,我将其作为答案。