Wie ordne ich ataX.0-Bezeichner in kern.log-Fehlermeldungen tatsächlichen / dev / sdY-Geräten zu?

11

Betrachten Sie folgendes kern.logSnippet:

 ata4.00: failed command: WRITE FPDMA QUEUED
 ata4.00: cmd 61/00:78:40:1e:6c/04:00:f0:00:00/40 tag 15 ncq 524288 out
        res 41/04:00:00:00:00/04:00:00:00:00/00 Emask 0x1 (device error)
 ata4.00: status: { DRDY ERR }
 ata4.00: error: { ABRT }
 ata4: hard resetting link
 ata4: nv: skipping hardreset on occupied port
 ata4: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
 ata4.00: configured for UDMA/133
 ata4: EH complete

Wie kann ich feststellen, welche Festplatte der Kernel tatsächlich bedeutet, wenn er darüber spricht ata4.00?

Wie finde ich den entsprechenden /dev/sdYGerätenamen?

maxschlepzig
quelle

Antworten:

10

Sie finden das entsprechende / dev / sdY-Gerät, indem Sie den /sysBaum durchlaufen :

$ find /sys/devices | grep '/ata[0-9]\+/.*/block/s[^/]\+$' \
    | sed 's@^.\+/\(ata[0-9]\+\)/.\+/block/\(.\+\)$@\1 => /dev/\2@'

Mit einer effizienteren /sysDurchquerung (vgl. Lsata.sh ):

$ echo /sys/class/ata_port/ata*/../../host*/target*/*/block/s* | tr ' ' '\n' \
    | awk -F/ '{printf("%s => /dev/%s\n", $5, $NF)}'

Beispielausgabe von einem 2-Platten-System:

ata1 => /dev/sda
ata2 => /dev/sdb

Um die tatsächliche Hardware zuverlässig zu identifizieren, müssen Sie / dev / sdY der Seriennummer zuordnen, z.

$ ls /dev/disk/by-id -l | grep 'ata.*sd[a-zA-Z]$'

lssci

Das lssciDienstprogramm kann auch verwendet werden, um die Zuordnung abzuleiten:

$ lsscsi | sed 's@^\[\([^:]\+\).\+\(/dev/.\+\)$@\1,\2@' \
    | awk -F, '{ printf("ata%d => %s\n", $1+1, $2) }'

Beachten Sie, dass die relevante lsscsi-Aufzählung bei 0 beginnt, während die ata-Aufzählung bei 0 beginnt.

Syslog

Wenn nichts anderes funktioniert, kann man sich das Syslog / Journal ansehen, um das Mapping abzuleiten.

Die /dev/sdYGeräte werden in derselben Reihenfolge erstellt, in der die ataX-Kennungen aufgelistet sind, kern.logwährend Nicht-Festplattengeräte (ATAPI) und nicht verbundene Links ignoriert werden.

Der folgende Befehl zeigt daher die Zuordnung an:

$ grep '^May 28 2'  /var/log/kern.log.0  | \
   grep 'ata[0-9]\+.[0-9][0-9]: ATA-' | \
   sed 's/^.*\] ata//' | \
   sort -n | sed 's/:.*//' | \
   awk ' { a="ata" $1; printf("%10s is /dev/sd%c\n", a, 96+NR); }'
ata1.00 is /dev/sda
ata3.00 is /dev/sdb
ata5.00 is /dev/sdc
ata7.00 is /dev/sdd
ata8.00 is /dev/sde
ata10.00 is /dev/sdf

(Beachten Sie, dass ata4 nicht angezeigt wird, da die obigen Protokollmeldungen von einem anderen System stammen.)

Ich benutze /var/log/kern.log.0und nicht, /var/log/kern.logweil die Boot-Meldungen bereits gedreht sind. Ich greife nach, May 28 2weil dies die letzte Startzeit war und ich vorherige Nachrichten ignorieren möchte.

Um die Zuordnung zu überprüfen, können Sie einige Überprüfungen durchführen, indem Sie die Ausgabe von:

$ grep '^May 28 2'  /var/log/kern.log.0  | \
grep 'ata[0-9]\+.[0-9][0-9]: ATA-'
May 28 20:43:26 hn kernel: [    1.260488] ata1.00: ATA-7: SAMSUNG SV0802N, max UDMA/100
May 28 20:43:26 hn kernel: [    1.676400] ata5.00: ATA-5: ST380021A, 3.19, max UDMA/10
[..]

Und Sie können diese Ausgabe mit der hdparmAusgabe vergleichen, z.

