dmesg不显示EIO等errno,因其记录内核驱动层硬件异常行为而非系统调用返回值;需通过关键词(如timeout、abort、READ)、设备上下文及smartctl/strace等工具交叉验证定位根因。

直接看 dmesg 里的错误码不现实——它不会输出像 EIO 这样的标准 errno,而是记录底层 I/O 异常行为;真正要定位“读取失败”的具体原因,得靠日志关键词 + 设备上下文 + 后续工具交叉验证。
为什么 dmesg 不显示 EIO、ENODEV 这类错误码
dmesg 输出的是内核驱动层的诊断信息,不是系统调用返回值。你看到的 I/O error 或 sector 123456789 是硬件/驱动报出的异常事件,而非 read(2) 系统调用返回的 errno。标准错误码(如 EIO)只在用户态程序收到系统调用失败时才出现,内核日志里不会直接写出来。
- 比如
blk_update_request: I/O error, dev sda, sector 123456789—— 这表示块层收到了设备返回的失败响应,但没告诉你这是电源不稳、链路 CRC 错还是控制器超时 -
ata1.00: failed command: READ FPDMA QUEUED后面可能跟status: { DRDY ERR }和error: { UNC },这才是 ATA 协议级错误码,需查 ATA spec 解码 - NVMe 设备报
NVMe status: 0x202 (abort) / 0x204 (timeout),对应的是 NVMe 命令状态码,不是 Linux errno
从 dmesg 提取有效线索的实操过滤方式
别搜 EIO,要搜能触发它的现象关键词,并绑定设备名:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 基础筛选:
dmesg | grep -E -i "(sd[a-z]|nvme|ata|vd[a-z])" | grep -i "error|fail|timeout|crc|bad|abort|reset" - 聚焦读操作:
dmesg | grep -A 3 -B 1 "READ\|read\|sector [0-9]\+"(-A 3 -B 1带上下文,看清是哪个命令、哪个队列、是否重试) - 排除干扰:加
| grep -v "usb\|hid\|firmware\|acpi"避免混入非存储设备日志 - 注意时间戳:同一设备反复出现
timeout+reset组合,比单次I/O error更可疑
结合 smartctl 和 errno 工具反向验证
当你在 dmesg 中看到某设备(如 /dev/sda)频繁报错,下一步不是猜 errno,而是查它是否真被内核判定为“不可用”:
- 运行
smartctl -a /dev/sda,重点看:Reallocated_Sector_Ct(已重映射扇区)、Current_Pending_Sector(待重映射)、UDMA_CRC_Error_Count(线缆干扰) - 如果
smartctl -H /dev/sda返回PASSED但仍有 sporadic timeout,可能是 NCQ 冲突或主板 AHCI Bug,用sudo hdparm -I /dev/sda | grep -i ncq确认是否启用 - 想查用户态程序实际收到什么 errno?复现问题时用
strace -e trace=read,open,io_submit -p $(pgrep -f 'your_app'),能看到read() = -1 EIO或open() = -1 ENXIO等真实返回值 - 查 errno 含义:
errno -l | grep -E "EIO|ENXIO|EBUSY|EROFS",但注意:这些是系统调用层面的结果,不是磁盘物理错误的根源
容易被忽略的深层陷阱
很多工程师卡在“看到 I/O error 就换盘”,结果发现是别的环节:
- 虚拟机里
/dev/vda报大量end_request: I/O error,宿主机上查journalctl -u qemu-system-x86_64才发现是 Ceph OSD 宕机,不是本地磁盘问题 -
dmesg显示nvme 0000:01:00.0: Device not ready,但lspci -vv -s 01:00.0的 AER 日志里有Uncorrectable Error (Non-Fatal),说明 PCIe 链路出错,换插槽或更新 BIOS 更有效 - RAID 卡后端盘报
softreset failed,但megacli -AdpEventLog -GetEvents -f /tmp/log.txt -aALL显示是电池充放电异常导致 write-back 缓存禁用,I/O 延迟飙升引发超时

















