首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在systemctl服务启动后执行udev的RUN语句

在systemctl服务启动后执行udev的RUN语句
EN

Stack Overflow用户
提问于 2015-10-12 08:26:50
回答 1查看 971关注 0票数 1

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

代码语言:javascript
复制
ENV{SYSTEMD_WANTS}="%s{manufacturer}.service"

一旦守护进程启动,它需要被告知要打开哪个设备,这是通过udev完成的:

代码语言:javascript
复制
RUN="/usr/bin/sercomc open %E{sd_name} %E{sd_proto} %N"

因此,完整的udev规则如下:

代码语言:javascript
复制
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是在守护进程启动之前执行的,所以这个命令显然没有效果:

代码语言:javascript
复制
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完成服务启动后触发运行命令?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-23 08:23:20

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

我现在所做的是对出现的每个设备使用一个带有单元文件/lib/systemd/system/sercomd@.service的实例化服务。

udev规则现在为:

代码语言:javascript
复制
    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文件中提取这些参数:

代码语言:javascript
复制
    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集线器添加设备或从USB集线器移除设备时,都会从systemd运行适当的客户端命令。通过添加

代码语言:javascript
复制
    Requires=sercomd.service
    After=sercomd.service

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33071589

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档