I'm getting kernel messages about 'ata3'. How do I figure out what device (/dev/sd_) that corresponds to?


From http://www.phuket-data-wizards.com/blog/2011/07/16/matching-linux-ata-numbers-to-the-device-names/:
The command grep '[0-9]' /sys/class/scsi_host/host{0..9}/unique_id will provide output like

so we can match the unique id used in kernel error messages to the host number. Then the command ls -l /sys/block/sd* will show us which device name belongs to which host number:
/sys/block/sda -> ../devices/pci0000:00/0000:00:13.2/usb1/1-6/1-6:1.0/host2/target2:0:0/2:0:0:0/block/sda
/sys/block/sdb -> ../devices/pci0000:00/0000:00:13.2/usb1/1-8/1-8:1.0/host3/target3:0:0/3:0:0:0/block/sdb
/sys/block/sdc -> ../devices/pci0000:00/0000:00:12.0/host6/target6:0:0/6:0:0:0/block/sdc /sys/block/sdd -> ../devices/pci0000:00/0000:00:13.2/usb1/1-8/1-8:1.0/host3/target3:0:0/3:0:0:1/block/sdd
/sys/block/sde -> ../devices/pci0000:00/0000:00:13.2/usb1/1-8/1-8:1.0/host3/target3:0:0/3:0:0:2/block/sde /sys/block/sdf -> ../devices/pci0000:00/0000:00:13.2/usb1/1-8/1-8:1.0/host3/target3:0:0/3:0:0:3/block/sdf
/sys/block/sdg -> ../devices/pci0000:00/0000:00:12.0/host7/target7:0:0/7:0:0:0/block/sdg

From these two outputs we can see that the unique id 6 maps to host7, and host7 maps to /dev/sdg. And finally, with the command hdparm -i /dev/sdg:
/dev/sdg: Model=ST3500418AS, FwRev=CC34, SerialNo=6VM2KSFD
we can find the serial number of the drive.

| improve this answer | |
  • 2
    I wrapped your answer in a one-liner so it can be more easier to use: ata=3; ls -l /sys/block/sd* | grep $(grep $ata /sys/class/scsi_host/host*/unique_id | awk -F'/' '{print $5}') – insider Jan 15 '14 at 10:20

Can't comment on previous answer, but for that one liner, you want to change the grep to be a little more restrictive as 1 and 10 are both valid ata#'s:

$ grep 1 /sys/class/scsi_host/host*/unique_id
$ grep ^1$ /sys/class/scsi_host/host*/unique_id


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

For my needs, I wanted to map a drive letter to an ata, so I wrote this, and on my system the ata string wasn't always the 5th component of the path:

name=`basename $dev`                                                            
readlink /sys/block/$name | perl -ne'm{/(ata\d+)/} && print "$1\n"'             

Use it like this:

$ ./map2ata /dev/sda
| improve this answer | |
  • I run this on CentOS 6 and it always returns blank output. Where is this getting $dev value from? – Edward_178118 Jun 25 '15 at 4:59
  • See the "Use it like this" section. You pass your device path to the script. – rrauenza Jun 25 '15 at 19:07
  • I did do that, and it always returns blank output. – Edward_178118 Jun 26 '15 at 10:19
  • Run each command in the script one by one. basename $dev just takes /path/whatever/xyz and returns xyz. It assigns xyz to name. readlink returns what /sys/block/$name actually points to, which is piped into perl to grab the ata[0-9]+ identifier and print it. – rrauenza Jun 26 '15 at 14:24
  • Similarly on centos6, and /sys/block/sdN doesn't point to an ata device name. # readlink /sys/block/sda ../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda – Dan Pritts Dec 15 '16 at 5:02

Just so we are clear the ATA number maps to the UNIQUE_ID, directly (they are the same number). So ATA #3 is UNIQUE_ID #3. Then you look up what HOST # is associated to the UNIQUE_ID


So here ATA #3 is UNIQUE_ID #3 is HOST #4

Then to get the drive letter just run “ls -lisah /sys/block” and find the HOST #4.

Here is a good stackexchange/superuser talking about this: Mapping ata device number to logical device name

| improve this answer | |

I'm not a Linux guru, but on my Ubuntu system everything was much easier:

# sudo ls /dev/disk/by-path -al
lrwxrwxrwx 1 root root   9 Jun 16 14:28 pci-0000:00:0b.0-ata-1 -> ../../sda
lrwxrwxrwx 1 root root  10 Jun 16 14:28 pci-0000:00:0b.0-ata-1-part1 -> ../../sda1
lrwxrwxrwx 1 root root  10 Jun 16 14:28 pci-0000:00:0b.0-ata-1-part2 -> ../../sda2
lrwxrwxrwx 1 root root  10 Jun 16 14:28 pci-0000:00:0b.0-ata-1-part3 -> ../../sda3
lrwxrwxrwx 1 root root   9 Jun 16 14:28 pci-0000:00:0b.0-ata-2 -> ../../sdb
lrwxrwxrwx 1 root root  10 Jun 16 14:28 pci-0000:00:0b.0-ata-2-part2 -> ../../sdb2
lrwxrwxrwx 1 root root  10 Jun 16 14:28 pci-0000:00:0b.0-ata-2-part5 -> ../../sdb5
lrwxrwxrwx 1 root root   9 Jun 16 14:28 pci-0000:00:0b.0-ata-3 -> ../../sdc
lrwxrwxrwx 1 root root  10 Jun 16 14:28 pci-0000:00:0b.0-ata-3-part1 -> ../../sdc1
lrwxrwxrwx 1 root root   9 Jun 16 14:28 pci-0000:00:0b.0-ata-4 -> ../../sdd
lrwxrwxrwx 1 root root  10 Jun 16 14:28 pci-0000:00:0b.0-ata-4-part1 -> ../../sdd1
| improve this answer | |
  • 1
    This is not an answer to the question. – Rich Michaels Jun 16 '19 at 11:45
  • Please explain why It's not. In my system, the ATA channel numbers exactly match the output of this command. – dredkin Jun 16 '19 at 11:51

I rather like this:

sg_inq /dev/sdq --verbose --id

VPD INQUIRY: Device Identification page
    inquiry cdb: 12 01 83 00 fc 00
    inquiry: requested 252 bytes but got 54 bytes
  Designation descriptor number 1, descriptor length: 24
    id_type: T10 vendor identification,  code_set: ASCII
    associated with the addressed logical unit
      vendor id: HITACHI
      vendor specific: R500D1075BCC
  Designation descriptor number 2, descriptor length: 6
    id_type: vendor specific [0x0],  code_set: Binary
    associated with the target port
 00     00 00                                               ..
  Designation descriptor number 3, descriptor length: 20
    id_type: NAA,  code_set: Binary
    associated with the addressed logical unit
      NAA 6, IEEE Company_id: 0x60e8
      Vendor Specific Identifier: 0x6d10700
      Vendor Specific Identifier Extension: 0xd10700005bcc

Logical device number in HEX:
vendor specific: R500D107**5BCC**
Array Serial in HEX:
vendor specific: R500**D107**5BCC

I'm not sure if this is good for other storage array manufacturers, but it works for Hitachi,

| improve this answer | |
  • This is interesting information but how does it help us map to ataX as reported by the kernel? – Dan Pritts Dec 15 '16 at 4:59

A perhaps easier, but not foolproof, method: Inspect the output of /bin/dmesg. The devices are listed there.

ata1: SATA max UDMA/133 abar m2048@0xf0616000 port 0xf0616100 irq 29
[ ... ]
ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
ata1.00: ATA-8: Hitachi HDT721010SLA360, ST6OA31B, max UDMA/133
ata1.00: 1953525168 sectors, multi 16: LBA48 NCQ (depth 31/32), AA
ata1.00: configured for UDMA/133
scsi 0:0:0:0: Direct-Access     ATA      Hitachi HDT72101 A31B PQ: 0 ANSI: 5
[ ... ] 
sd 0:0:0:0: [sda] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA

It's not foolproof for a few reasons. /bin/dmesg lists the contents of the kernel's "ring buffer"; the boot messages can be overwritten by later kernel messages.

It requires you to follow along and translate from ata1.00 to (here) Hitachi HDT72101, and then see that immediately that scsi 0:0:0:0: is that same disk. Then sd 0:0:0:0: is shown to be sda.

If you have multiple drives with identical model numbers and firmware levels, you won't be able to tell for sure which is which using this method. You hopefully can infer it from the order of probes in the dmesg output.

On my centos6 system, /var/log/dmesg contains the dmesg from the last boot.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.