Frage Linux ATA-Fehler: Übersetzen auf einen Gerätenamen?


Wenn eine Linux-Box einen ATA-Fehler erhält, meldet sie dies mit einer Meldung, die den Datenträger als "ata% d.00" identifiziert. Wie übersetze ich das zu einem Gerätenamen (z.B. /dev/sdb) Ich denke, das sollte trivial sein, aber ich kann es nicht herausfinden.


30
2018-03-08 23:00


Ursprung


Siehe auch meine Antwort auf eine ähnliche Frage zu Unix-SE: unix.stackexchange.com/a/13988/1131 - maxschlepzig


Antworten:


Peter hat mich dazu inspiriert, ein fortgeschrittenes Skript zu schreiben (let), das sogar USB-Sticks erkennen kann (anstatt dumme Sachen wie "ata0.00" auszugeben). Im Gegensatz zu Peters Skript erhalten Sie auch die Unternummer (wie in 4.01), wenn Sie mehr als ein Gerät am gleichen Controller haben. Kanal. Die Ausgabe wird genau so sein, wie Sie es erhalten syslog. Geprüft. Es funktioniert sehr gut auf meiner Debian-Box, obwohl es immer eine Menge Verbesserungen gibt (z. B. zu plumpe Regexps). Aber halt es! Die scheinbar zu hohe Anzahl von maskierten Zeichen, die du in meinen Regexps finden kannst, ist nur aus Kompatibilitätsgründen! Sie können GNU nicht annehmen sed mit jedem, weshalb ich bewusst auf erweiterte Regexs verzichtet habe.

AKTUALISIERUNG
(1) Wird nicht mehr analysieren ls Ausgabe. (oops!) Da ihr alle wisst: Analysiere ls nicht.
(2) Funktioniert jetzt auch in schreibgeschützten Umgebungen.
(3) Inspiriert von einem Vorschlag aus diesem Geplauder Hier Ich habe es geschafft, die sed-Anweisungen wieder etwas unkomplizierter zu bekommen.

#!/bin/bash
# note: inspired by Peter
#
# *UPDATE 1* now we're no longer parsing ls output
# *UPDATE 2* now we're using an array instead of the <<< operator, which on its
# part insists on a writable /tmp directory: 
# restricted environments with read-only access often won't allow you that

# save original IFS
OLDIFS="$IFS"

for i in /sys/block/sd*; do 
 readlink $i |
 sed 's^\.\./devices^/sys/devices^ ;
      s^/host[0-9]\{1,2\}/target^ ^ ;
      s^/[0-9]\{1,2\}\(:[0-9]\)\{3\}/block/^ ^' \
 \
  |
  while IFS=' ' read Path HostFull ID
  do

     # OLD line: left in for reasons of readability 
     # IFS=: read HostMain HostMid HostSub <<< "$HostFull"

     # NEW lines: will now also work without a hitch on r/o environments
     IFS=: h=($HostFull)
     HostMain=${h[0]}; HostMid=${h[1]}; HostSub=${h[2]}

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

  done

done

# restore original IFS
IFS="$OLDIFS"

26
2017-09-12 01:15



Nur daran erinnert, dass das Skript möglicherweise keine Geräte mit Problemen anzeigt. Ich hatte ata6 Fehler mit Softreset fehlgeschlagen (1. FIS gescheitert) (Kleinere Probleme) aufgeführt dvices und es war nicht vorhanden. Wenn Sie wissen, dass Sie 4 Festplatten im PC haben und nur 3 auftauchen, kann das der Grund sein. - Kendrick
@Kendrick Nun, ich würde das Skript in diesem Fall nicht beschuldigen. Denn wenn du weißt, wie die Kernel-Treiber funktionieren, wird dir das mehr als klar sein :) Kernel-Subsystemtreiber sind dafür bekannt Gib auf sobald die "Probleme" ernst genug sind. Dies liest, dass es für ein UDMA-fähiges Laufwerk mehrere Laufwerksresets induzieren und (möglicherweise) eine Laufwerksoperation im PIO-Modus versuchen kann. jedoch, wenn diese erweist sich auch als zu instabil (verschiedene Timing-Fehler usw.), der Fahrer wird sagen "Geh weg" zum Laufwerk. Für alte PATA-Laufwerke bedeutet dies, dass a kalter Neustart ist erforderlich, damit das Laufwerk wieder angezeigt wird. - syntaxerror
Nicht meine Absicht, dem Drehbuch die Schuld zu geben. nur eine Erinnerung, warum es vielleicht fehlt :) dumm Blättchen seagate Controller Board machte es zu einem Schmerz, um herauszufinden, was los war. - Kendrick
@Kendrick Du sagst es mir Mann :) Also, in meinem Buch sollte Seagate noch nie habe Samsung gekauft. Liebte die letzteren Laufwerke (als Samsung noch im Massenspeichergeschäft war), plus ihr exzellentes Support-Team. Jetzt hat Seagate all das übernommen ... und ... uh-oh. - syntaxerror


