对多个单元中的任意一个指定 systemd 依赖性?

对多个单元中的任意一个指定 systemd 依赖性?

是否可以对多个单元中的任意一个指定 systemd 依赖性?

目前,我有一个单元 Z,它至少依赖于单元 A 或单元 B 中的一个。

将单元 A 配置为WantedBy单元 Z,将单元 B 配置为WantedBy单元 Z 基本可行。

但是,如果只有单元 A 或 B 中的一个能够启动,则启动过程将等待另一个单元超时,然后才能启动单元 Z。我想消除这个超时。

单元 A 和 B 需要超时才能正常运行,但是,一旦其中一个单元启动,就无需等待另一个单元超时即可启动单元 Z。

有没有办法指定单元 Z 依赖于单元 A 或单元 B,但在启动单元 Z 之前不需要等待单元 A 和单元 B 同时启动?

在 Debian 世界中,包装系统用于Provides指定与我希望在这里完成的事情类似的内容。

我想要实现的目标

Debian 曾经支持keyscript中的选项,crypttab但上游重写了迁移到 的启动脚本后,Debian 并未重新实现该选项systemd。以前,我使用 来keyscript从 USB 驱动器读取密钥。目前,我使用systemd单元文件来代替该keyscript选项(单元 A)。效果非常好。但是,USB 驱动器很容易发生故障,因此为了实现冗余,我想在第二个 USB 驱动器上携带我的密钥的第二份副本。我想systemd为第二个 USB 驱动器(单元 B)添加第二个单元文件,这样无论插入哪个 USB 驱动器,systemd都可以使用该 USB 驱动器并继续操作而不会超时。

我尝试过的其他方法

使用Conflicts指定 A 与 B 冲突,且 B 与 A 冲突。遗憾的是,systemd 在尝试启动单元 A 或 B 之前会处理冲突,并在尝试启动剩余单元之前从调度程序中删除其中一个单元。因此,Z 有时会失败,例如,如果 A 失败,但如果 B 已因与 A 冲突而被排除在考虑范围之外,则 B 会成功。

用来JobTimeoutSec缩短超时时间。不幸的是,如果 A 和 B 超时,这可能会导致 Z 失败。

Michael Hampton 的建议。正如他所提到的,NTP 示例在每个客户端和目标之间创建了弱依赖关系。每个 NTP 客户端都需要目标,但目标不依赖于每个 NTP 客户端,因此这有效。但是,据我所知,弱依赖关系不会拉入单元,除非该单元还具有[Install]指定其他依赖关系的部分。因此,当我拉入我的单元 A 和 B 时,WantedBy该部分中的[Install]会创建阻塞超时。如果我删除该[Install]部分,单元 A 和 B 将被忽略。

答案1

这是 systemd 目标单元的一项工作。

我不会给出一个虚构的例子,而是给出一个已经存在于您的系统上的真实例子。

考虑 NTP。大多数计算机通过 NTP 同步,但有三个(甚至更多)NTP 客户端可供选择:systemd-timesyncd、chronyd 或(经典)ntpd。

这些 NTP 客户端的每个服务单元都是名为 的目标的一部分time-sync.target,并且弱地需要它。

Before=time-sync.target
Wants=time-sync.target

因此,当您启动任何 NTP 客户端时,time-sync.target将在 NTP 客户端启动后启动。请注意,它time-sync.target本身是空的,实际上不会自行执行任何操作。

因此,如果您运行的服务需要系统时间已同步,否则将会失败,则您可以要求它仅在time-sync.target启动后启动。

After=time-sync.target
Requires=time-sync.target

您应该能够轻松地将其适应于您自己的服务。

答案2

我认为如果此功能存在,它会出现在systemd.unit手册页中,但我在那里没有看到它。

解决方案可以是使用一个小bash脚本,只要 A 或 B 启动,该脚本就会成功,如果 A 和 B 都无法启动,则失败。

相关内容