miriup.de

...because open source matters

  • Increase font size
  • Default font size
  • Decrease font size

Mapping Linux kernel ATA errors to a device

E-mail Print

I found it quite difficult to map Linux kernel ATA warnings to a particular device. These article gives some insights.

I have a dying drive in my system and I'm getting Linux kernel warnings like those ones:

[ 3180.294013] ata6: SATA link up 1.5 Gbps (SStatus 113 SControl 310)
[ 3180.316290] ata6.00: configured for UDMA/33
[ 3180.316294] ata6: EH complete
[ 3180.547232] ata6: exception Emask 0x50 SAct 0x0 SErr 0x90800 action 0xe frozen
[ 3180.547234] ata6: irq_stat 0x00400000, PHY RDY changed
[ 3180.547238] ata6: SError: { HostInt PHYRdyChg 10B8B }
[ 3180.547244] ata6: hard resetting link
[ 3182.698012] ata6: SATA link up 1.5 Gbps (SStatus 113 SControl 310)
[ 3182.736664] ata6.00: configured for UDMA/33
[ 3182.736667] ata6: EH complete
[ 3182.864164] ata6.00: exception Emask 0x50 SAct 0x1 SErr 0x90800 action 0xe frozen
[ 3182.864167] ata6.00: irq_stat 0x00400000, PHY RDY changed
[ 3182.864170] ata6: SError: { HostInt PHYRdyChg 10B8B }
[ 3182.864173] ata6.00: failed command: READ FPDMA QUEUED
[ 3182.864179] ata6.00: cmd 60/cutout/00:00:02:00:00/40 tag 0 ncq 4096 in
[ 3182.864181]          res 40/cutout/00:00:02:00:00/40 Emask 0x50 (ATA bus error)
[ 3182.864183] ata6.00: status: { DRDY }
[ 3182.864189] ata6: hard resetting link
To figure out who is ata6 I had to look at my drives in the /sys file-system:
dirk@topo ~ $ ls -l /sys/block/sd{a,b,c,d}
lrwxrwxrwx 1 root root 0 Apr  9 01:24 /sys/block/sda -> ../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
lrwxrwxrwx 1 root root 0 Apr  9 01:24 /sys/block/sdb -> ../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sdb
lrwxrwxrwx 1 root root 0 Apr  9 01:24 /sys/block/sdc -> ../devices/pci0000:00/0000:00:1f.2/host4/target4:0:0/4:0:0:0/block/sdc
lrwxrwxrwx 1 root root 0 Apr  9 01:24 /sys/block/sdd -> ../devices/pci0000:00/0000:00:1f.2/host5/target5:0:0/5:0:0:0/block/sdd

On PCI bus 1, PCI device 00:1f.2 is my SATA controller, a Intel Corporation 82801HB (ICH8) 4 port SATA AHCI Controller (rev 02). It provides 4 hosts to each of which I have attached a disk.

To get that ID, Instead of looking into the target structure, we're looking into the scsi_host structure. It has a directory for the host and in it a file unique_id. That's the ID appended to ata.

So for each of the hosts above I can display the ID like this:

dirk@topo ~ $ for host in 0 1 4 5; do echo -n host${host}:; cat /sys/devices/pci0000:00/0000:00:1f.2/host${host}/scsi_host/host${host}/unique_id; done
host0:1
host1:2
host4:5
host5:6

So going back to where we came, ata6 is host5, which hostsĀ sdd.

 

Comments   

 
0 #7 Guest 2014-06-05 10:59
whoah this weblog is magnificent i really like reading your posts.

Keep up the great work! You understand, lots of persons are hunting
around for this information, you can help them greatly.


My page product descriptions
Quote
 
 
0 #6 Guest 2014-05-26 08:57
Hi to all, since I am truly eager of reading this website's post to be
updated regularly. It includes good data.

Feel free to visit my site ... asp.net hosting
Quote
 
 
0 #5 Guest 2014-05-08 08:32
wonderful post, very informative. I ponder why the opposite specialists of this sector do not notice this.
You should continue your writing. I'm confident, you've a huge readers' base already!



Also visit my web site ... Towing and Repossession Software
Quote
 
 
0 #4 Guest 2014-05-05 12:24
Hello there, just became alert to your blog through Google, and found that it is
really informative. I'm gonna watch out for brussels.
I'll be grateful if you continue this in future. A lot of people will be benefited from
your writing. Cheers!

Here is my web site; Auto Shop Repair Software
Quote
 
 
0 #3 Guest 2013-11-25 22:45
Sorry try again with the code :)

$dir = "/sys/block/";
$drives = array();

// Open a known directory, and proceed to read its contents
if (is_dir($dir))
{
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if (preg_match('/^sd./', $file) && filetype($dir . $file) == "link")
{
$link = readlink($dir.$file);

$drives[$file]["link"] = $link;

preg_match('/(pci.+)\/host(\d+)\//', $link, $m);
$madPciBit = $m[1];
$host = $m[2];
$drives[$file]["host"] = $host;

$ataFile = "/sys/devices/$madPciBit/host$host/scsi_host/host$host/unique_id";
$res = trim(file_get_contents($ataFile));
$drives[$file]["ata"] = $res;
}
}
closedir($dh);
}
}

foreach (array_keys($drives) as $drive)
{
print ("$drive - ata".$drives[$drive]["ata"]."\n");
}
Quote
 
 
0 #2 Guest 2013-11-25 22:44
Here's a little bit of PHP code for determining this automatically. The above example is not completely correct as the magic PCI number can be different.

Many thanks for this useful article.
Hope someone finds this useful
Quote
 
 
+1 #1 Brady Cox 2011-08-04 20:24
So you're saying that the ata number assigned is always going to be ata$unique_id?

Do you have any documentation showing this? I'd like to get some more in depth knowledge on this subject.

Also thanks for posting this! I spent about four hours over the past two days searching for this info.
Quote
 

Add comment


Security code
Refresh