udev启动LonWorks USB驱动守护进程时socket()调用失败的问题求助
udev启动LonWorks USB驱动守护进程时socket()调用失败的问题求助
我正在移植Echelon U60 FT Network Interface(LonWorks USB接口,设备ID 0920:5550)的驱动,已经加载了u50.ko内核模块。现在遇到一个棘手的问题:
- 手动在Shell中启动守护进程(u50/u60 USB设备驱动守护进程)时完全正常,能成功创建lon10网络设备,设备信息如下:
5: lon10: <BROADCAST,UP,LOWER_UP> mtu 1280 qdisc fq_codel state UNKNOWN group default qlen 10 link/[2384] inet 44.1.110.125/24 brd 44.1.110.255 scope global lon10 valid_lft forever preferred_lft forever
- 但通过udev开机自动启动该守护进程时,
socket()调用直接失败。我了解到现在udev属于systemd的一部分,应该会通过套接字激活机制传递预创建的套接字给守护进程,于是尝试用sd_listen_fds()获取预传递的文件描述符,但它返回的num_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 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接口获取预创建的套接字 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); }
从syslog日志可以看到,进入udev分支后sd_listen_fds()返回的num_fds一直是0,完全没有可用的文件描述符。有没有朋友遇到过类似的场景?或者能帮我排查下代码中sd_listen_fds()的使用是否正确,或者udev配置有没有遗漏的关键步骤?
备注:内容来源于stack exchange,提问作者William Dickerson
相关产品推荐
相关产品推荐

