Systemd 服务在系统启动期间不工作

Systemd 服务在系统启动期间不工作

所以我写了一个systemd服务文件Manjaro Linux运行两个 shell 命令在运行时设置一些内核参数以启用自定义省电操作。

顺便说一句:这是德国计算机杂志的提示。本来我应该将 shell 命令放在文件中/etc/rc.local,但我想使用 systemd 服务来制作它。因为rc.local被认为已弃用,我想学习新的东西。

下面您可以看到我的服务文件已保存为/etc/systemd/system/power-savings.service。因为有两个ExecStart指令,所以我选择了Type=oneshot

[Unit]
Description=Enable custom power saving actions provided by c't magazine
# Quelle(n):  c't 25/2016, S. 77
#             c't 26/2016, S. 12

[Service]
Type=oneshot
# SATA Link Power Management aktivieren
ExecStart=/usr/bin/sh -c 'for I in /sys/class/scsi_host/host?/link_power_management_policy; do echo min_power > $I; done'
# Energieverwaltung für den Audiocodec aktivieren
ExecStart=/usr/bin/sh -c 'echo 1 > /sys/module/snd_hda_intel/parameters/power_save'

[Install]
WantedBy=multi-user.target

我通过以下方式验证了服务文件:

$ sudo systemd-analyze verify /etc/systemd/system/power-savings.service

然后我用以下命令重新加载了守护进程:

$ sudo systemctl daemon-reload

我启用它:

$ sudo systemctl enable power-savings.service

然后我运行该服务:

$ sudo systemctl start power-savings.service

它成功了!内核参数已设置。

但是,重新启动系统后,该服务似乎没有任何效果。虽然,服务状态显示成功......

$ systemctl status power-savings.service

Process: 412 ExecStart=/usr/bin/bash -c echo 1 > /sys/module/snd_hda_intel/parameters/power_save (code=exited, status=0/SUCCESS)
Process: 404 ExecStart=/usr/bin/bash -c for I in /sys/class/scsi_host/host?/link_power_management_policy; do echo min_power > $I; done (code=exited, status=0/SUCCESS)
Main PID: 412 (code=exited, status=0/SUCCESS)

但内核参数没有设置。所以我的服务仅在用户会话期间工作。不幸的是,它不是在系统启动期间正常工作的。

有什么我可能错过的吗?我需要其中一些AfterRequire指令吗?我如何才能调试ExecStart指令的实际情况?

答案1

在对我的问题进行进一步研究时,我发现了 Arch Linux 社区的一个有趣的声明。在这个帖子用户卡尔松65正在尝试做一些和我类似的事情。

讨论将我重定向到一篇文章关于tmpfiles.d这可能是将值写入文件而不是使用管道或重定向的可能解决方案。不过这篇文章有一个有趣的地方笔记:

此方法可能无法设置选项,/sys因为systemd-tmpfiles-设置服务可以在加载适当的设备模块之前运行。

我们的项目的共同点是我们都确实尝试/sys/...在系统启动期间写入。这个事实可能就是为什么它不起作用的问题的答案。

答案2

根据您自己的答案中的信息,我所知道的解决您的问题的最正确方法是弄清楚在 systemd 启动顺序的哪个阶段设置模块/sys

一旦您知道了这一点,您就可以简单地将指令添加After=<whatever>.target到您的自定义服务文件中,这样 systemd 就知道在先决条件步骤完成之前不要启动它。

如果您无法追踪具体包含/sys模块的目标,您总是可以猜测一些会使您的服务在启动期间加载相对较晚的内容,例如After=local-fs.target。这不是最多正确的方法,但只要你小心不要引入“订购周期”,它可能会工作得很好。

相关内容