Tell me more ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

When a Linux box gets an ATA error, it syslogs it with a message identifying the disk as "ata%d.00". How do I translate that to a device name (e.g. /dev/sdb)? I feel like this should be trivial, but I cannot figure it out.

share|improve this question

5 Answers

Look at /proc/scsi/scsi, which will look something like this:

$ cat /proc/scsi/scsi
Attached devices:
Host: scsi0 Channel: 00 Id: 00 Lun: 00
  Vendor: ATA      Model: ST3250823AS      Rev: 3.03
  Type:   Direct-Access                    ANSI SCSI revision: 05
Host: scsi1 Channel: 00 Id: 00 Lun: 00
  Vendor: ATA      Model: ST3750528AS      Rev: CC44
  Type:   Direct-Access                    ANSI SCSI revision: 05
Host: scsi2 Channel: 00 Id: 00 Lun: 00
  Vendor: ATA      Model: ST3750330AS      Rev: SD1A
  Type:   Direct-Access                    ANSI SCSI revision: 05
Host: scsi10 Channel: 00 Id: 00 Lun: 00
  Vendor: WDC WD20 Model: EARS-00MVWB0     Rev:     
  Type:   Direct-Access                    ANSI SCSI revision: 02

scsi0 id 0 is sda and ata1.00, scsi1 id 0 is sdb and ata2.00, etc.

Also look at /var/log/dmesg, which shows the ata driver loading info and will make things a little clearer. Look for the line starting "libata".

share|improve this answer
You might also need to use 'lsscsi' - which gives a slightly more human friendly output - e.g. [0:0:0:0] cd/dvd TSSTcorp CDDVDW SH-S202H SB00 /dev/sr0 [2:0:0:0] disk ATA ST3500630AS 3.AA /dev/sda [3:0:0:0] disk ATA WDC WD5000AAKS-0 01.0 /dev/sdb (On this server, running a 3.2.x kernel, there is no /proc/scsi*) (Sorry, I Can't seem to figure out how to get any formatting into the above, to make it readable) – GingerDog May 21 '12 at 11:12

Peter inspired me to write an advanced script(let), which can even detect USB sticks (instead of outputting silly things like "ata0.00"). In contrary to Peter's script, you will also get the sub-number (as in 4.01) if you have more than one device at the same controller resp. channel. The output will be exactly as you get it in syslog. Tested. Working very well on my Debian box, though there is always lots of improvement (e. g. too clumsy regexps). But HOLD IT! You might find a seemingly too high number of escaped characters in my regexps, but this is for compatibility reasons! You can't assume GNU sed with everyone, which is why I did without extended regexps on purpose.

Furthermore, I'm no pro, so please bear with me if you think things are way too complicated.

#!/bin/bash
# note: inspired by Peter
ls -l /sys/block/sd* \
\
 | sed -e 's^.*-> \.\.^/sys^' \
       -e 's^/host[0-9]\{1,2\}/target^ ^' \
       -e 's^/[0-9]\{1,2\}\(:[0-9]\)\{3\}/block/^ ^' \
\
 |  while read Path HostFull ID
    do

      # this nifty line will tokenize HostFull into named substrings ( = host numbers)
      IFS=: read HostMain HostMid HostSub <<< "$HostFull"

      if grep -q '/usb[0-9]*/' <<< $Path; then
        echo "(Device $ID is not an ATA device, but a USB device [e. g. a pen drive])"
      else
        echo $ID: ata$(cat $Path/host$HostMain/scsi_host/host$HostMain/unique_id).$HostMid$HostSub
      fi

     done
share|improve this answer
How did I get mixed up in this? – Michael Hampton Oct 15 '12 at 14:31
Simple: When I read Peter's script,I saw that you edited it, so I assumed that you were doing some code-wise enhancements. However, you're right: you simply improved code formatting, whilst leaving the original code as -is. Fair enough; I will remove your name from the credits then. – syntaxerror Nov 28 '12 at 19:36
Aha. I did nothing of substance there; only formatted it so that it appeared within a code block. – Michael Hampton Nov 28 '12 at 19:38
Yeah, I got it as far as that now. :) Sometimes it takes a little longer. – syntaxerror Nov 28 '12 at 19:39

