目录

Intel I226-V 网卡 Ubuntu 挂起唤醒掉网?systemd-sleep hook 永久自动修复

systemd-sleep hook 自动修复 igc 驱动,告别挂起唤醒掉网

Intel I226-V 网卡在 Ubuntu 挂起唤醒后掉网?终极修复方案

Intel 网卡在 Ubuntu 上"睡一觉醒来就不认了",是许多 DIY 玩家和服务器管理员都会遇到的痛点。你刚睡醒的系统发现有线网络完全消失,ip a 里找不到接口,ip link set enp5s0 up 直接报 No such device——但 lspci -k 明明还显示设备在、驱动也在,只是不干活了。

这篇文章整理了一次可复现、可验证、可回滚的完整方案,帮你彻底告别每次唤醒后手动敲命令的痛苦。

一、问题现象:挂起唤醒后网卡消失

这类[[Ubuntu]] 故障的典型症状有三种:

  • 接口完全消失ip a 里看不到任何以太网接口,但 lspci 能看到硬件
  • 接口存在但 DOWN:能看到 eno2enp5s0,但状态为 DOWN,执行 ip link set upRTNETLINK answers: No such device
  • 链路无法恢复:接口 UP 了但拿不到 IP,ping 不通网关

Intel I226-V 的场景里有一个关键细节:lspci -k 往往仍然显示设备存在且 Kernel driver in use: igc。这说明 PCI 设备本身没有丢,问题出在驱动层面的恢复流程——驱动加载了,但内部状态卡在挂起时的省电模式里,无法正常响应网络请求。

Intel I226-V 故障状态示意图:lspci 可见设备但网络接口不可用

二、根因判断:是驱动问题还是硬件问题?

判断故障核心,不要纠结于"接口名在不在",而要看驱动重载后能否立即恢复链路与 IP

执行下面两步,如果接口重新出现并回到 UP, LOWER_UP,就基本确认故障点在 igc 驱动或其恢复后的省电状态:

sudo modprobe -r igc
sudo modprobe igc
ip a

公开资料也佐证了这一点:I225/I226 系列与 EEE(Energy Efficient Ethernet,节能以太网)相关的链路异常并不罕见。补丁讨论中直接提到 I226-V 在启用 EEE 时可能发生 hang,因此禁用 EEE 是合理的辅助缓解措施。

三、为什么用 systemd-sleep hook 而不是自定义 service?

网上很多教程会教你写一个 [[systemd]] service,然后把它挂到 suspend.targetsleep.target 上。这个思路有一个根本性的问题:systemd 的 sleep target 很模糊——有些 target 在睡眠前触发,有些在唤醒后触发,不同发行版的语义还有细微差异,很容易搞反顺序。

systemd-sleep(8) 的文档说得更直白:系统进入睡眠前和恢复后,会调用 /usr/lib/systemd/system-sleep/ 下的脚本,并分别传入 prepost 参数。对于"唤醒后自动修复网卡"这种场景,system-sleep hook 比自建 service 更标准、更简单、也更不容易写错

systemd-sleep hook 工作流程图:pre/post 两阶段触发逻辑

四、先手动验证:确认修复方案有效

在部署自动化脚本之前,先做一次手动验证,确认这台机器确实能被"驱动重载"修好。

第一步:确认驱动与设备

lspci -k | grep -A 3 -i ethernet

如果输出里能看到 Intel I226-V,并且 Kernel driver in use: igc,说明设备识别正常,后续修复方向应围绕 igc 展开。

第二步:重载驱动

sudo modprobe -r igc
sudo modprobe igc

这一步是核心。社区案例反复验证:这一组命令能够直接恢复挂起后不可用的以太网接口,比单纯 ip link set up 有效得多。

第三步:确认接口回归

ip a

成功时接口重新出现,进入 UP, LOWER_UP 状态。接口索引号变化是正常的——内核把它当作"重新注册的一块网卡"处理。

第四步:重新获取地址

根据你的网络环境选择:

# 传统 DHCP 客户端
sudo dhclient eno2 -v

# 或者 [[NetworkManager]](桌面系统更常见)
nmcli device reapply eno2

如果这四步跑通,说明你的机器完全适合下面的自动化方案。

五、一键安装:自动修复脚本

下面是最终版脚本,具备以下能力:

  • 只在唤醒后执行post 阶段),不会干扰睡眠前流程
  • 自动识别网卡接口,优先尝试 eno2enp5s0,兼容其他 en 开头的有线接口
  • 自动重载 igc 驱动
  • 自动禁用 EEE,降低 I226-V 的链路异常概率
  • 自动恢复网络,优先 dhclient,fallback 到 nmcli
  • 记录日志到 systemd journal,方便事后排查

安装命令(一条搞定)

