I'm getting kernel messages about 'ata3'. How do I figure out what device (/dev/sd_) that corresponds to?
8 Answers
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.
-
3I 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}')
– insiderJan 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.Jul 12, 2021 at 14:39
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
-
1
-
2Please explain why It's not. In my system, the ATA channel numbers exactly match the output of this command.– dredkinJun 16, 2019 at 11:51
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
-
I run this on CentOS 6 and it always returns blank output. Where is this getting $dev value from? Jun 25, 2015 at 4:59
-
See the "Use it like this" section. You pass your device path to the script.– rrauenzaJun 25, 2015 at 19:07
-
-
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.– rrauenzaJun 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 Dec 15, 2016 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
/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
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,
-
This is interesting information but how does it help us map to ataX as reported by the kernel? Dec 15, 2016 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
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.
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
See the first listing (
ata_port
) to map e.g.ata3
to PCI device name to get1f.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).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 identifierpci-0000:00:1f.2-ata-3
is the correct one and that maps tosdc
. 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.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 dolsblk -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 offindmnt
may be easier to read. However, both outputs are spammed with loop devices from Canonical implementation of programsnap
. For purposes of figuring out actual storage devices, you can ignore all lines that have/dev/loopN
or justloopN
where N is an integer.
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
andata9
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
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 ..
^^ 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