I prefer scriptlets instead of lenghty explanations. This works on my Ubuntu box. Add comments to your liking:

# on Ubuntu get ata ID for block devices sd*
ls -l /sys/block/sd* \
| sed -e 's^.*-> \.\.^/sys^' \
       -e 's^/host^ ^'        \
       -e 's^/target.*/^ ^'   \
| while read Path HostNum ID
  do
     echo ${ID}: $(cat $Path/host$HostNum/scsi_host/host$HostNum/unique_id)
  done
share|improve this answer

The easiest way is to review the kernel log from boot, since the drive device names are mixed in from various sources (eg USB drives), or are assigned based on type of device (ie cdrom may be scdX instead, and everything has a sgX). In practice, unless you have mixed different kinds of buses (eg SATA+USB) the lowest numbered ata device is going to be sda unless it's a cdrom device.

Depending on your system, it might be divined by wandering around sysfs. On my system ls -l /sys/dev/block reveals that 8:0 (major:minor from /dev entry) points to /sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda Likewise, ls -l /sys/class/ata_port reveals that ata1 points to /sys/devices/pci0000:00/0000:00:1f.2/ata1/ata_port/ata1 which is on the same PCI sub-device.

Since I use SATA, and only one drive is on each port I can deduce that ata1.00 = sda. All of my drives are .00, I suspect that if I used a port multiplier, my drives would be given .01, .02, .03 etc. Looking at other people's logs PATA controllers use .00 and .01 for master and slave, and based on their logs if you have ataX.01, the .01 should be mapped to the "ID" in the host:channel:ID:LUN folder from the /sys/dev/block/ listing. If you have multiple ataX/ and hostY/ folders in the same PCI device folder, then I suspect that the lowest numbered ataX folder matches the lowest numbered hostY folder.

share|improve this answer

I had the same problem and was able to identify drives by checking dmesg. There you can see the controller identifier (correct term??) and the model of the disk. Then use ls -l /dev/disk/by-id to match the model number to /dev/sda (or whatever). Alternatively, I like Disk Utility for this information. Note: this only works if your disks have different model numbers, otherwise you can't distinguish between the two.

>dmesg |grep ata
...
[   19.178040] ata2.00: ATA-8: WDC WD2500BEVT-00A23T0, 01.01A01, max UDMA/133
[   19.178043] ata2.00: 488397168 sectors, multi 16: LBA48 NCQ (depth 31/32), AA
[   19.179376] ata2.00: configured for UDMA/133
[   19.264152] ata3.00: ATA-8: WDC WD3200BEVT-00ZCT0, 11.01A11, max UDMA/133
[   19.264154] ata3.00: 625142448 sectors, multi 16: LBA48 NCQ (depth 31/32), AA
[   19.266767] ata3.00: configured for UDMA/133
...

>ls -l /dev/disk/by-id
lrwxrwxrwx 1 root root  9 Feb 18 12:17 ata-WDC_WD2500BEVT-00A23T0_WD-WXE1A7131446 -> ../../sda
lrwxrwxrwx 1 root root 10 Feb 18 11:48 ata-WDC_WD2500BEVT-00A23T0_WD-WXE1A7131446-part1 -> ../../sda1
lrwxrwxrwx 1 root root  9 Feb 18 12:17 ata-WDC_WD3200BEVT-00ZCT0_WD-WXHZ08045183 -> ../../sdb
lrwxrwxrwx 1 root root 10 Feb 18 11:48 ata-WDC_WD3200BEVT-00ZCT0_WD-WXHZ08045183-part1 -> ../../sdb1
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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