如何将 kern.log 错误消息中的 ataX.0 标识符映射到实际的 /dev/sdY 设备?

max*_*zig 11 linux sata

考虑以下kern.log片段:

 ata4.00: failed command: WRITE FPDMA QUEUED
 ata4.00: cmd 61/00:78:40:1e:6c/04:00:f0:00:00/40 tag 15 ncq 524288 out
        res 41/04:00:00:00:00/04:00:00:00:00/00 Emask 0x1 (device error)
 ata4.00: status: { DRDY ERR }
 ata4.00: error: { ABRT }
 ata4: hard resetting link
 ata4: nv: skipping hardreset on occupied port
 ata4: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
 ata4.00: configured for UDMA/133
 ata4: EH complete
Run Code Online (Sandbox Code Playgroud)

我如何识别内核在谈论时实际表示的硬盘驱动器ata4.00

如何找到对应的/dev/sdY设备名称?

max*_*zig 12

通过遍历/sys树可以找到对应的/dev/sdY设备:

$ find /sys/devices | grep '/ata[0-9]\+/.*/block/s[^/]\+$' \
    | sed 's@^.\+/\(ata[0-9]\+\)/.\+/block/\(.\+\)$@\1 => /dev/\2@'
Run Code Online (Sandbox Code Playgroud)

使用更有效的/sys遍历(参见lsata.sh):

$ echo /sys/class/ata_port/ata*/../../host*/target*/*/block/s* | tr ' ' '\n' \
    | awk -F/ '{printf("%s => /dev/%s\n", $5, $NF)}'
Run Code Online (Sandbox Code Playgroud)

2 磁盘系统的示例输出:

ata1 => /dev/sda
ata2 => /dev/sdb
Run Code Online (Sandbox Code Playgroud)

然后,为了可靠地识别实际硬件,您需要将 /dev/sdY 映射到序列号,例如:

$ ls /dev/disk/by-id -l | grep 'ata.*sd[a-zA-Z]$'
Run Code Online (Sandbox Code Playgroud)

lssci

lssci实用程序还可用于派生映射:

$ lsscsi | sed 's@^\[\([^:]\+\).\+\(/dev/.\+\)$@\1,\2@' \
    | awk -F, '{ printf("ata%d => %s\n", $1+1, $2) }'
Run Code Online (Sandbox Code Playgroud)

请注意,相关的 lsscsi 枚举从 0 开始,而 ata 枚举从 0 开始。

系统日志

如果没有其他工作,可以查看系统日志/日志以导出映射。

/dev/sdY以相同的顺序被创建器件作为ataX标识符在所列举的kern.log,而忽略非磁盘设备(ATAPI)和未连接的链路。

因此,以下命令显示映射:

$ grep '^May 28 2'  /var/log/kern.log.0  | \
   grep 'ata[0-9]\+.[0-9][0-9]: ATA-' | \
   sed 's/^.*\] ata//' | \
   sort -n | sed 's/:.*//' | \
   awk ' { a="ata" $1; printf("%10s is /dev/sd%c\n", a, 96+NR); }'
ata1.00 is /dev/sda
ata3.00 is /dev/sdb
ata5.00 is /dev/sdc
ata7.00 is /dev/sdd
ata8.00 is /dev/sde
ata10.00 is /dev/sdf
Run Code Online (Sandbox Code Playgroud)

(注意 ata4 没有显示,因为上面的日志消息来自另一个系统。)

我正在使用/var/log/kern.log.0而不是/var/log/kern.log因为启动消息已经轮换了。我 grepMay 28 2因为这是最后一次启动时间,我想忽略以前的消息。

要验证映射,您可以通过查看以下输出进行一些检查:

$ grep '^May 28 2'  /var/log/kern.log.0  | \
grep 'ata[0-9]\+.[0-9][0-9]: ATA-'
May 28 20:43:26 hn kernel: [    1.260488] ata1.00: ATA-7: SAMSUNG SV0802N, max UDMA/100
May 28 20:43:26 hn kernel: [    1.676400] ata5.00: ATA-5: ST380021A, 3.19, max UDMA/10
[..]
Run Code Online (Sandbox Code Playgroud)

您可以将此输出与hdparm输出进行比较,例如:

$ hdparm -i /dev/sda

/dev/sda:

Model=SAMSUNG SV0802N [..]
Run Code Online (Sandbox Code Playgroud)

(使用内核 2.6.32-31)