14

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

1

8 Answers 8

13

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

/sys/class/scsi_host/host0/unique_id:1  
/sys/class/scsi_host/host1/unique_id:2  
/sys/class/scsi_host/host2/unique_id:0  
/sys/class/scsi_host/host3/unique_id:0  
/sys/class/scsi_host/host4/unique_id:3  
/sys/class/scsi_host/host5/unique_id:4  
/sys/class/scsi_host/host6/unique_id:5  
/sys/class/scsi_host/host7/unique_id:6

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.

2
  • 3
    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
    Commented Jan 15, 2014 at 10:20
  • and when there is an error on the ata bus and ther kernel doesnt connect and no device is created? how to find out which cable it is? last time I looked they were not labeled ;)
    – U.V.
    Commented Jul 12, 2021 at 14:39
6

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
2
  • 1
    This is not an answer to the question. Commented Jun 16, 2019 at 11:45
  • 2
    Please explain why It's not. In my system, the ATA channel numbers exactly match the output of this command.
    – dredkin
    Commented Jun 16, 2019 at 11:51
1

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
/sys/class/scsi_host/host0/unique_id:1
/sys/class/scsi_host/host9/unique_id:10
$ grep ^1$ /sys/class/scsi_host/host*/unique_id
/sys/class/scsi_host/host0/unique_id:1

So...

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:

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

Use it like this:

$ ./map2ata /dev/sda
ata2
5
  • I run this on CentOS 6 and it always returns blank output. Where is this getting $dev value from? Commented Jun 25, 2015 at 4:59
  • See the "Use it like this" section. You pass your device path to the script.
    – rrauenza
    Commented Jun 25, 2015 at 19:07
  • I did do that, and it always returns blank output. Commented Jun 26, 2015 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
    Commented Jun 26, 2015 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
    Commented Dec 15, 2016 at 5:02
1

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

/sys/class/scsi_host/host4/unique_id:3

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

0

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
      [0x60060e8006d107000000d10700005bcc]


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,

1
  • This is interesting information but how does it help us map to ataX as reported by the kernel?
    – Dan Pritts
    Commented Dec 15, 2016 at 4:59
0

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
 sda:

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.

0

Here're instructions for modern kernels, the example with Linux kernel version 5.4:

$ ls -l /sys/class/ata_port; ls -l /dev/disk/by-path

