Given a kernel ATA exception, how to determine which physical disk is affected?

I wrote one-liner based on Tobi Hahn answer.

For example, you want to know what device stands for ata3:

ata=3; ls -l /sys/block/sd* | grep $(grep $ata /sys/class/scsi_host/host*/unique_id | awk -F'/' '{print $5}')

It will produce something like this

lrwxrwxrwx 1 root root 0 Jan 15 15:30 /sys/block/sde -> ../devices/pci0000:00/0000:00:1f.5/host2/target2:0:0/2:0:0:0/block/sde

Use this command:

ls -l /sys/block/sd* | sed 's/.*\(sd.*\) -.*\(ata.*\)\/h.*/\2 => \1/'

On my system this produces the output:

ata1 => sda
ata2 => sdb
ata3 => sdc
ata4 => sdd
ata7 => sde
ata8 => sdf

This will work even if all disks have the same drive model (between those 6 disks there are only two different models). Note that this depends on sysfs naming and works in my kernel 3.10.17. I know at some point in the past it wasn't this clean to retrieve the mappings but I'm not sure what the earliest kernel version this will work for.

If it doesn't work for you, see this link for a more roundabout way of determining the mappings: http://www.miriup.de/index.php?option=com_content&view=article&id=84:mapping-linux-kernel-ata-errors-to-a-device&catid=8:linux&Itemid=25


Turns out doing the mapping was easier than I realized.

dmesg | grep ata2 | head gives the kernel's mapping of the drive during the boot process. Or you could just go for ata2.00 right away.

[    2.448300] ata2: SATA max UDMA/133 abar m1024@0xfeb0b000 port 0xfeb0b180 irq 19
[    2.940139] ata2: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[    2.942143] ata2.00: ATA-8: ST31000340NS, SN05, max UDMA/133
[    2.942149] ata2.00: 1953525168 sectors, multi 16: LBA48 NCQ (depth 31/32)
[    2.944573] ata2.00: configured for UDMA/133
  (and some stuff I'd rather never have to see about drive errors)

As you can see, one of those lines contains my drive model number (ST31000340NS) which I can then use to map to a /dev file:

$ readlink /dev/disk/by-id/*ST31000340NS* | head -n1
../../sda