有没有办法让 systemd 服务找出设备路径并在更改时重新启动?

有没有办法让 systemd 服务找出设备路径并在更改时重新启动?

我正在运行一个守护程序,启动时需要设备的路径。该设备已连接到 USB 总线,但有时会断开 USB 并再次重新连接(连接器松动或硬件崩溃,尚未发现问题),但随后该设备会获得另一个名称,例如,/dev/ttyACM0变为/dev/ttyACM1

它是一个虚拟串行端口,可从 AIS 接收器(感兴趣的 Quark-elec QK-A022)输出 NMEA 数据。

我非常确定只有一台设备会同时连接到 USB。

当系统中插入特定类型的设备时,有没有办法使用 systemd 启动/重新启动服务?我注意到systemctl list-units --type=device其中列出了设备,所以我充满希望,但到目前为止我找到的每个示例都是基于显式启动 servicename@device 。

root@ais:/home/pi# systemctl list-units --type=device | fgrep STM
sys-devices-platform-soc-3f980000.usb-usb1-1\x2d1-1\x2d1.2-1\x2d1.2:1.0-tty-ttyACM1.device                      loaded active plugged STM32F407

我非常确定只有一台设备会同时连接到 USB。

答案1

如今,插入设备时运行守护程序的规范方法似乎是为守护程序创建一个 systemd 单元,并为引用该单元的设备添加一个 udev 条目。例如,/etc/udev/rules.d/90-my.rules使用以下行创建一个文件

ACTION=="add", KERNEL=="ttyACM*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="myacm@%k.service"

和一个文件/etc/systemd/system/[email protected]

[Unit]
Description=my serial daemon for ttyACM0
[Service]
ExecStart=/bin/myscript %i

您可能需要sudo udevadm control --reloadsudo systemctl daemon-reload。当您插入设备时,您的脚本应该使用参数运行(ttyACM0如果这是它的名称)。检查日志文件中是否有错误。

参见man 7 daemon部分新型守护进程基于设备的激活, 也man systemd.device

答案2

我不知道您是否可以在 systemd 中执行此操作,但如果检测到设备更改,您可以使用 udev 重新启动/重新加载服务。

相关内容