【问题标题】:Execution of udev's RUN statement after systemctl start of servicesystemctl启动服务后执行udev的RUN语句
【发布时间】:2015-10-12 00:26:50
【问题描述】:

我编写了一个守护进程,它通过一个或多个 RS232 设备(通常是 FT232R usb2serial)管理多个通信协议。 一旦出现 /dev/ttyUSB* 设备,如果检测到某些属性, systemd 被告知通过 udev 启动该守护进程:

ENV{SYSTEMD_WANTS}="%s{manufacturer}.service"

守护程序启动后,需要告诉它要打开哪个设备,我通过 udev 执行此操作:

RUN="/usr/bin/sercomc open %E{sd_name} %E{sd_proto} %N"

所以完整的 udev 规则如下所示:

ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{manufacturer}=="sercomd", ENV{SYSTEMD_WANTS}="%s{manufacturer}.service", ENV{sd_proto}="%s{product}", ENV{sd_name}="%s{serial}", RUN="/usr/bin/sercomc open %E{sd_name} %E{sd_proto} %N"

现在的问题是 RUN 在守护程序启动之前执行,因此 这个命令显然没有效果:

systemd-udevd[1638]: starting '/usr/bin/sercomc open ctl-vk1 ctserial /dev/ttyUSB0'
systemd-udevd[1632]: '/usr/bin/sercomc open ctl-vk1 ctserial /dev/ttyUSB0'(err) 'Couldn't connect to server: Connect failed: Connection refused'
[...]
sercomctl[1639]: [2015-10-12 03:05:39:291634] Serial communication daemon ver. 0.5 starting up

是否有解决此问题的推荐方法,即在 systemd 完成启动服务后触发运行命令?

【问题讨论】:

    标签: udev systemd


    【解决方案1】:

    如果您偶然发现了类似的问题并阅读了该问题,请不要被我正在使用的软件的名称所迷惑。让我们快速地说,“sercomd”是管理串行连接的守护进程的名称,“sercomc”是一个客户端程序,它告诉 sercomd 使用特定协议打开该设备。 此外,我还操纵了 FTDI usb2serial 芯片的 EEPROM,以便产品、制造商和串行字符串显示用户定义的值,我可以将其用于“即插即用”串行适配器的自动识别。

    我现在正在使用带有单元文件的实例化服务 /lib/systemd/system/sercomd@.service 对于出现的每台设备。

    udev 规则现在变为:

        SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{manufacturer}=="sercomd", ACTION=="add", SYMLINK="tty%s{serial}", PROGRAM="/bin/systemd-escape %s{serial}", ENV{SYSTEMD_WANTS}="sercomd@%c.service", ENV{sd_proto}="%s{product}", ENV{sd_dev}="%N"
    

    这个规则设置了一些环境变量sd_proto和sd_dev,第三个参数sd_dev可以从sercomd@.service文件中提取出来:

        ExecStart=/bin/bash -c "eval $$( udevadm info --query=env --export /dev/tty%I ); sercomc open %I $$sd_proto $$sd_dev"
        ExecStop=/usr/bin/sercomc -l %I close
    

    因此,每次从 USB 集线器添加或删除设备时,都会从 systemd 运行相应的客户端命令。 通过添加

        Requires=sercomd.service
        After=sercomd.service
    

    对于单元文件,它还将确保在客户端运行之前启动实际管理这些接口的守护进程。

    【讨论】:

    • 如果您认为您的问题令人困惑,请编辑您的问题进行解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 2022-08-13
    • 1970-01-01
    • 2014-01-09
    • 2018-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多