内核故障排查
核心知识点
1. 内核故障概述
1.1 内核故障的类型
内核崩溃(Kernel Panic)
内核崩溃是指内核遇到无法恢复的错误,导致系统无法继续运行,通常会显示错误信息并停止所有操作。
系统挂起(System Hang)
系统挂起是指系统无响应,无法执行任何操作,可能是由于内核死锁、硬件故障或资源耗尽等原因导致的。
内核 oops
内核 oops 是指内核遇到错误,但仍然可以继续运行,通常会在系统日志中记录错误信息。
内存泄漏(Memory Leak)
内存泄漏是指内核或应用程序分配内存后未释放,导致内存使用量逐渐增加,最终可能导致系统内存耗尽。
死锁(Deadlock)
死锁是指两个或多个进程或线程相互等待对方释放资源,导致所有进程或线程都无法继续执行。
软锁(Soft Lockup)
软锁是指内核代码在某个 CPU 上执行时间过长,占用了过多的 CPU 时间,可能导致系统响应缓慢。
硬锁(Hard Lockup)
硬锁是指 CPU 完全被占用,无法执行其他任务,通常是由于内核代码中的无限循环或硬件故障导致的。
1.2 内核故障的原因
硬件问题
- CPU 故障:CPU 过热、损坏或不兼容。
- 内存故障:内存模块损坏、不兼容或接触不良。
- 磁盘故障:磁盘损坏、分区错误或文件系统损坏。
- 网络故障:网络适配器损坏、驱动程序错误或网络配置错误。
- 其他硬件故障:主板、电源、显卡等硬件故障。
软件问题
- 内核 bug:内核代码中的错误或缺陷。
- 驱动程序问题:硬件驱动程序中的错误或不兼容。
- 模块冲突:内核模块之间的冲突或不兼容。
- 系统配置错误:内核参数配置错误、文件系统配置错误或网络配置错误。
- 应用程序问题:应用程序中的错误或恶意代码。
环境问题
- 电源问题:电源不稳定或断电。
- 温度问题:系统温度过高,导致硬件故障。
- 电磁干扰:电磁干扰导致硬件故障或数据损坏。
- 灰尘问题:灰尘过多导致硬件散热不良或短路。
2. 内核故障的识别
2.1 系统日志分析
查看系统日志
使用 journalctl 或 dmesg 查看系统日志,寻找内核故障的相关信息。
# 查看系统日志
sudo journalctl -xn
# 查看内核日志
dmesg
# 查看特定时间范围的系统日志
sudo journalctl --since "2023-01-01 00:00:00" --until "2023-01-01 23:59:59"
# 查看内核相关的系统日志
sudo journalctl -k
# 查看内核错误信息
dmesg | grep -i error
dmesg | grep -i fail
dmesg | grep -i panic内核崩溃日志
内核崩溃时,会在 /var/log/ 目录下生成崩溃日志文件,如 vmcore、crash.log 等。
# 查看内核崩溃日志
ls -la /var/log/ | grep -i crash
# 查看 vmcore 文件
ls -la /var/crash/
# 使用 crash 工具分析 vmcore 文件
sudo crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/vmcore2.2 系统状态检查
查看系统负载
使用 top、uptime 等命令查看系统负载,判断系统是否过载。
# 查看系统负载
uptime
# 查看系统状态
top
# 查看 CPU 使用情况
top -b -n 1 | grep Cpu
# 查看内存使用情况
free -h
# 查看磁盘使用情况
df -h
# 查看磁盘 I/O 情况
iostat -x 1
# 查看网络状态
netstat -tuln
netstat -s查看进程状态
使用 ps、pstree 等命令查看进程状态,寻找异常进程。
# 查看所有进程
ps aux
# 查看进程树
pstree
# 查看占用 CPU 最多的进程
ps aux --sort=-%cpu | head -10
# 查看占用内存最多的进程
ps aux --sort=-%mem | head -10
# 查看进程状态
ps -eo pid,comm,state | grep -E 'D|R|Z'查看内核模块状态
使用 lsmod、modinfo 等命令查看内核模块状态,寻找异常模块。
# 查看已加载的内核模块
lsmod
# 查看特定模块的信息
modinfo <module_name>
# 查看模块加载情况
dmesg | grep <module_name>2.3 硬件诊断
CPU 诊断
使用 lscpu、cpuid 等命令查看 CPU 信息,使用 stress 等工具测试 CPU 稳定性。
# 查看 CPU 信息
lscpu
# 查看 CPU 详细信息
cpuid
# 测试 CPU 稳定性
sudo apt install stress # 安装 stress 工具
stress --cpu 4 --timeout 60 # 测试 4 个 CPU 核心,持续 60 秒
# 查看 CPU 温度
sensors内存诊断
使用 memtest86+ 等工具测试内存稳定性,使用 free、vmstat 等命令查看内存使用情况。
# 安装 memtest86+
sudo apt install memtest86+ # Debian/Ubuntu
sudo yum install memtest86+ # CentOS/RHEL
# 重启系统并在 GRUB 菜单中选择 memtest86+ 进行内存测试
# 查看内存使用情况
free -h
vmstat 1
# 查看内存详细信息
cat /proc/meminfo磁盘诊断
使用 smartctl、fsck 等工具测试磁盘健康状态,使用 hdparm 等命令查看磁盘信息。
# 安装 smartmontools
sudo apt install smartmontools # Debian/Ubuntu
sudo yum install smartmontools # CentOS/RHEL
# 查看磁盘 SMART 信息
sudo smartctl -a /dev/sda
# 测试磁盘读写速度
hdparm -t /dev/sda
# 检查文件系统
fsck -n /dev/sda1
# 查看磁盘分区信息
fdisk -l /dev/sda网络诊断
使用 ping、traceroute、netstat 等命令测试网络连接,使用 ethtool 等工具查看网络设备信息。
# 测试网络连接
ping -c 4 google.com
# 测试网络路由
traceroute google.com
# 查看网络设备信息
ethtool eth0
# 查看网络设备统计信息
ethtool -S eth0
# 查看网络连接状态
netstat -tuln
netstat -an | grep ESTABLISHED3. 内核故障排查工具
3.1 系统工具
dmesg
dmesg 命令用于查看内核环形缓冲区中的信息,包含内核启动信息和运行时的错误信息。
# 查看内核日志
dmesg
# 查看最近的内核日志
dmesg | tail -n 50
# 查看包含错误信息的内核日志
dmesg | grep -i error
# 查看包含警告信息的内核日志
dmesg | grep -i warn
# 查看包含特定模块信息的内核日志
dmesg | grep <module_name>journalctl
journalctl 命令用于查看 systemd 日志,包含系统启动信息、服务状态和错误信息。
# 查看系统日志
sudo journalctl -xn
# 查看内核日志
sudo journalctl -k
# 查看特定时间范围的系统日志
sudo journalctl --since "2023-01-01 00:00:00" --until "2023-01-01 23:59:59"
# 查看特定服务的日志
sudo journalctl -u <service_name>
# 查看包含错误信息的系统日志
sudo journalctl -p err..emergtop
top 命令用于实时监控系统状态,包含 CPU 使用率、内存使用率、进程状态等信息。
# 运行 top
top
# 常用快捷键:
# 1: 显示所有 CPU 核心
# M: 按内存使用排序
# P: 按 CPU 使用排序
# T: 按运行时间排序
# k: 终止进程
# q: 退出
# 批处理模式运行 top
top -b -n 1vmstat
vmstat 命令用于查看虚拟内存、进程、CPU 活动等系统状态。
# 查看系统状态
vmstat 1
# 查看详细信息
vmstat -a 1
# 查看内存分页情况
vmstat -s
# 查看磁盘 I/O 情况
vmstat -d
# 查看磁盘分区情况
vmstat -p /dev/sda1iostat
iostat 命令用于查看 CPU 使用率和磁盘 I/O 情况。
# 查看 CPU 和磁盘 I/O 情况
iostat -x 1
# 查看详细信息
iostat -xz 1
# 查看特定磁盘的 I/O 情况
iostat -x 1 /dev/sda
# 查看磁盘吞吐量
iostat -d 1netstat
netstat 命令用于查看网络连接、路由表、接口统计等网络信息。
# 查看网络连接
etstat -tuln
# 查看网络统计信息
netstat -s
# 查看网络路由表
netstat -r
# 查看网络接口信息
netstat -i
# 查看 ESTABLISHED 连接
netstat -an | grep ESTABLISHED3.2 内核调试工具
crash
crash 工具用于分析内核崩溃转储文件(vmcore),可以查看内核状态、进程状态、内存使用情况等信息。
# 安装 crash 工具
sudo apt install crash # Debian/Ubuntu
sudo yum install crash # CentOS/RHEL
# 分析 vmcore 文件
sudo crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/vmcore
# crash 工具常用命令:
# bt: 查看当前进程的堆栈跟踪
# ps: 查看所有进程
# files: 查看打开的文件
# net: 查看网络状态
# kmem: 查看内存使用情况
# log: 查看内核日志
# exit: 退出 crash 工具kdb
kdb 是内核内置的调试器,可以在运行时调试内核,查看内核状态、设置断点等。
# 启用 kdb
# 在 GRUB 配置文件中添加:
# GRUB_CMDLINE_LINUX="kdb=on kgdboc=ttyS0,115200"
# 重启系统
# 进入 kdb
# 在系统运行时按 Scroll Lock 键,或使用 sysrq 键:
# echo g > /proc/sysrq-trigger
# kdb 常用命令:
# help: 查看帮助
# bt: 查看当前进程的堆栈跟踪
# ps: 查看所有进程
# lsmod: 查看已加载的模块
# exit: 退出 kdbkgdb
kgdb 是内核内置的远程调试器,可以通过串口或网络远程调试内核。
# 启用 kgdb
# 在 GRUB 配置文件中添加:
# GRUB_CMDLINE_LINUX="kgdboc=ttyS0,115200"
# 编译带有调试信息的内核
make menuconfig
# 启用 CONFIG_DEBUG_INFO 和 CONFIG_KGDB
# 编译内核
make -j$(nproc)
# 安装内核
sudo make modules_install
sudo make install
# 重启系统
# 使用 gdb 远程调试内核
gdb vmlinux
target remote /dev/ttyS0
break sys_open
continueftrace
ftrace 是内核内置的追踪工具,可以追踪内核函数调用、调度事件等。
# 挂载 debugfs
mount -t debugfs debugfs /sys/kernel/debug
# 查看可用的追踪器
cat /sys/kernel/debug/tracing/available_tracers
# 启用函数追踪
echo function > /sys/kernel/debug/tracing/current_tracer
# 开始追踪
echo 1 > /sys/kernel/debug/tracing/tracing_on
# 执行需要追踪的操作
# 停止追踪
echo 0 > /sys/kernel/debug/tracing/tracing_on
# 查看追踪结果
cat /sys/kernel/debug/tracing/trace
# 清空追踪缓冲区
echo > /sys/kernel/debug/tracing/tracesystemtap
systemtap 是一个动态追踪工具,可以编写脚本对内核进行动态追踪,无需重新编译内核。
# 安装 systemtap
sudo apt install systemtap systemtap-runtime # Debian/Ubuntu
sudo yum install systemtap systemtap-runtime # CentOS/RHEL
# 创建追踪脚本
cat > trace.stp << 'EOF'
probe kernel.function("sys_open") {
printf("sys_open called with filename: %s\n", user_string($filename))
}
EOF
# 运行追踪脚本
sudo stap trace.stp
# 执行需要追踪的操作
# 按 Ctrl+C 停止追踪perf
perf 是内核内置的性能分析工具,可以分析系统性能、查看内核事件、追踪函数调用等。
# 安装 perf
sudo apt install linux-tools-common # Debian/Ubuntu
sudo yum install perf # CentOS/RHEL
# 查看系统性能
perf top
# 记录性能数据
perf record -a -g sleep 10
# 分析性能数据
perf report
# 追踪特定函数
perf record -g -p <pid> -e cpu-clock
perf report
# 查看内核事件
perf list
perf stat -e cycles,instructions,cache-references,cache-misses ./program3. 常见内核故障的解决方案
3.1 内核崩溃(Kernel Panic)
故障现象
系统突然停止运行,显示错误信息,如 "Kernel panic - not syncing: Attempted to kill init!" 等。
可能原因
- 内核代码中的错误
- 硬件故障(如内存损坏、CPU 故障)
- 驱动程序错误
- 文件系统损坏
- 内核参数配置错误
解决方案
- 查看内核崩溃日志:分析
/var/log/messages、/var/crash/vmcore等文件,了解崩溃原因。 - 检查硬件:使用
memtest86+测试内存,使用smartctl检查磁盘健康状态。 - 更新内核:安装最新的内核版本,修复已知的内核 bug。
- 更新驱动程序:安装最新的驱动程序,修复已知的驱动程序 bug。
- 检查文件系统:使用
fsck检查并修复文件系统错误。 - 调整内核参数:修改内核参数,如
vm.swappiness、kernel.panic等。 - 禁用有问题的模块:使用
modprobe -r命令卸载有问题的内核模块,或在/etc/modprobe.d/目录中创建黑名单文件。
示例
# 查看内核崩溃日志
dmesg | grep -i panic
# 检查内存
sudo apt install memtest86+
# 重启系统并在 GRUB 菜单中选择 memtest86+
# 检查磁盘
sudo smartctl -a /dev/sda
# 检查文件系统
sudo fsck -n /dev/sda1
# 更新内核
sudo apt update
sudo apt install linux-image-generic
# 禁用有问题的模块
echo "blacklist problematic_module" | sudo tee /etc/modprobe.d/blacklist-problematic.conf3.2 系统挂起(System Hang)
故障现象
系统无响应,无法执行任何操作,键盘和鼠标可能也无响应。
可能原因
- 内核死锁
- 硬件故障(如 CPU 过热、内存故障)
- 资源耗尽(如内存不足、磁盘空间不足)
- 驱动程序错误
- 内核代码中的无限循环
解决方案
- 检查系统状态:使用
sysrq键强制获取系统状态,如echo t > /proc/sysrq-trigger查看进程状态。 - 检查硬件:检查 CPU 温度、内存使用情况、磁盘空间等。
- 检查系统日志:查看
/var/log/messages、/var/log/syslog等文件,了解系统挂起的原因。 - 更新内核和驱动程序:安装最新的内核和驱动程序,修复已知的 bug。
- 调整系统参数:修改系统参数,如
vm.swappiness、kernel.softlockup_panic等。 - 检查应用程序:检查是否有应用程序导致系统挂起,如内存泄漏的应用程序。
示例
# 使用 sysrq 键获取系统状态
echo t > /proc/sysrq-trigger # 查看进程状态
echo m > /proc/sysrq-trigger # 查看内存使用情况
echo p > /proc/sysrq-trigger # 查看当前处理器的寄存器和标志
echo c > /proc/sysrq-trigger # 强制崩溃,生成 vmcore 文件
# 查看系统日志
sudo journalctl -xn
# 检查 CPU 温度
sensors
# 检查内存使用情况
free -h
# 检查磁盘空间
df -h
# 检查进程状态
ps aux --sort=-%cpu | head -10
ps aux --sort=-%mem | head -103.3 内核 oops
故障现象
系统继续运行,但在系统日志中记录了内核 oops 错误信息。
可能原因
- 内核代码中的错误
- 驱动程序错误
- 硬件故障
- 内存损坏
解决方案
- 查看系统日志:分析
/var/log/messages、/var/log/syslog等文件,了解内核 oops 的原因。 - 检查硬件:使用
memtest86+测试内存,使用smartctl检查磁盘健康状态。 - 更新内核和驱动程序:安装最新的内核和驱动程序,修复已知的 bug。
- 禁用有问题的模块:使用
modprobe -r命令卸载有问题的内核模块,或在/etc/modprobe.d/目录中创建黑名单文件。 - 报告 bug:如果无法解决,向内核开发团队报告 bug。
示例
# 查看系统日志中的内核 oops 信息
dmesg | grep -i oops
# 检查内存
sudo apt install memtest86+
# 重启系统并在 GRUB 菜单中选择 memtest86+
# 检查磁盘
sudo smartctl -a /dev/sda
# 更新内核
sudo apt update
sudo apt install linux-image-generic
# 禁用有问题的模块
echo "blacklist problematic_module" | sudo tee /etc/modprobe.d/blacklist-problematic.conf3.4 内存泄漏(Memory Leak)
故障现象
系统内存使用量逐渐增加,最终可能导致系统内存耗尽,出现 OOM(Out of Memory)错误。
可能原因
- 内核模块中的内存泄漏
- 应用程序中的内存泄漏
- 内核代码中的错误
- 驱动程序错误
解决方案
- 检查内存使用情况:使用
free、top等命令查看内存使用情况,确定内存泄漏的进程或模块。 - 使用内存分析工具:使用
kmemleak、valgrind等工具分析内存泄漏。 - 更新内核和驱动程序:安装最新的内核和驱动程序,修复已知的内存泄漏 bug。
- 禁用有问题的模块:使用
modprobe -r命令卸载有问题的内核模块,或在/etc/modprobe.d/目录中创建黑名单文件。 - 调整系统参数:修改系统参数,如
vm.swappiness、vm.overcommit_memory等。
示例
# 查看内存使用情况
free -h
top
# 启用 kmemleak
echo scan > /sys/kernel/debug/kmemleak
cat /sys/kernel/debug/kmemleak
# 检查进程内存使用情况
ps aux --sort=-%mem | head -10
# 检查内核模块内存使用情况
lsmod | sort -k 2 -n -r | head -10
# 更新内核
sudo apt update
sudo apt install linux-image-generic
# 禁用有问题的模块
echo "blacklist problematic_module" | sudo tee /etc/modprobe.d/blacklist-problematic.conf3.5 死锁(Deadlock)
故障现象
系统无响应或响应缓慢,多个进程或线程相互等待对方释放资源。
可能原因
- 内核代码中的死锁
- 应用程序中的死锁
- 资源争用
- 锁顺序不一致
解决方案
- 检查系统状态:使用
sysrq键获取系统状态,如echo t > /proc/sysrq-trigger查看进程状态。 - 使用调试工具:使用
crash、systemtap等工具分析死锁原因。 - 更新内核和应用程序:安装最新的内核和应用程序,修复已知的死锁 bug。
- 调整系统参数:修改系统参数,如
kernel.sched_rt_runtime_us、kernel.softlockup_panic等。 - 优化应用程序:优化应用程序代码,避免死锁,如使用非阻塞 I/O、合理的锁顺序等。
示例
# 使用 sysrq 键获取系统状态
echo t > /proc/sysrq-trigger # 查看进程状态
# 查看系统日志
sudo journalctl -xn
# 使用 systemtap 分析死锁
cat > deadlock.stp << 'EOF'
probe kernel.function("mutex_lock").call {
printf("%s: mutex_lock called at %s:%d\n", execname(), probefunc(), __LINE__)
}
probe kernel.function("mutex_unlock").call {
printf("%s: mutex_unlock called at %s:%d\n", execname(), probefunc(), __LINE__)
}
EOF
sudo stap deadlock.stp
# 更新内核
sudo apt update
sudo apt install linux-image-generic3.6 软锁(Soft Lockup)
故障现象
系统日志中出现 "BUG: soft lockup - CPU#X stuck for Xs!" 错误信息,系统可能响应缓慢。
可能原因
- 内核代码中的长时间循环
- 驱动程序中的长时间操作
- 硬件故障(如 CPU 过热)
- 资源争用
解决方案
- 查看系统日志:分析
/var/log/messages、/var/log/syslog等文件,了解软锁的原因。 - 检查硬件:检查 CPU 温度、内存使用情况等。
- 更新内核和驱动程序:安装最新的内核和驱动程序,修复已知的软锁 bug。
- 调整系统参数:修改系统参数,如
kernel.softlockup_panic、kernel.watchdog_thresh等。 - 禁用有问题的模块:使用
modprobe -r命令卸载有问题的内核模块,或在/etc/modprobe.d/目录中创建黑名单文件。
示例
# 查看系统日志中的软锁信息
dmesg | grep -i soft lockup
# 检查 CPU 温度
sensors
# 检查内存使用情况
free -h
# 更新内核
sudo apt update
sudo apt install linux-image-generic
# 调整系统参数
echo "kernel.softlockup_panic = 1" | sudo tee /etc/sysctl.d/50-softlockup.conf
echo "kernel.watchdog_thresh = 30" | sudo tee -a /etc/sysctl.d/50-softlockup.conf
sudo sysctl -p /etc/sysctl.d/50-softlockup.conf
# 禁用有问题的模块
echo "blacklist problematic_module" | sudo tee /etc/modprobe.d/blacklist-problematic.conf3.7 硬锁(Hard Lockup)
故障现象
系统日志中出现 "BUG: hard lockup - CPU#X stuck for Xs!" 错误信息,系统可能完全无响应。
可能原因
- 内核代码中的无限循环
- 硬件故障(如 CPU 故障、内存故障)
- 驱动程序错误
- 内核模块冲突
解决方案
- 查看系统日志:分析
/var/log/messages、/var/log/syslog等文件,了解硬锁的原因。 - 检查硬件:使用
memtest86+测试内存,检查 CPU 温度和健康状态。 - 更新内核和驱动程序:安装最新的内核和驱动程序,修复已知的硬锁 bug。
- 调整系统参数:修改系统参数,如
kernel.hardlockup_panic、kernel.watchdog_thresh等。 - 禁用有问题的模块:使用
modprobe -r命令卸载有问题的内核模块,或在/etc/modprobe.d/目录中创建黑名单文件。
示例
# 查看系统日志中的硬锁信息
dmesg | grep -i hard lockup
# 检查 CPU 温度
sensors
# 测试内存
sudo apt install memtest86+
# 重启系统并在 GRUB 菜单中选择 memtest86+
# 更新内核
sudo apt update
sudo apt install linux-image-generic
# 调整系统参数
echo "kernel.hardlockup_panic = 1" | sudo tee /etc/sysctl.d/50-hardlockup.conf
echo "kernel.watchdog_thresh = 30" | sudo tee -a /etc/sysctl.d/50-hardlockup.conf
sudo sysctl -p /etc/sysctl.d/50-hardlockup.conf
# 禁用有问题的模块
echo "blacklist problematic_module" | sudo tee /etc/modprobe.d/blacklist-problematic.conf4. 内核故障排查的最佳实践
4.1 预防措施
保持系统更新
定期更新内核和驱动程序,修复已知的 bug 和安全漏洞。
# 更新系统
sudo apt update
sudo apt upgrade
# 或
sudo yum update监控系统状态
使用监控工具(如 Nagios、Zabbix、Prometheus 等)监控系统状态,及时发现异常。
# 安装监控工具
sudo apt install nagios-server nagios-plugins # Debian/Ubuntu
sudo yum install nagios nagios-plugins-all # CentOS/RHEL
# 配置监控项
# 编辑 /etc/nagios/nagios.cfg 文件
# 启动监控服务
sudo systemctl start nagios
sudo systemctl enable nagios定期检查硬件
定期检查硬件健康状态,如 CPU 温度、内存使用情况、磁盘健康状态等。
# 检查 CPU 温度
sensors
# 检查内存使用情况
free -h
# 检查磁盘健康状态
sudo smartctl -a /dev/sda
# 检查网络状态
ping -c 4 google.com备份系统
定期备份系统和数据,以便在系统故障时能够快速恢复。
# 备份系统
sudo rsync -avz --exclude=/proc --exclude=/sys --exclude=/dev --exclude=/tmp --exclude=/var/tmp / /backup/
# 备份关键数据
sudo rsync -avz /home/ /backup/home/
sudo rsync -avz /etc/ /backup/etc/4.2 故障排查流程
1. 识别故障类型
根据故障现象和系统日志,确定故障类型,如内核崩溃、系统挂起、内存泄漏等。
2. 收集故障信息
收集系统日志、系统状态、硬件信息等故障相关信息,以便分析故障原因。
3. 分析故障原因
根据收集的信息,分析故障原因,如硬件故障、软件 bug、配置错误等。
4. 实施解决方案
根据故障原因,实施相应的解决方案,如更新内核、修复硬件、调整配置等。
5. 验证解决方案
验证解决方案是否有效,如系统是否能够正常启动、故障是否不再出现等。
6. 记录故障信息
记录故障的详细信息,包括故障类型、故障原因、解决方案、验证结果等,以便后续参考。
4.3 常见问题的快速解决方法
系统无法启动
- 检查 GRUB 配置
- 检查文件系统
- 尝试使用救援模式启动
- 恢复系统备份
系统无响应
- 使用 sysrq 键获取系统状态
- 检查系统负载和资源使用情况
- 重启系统
- 检查硬件健康状态
内核崩溃
- 分析内核崩溃日志
- 检查硬件健康状态
- 更新内核和驱动程序
- 调整内核参数
内存不足
- 检查内存使用情况
- 关闭不必要的应用程序和服务
- 增加系统内存
- 调整虚拟内存设置
磁盘空间不足
- 检查磁盘使用情况
- 删除不必要的文件
- 清理系统日志
- 扩展磁盘空间
网络连接问题
- 检查网络连接状态
- 检查网络配置
- 重启网络服务
- 检查网络硬件
实用案例分析
案例 1:内核崩溃故障排查
场景描述
系统在启动时发生内核崩溃,显示 "Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)" 错误信息。
解决方案
步骤 1:分析故障信息
- 错误信息表明内核无法挂载根文件系统。
- 可能的原因:GRUB 配置错误、文件系统损坏、磁盘故障等。
步骤 2:收集故障信息
- 检查 GRUB 配置文件。
- 检查磁盘分区和文件系统。
- 检查磁盘健康状态。
步骤 3:实施解决方案
- 检查 GRUB 配置
# 使用救援模式启动系统
# 在 GRUB 菜单中选择 "Advanced options for Ubuntu" -> "Ubuntu, with Linux ... (recovery mode)"
# 检查 GRUB 配置文件
cat /boot/grub/grub.cfg
# 检查 /etc/fstab 文件
cat /etc/fstab
# 检查磁盘分区
fdisk -l
# 检查文件系统
e2fsck -n /dev/sda1- 修复 GRUB 配置
# 修复 GRUB 配置
sudo update-grub
# 或重新安装 GRUB
sudo grub-install /dev/sda
sudo update-grub- 修复文件系统
# 修复文件系统
sudo e2fsck -y /dev/sda1- 检查磁盘健康状态
# 检查磁盘健康状态
sudo smartctl -a /dev/sda步骤 4:验证解决方案
- 重启系统,检查是否能够正常启动。
- 检查系统日志,确认故障是否已解决。
案例 2:系统挂起故障排查
场景描述
系统在运行过程中突然无响应,键盘和鼠标也无响应,只能通过强制断电重启系统。
解决方案
步骤 1:分析故障信息
- 系统无响应,可能是由于内核死锁、硬件故障或资源耗尽等原因导致的。
- 收集系统日志和系统状态信息,分析故障原因。
步骤 2:收集故障信息
- 使用 sysrq 键获取系统状态
# 启用 sysrq 键
echo 1 > /proc/sys/kernel/sysrq
# 获取进程状态
echo t > /proc/sysrq-trigger
# 获取内存使用情况
echo m > /proc/sysrq-trigger
# 获取当前处理器的寄存器和标志
echo p > /proc/sysrq-trigger
# 强制崩溃,生成 vmcore 文件
echo c > /proc/sysrq-trigger- 检查系统日志
# 查看系统日志
sudo journalctl -xn
# 查看内核日志
dmesg- 检查硬件状态
# 检查 CPU 温度
sensors
# 检查内存使用情况
free -h
# 检查磁盘空间
df -h
# 检查磁盘 I/O 情况
iostat -x 1步骤 3:分析故障原因
根据收集的信息,分析故障原因,如:
- 内核死锁:多个进程相互等待对方释放资源。
- 硬件故障:CPU 过热、内存故障等。
- 资源耗尽:内存不足、磁盘空间不足等。
- 驱动程序错误:驱动程序中的 bug 导致系统挂起。
步骤 4:实施解决方案
- 修复内核死锁
# 更新内核
sudo apt update
sudo apt install linux-image-generic
# 或
sudo yum update- 修复硬件故障
# 清理 CPU 风扇和散热器
# 更换故障的内存模块
# 更换故障的磁盘- 解决资源耗尽问题
# 增加系统内存
# 扩展磁盘空间
# 关闭不必要的应用程序和服务
sudo systemctl stop unnecessary-service
sudo systemctl disable unnecessary-service- 修复驱动程序错误
# 更新驱动程序
sudo apt update
sudo apt install linux-firmware
# 或
sudo yum update
# 禁用有问题的驱动程序
echo "blacklist problematic_driver" | sudo tee /etc/modprobe.d/blacklist-problematic.conf步骤 5:验证解决方案
- 重启系统,检查是否能够正常运行。
- 监控系统状态,确认故障是否不再出现。
案例 3:内存泄漏故障排查
场景描述
系统内存使用量逐渐增加,最终导致系统内存耗尽,出现 OOM(Out of Memory)错误。
解决方案
步骤 1:分析故障信息
- 系统内存使用量逐渐增加,可能是由于内存泄漏导致的。
- 收集系统状态和内存使用情况,分析内存泄漏的原因。
步骤 2:收集故障信息
- 检查内存使用情况
# 查看内存使用情况
free -h
# 查看进程内存使用情况
ps aux --sort=-%mem | head -10
# 查看内核模块内存使用情况
lsmod | sort -k 2 -n -r | head -10- 使用内存分析工具
# 启用 kmemleak
echo scan > /sys/kernel/debug/kmemleak
cat /sys/kernel/debug/kmemleak
# 使用 valgrind 分析应用程序内存泄漏
valgrind --leak-check=full --show-leak-kinds=all ./application- 检查系统日志
# 查看系统日志
sudo journalctl -xn
# 查看内核日志
dmesg | grep -i oom步骤 3:分析故障原因
根据收集的信息,分析内存泄漏的原因,如:
- 应用程序内存泄漏:应用程序分配内存后未释放。
- 内核模块内存泄漏:内核模块分配内存后未释放。
- 驱动程序内存泄漏:驱动程序分配内存后未释放。
- 内核代码内存泄漏:内核代码中的 bug 导致内存泄漏。
步骤 4:实施解决方案
- 修复应用程序内存泄漏
# 更新应用程序
sudo apt update
sudo apt install application
# 或修复应用程序代码- 修复内核模块内存泄漏
# 更新内核
sudo apt update
sudo apt install linux-image-generic
# 或
sudo yum update
# 禁用有问题的内核模块
echo "blacklist problematic_module" | sudo tee /etc/modprobe.d/blacklist-problematic.conf- 修复驱动程序内存泄漏
# 更新驱动程序
sudo apt update
sudo apt install linux-firmware
# 或
sudo yum update
# 禁用有问题的驱动程序
echo "blacklist problematic_driver" | sudo tee /etc/modprobe.d/blacklist-problematic.conf- 调整系统参数
# 调整虚拟内存设置
echo "vm.swappiness = 60" | sudo tee /etc/sysctl.d/50-vm.conf
echo "vm.overcommit_memory = 1" | sudo tee -a /etc/sysctl.d/50-vm.conf
sudo sysctl -p /etc/sysctl.d/50-vm.conf步骤 5:验证解决方案
- 重启系统,检查内存使用情况是否正常。
- 监控系统内存使用情况,确认内存泄漏是否已解决。
最佳实践
- 保持系统更新:定期更新内核和驱动程序,修复已知的 bug 和安全漏洞。
- 监控系统状态:使用监控工具监控系统状态,及时发现异常。
- 定期检查硬件:定期检查硬件健康状态,如 CPU 温度、内存使用情况、磁盘健康状态等。
- 备份系统:定期备份系统和数据,以便在系统故障时能够快速恢复。
- 建立故障排查流程:建立标准化的故障排查流程,提高故障排查效率。
- 使用调试工具:熟练使用内核调试工具,如 crash、systemtap、perf 等。
- 分析系统日志:仔细分析系统日志,了解系统运行状态和故障原因。
- 记录故障信息:记录故障的详细信息,包括故障类型、故障原因、解决方案、验证结果等。
- 学习经验教训:从故障中学习经验教训,避免类似故障的再次发生。
- 寻求专业帮助:如果无法解决故障,寻求专业人士的帮助。
总结
本教程详细介绍了 Linux 内核故障排查的核心概念、工具和方法,包括故障类型识别、日志分析、调试工具使用、常见故障解决方案等内容。通过学习,读者可以掌握内核故障排查的技能,提高系统的可靠性和稳定性。
内核故障排查是一项复杂而又挑战性的工作,需要综合考虑系统的硬件配置、软件环境和应用需求。通过合理的预防措施、标准化的故障排查流程和熟练的调试工具使用,可以快速识别和解决内核故障,确保系统的正常运行。
希望本教程能够帮助读者在 Linux 内核故障排查的道路上取得更大的进步,为构建稳定、可靠的 Linux 系统做出贡献。