依赖于系统单元的 Systemd 用户单元 (sleep.target)

依赖于系统单元的 Systemd 用户单元 (sleep.target)

我正在阅读文档,但我仍然不清楚是否可以完成以下任务:

其中定义的服务~/.config/systemd/user/task.service依赖于系统sleep.target( ~/.config/systemd/user/sleep.target.wants/task.service)。

现在我希望task.service在运行时启动$ systemctl suspend,但task.service没有启动。

我正在运行 debian,systemd 版本为 208,systemd --user配置或多或少如建筑维基百科

我想知道我的场景是否可以用 systemd 来实现,或者通过设计完全--system隔离--user,以便该--user单元可能不是--system单元的依赖项。

如果可能的话,我的情况可能是什么问题?

答案1

systemd/用户 - Archwiki

systemd --user作为独立于systemd --system进程的进程运行。用户单位不能引用或依赖系统单位。

有一个systemd GitHub 存储库中的功能请求跟踪这个问题。

答案2

您还可以为服务和用户实例之间的所有睡眠/挂起目标创建“代理”。

在以下位置创建此文件:/etc/systemd/system/[email protected]

[Unit]
Description=Call user's suspend target after system suspend
After=suspend.target

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl --user --machine=%i@ start --wait suspend.target

[Install]
WantedBy=suspend.target

并通过运行启用它sudo systemctl daemon-reload && sudo systemctl enable suspend@youruser

现在创建您的suspend.target用户~/.config/systemd/user/suspend.target

[Unit]
Description=User level suspend target
StopWhenUnneeded=yes
Wants=my-etc-service.service

然后将您的服务添加到Wants列表中并确保运行systemctl --user daemon-reload

答案3

systemd用户会话服务在完全独立的实例中运行systemd,并且没有任何方式直接依赖于系统服务。

不过,还有其他方法可以实现您想要的目标。最干净的方法可能是在系统将要睡眠时将您想要运行的任何内容挂钩到logind的抑制剂中,然后将其作为后台守护进程运行。

一个更通用的解决方案是让一个守护进程挂钩到logind抑制剂中,(参见系统锁处理程序xss锁,),然后当系统进入睡眠状态时,它将激活一个用户会话目标,您可以在该目标下订购服务。

答案4

您可以执行以下操作来在用户空间中实现sleep.target(和补充awake.target):

在中创建以下服务模板/etc/systemd/system/[email protected]

[Unit]
Description=%I sleep hook
PartOf=sleep.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/systemctl --user --machine=%i@ start sleep.target
ExecStop=/usr/bin/systemctl --user --machine=%i@ start awake.target

[Install]
WantedBy=sleep.target

为您的用户创建它的实例(不要启动它):

sudo systemctl enable sleep@$(whoami)

现在对于用户来说相当于sleep.target

[Unit]
Description=User-level Sleep Target
Conflicts=awake.target

awake.target

[Unit]
Description=User-level Awake Target
Conflicts=sleep.target

[Install]
WantedBy=default.target

启用systemctl --user enable awake.target,以便在登录时启动

当达到其中一个目标时,它们会停止另一个目标,这要归功于Conflicts指令,这使得它们成为互斥的目标。

对于我的用例,我实际上发现比awake.target更有用,sleep.target因为我可以让一些用户服务使用PartOf指令来开始和停止它。

我能想到的唯一可以从目标中受益的用例sleep是,如果有人试图systemd-inhibit在系统进入睡眠状态之前进行一些最后一刻的清理。这也意味着将实际的睡眠目标推迟到工作完成之后。

相关内容