sudo tee /usr/lib/systemd/system-sleep/igc-fix >/dev/null <<'EOF'
#!/bin/bash

LOGTAG="igc-fix"
PATH="/usr/sbin:/usr/bin:/sbin:/bin"

log() {
  logger -t "$LOGTAG" "$*"
}

get_iface() {
  for n in eno2 enp5s0; do
    if ip link show "$n" >/dev/null 2>&1; then
      echo "$n"
      return 0
    fi
  done
  ip -o link show | awk -F': ' '$2 ~ /^en/ {print $2; exit}' | cut -d'@' -f1
}

case "$1" in
  post)
    IFACE="$(get_iface)"
    if [ -z "$IFACE" ]; then
      log "no ethernet interface found"
      exit 0
    fi

    log "resume hook start, iface=$IFACE"

    modprobe -r igc || true
    modprobe igc
    sleep 2

    if ip link show "$IFACE" >/dev/null 2>&1; then
      ip link set "$IFACE" up || true

      if command -v ethtool >/dev/null 2>&1; then
        ethtool --set-eee "$IFACE" eee off || true
      fi

      if command -v dhclient >/dev/null 2>&1; then
        dhclient "$IFACE" -v || true
      elif command -v nmcli >/dev/null 2>&1; then
        nmcli device reapply "$IFACE" || true
      fi

      log "resume hook done, iface=$IFACE"
    else
      log "iface disappeared after modprobe, iface=$IFACE"
    fi
    ;;
esac
EOF

sudo chmod 755 /usr/lib/systemd/system-sleep/igc-fix
echo "✅ igc-fix 已安装"

注意:安装完成后不需要执行 systemctl enable 之类的操作。system-sleep hook 只要文件存在且可执行,就会被 systemd 在睡眠前后自动调用。

六、验证:实际测试一遍

安装完毕后,按以下步骤验证:

# 1. 让系统进入挂起
sudo systemctl suspend

# 2. 唤醒后检查网络状态
ip a
# 期望:接口回到 UP, LOWER_UP 状态,有正确的 IP 地址

# 3. 检查脚本日志
journalctl -b -t igc-fix
# 期望看到:
#   igc-fix: resume hook start, iface=enp5s0
#   igc-fix: resume hook done, iface=enp5s0

如果三步都通过,说明自动修复链路已打通,后续无需再手动干预。

七、常见问题

这通常说明接口在那个时间点还没有被内核重新注册回来,或者刚好处于驱动卸载后的空窗期。只要重新加载 igc 后接口能回来,就不表示硬件损坏,而是恢复流程中的时序问题——你的脚本里 sleep 2 就是给内核留出重新枚举设备的时间。

Q2:为什么接口有时叫 eno2,有时又叫 enp5s0

现代 Linux 使用可预测接口命名规则(predictable network interface names),同一张物理网卡可能有主接口名和替代名(altname)。脚本里的 get_iface() 函数会按顺序尝试已知名称,最后 fallback 到自动扫描,所以不管系统给你什么名字都能覆盖。

Q3:EEE 一定要关闭吗?

不是必须的,但强烈建议保留。已有资料明确指出 I225/I226 系列控制器存在 EEE 导致 hang 的情况。suspend/resume 本身就是 EEE 的边界场景——网卡刚从省电模式醒过来,如果 EEE 还开着,链路协商可能失败。关闭 EEE 是低成本、可回退的稳定性增强措施。

Q4:升级内核后问题消失了怎么办?

直接删除 hook 脚本即可:

sudo rm -f /usr/lib/systemd/system-sleep/igc-fix

system-sleep hook 不需要额外禁用服务,文件删除后 systemd 就不会再执行它。脚本是完全可回滚的。

八、方案的边界

这套方案适用于"挂起恢复后 Intel I226-V / igc 网卡失联,但手动重载驱动能够恢复"的场景。

如果你的机器重载驱动也无法恢复,或者 lspci -k 都看不到设备,那问题可能上升到更底层:

  • BIOS/UEFI 电源管理设置
  • PCIe ASPM(Active State Power Management)
  • 当前内核版本的已知 bug
  • 主板层面的兼容性问题

这种情况下应转向内核日志排查(dmesg | grep -i igc)、检查 BIOS 设置、或考虑内核版本回退。


如果你正在被 I226-V 的挂起唤醒掉网问题困扰,希望这篇指南能帮你一劳永逸。有问题欢迎在评论区交流。

关联阅读

  • [[Ubuntu 登录循环与用户级 systemd 服务——从死循环到干净桌面的修复路径]] — 同样是 systemd 服务故障排查,与本文的 systemd-sleep hook 方案形成互补
  • [[网卡是 Intel I226-V,驱动名为 igc。现在系统里完全找不到 enp5s0]] — 本文的前身原始笔记,记录了发现 I226-V 网卡驱动问题的过程

参考来源