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:能看到
eno2或enp5s0,但状态为DOWN,执行ip link set up报RTNETLINK answers: No such device - 链路无法恢复:接口 UP 了但拿不到 IP,ping 不通网关
Intel I226-V 的场景里有一个关键细节:lspci -k 往往仍然显示设备存在且 Kernel driver in use: igc。这说明 PCI 设备本身没有丢,问题出在驱动层面的恢复流程——驱动加载了,但内部状态卡在挂起时的省电模式里,无法正常响应网络请求。

二、根因判断:是驱动问题还是硬件问题?
判断故障核心,不要纠结于"接口名在不在",而要看驱动重载后能否立即恢复链路与 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.target 或 sleep.target 上。这个思路有一个根本性的问题:systemd 的 sleep target 很模糊——有些 target 在睡眠前触发,有些在唤醒后触发,不同发行版的语义还有细微差异,很容易搞反顺序。
systemd-sleep(8) 的文档说得更直白:系统进入睡眠前和恢复后,会调用 /usr/lib/systemd/system-sleep/ 下的脚本,并分别传入 pre 与 post 参数。对于"唤醒后自动修复网卡"这种场景,system-sleep hook 比自建 service 更标准、更简单、也更不容易写错。

四、先手动验证:确认修复方案有效
在部署自动化脚本之前,先做一次手动验证,确认这台机器确实能被"驱动重载"修好。
第一步:确认驱动与设备
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阶段),不会干扰睡眠前流程 - 自动识别网卡接口,优先尝试
eno2和enp5s0,兼容其他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如果三步都通过,说明自动修复链路已打通,后续无需再手动干预。
七、常见问题
Q1:为什么 ip link set eno2 up 会提示 No such device?
这通常说明接口在那个时间点还没有被内核重新注册回来,或者刚好处于驱动卸载后的空窗期。只要重新加载 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-fixsystem-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 网卡驱动问题的过程
梦行志