How to Map Linux ATA Error Codes (ata%d.00) to Physical Devices (/dev/sdX)


2 views

When Linux encounters disk errors, it logs them with identifiers like ata1.00 or ata5.01. These don't directly correspond to the /dev/sdX names we use in commands. The numbering follows the kernel's detection order during boot.

1. Using lsscsi Command

The simplest method is using the lsscsi utility (may require installation):

# Install if needed
sudo apt-get install lsscsi

# Run the command
lsscsi -g

Sample output showing the mapping:

[0:0:0:0]    disk    ATA      WDC WD2003FZEX-0 1A01  /dev/sda   /dev/sg0
[2:0:0:0]    disk    ATA      Samsung SSD 860  3B6Q  /dev/sdb   /dev/sg1

2. Checking sysfs Directly

The kernel exposes this information in /sys:

ls -l /sys/block/sd*/device

You'll see symlinks like:

lrwxrwxrwx 1 root root 0 Jan 15 10:30 /sys/block/sda/device -> ../../0:0:0:0

For a specific ATA port (e.g., ata3):

readlink -f /sys/class/ata_port/ata3/../../host*/target*/*/block/*

3. Parsing dmesg Output

During boot, the kernel logs device assignments:

dmesg | grep -E 'ata[0-9]|sd[a-z]' | grep -B1 'Attached'

Sample correlation:

[    2.302104] ata3: SATA link up 6.0 Gbps
[    2.302130] ata3.00: ATA-9: Samsung SSD 860 EVO 1TB, RVT03B6Q, max UDMA/133
[    2.302132] ata3.00: 1953525168 sectors, multi 1: LBA48 NCQ (depth 32)
[    2.302214] ata3.00: configured for UDMA/133
[    2.302418] scsi 2:0:0:0: Direct-Access     ATA      Samsung SSD 860  3B6Q PQ: 0 ANSI: 5
[    2.302688] sd 2:0:0:0: [sdb] 1953525168 512-byte logical blocks: (1.00 TB/932 GiB)

Here's a bash script to generate an ATA-to-device map:

#!/bin/bash
for ata in /sys/class/ata_port/ata*; do
    port=${ata##*/}
    device=$(readlink -f "${ata}/../../host*/target*/*/block/*" 2>/dev/null)
    [[ -n $device ]] && echo "${port} -> ${device##*/}"
done

For NVMe devices or complex storage setups, additional steps may be needed. Check multipath devices with:

ls -l /dev/mapper/
multipath -ll

When working with Linux systems, you'll often encounter disk errors logged in system logs with identifiers like ata1.00 or ata3.01. These messages appear when the kernel detects ATA command failures, but they don't directly tell you which physical device (/dev/sda, /dev/sdb, etc.) is experiencing problems.

In production environments, quickly identifying the failing hardware is crucial for:

  • Replacing faulty drives before complete failure
  • Monitoring specific devices for degradation
  • Correlating SMART data with error events

Method 1: Using sysfs

The most reliable way to map ATA ports to device names is through sysfs:

# Find the device associated with ata1.00
$ readlink -f /sys/class/ata_port/ata1/../../host*/target*/*/block/*
/dev/sda

# For scripted solutions:
for port in /sys/class/ata_port/ata*; do
    device=$(readlink -f "${port}/../../host*/target*/*/block/*" 2>/dev/null)
    [ -n "$device" ] && echo "${port##*/} -> ${device##*/}"
done

Method 2: Parsing dmesg

The kernel boot messages often contain the mapping information:

$ dmesg | grep -A5 'ata.*link up'
[    1.280145] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[    1.280160] ata1.00: ATA-8: INTEL SSDSC2KW256G8, BTHV7410, max UDMA/133
[    1.280162] ata1.00: 500118192 sectors, multi 16: LBA48 NCQ (depth 32)
[    1.280985] ata1.00: configured for UDMA/133
[    1.281339] scsi 0:0:0:0: Direct-Access     ATA      INTEL SSDSC2KW25 BTHV PQ: 0 ANSI: 5
[    1.281626] sd 0:0:0:0: [sda] 500118192 512-byte logical blocks: (256 GB/238 GiB)

Method 3: Using lsscsi

The lsscsi utility provides a clean overview:

$ lsscsi -v
[0:0:0:0]    disk    ATA      INTEL SSDSC2KW256G8  BTHV  /dev/sda 
  dir: /sys/bus/scsi/devices/0:0:0:0  [/sys/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0]

For system monitoring, you might want to create a script that watches for ATA errors and immediately identifies the affected device:

#!/bin/bash

tail -fn0 /var/log/syslog | while read line
do
    if [[ "$line" =~ ata([0-9]+)\.00 ]]; then
        port_num=${BASH_REMATCH[1]}
        device=$(readlink -f "/sys/class/ata_port/ata${port_num}/../../host*/target*/*/block/*")
        echo "ATA error detected on $(basename "$device") (ata${port_num}.00)"
        # Additional actions: send email, trigger smartctl, etc.
    fi
done
  • Some NVMe devices may appear under ATA ports due to controller abstraction
  • Hot-swap scenarios might temporarily break the mapping
  • RAID controllers can add another layer of abstraction

For more reliable identification across reboots, consider using:

  • Filesystem UUIDs (blkid)
  • World Wide Names (WWNs) from /dev/disk/by-id/
  • Physical slot mapping with lshw