deepin的系统假死恢复
Easul Lv6

背景

由于昨天我在工作站上装了KVM来运行ubuntu,结果发现昨天和今天有两次系统都出现异常无法访问。
早上重启了下,以为没什么,所以没有关注,结果2小时后又卡住了,遂对相应问题进行了更多分析。

相关分析

由于系统上除了KVM,还有别人以网络硬盘的形式挂载的NFS。原本猜测是两个程序互相竞争,导致磁盘IO过载,然后CPU无法被访问,最终机器失联。
但是之后通过查看系统日志,发现有如下内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 查看机器无法访问期间的日志内容
sudo journalctl --since "2026-03-26 10:00:00" --until "2026-03-26 10:46:00"
# 然后发现有如下日志
# 3月 26 10:37:26 easul deepin-service-manager[912]: check Url: "http://detectportal.deepin.com" exitCode: 28
# 3月 26 10:37:33 easul deepin-service-manager[1475]: check Url: "http://detect.uniontech.com" exitCode: 28
# 3月 26 10:37:33 easul deepin-service-manager[1475]: check Url: "http://detectportal.deepin.com" exitCode: 28
# 3月 26 10:37:40 easul kernel: e1000e 0000:00:1f.6 eno1: Detected Hardware Unit Hang:
# TDH <62>
# TDT <7e>
# next_to_use <7e>
# next_to_clean <62>
# buffer_info[next_to_clean]:
# time_stamp <1001b6d76>
# next_to_watch <63>
# jiffies <1001b7028>
# next_to_watch.status <0>
# MAC Status <80083>
# PHY Status <796d>
# PHY 1000BASE-T Status <3800>
# PHY Extended Status <3000>
# PCI Status <10>
# 3月 26 10:37:42 easul kernel: e1000e 0000:00:1f.6 eno1: Detected Hardware Unit Hang:
# TDH <62>
# TDT <7e>
# next_to_use <7e>
# next_to_clean <62>
# buffer_info[next_to_clean]:
# time_stamp <1001b6d76>
# next_to_watch <63>
# jiffies <1001b7218>
# next_to_watch.status <0>
# MAC Status <80083>
# PHY Status <796d>
# PHY 1000BASE-T Status <3800>
# PHY Extended Status <3000>
# PCI Status <10>

询问 ChatGPT 后,他说出了如下逻辑

内核尝试发数据到网卡,但网卡硬件/驱动没有响应
导致网络阻塞,TCP 堆栈卡死
最终 SSH / ping 都不通

另外一个就是 check Url: "http://detectportal.deepin.com" exitCode: 28 这种报错日志出现了很多,于是联想起昨天内网环境下搭建的DNS服务器挂了,我切换为公有 DNS 之后就不再出现该问题。

解决方法

  • 首先处理DNS相关的问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# DNS 的文件是在如下路径中存放的,可以先查看当前的DNS都有什么
cat /etc/resolv.conf
# 显示的内容如下

# # Generated by NetworkManager
# nameserver 192.168.1.21
# nameserver 119.29.29.29

# 所以我选择把 119.29.29.29 的顺序提前,这样就能够先用腾讯的DNS来解析了
# 修改后的内容如下

# # Generated by NetworkManager
# nameserver 119.29.29.29
# nameserver 192.168.1.21

# 此时再 curl 一下 http://detectportal.deepin.com,显示 success 则DNS解析不再有问题
curl http://detectportal.deepin.com

PS: 重启下DNS服务器也不是不可以 ^_^

  • 然后处理网卡挂起的问题

我这里直接创建这个脚本没生效,最后用的 systemd 的服务就OK了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 先安装 ethtool
sudo apt-get update
sudo apt-get install -y ethtool

# 先查看原本的配置
# tcp-segmentation-offload 对应下边的 tso
# generic-segmentation-offload 对应下边的 gso
# generic-receive-offload 对应下边的 gro
sudo ethtool -k eno1
# 调整当前网卡的配置,ChatGPT说,这样会
# 关闭 TSO / GSO / GRO(发送/分段/汇聚等高级功能)
# 减少硬件在高负载下的 buffer 压力
# 避免该硬件 hang 触发
sudo ethtool -K eno1 tso off gso off gro off
# 如果需要恢复原本的设置,可以使用该命令
# sudo ethtool -K eno1 tso on gso on gro on

# 然后开启了KVM之后,没有发现问题,故将该命令放到了网络启动脚本当中
sudo touch /etc/network/if-up.d/disable-offload
sudo chmod 666 /etc/network/if-up.d/disable-offload
# 这个脚本可以在网卡被拉起的时候就运行
sudo tee >> /etc/network/if-up.d/disable-offload <<EOF
#!/bin/bash

/sbin/ethtool -K eno1 tso off gso off gro off
EOF
sudo chmod 755 /etc/network/if-up.d/disable-offload

如果上边的脚本在网卡拉起的时候没有自动生效,可以将命令设置成 systemd 服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 也可以创建为 systemd 的服务
sudo touch /etc/systemd/system/disable-offload.service
sudo chmod 666 /etc/systemd/system/disable-offload.service
sudo tee >> /etc/systemd/system/disable-offload.service <<EOF
[Unit]
Description=Disable NIC offloading
After=network.target

[Service]
Type=oneshot
ExecStart=/sbin/ethtool -K eno1 tso off gso off gro off
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF
sudo chmod 755 /etc/systemd/system/disable-offload.service
sudo systemctl daemon-reexec
sudo systemctl enable disable-offload
# 然后删掉原本的脚本
sudo rm -rf /etc/network/if-up.d/disable-offload
 评论