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

Mar*_*377 11 scripting virtual-machine automounting mount libvirt

这与我在 Ask Ubuntu: AddPhysical Partition to QEMU/KVM virtual machine in virt-manager 上的问题有关(如果需要,请参阅末尾处的“更新”)。

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

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

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

Mar*_*377 10

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

\n
\n

脚本名称

\n

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

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

    \n
  • \n
  • /etc/libvirt/hooks/qemu
    \n当 QEMU 来宾启动、停止或迁移时执行

    \n
  • \n
\n

(...)

\n

脚本参数

\n

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

\n

(...)

\n

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

\n
    \n
  1. 第一个参数是参与操作的对象的名称,如果没有则为“-”。
    \n例如,正在启动的来宾的名称。

    \n
  2. \n
  3. 第二个参数是正在执行的操作的名称。
    \n例如,如果正在启动来宾,则为“start”。

    \n
  4. \n
\n

(...)

\n

/etc/libvirt/hooks/qemu

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

    \n

    第二个位置自 0.8.0 起可用,出现在 libvirt 完成标记所有资源但尚未启动\nguest 之后,称为:
    \n/etc/libvirt/hooks/qemu guest_name start begin -

    \n

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

    \n
  • \n
\n

(...)

\n
\n
\n

所以,在实践中,这样:

\n

/etc/libvirt/hooks/qemu(不带扩展名)

\n
#!/bin/bash\n\nif [[ $1 == "<domain_name>" ]] && [[ $2 == "start" || $2 == "stopped" ]]\nthen\n  if [[ $2 == "start" ]]\n  then\n    # unmount logic here\n  else\n    # mount logic here\n  fi\nfi\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

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

\n

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

\n
\n

附录:对于fstab这个特定的用例,\n您可能会发现使用选项noauto\nand\xc2\xa0 也可能x-systemd.automount\nand来设置文件很有用。\xc2\xa0\n请参阅\xc2\xa0 fstab(5)和\xc2 \xa0 systemd.automount(5)x-systemd.device-timeout=<seconds>

\n