Ansehen /proc/scsi/scsi, die in etwa so aussehen:

$ 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 ist sda und ata1.00, scsi1 id 0 ist sdb und ata2.00 usw.

Sieh dir auch an /var/log/dmesg, die die ATA-Treiber-Lade-Info zeigt und die Dinge ein wenig klarer macht. Suchen Sie nach der Zeile, die "libata" startet.


11
2018-03-09 00:22



Sie müssen möglicherweise auch "lsscsi" verwenden - was eine etwas menschlichere Ausgabe ergibt - z. [0: 0: 0: 0] CD / DVD TSSTcorp CDDVDW SH-S202H SB00 / dev / sr0 [2: 0: 0: 0] Festplatte ATA ST3500630AS 3.AA / dev / sda [3: 0: 0: 0] Festplatte ATA WDC WD5000AAKS-0 01.0 / dev / sdb (Auf diesem Server, auf dem ein 3.2.x-Kernel läuft, gibt es kein / proc / scsi *) (Sorry, ich kann nicht herausfinden, wie man Formatierungen in die oben, um es lesbar zu machen) - David Goodwin
Dies sollte eher eine Antwort als ein Kommentar sein. Nützlich, schnell und einfach von einer Maschine zu lesen und bei Problemen mit einer anderen einzugeben. - Elder Geek


Ich bevorzuge Scriptlets statt langwieriger Erklärungen. Das funktioniert auf meiner Ubuntu-Box. Fügen Sie Kommentare zu Ihren Wünschen hinzu:

# 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

10
2017-08-01 12:42



Dein Skript ist ein bisschen weniger beängstigend als die Antwort, hauptsächlich weil ich die ganze Sache sehen kann. - isaaclw
Ein wenig vereinfacht (funktioniert für mich auf Centos) ls -l /sys/block/sd* | sed -e 's@.*-> \.\..*/ata@/ata@' -e 's@/host@ @' -e 's@/target.*/@ @' - Shirker


Das ist eigentlich ziemlich schwierig. Während man davon ausgehen kann, dass "die scsi ID" "die SATA ID minus eins" ist, bin ich lieber wirklich sicher und inspiziere die unique_id was ich vermute (basierend auf dieser Beitrag) ist der SATA-Bezeichner.

Mein Fehler war:

[6407990.328987] ata4.00: exception Emask 0x10 SAct 0x1 SErr 0x280100 action 0x6 frozen
[6407990.336824] ata4.00: irq_stat 0x08000000, interface fatal error
[6407990.343012] ata4: SError: { UnrecovData 10B8B BadCRC }
[6407990.348395] ata4.00: failed command: READ FPDMA QUEUED
[6407990.353819] ata4.00: cmd 60/20:00:28:c2:39/00:00:0c:00:00/40 tag 0 ncq 16384 in
[6407990.353820]          res 40/00:00:28:c2:39/00:00:0c:00:00/40 Emask 0x10 (ATA bus error)
[6407990.369618] ata4.00: status: { DRDY }
[6407990.373504] ata4: hard resetting link
[6407995.905574] ata4: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
[6407995.976946] ata4.00: configured for UDMA/133
[6407995.976961] ata4: EH complete