total 0
lrwxrwxrwx 1 root root 0 2020-11-19 12:15 ata1 -> ../../devices/pci0000:00/0000:00:1f.2/ata1/ata_port/ata1
lrwxrwxrwx 1 root root 0 2020-11-19 12:15 ata2 -> ../../devices/pci0000:00/0000:00:1f.2/ata2/ata_port/ata2
lrwxrwxrwx 1 root root 0 2020-11-19 12:15 ata3 -> ../../devices/pci0000:00/0000:00:1f.2/ata3/ata_port/ata3
lrwxrwxrwx 1 root root 0 2020-11-19 12:15 ata4 -> ../../devices/pci0000:00/0000:00:1f.2/ata4/ata_port/ata4
lrwxrwxrwx 1 root root 0 2020-11-19 12:15 ata5 -> ../../devices/pci0000:00/0000:00:1f.2/ata5/ata_port/ata5
lrwxrwxrwx 1 root root 0 2020-11-19 12:15 ata6 -> ../../devices/pci0000:00/0000:00:1f.2/ata6/ata_port/ata6
total 0
lrwxrwxrwx 1 root root  9 2020-11-08 16:48 pci-0000:00:1f.2-ata-1 -> ../../sda
lrwxrwxrwx 1 root root 10 2020-11-08 16:48 pci-0000:00:1f.2-ata-1-part1 -> ../../sda1
lrwxrwxrwx 1 root root  9 2020-11-08 16:48 pci-0000:00:1f.2-ata-2 -> ../../sdb
lrwxrwxrwx 1 root root 10 2020-11-08 16:48 pci-0000:00:1f.2-ata-2-part1 -> ../../sdb1
lrwxrwxrwx 1 root root  9 2020-11-08 16:48 pci-0000:00:1f.2-ata-3 -> ../../sdc
lrwxrwxrwx 1 root root 10 2020-11-08 16:48 pci-0000:00:1f.2-ata-3-part1 -> ../../sdc1
lrwxrwxrwx 1 root root  9 2020-11-08 16:48 pci-0000:00:1f.2-ata-4 -> ../../sr0
  1. See the first listing (ata_port) to map e.g. ata3 to PCI device name to get 1f.2/ata3 (I'm skipping the full identifier but in case you have multiple PCI storage interfaces you may need to match the whole name).

  2. Then you look at the by-path listing to match the same PCI device and port identifier (unfortunately, kernel uses sligtly different naming here so you need to figure the correct match yourself). The names ending with -partN where N is an integer are logical partitions within the devices. In this case the identifier pci-0000:00:1f.2-ata-3 is the correct one and that maps to sdc. Note that all logical partitions are still stored within the same storage device so you should consider all partitions affected if you see errors in syslog.

  3. In case you also need to know the affected filesystems or mount points, you can then do lsblk to get list of block devices and the mount points (sometimes you want to do lsblk -s but for this specific use case the output without the -s flag is probably easier to read). This will also show which RAID devices are affected if the problematic disk is a member of a software RAID. In some cases, the output of findmnt may be easier to read. However, both outputs are spammed with loop devices from Canonical implementation of program snap. For purposes of figuring out actual storage devices, you can ignore all lines that have /dev/loopN or just loopN where N is an integer.

0

I have a slightly odd scenario, and by analysing the above posts I have another slightly different direction to use.

My scenario is slightly different:

Two drives are SATA dead, reporting as SATA link down , and therefore are not showing as block devices. (no /dev/sd* mapping.) and I want to identify them, physically.

rbuckland@saxon:~$ dmesg | grep "SATA link down" | tail -2
[32829.645606] ata9: SATA link down (SStatus 0 SControl 310)
[32830.101592] ata2: SATA link down (SStatus 0 SControl 310)

Scenario:

  • NAS/Server, 10 Physical SATA drives, 2 NVME drives.
  • Only 8 are mounted and working (2x NVME and 6 Sata's)
  • The two I need to identify are reporting as failed SATA links.
  • Two drives are dead and not even showing.
  • Identify which cable, ata2 and ata9 are on

Step 1 - Identify the ATA hosts

grep '[0-9]' /sys/class/scsi_host/host{0..9}/unique_id - from Lily Hahn above

Step 2 - Which hosts have a block device, which don't ?

rbuckland@saxon:~$ grep '[0-9]' /sys/class/scsi_host/host{0..9}/unique_id | awk -F'/' '{print $0,$5}' | xargs -n2 sh -c 'echo -n "$0 - $1 - " ; (ls -l /sys/block/sd* | grep $1 ) || echo "no block device showing"'
/sys/class/scsi_host/host0/unique_id:1 - host0 - no block device showing
/sys/class/scsi_host/host1/unique_id:2 - host1 - no block device showing
/sys/class/scsi_host/host2/unique_id:3 - host2 - lrwxrwxrwx 1 root root 0 Jan  7 10:46 /sys/block/sda -> ../devices/pci0000:00/0000:00:17.0/ata3/host2/target2:0:0/2:0:0:0/block/sda
/sys/class/scsi_host/host3/unique_id:4 - host3 - lrwxrwxrwx 1 root root 0 Jan  7 10:46 /sys/block/sdb -> ../devices/pci0000:00/0000:00:17.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb
/sys/class/scsi_host/host4/unique_id:5 - host4 - no block device showing
/sys/class/scsi_host/host5/unique_id:6 - host5 - lrwxrwxrwx 1 root root 0 Jan  7 10:46 /sys/block/sdc -> ../devices/pci0000:00/0000:00:17.0/ata6/host5/target5:0:0/5:0:0:0/block/sdc
/sys/class/scsi_host/host6/unique_id:7 - host6 - lrwxrwxrwx 1 root root 0 Jan  7 10:46 /sys/block/sdd -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/0000:02:01.0/0000:03:00.0/ata7/host6/target6:0:0/6:0:0:0/block/sdd
/sys/class/scsi_host/host7/unique_id:8 - host7 - lrwxrwxrwx 1 root root 0 Jan  7 10:46 /sys/block/sde -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/0000:02:01.0/0000:03:00.0/ata8/host7/target7:0:0/7:0:0:0/block/sde
/sys/class/scsi_host/host8/unique_id:9 - host8 - no block device showing
/sys/class/scsi_host/host9/unique_id:10 - host9 - lrwxrwxrwx 1 root root 0 Jan  7 10:46 /sys/block/sdf -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/0000:02:05.0/0000:04:00.0/ata10/host9/target9:0:0/9:0:0:0/block/sdf
  • Step 3 * - See a layout of all drives
rbuckland@saxon:~$ ls -l /sys/block/[sn]*
lrwxrwxrwx 1 root root 0 Jan  7 10:56 /sys/block/nvme0n1 -> ../devices/pci0000:00/0000:00:1d.0/0000:0a:00.0/nvme/nvme1/nvme0n1
lrwxrwxrwx 1 root root 0 Jan  7 10:56 /sys/block/nvme1n1 -> ../devices/pci0000:00/0000:00:1c.4/0000:09:00.0/nvme/nvme0/nvme1n1
lrwxrwxrwx 1 root root 0 Jan  7 10:56 /sys/block/sda -> ../devices/pci0000:00/0000:00:17.0/ata3/host2/target2:0:0/2:0:0:0/block/sda
lrwxrwxrwx 1 root root 0 Jan  7 10:56 /sys/block/sdb -> ../devices/pci0000:00/0000:00:17.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb
lrwxrwxrwx 1 root root 0 Jan  7 10:56 /sys/block/sdc -> ../devices/pci0000:00/0000:00:17.0/ata6/host5/target5:0:0/5:0:0:0/block/sdc
lrwxrwxrwx 1 root root 0 Jan  7 10:56 /sys/block/sdd -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/0000:02:01.0/0000:03:00.0/ata7/host6/target6:0:0/6:0:0:0/block/sdd
lrwxrwxrwx 1 root root 0 Jan  7 10:56 /sys/block/sde -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/0000:02:01.0/0000:03:00.0/ata8/host7/target7:0:0/7:0:0:0/block/sde
lrwxrwxrwx 1 root root 0 Jan  7 10:56 /sys/block/sdf -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/0000:02:05.0/0000:04:00.0/ata10/host9/target9:0:0/9:0:0:0/block/sdf

Observation 1

There are two unique PCI SATA devices.

pci0000:00/0000:00:17.0 - has 6 ports (hosts)

  • 3 "dead or missing" drives.
  • 3 drives sda,sdb,sdc are working.

pci0000:00/0000:00:01.0 - has 4 ports (hosts)

  • 1 "dead or missing" drive
  • 3 drives sdd,sde,sdf are working.

Looking along the pci path, I can see the ata8, ata10, ata4 identifiers eg: pci0000:00/0000:00:17.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb and pci0000:00/0000:00:01.0/0000:01:00.0/0000:02:01.0/0000:03:00.0/ata8/host7/target7:0:0/7:0:0:0/block/sde

so my missing ata2 drive, is going to be plugged into the same "card" as drives sda,sdb and sdc (see below)^^.

the missing ata9 drive, is going to be plugged into the same "card" as drives, sdd, sde, sdf

ata drive listing

I can use the output of show-disks to see serial's and map those to the physicals when I get the server, to compare cables. (show-disks was from https://serverfault.com/a/633979^^

rbuckland@saxon:~$ sudo show-disks 
sdd [____8.0_TB] ST8000AS0002-1NA17Z, Z840FKRY pci0000:00/0000:00:01.0/0000:01:00.0/0000:02:01.0/0000:03:00.0/ata7/host6/target6:0:0/6:0:0:0/block/sdd
sde [____4.0_TB] ST4000DM000-1F2168, Z304S6N5 pci0000:00/0000:00:01.0/0000:01:00.0/0000:02:01.0/0000:03:00.0/ata8/host7/target7:0:0/7:0:0:0/block/sde
sdf [____4.0_TB] ST4000VN000-1H4168, W301963G pci0000:00/0000:00:01.0/0000:01:00.0/0000:02:05.0/0000:04:00.0/ata10/host9/target9:0:0/9:0:0:0/block/sdf
sda [____0.5_TB] MAXTOR STM3500630AS, 6QG35010 pci0000:00/0000:00:17.0/ata3/host2/target2:0:0/2:0:0:0/block/sda
sdb [ ------ GB] ST4000DM000, Z303J9L8 pci0000:00/0000:00:17.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb
sdc [____4.0_TB] ST4000DM000-1F2168, Z304QSMC pci0000:00/0000:00:17.0/ata6/host5/target5:0:0/5:0:0:0/block/sdc

Observation 2

The nvme numbering is wrong .. enter image description here

^^ show-disks

Original - https://serverfault.com/a/633979 Fixed the sed grep line (fdisk changed)

#!/bin/bash
BLKDEVS=`ls -l /sys/block/sd*|sed -e 's/^.* -> //' -e 's/^...devices.//'`
echo $BLKDEVS|tr \  \\n |sort| \
while read DISK ; do
    SD=`echo $DISK|sed -e 's/^.*\///'`
    INFO=`hdparm -i /dev/$SD 2>/dev/null|grep Model=|sed -e 's/Model=//' -e 's/FwRev=[^ ]*//' -e 's/SerialNo=//'`
    ! [[ $INFO ]] && INFO='--'
    SIZE=`fdisk -l /dev/$SD 2>/dev/null|grep '^Disk .* bytes'|sed -e 's/.* \([0-9]*\) bytes.*$/\1/'`
    if [[ $SIZE ]] ; then
        SIZE=`echo $SIZE|awk '{printf "[%7.1f TB]" , $1/1000/1000/1000/1000}'|tr \  _`
    else
        SIZE='[ ------ GB]'
    fi
    echo $SD $SIZE $INFO $DISK
done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .