udev启动的程序如何调用socket()?

问题描述 投票:0回答:1

程序(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()失败。

sockets linux-device-driver udev
1个回答
0
投票

根据评论,我更改了启动服务的规则。现在,如果找到设备,它会在启动时运行“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
© www.soinside.com 2019 - 2024. All rights reserved.