You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开机时自定义守护进程通过getifaddrs无法获取预期网络接口

问题诊断与解决方案

根本原因

守护进程重启后仅能获取eth0 17(AF_PACKET)而无法获取eth0 2(AF_INET),核心原因是服务启动时eth0的IP地址尚未完成配置。
虽然服务文件中配置了After=network.target network-online.target,但:

  • network.target仅表示网络管理服务已启动,不代表具体网卡的IP配置完成;
  • network-online.target的就绪状态依赖于系统网络配置工具(如systemd-networkd、ifupdown、NetworkManager)的状态上报,若工具未正确向systemd报告网络就绪,该target不会真正等待IP配置完成。

解决方案

1. 修正systemd服务依赖

修改服务文件,强化网络就绪的依赖约束,确保服务仅在eth0设备就绪且网络在线后启动:

[Unit]
Description=test
Requires=network-online.target
After=network.target network-online.target sys-subsystem-net-devices-eth0.device

[Service]
Type=forking
ExecStart=/opt/test
Restart=always

[Install]
WantedBy=multi-user.target
  • Requires=network-online.target:强制服务必须等待该target就绪才启动,而非仅"期望";
  • sys-subsystem-net-devices-eth0.device:明确等待eth0物理设备初始化完成。

2. 确保网络配置工具正确上报在线状态

根据你使用的网络管理工具,补充对应的配置:

  • 使用systemd-networkd:在eth0的.network配置文件中添加RequiredForOnline=yes:
    [Network]
    Address=172.18.0.3/24
    RequiredForOnline=yes
    
    这样systemd-networkd会在IP配置完成后标记network-online.target为就绪。
  • 使用ifupdown(/etc/network/interfaces):安装ifupdown-extra包,它会为每个网卡提供ifup@eth0.service,可将服务依赖改为After=ifup@eth0.service;
  • 使用NetworkManager:确保NetworkManager服务已启用,且eth0配置为自动连接,NetworkManager会自动处理network-online.target的就绪状态。

3. 程序层面兜底处理(可选)

在代码中添加重试逻辑,避免因极端情况导致的网络未就绪问题:

#include <stdio.h>
#include <ifaddrs.h>
#include <unistd.h>
#include <string.h>

int has_eth0_inet() {
    struct ifaddrs *ifaddr;
    int found = 0;
    if (getifaddrs(&ifaddr) == -1) {
        perror("getifaddrs");
        return 0;
    }
    for(struct ifaddrs *ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr == NULL) continue;
        if (strcmp(ifa->ifa_name, "eth0") == 0 && ifa->ifa_addr->sa_family == AF_INET) {
            found = 1;
            break;
        }
    }
    freeifaddrs(ifaddr);
    return found;
}

int main() {
    // 最多重试5次,每次间隔5秒
    int retry_count = 5;
    while (retry_count-- > 0 && !has_eth0_inet()) {
        printf("Waiting for eth0 IPv4 address...\n");
        sleep(5);
    }

    // 执行原有接口检测逻辑
    struct ifaddrs *ifaddr;
    if (getifaddrs(&ifaddr) == -1) {
        perror("getifaddrs");
        return 1;
    }
    for(struct ifaddrs *ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr == NULL) continue;
        printf("Found interfaces %-8s %d\n", ifa->ifa_name, ifa->ifa_addr->sa_family);
    }
    freeifaddrs(ifaddr);
    return 0;
}

内容的提问来源于stack exchange,提问作者taptiptop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 18:01:12