如何在网络关闭之前触发挂起的 systemd 单元?

Dav*_*vid 10 suspend networkmanager systemd

(库存 Debian 测试又名拉伸 9,所以我有一个常规的 systemd+logind+NetworkManager+GNOME 堆栈)

我有一对要在启动/关闭和恢复/挂起时运行的脚本。此脚本需要在运行时存在网络。我已尝试使用以下脚本进行此操作:

[Unit]
Description=Yamaha Reciever power
Requires=network-online.target
After=network-online.target
Before=sleep.target
Conflicts=sleep.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/av-up
ExecStop=/usr/local/bin/av-down
RemainAfterExit=yes

[Install]
WantedBy=graphical.target
Run Code Online (Sandbox Code Playgroud)

这在启动/关闭时正常工作,但是在挂起期间它网络关闭运行,因此失败。

我已经确定这是因为在 systemd 下挂起是如何进行的:

  1. 挂起由程序(例如systemctl suspend)向 logind 发送 dbus 调用启动。
  2. 然后 Logind 向任何收听的人发送 PrepareToShutdown dbus 信号。
  3. Logind 然后向 systemd 发送一个 StartUnit dbus 调用来运行 suspend.target 单元。

NetworkManager 侦听 PrepareToShutdown,因此在 (2) 处移除网络,而当 systemd 在 (3) 处实际开始挂起时,我的单元会被触发。NetworkManager 使用 logind 保持“禁止”锁定,以确保它在 (3) 之前关闭网络。(旁注:像 systemd 控制挂起/恢复这样的东西似乎很疯狂,只是为了用 logind 来颠覆它,让东西规避这一点)

在网络仍在运行时触发程序在挂起/恢复时运行的正确方法是什么?

我应该使用 NetworkManager pre-down 脚本吗?如果是这样,如果网络出现故障但我没有挂起,我该如何阻止它触发?

有没有办法提前挂入挂起过程?

有没有办法让 NetworkManager 使网络保持更长时间?

注意:这与如何编写 Systemd 单元不同,该单元将在网络中断之前触发,因为我正在谈论挂起/恢复。

Dav*_*vid 5

https://unix.stackexchange.com/a/139664/160746 的启发,我将启动/停止脚本升级为一个完整的守护进程,并让它监听 PrepareToShutdown 信号。这是每次启动/停止都与 NetworkManager 的竞赛,但它似乎在我的系统上可靠地工作。

我已经在https://github.com/davidn/av上传了我的代码和 systemd 单元。