Also mein Verfahren um was herauszufinden ata4 ist:

  1. finde die PCI-ID des SATA-Controllers

    # lspci | grep -i sata
    00:1f.2 SATA controller: Intel Corporation 631xESB/632xESB SATA AHCI Controller (rev 09)
    
  2. Finde die passende eindeutige ID:

    # grep 4 /sys/devices/pci0000:00/0000:00:1f.2/*/*/*/unique_id
    /sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/unique_id:4
    
  3. also ist es an scsi_host/host3zu dem wir übersetzen können 3:x:x:xfür die wir uns begeistern können dmesg um mehr herauszufinden:

    # dmesg | grep '3:.:.:.'
    [    2.140616] scsi 3:0:0:0: Direct-Access     ATA      ST3250310NS      SN06 PQ: 0 ANSI: 5
    [    2.152477] sd 3:0:0:0: [sdd] 488397168 512-byte logical blocks: (250 GB/232 GiB)
    [    2.152551] sd 3:0:0:0: [sdd] Write Protect is off
    [    2.152554] sd 3:0:0:0: [sdd] Mode Sense: 00 3a 00 00
    [    2.152576] sd 3:0:0:0: [sdd] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
    [    2.157004] sd 3:0:0:0: [sdd] Attached SCSI disk
    [    2.186897] sd 3:0:0:0: Attached scsi generic sg3 type 0
    
  4. Hier ist unser Gerät, wir können (optional) die Seriennummer finden, um das Gerät von dort zu entfernen (oder Kabel überprüfen oder was auch immer), bevor unser RAID-Array vollständig ausfällt:

    # hdparm -i /dev/sdd | grep Serial
     Model=ST3250310NS, FwRev=SN06, SerialNo=9SF19GYA
    

Und du bist fertig!


8
2018-06-20 17:12





Ich hatte das gleiche Problem und konnte Laufwerke durch das Überprüfen von dmesg identifizieren. Dort können Sie die Controller-ID (korrekte Bezeichnung ??) und das Modell der Festplatte sehen. Verwenden Sie dann ls -l / dev / disk / by-id, um die Modellnummer mit / dev / sda (oder was auch immer) zu vergleichen. Alternativ mag ich Festplatten-Dienstprogramm für diese Information. Hinweis: Dies funktioniert nur, wenn Ihre Festplatten unterschiedliche Modellnummern haben, andernfalls können Sie nicht zwischen den beiden unterscheiden.

>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

5
2018-02-18 18:31





Der einfachste Weg besteht darin, das Kernel-Protokoll vom Boot aus zu überprüfen, da die Laufwerksnamen aus verschiedenen Quellen (z. B. USB-Laufwerke) stammen oder je nach Gerätetyp zugewiesen sind (dh cdrom kann stattdessen scdX sein, und alles hat ein sgX). In der Praxis wird, wenn Sie nicht verschiedene Arten von Bussen gemischt haben (zB SATA + USB), das Gerät mit der niedrigsten Nummer ein Sda sein, es sei denn, es handelt sich um ein CD-ROM-Gerät.

Abhängig von Ihrem System kann es durch das Umherlaufen von sysfs erkannt werden. Auf meinem System ls -l /sys/dev/block enthüllt das 8:0 (major: minor from / dev entry) zeigt auf /sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda  Gleichfalls, ls -l /sys/class/ata_port enthüllt das ata1 verweist auf /sys/devices/pci0000:00/0000:00:1f.2/ata1/ata_port/ata1 Das ist auf dem gleichen PCI-Sub-Gerät.

Da ich SATA verwende, und nur ein Laufwerk an jedem Port ist, kann ich folgern, dass ata1.00 = sda. Alle meine Laufwerke sind .00, ich vermute, dass, wenn ich einen Portmultiplikator verwendete, meine Laufwerke .01, .02, .03 usw. erhalten würden. Mit Blick auf die Protokolle anderer Leute verwenden PATA-Controller .00 und .01 für Master und Slave , und basierend auf ihren Protokollen, wenn Sie AtaX.01 haben, sollte die .01 auf die "ID" im Host: Kanal: ID: LUN - Ordner von der /sys/dev/block/ Auflistung. Wenn Sie mehrere haben ataX/ und hostY/ Ordner im selben PCI-Geräteordner, dann ich vermuten dass der ataX-Ordner mit der niedrigsten Nummer mit dem HostY-Ordner mit der niedrigsten Nummer übereinstimmt.


2
2018-03-09 01:16





Versuche dies:

# find -L /sys/bus/pci/devices/*/ata*/host*/target* \
-maxdepth 3 -name "sd*" 2>/dev/null |\
egrep block |egrep --colour '(ata[0-9]*)|(sd.*)' \
;

Ich habe das dmesg nie verstanden - einige Zeilen sind über "ata4" einige andere über "scsi" oder sdc, aber niemand ordnet "ata4... Sdc" zu. Der angezeigte Befehl findet den Pfad / sys / bus /, in dem sowohl ata4 als auch sdc angegeben sind.

J.


2
2017-08-16 11:46





Das folgende Skript gibt Ihnen eine schöne Zusammenfassung:

sda [  180.0 GB] INTEL SSDSC2BW180A4, BTDA4052066D1802GN pci0000:00/0000:00:11.0/ata1/host0/target0:0:0/0:0:0:0/block/sda
sdb [ 1000.2 GB] WDC WD1000DHTZ-04N21V1, WD-WXM1E83CNTX5 pci0000:00/0000:00:11.0/ata3/host2/target2:0:0/2:0:0:0/block/sdc
sdc [ ------ GB] -- pci0000:00/0000:00:12.2/usb1/1-5/1-5:1.0/host6/target6:0:0/6:0:0:0/block/sdf

Also in einer Zeile pro Laufwerk SDX Gerätename, Größe, Modell-, s / n und das pci und an einer Zahlen. Die obige SDC entspricht einem USB-SD-Kartenleser ohne eingesetzte Karte. Daher die ---- anstelle von echten Informationen.

#!/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 GB]" , $1/1000/1000/1000}'|tr \  _`
    else
        SIZE='[ ------ GB]'
    fi
    echo $SD $SIZE $INFO $DISK
done

(nur getestet auf Ubuntu 12.04 / 14.04 und CentOS 6)


0
2017-10-06 20:55



Wie sieht das aus, um Ihnen zu zeigen, was zum Beispiel ATA 4.01 ist? - Edward_178118
In der Beispielausgabe sehen Sie sda: ... ata1 ... und sdb: ... ata3 .... Und tatsächlich war sda ata1 und sdb ata2. Seit ich es geschrieben und auf 4 verschiedenen Hosts getestet habe, habe ich HW gefunden, wo das obige Skript keinen Verweis auf ata enthält. Ich muss darauf hinweisen, dass dmesg | grep "ata [0-9]" mich nie im Stich gelassen hat. - ndemou


Im /sys/class/ata_port/ata${n}/device/du kannst a sehen host${x} Mappe. ZB auf meiner Maschine:

gibby ~ # ls /sys/class/ata_port/ata1/device/
ata_port  host0  link1  power  uevent
gibby ~ # ls /sys/class/ata_port/ata2/device/
ata_port  host1  link2  power  uevent
gibby ~ # lsscsi
[0:0:0:0]    disk    ATA      WDC WD1002FAEX-0 1D05  /dev/sda
[1:0:0:0]    disk    ATA      WDC WD2001FFSX-6 0A81  /dev/sdb
[2:0:0:0]    disk    ATA      WDC WD1002FAEX-0 1D05  /dev/sdc
[3:0:0:0]    disk    ATA      WDC WD2001FFSX-6 0A81  /dev/sdd
[5:0:0:0]    disk    ATA      SAMSUNG MZ7TD256 2L5Q  /dev/sde

Das ${x} im host${x} bezieht sich auf diese erste Zahl in der [0:0:0:0]. Also für mich ata1 bezieht sich auf host0 das kann auch in SCSI-Form als dargestellt werden 0:*:

gibby ~ # lsscsi 0:\*
[0:0:0:0]    disk    ATA      WDC WD1002FAEX-0 1D05  /dev/sda

0
2017-11-25 21:51





Ein Skript, um diese Informationen zu finden, und mehr finden Sie unter    https://www.av8n.com/computer/disk-hw-host-bus-id

Es ist ähnlich dem Skript von Mr. Syntaxerror, aber Züchter.  - Es funktioniert für USB-Laufwerke sowie ATA-Laufwerke.  - Es bietet die Laufwerksmarke und Modell und Seriennummer,  - und natürlich der Befestigungspunkt.  - Es ist einfacher, lesbar und wartbar.


0
2017-12-06 18:11