systemd 根据条件重新启动作业

sim*_*szu 1 daemon wine systemd

我有一个仅运行在带有 wine 和 Xvfb 的 linux 机器上的 Windows 守护程序。由于这个相当实验性的设置,守护程序会定期崩溃,我想实现某种机制来自动重新启动守护程序。目前我有一个带有Restart=always设置的 systemd 单元定义。

但是,我注意到有时守护程序会崩溃,但不会退出它的进程。这相当于显示一个带有“守护程序崩溃,您要发送错误报告吗?”问题的对话框。因此,该进程仍在运行,但守护进程已停止工作。

我可以在我的 linux 机器上检查的这种现象的唯一外部行为是两个新文件,它们出现在某个位置但具有可变文件名(它们依赖于时间,并且名称中有时间戳)。我认为它们是某种内存转储或堆栈跟踪,最初应该用于发送错误报告。

所以现在我正在为 systemd 寻找一个解决方案来捕获这个解决方案,比如

  1. 在单元启动时,查看故障转储目标目录并制作目录内容的快照
  2. 启动守护进程
  3. 定期查看目录,如果有新文件,不在快照中,根据一些正则表达式,重新启动守护进程并刷新快照。

我想过一个用 bash 或其他东西编写的包装器,但有两个问题:首先我不知道如何实现这种行为,其次,这将使 systemd 的使用完全过时,因为脚本处理所有崩溃处理,而 systemd 只会执行脚本。

我还考虑过使用 systemd 的给定功能定期重新启动守护程序,但这会非常低效(考虑到 Wine 包装器中的 Windows 守护程序一开始并不是低效的),因为它有时会重新启动守护程序当不需要时,或者在守护程序崩溃后需要一段时间才能定期重新启动。

解决这个问题的最佳解决方案是什么?

仅供参考:我正在谈论的守护程序是 Google 相册的上传程序。出于某种原因,谷歌没有为 Linux 发布它。

sim*_*szu 5

好的,我发现了 systemd.path 的强大功能。

我用ExecStart=systemctl restart daemon.unit和创建了第二个服务单元Type=oneshot。之后,我创建了第三个单元,一个带有PathModified=<crashdump output directory>和的路径单元Unit=daemon-restart.unit

它现在有效。我只需要确保没有其他进程正在写入输出目录,但这可以通过多个不同的 wineprefixes 解决。