$ hdparm -i /dev/sda

/dev/sda:

Model=SAMSUNG SV0802N [..]

(mit Kernel 2.6.32-31)

maxschlepzig
quelle
Das ist einfach großartig, vielen Dank für diese hervorragende Antwort ...
stuartc
@stuarte, Sie sind willkommen - btw, cks hat eine Zuschreibung über alles getan , was die unterschiedlichen Namensgebung von SATA - Geräten auf aktuellen Linux - Systemen . In Bezug auf ataX-Bezeichner schreibt er: "Diese Namen erscheinen, soweit ich sehen kann, überhaupt nicht in sysfs"
maxschlepzig
1
Hmm. Mein Problem bei der Überprüfung ist, dass ich normalerweise mehr als 8 Festplatten des exakt gleichen Modells habe, sodass Herstellerprüfungen nicht so wertvoll sind.
Drescherjm
1
@drescherjm, ich habe meine Antwort aktualisiert. Die neue Methode sollte robust sein und daher keine Lieferantenprüfung erforderlich machen.
Maxschlepzig
Ich habe ein meiner Meinung nach verbessertes sysfs-Skript. Insbesondere werden zweistellige ata-Nummern verarbeitet (/ ata [0-9] / stimmt nicht mit ata10 überein) und es werden auch Sata-Geräte gefunden, die nicht den Namen sd * haben (z. B. sr0): für ein in / sys / class / ata_port / ata * ;; do printf '% s \ t% s \ n' "$ (Basisname" $ ​​a ")" "$ (finde" $ a / device / "-iname 'block' -exec ls {} \;)"; fertig
Jason
2

Hier ist meine Version, von oben modifiziert. Da ich nicht genau weiß, wann das System gestartet wurde (zum Testen war es vor 27 Tagen) und ich nicht weiß, welches kern.log die benötigten Daten enthält (einige befinden sich möglicherweise gzippedauf meinem System), verwende ich uptimeund dateum ein ungefähres Systemstartdatum (jedenfalls auf den Tag) zu berechnen zgrep, durchsuchen Sie anschließend alle verfügbaren kern.log-Dateien.

Ich habe auch die zweite grepAnweisung leicht modifiziert , da sie nun auch ein ATAPI-CD / DVD-Laufwerk sowie ATA- * -Laufwerke anzeigt.

Es könnte noch verfeinert werden (dh wenn die Systemverfügbarkeit länger als ein Jahr ist), sollte aber vorerst in Ordnung sein.

#!/bin/bash

