程序(u50/u60 USB 设备驱动程序守护程序)从 shell 成功,但如果通过 udev 启动则失败。
我尝试使用 sd_listen_fds() 但它返回 0。
int lonsd; // file descriptor for the new socket
struct ifreq ifr = {0};
struct ifaddrs *ifaddr, *ifa;
int found = 0;
int fd;
int num_fds; // number of file descriptors
// https://insujang.github.io/2018-11-27/udev-device-manager-for-the-linux-kernel-in-userspace/
// Currently, udev is a part of systemd, therefore it uses systemd’s socket protocol.
syslog(LOG_INFO, "%s devstr:%s, ldisc:%d\n", __func__, devstr, ldisc);
lonsd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
if (lonsd < 0) {
syslog(LOG_INFO, "%s socket() failed - must be udev\n", __func__);
lonsd = -EBADF;
//systemd/src/udev/udevd.c:
//static int listen_fds(int* ret_ctrl, int* ret_netlink) {
num_fds = sd_listen_fds(true);
if (num_fds < 0) {
syslog(LOG_CRIT, "%s sd_listen_fds() failed\n", __func__);
}
syslog(LOG_INFO, "%s num_fds:%d\n", __func__, num_fds);
for (fd = SD_LISTEN_FDS_START; fd < num_fds + SD_LISTEN_FDS_START; fd++) {
if (sd_is_socket(fd, AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)) > 0) {
if (lonsd >= 0) {
syslog(LOG_CRIT, "%s EINVAL: lonsd >= 0\n", __func__);
return -EINVAL;
}
lonsd = fd;
}
}
}
else syslog(LOG_INFO, "%s lonsd:%d\n", __func__, lonsd);
我正在移植 LonWorks USB 接口的驱动程序(总线 003 设备 004:ID 0920:5550 Echelon Co. Echelon U60 FT 网络接口)。 u50.ko 驱动程序已插入。从 shell 运行时,“lonifd”会创建一个网络设备。
5:lon10:
mtu 1280 qdisc fq_codel状态 未知组默认 qlen 10 link/[2384] inet 44.1.110.125/24 brd 44.1.110.255 范围全局 lon10 valid_lft 永远 Preferred_lft 永远 –
但是当由udev启动时,socket()失败。
根据评论,我更改了启动服务的规则。现在,如果找到设备,它会在启动时运行“lonifd”,并且在插入设备时运行“lonifd”,并在拔出插头时停止运行。
修改后的规则:/etc/udev/rules.d/90-liftd.rules。
SUBSYSTEM=="tty", ATTRS{idVendor}=="0920", ATTRS{idProduct}=="5550", ENV{SYSTEMD_WANTS}+="u60.service"
/etc/systemd/system/u60.service
[Unit]
Description=U60 USB Lontalk Interface
Documentation=
[Service]
ExecStart=/usr/bin/lonifd
Type=exec
Restart=on-failure