我对 systemd 服务的行为有点困惑。我有上述系统服务。
[Unit]
After=libvirtd.service
[Service]
Type=simple
Environment=VM_XML=xxxxxxx
ExecStartPre=/usr/bin/bash /usr/local/lib/common/createQcowImage.sh ${VM_XML}
ExecStart=/usr/bin/bash /usr/local/lib/common/createVM.sh ${VM_XML}
ExecStop=/usr/bin/bash /usr/local/lib/common/destroyVM.sh ${VM_XML}
Restart=always
[Install]
WantedBy=multi-user.target
当这个单元在 createVM.sh 脚本中启动时,它会创建一个 VM 并监控它的状态。如果 VM 的 PID 不再存在,则脚本以返回码 1 退出。我注意到,当发生这种情况时,ExecStop 被执行(我正在管理 /var/log/messages,当我手动销毁 VM 时)使用 virsh destroy 我在从 ExecStop 执行的脚本中播下用于调试的回声,以打印在 /var/log/messages 中)。这是 systemd 的默认行为吗?在单元退出时执行 ExecStop(我也尝试使用代码 0 退出,这是相同的行为)。这不是我真正想做的,因为在我销毁 VM 后,ExecStop 会尝试销毁导致 systemd 单元故障的同一 VM。有没有办法避免这种情况?
如果您想创建一个按预期运行的 systemd 服务配置,您需要很好地了解所有选项的含义。
我建议您开始阅读
man systemd.service
有关Type=
,ExecStart=
,ExecStop=
. 也许Type=exec
,或者Type=oneshot
更适合您的脚本?您描述的行为在我看来确实符合预期。
要处理您的 VM 已被其用户停止的情况,您需要测试它是否仍在运行,如果没有则避免破坏它。也不要忘记 ExecStop 必须等待机器停止,而不仅仅是要求它停止。
我附上了我用来启动 VirtualBox VM 的用户服务,也许你可以在那里找到一些灵感。
这是 systemd 的默认行为
当使用ExecStart配置的进程是服务的主进程时,使用type=simple(默认设置)。此类单元将等到 ExecStart 指定的进程返回,然后通过运行 ExecStop 指定的进程来停用
我设法通过在从 ExecStop 执行的脚本中添加一个小检查来解决我的问题,以便仅在 VM 存在时才销毁 VM。