uptime=$(uptime | awk -F' '  '{ print $3" "$4 }' | sed s/,//)
date=$(date -d "$uptime ago" | awk '{print $2" "$3 }')
zgrep "$date"  /var/log/kern.log*  | \
grep 'ata[0-9]\+.[0-9][0-9]: ATA'  | \
sed 's/^.*\] ata//' | \
sort -n | sed 's/:.*//' | \
awk ' { a="ata" $1; printf("%10s is /dev/sd%c\n", a, 96+NR); }'
Ektospasmus
quelle
1

Hatte gerade das gleiche Problem und fand eine andere Lösung, die man mögen könnte.

Das lsscsi-Tool listet SCSI-Geräte (oder Hosts) und deren Attribute auf.

Mit lsscsi erhält man den ata-Namen und den Gerätenamen.

Sieht aus wie das:

$ lsscsi --long
[0:0:1:0]    cd/dvd  MATSHITA DVD-ROM UJDA780  1.50  /dev/sr0
  state=running queue_depth=1 scsi_level=6 type=5 device_blocked=0 timeout=30
[2:0:0:0]    disk    ATA      WDC WD3000FYYZ-0 01.0  /dev/sda
  state=running queue_depth=1 scsi_level=6 type=0 device_blocked=0 timeout=30
[3:0:0:0]    disk    ATA      WDC WD1002FBYS-0 03.0  /dev/sdb
  state=running queue_depth=1 scsi_level=6 type=0 device_blocked=0 timeout=30
[4:0:0:0]    disk    ATA      WDC WD1002FBYS-0 03.0  /dev/sdc
  state=running queue_depth=1 scsi_level=6 type=0 device_blocked=0 timeout=30
[5:0:0:0]    disk    ATA      WDC WD1002FBYS-0 03.0  /dev/sdd
  state=running queue_depth=1 scsi_level=6 type=0 device_blocked=0 timeout=30
[6:0:0:0]    disk    ATA      WDC WD3000FYYZ-0 01.0  /dev/sde
  state=running queue_depth=1 scsi_level=6 type=0 device_blocked=0 timeout=30
[7:0:0:0]    disk    ATA      WDC WD1002FBYS-0 03.0  /dev/sdf
  state=running queue_depth=1 scsi_level=6 type=0 device_blocked=0 timeout=30

Unter Ubuntu kann man lsscsi einfach mit installieren

$ sudo apt-get install lsscsi
langer Schlaf
quelle
2
hm, und wie ataXordnet man welchen Teil der lsscsiAusgabe zu?
Maxschlepzig
1
@maxschlepzig Die erste Zahl in den: Quads ist die gleiche wie die ataX mit einem wichtigen Unterschied; Die Ausgabe von lsscsi ist 0-indiziert und ataZ ist 1-indiziert. also [2: 0: 0: 0] wäre ata3, was / dev / sda in der Ausgabe ist, die longsleep gepostet hat
Jason
@ Jason, ok, hier ist ein lsscsi | sed 's@^\[\([^:]\+\).\+\(/dev/.\+\)$@\1,\2@' | awk -F, '{ printf("ata%d => %s\n", $1+1, $2) }'
Einzeiler
@ Jason, siehe auch meine aktualisierte Antwort für eine Alternative, die direkt /sys/devicesohne zugreift lsscsi.
Maxschlepzig
0

Keine der oben genannten Antworten hat bei mir funktioniert, und der lsscsi-Ansatz ergab aufgrund von Diskrepanzen zwischen SCSI-Busnummern und ATA-Nummern tatsächlich die falsche Antwort. Auf einem 21-Platten-System hatte ich viele Syslog-Berichte über Probleme mit ATA18 (HSM-Verstöße). Welche Festplatte hat diese Fehler verursacht? Einige waren USB-Laufwerke, was die Dinge erheblich verwirrender machte. Ich brauchte eine Abrechnung darüber, wie jedes SCSI-Laufwerk an das System angeschlossen ist, und schrieb das folgende Skript, das tabellarische Auflistungen für alle SCSI-Festplatten (/ dev / s [dr]?) Gibt, unabhängig davon, ob ATA oder USB.

Dann mit allen Festplatten voll bilanzierte für, war ich überrascht zu sehen , dass meine ATA Fehler nichts mit dem zu tun hatten , jede meiner Plattenlaufwerke. Ich hatte die falsche Frage gestellt, und ich denke, andere könnten leicht in dieselbe Falle tappen, weshalb ich sie hier erwähne. Ich habe dann einen zweiten Ansatz verwendet, der die Hardware identifizierte, die die HSM-Verstoßmeldungen generiert hat. Dies wird auch in der Dokumentation im folgenden Skript beschrieben.

#!/bin/bash

## This script lists the ata and usb bus numbers, as well as the
## overall "host" numbers, of each scsi disk.  The same information
## appears formatted four ways, redundantly, for ease of lookup by (1)
## device lettername, (2) ata bus, (3) usb bus, or (4) overall "host"
## number.

#######################################################

## Q: What if you're looking for an ATA bus number, e.g. ata18, that
##    isn't listed by this script?

## (1) Well, it's probably not a SCSI disk, at least not one that's
##     operating.

## (2) Somewhere in /sys you can find a mapping from the ATA bus
##     number to some overall host number, such as host17.  For example,
##     if you're looking for ata18, you can use a find command...

##     find /sys -type l -exec bash -c 'link=`readlink "$0"`; if [[ "$link" =~ /ata18/ ]] ; then echo $link ; fi' {} \;

##     ...which, after some delay, might yield output something like this:

##    ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/ata_port/ata18
##    ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/scsi_generic/sg5
##    ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/link18/dev18.0/ata_device/dev18.0
##    ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/scsi_host/host17
##    ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/link18/ata_link/link18
##    ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/bsg/17:0:0:0
##    ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/scsi_device/17:0:0:0
##    ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/scsi_generic/sg5
##    ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/bsg/17:0:0:0
##    ../../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0
##    ../../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17
##    ../../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0

##     Then you might notice the "/host17/" or "scsi_device/17:0:0:0"
##     in the above output lines, and look in the output of...

##     lshw

##     .. for "scsi17" or "17:0" or such, and discover, somewhere in it ...

##     ...
##        *-scsi:5
##           physical id: 8
##           logical name: scsi17
##           capabilities: emulated
##         *-processor UNCLAIMED
##              description: SCSI Processor
##              product: 91xx Config
##              vendor: Marvell
##              physical id: 0.0.0
##              bus info: scsi@17:0.0.0
##              version: 1.01
##              capabilities: removable
##              configuration: ansiversion=5
##     ...

## ...thus learning that ata18 corresponds to an unclaimed device (but
## not actually a disk).  Q.E.D.

## P.S. the lsscsi command yields the following, which might lead
## one to think that the problem was being caused by a CD-ROM drive
## (SCSI18:0) rather than emanating from the Marvell (SCSI17:0):

## [17:0:0:0]   process Marvell  91xx Config      1.01  -        
## [18:0:0:0]   cd/dvd  HL-DT-ST DVDRAM GH22NS90  HN00  /dev/sr0 

## ... but ATA != SCSI, and 17 != 18.  The CD/DVD drive was ATA19, 
## actually.  You can still use lsscsi, but
## bear in mind that what you're seeing in the left column
## is *not* ATA numbers but rather SCSI bus numbers, and the two
## are not to be confused.
#######################################################

blockDevsDir=/sys/dev/block

declare -A scsiDevLetters
declare -A hostNumbers
declare -A ataNumbers
declare -A usbNumbers

scsiDevLetterRE='/s(d[a-z]|r[0-9])$'
hostNumberRE='/host([0-9]+)/'
ataNumberRE='/ata([0-9]+)/'
usbNumberRE='/usb([0-9]+)/'

cd "$blockDevsDir"
for busid in `ls -1` ; do
    linkval=`readlink "$busid" `
    if [[ "$linkval" =~ $scsiDevLetterRE ]] ; then
        scsiDevLetter="${BASH_REMATCH[1]}"
        if [[ "$linkval" =~ $hostNumberRE ]] ; then
            hostNumber="${BASH_REMATCH[1]}"
            if [[ "$linkval" =~ $ataNumberRE ]] ; then
                ataNumber="${BASH_REMATCH[1]}"
                scsiDevLetters[$scsiDevLetter]=`printf 'ata%-2.2s  host%-2.2s' "${ataNumber}" "${hostNumber}"`
                hostNumbers[${hostNumber}]=`printf '/dev/sd%s  ata%-2.2s' "${scsiDevLetter}" "${ataNumber}"`
                ataNumbers[${ataNumber}]=`printf '/dev/sd%s  host%-2.2s' "${scsiDevLetter}" "${hostNumber}"`
            elif [[ "$linkval" =~ $usbNumberRE ]] ; then
                usbNumber="${BASH_REMATCH[1]}"
                scsiDevLetters[$scsiDevLetter]=`printf 'usb%-2.2s  host%-2.2s' "${usbNumber}" "${hostNumber}"`
                hostNumbers[${hostNumber}]=`printf '/dev/sd%s  usb%-2.2s' "${scsiDevLetter}" "${usbNumber}"`

                existingUsbValue="${usbNumbers[${usbNumber}]}"
                addedUsbValue=`printf '/dev/sd%s  host%-2.2s' "${scsiDevLetter}" "${hostNumber}"`
                if [ -n "$existingUsbValue" ] ; then
                    usbNumbers[${usbNumber}]="$existingUsbValue | $addedUsbValue"
                else
                    usbNumbers[${usbNumber}]="$addedUsbValue"
        fi
            else
        echo "Neither ata nor usb: /dev/sd${scsiDevLetter} (host${hostNumber}) !"
            fi
        else
        echo "No host number for /dev/sd${scsiDevLetter}"
        fi
    fi
done    

echo '/dev/sd?'
echo '--------'
for scsiDevLetter in `echo "${!scsiDevLetters[*]}" | tr ' ' '\n' | sort` ; do
    echo "/dev/sd${scsiDevLetter}    ${scsiDevLetters[$scsiDevLetter]}"
done
echo
echo 'ataNN'
echo '-----'
for ataNumber in `echo "${!ataNumbers[*]}" | tr ' ' '\n' | sort -n` ; do
    printf 'ata%-2.2s    %s\n' "$ataNumber" "${ataNumbers[$ataNumber]}"
done
echo
echo 'usbNN'
echo '-----'
for usbNumber in `echo "${!usbNumbers[*]}" | tr ' ' '\n' | sort -n` ; do
    printf 'usb%-2.2s    %s\n' "$usbNumber" "${usbNumbers[$usbNumber]}"
done
echo
echo 'hostNN'
echo '------'
for hostNumber in `echo "${!hostNumbers[*]}" | tr ' ' '\n' | sort -n` ; do
    printf 'host%-2.2s    %s\n' "$hostNumber" "${hostNumbers[$hostNumber]}"
done
Steve Newcomb
quelle