Kern.log hata mesajlarındaki ataX.0 tanımlayıcılarını gerçek / dev / sdY aygıtlarıyla nasıl eşleyebilirim?


11

kern.logSnippet'i takip etmeyi düşünün :

 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

Çekirdek hakkında konuştuğunda aslında hangi sabit diskin ne anlama geldiğini nasıl belirleyebilirim ata4.00?

İlgili /dev/sdYcihaz adını nasıl bulabilirim ?

Yanıtlar:


11

İlgili / dev / sdY cihazını /sysağaçta gezerek bulabilirsiniz :

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

Daha verimli bir geçişle/sys (çapraz başvuru lsata.sh ):

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

2 diskli sistemden örnek çıktı:

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

Daha sonra, gerçek donanımı güvenilir bir şekilde tanımlamak için / dev / sdY'yi seri numarasına eşlemeniz gerekir, örneğin:

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

lssci

Yardımcı lssciprogram ayrıca eşleştirmeyi türetmek için de kullanılabilir:

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

Ata numaralandırma 0'dan başlarken, ilgili lsscsi numaralandırmasının 0'dan başladığını unutmayın.

Sistem günlüğü

Başka bir şey işe yaramazsa, eşlemeyi türetmek için sistem günlüğüne / günlüğüne bakabilirsiniz.

/dev/sdYAtaX kimliğini oluşturan Numaralandırılmış gibi cihazlar aynı sırayla oluşturulan kern.logolmayan bir disk aygıtlarını (ATAPI) ve bağlantılı linkler görmezden.

Böylece, aşağıdaki komut eşleştirmeyi görüntüler:

$ 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

(Yukarıdaki günlük iletileri başka bir sistemden geldiğinden ata4'ün görüntülenmediğini unutmayın.)

Ben kullanıyorum /var/log/kern.log.0ve /var/log/kern.logçizme mesajları zaten döndürülür çünkü. May 28 2Çünkü son açılış zamanı oldu ve önceki mesajları göz ardı etmek istiyorum için grep .

Eşlemeyi doğrulamak için aşağıdakilerin çıktısına bakarak bazı kontroller yapabilirsiniz:

$ 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
[..]

Ve bu çıktıyı çıktı ile karşılaştırabilirsiniz hdparm, örneğin:

$ hdparm -i /dev/sda

/dev/sda:

Model=SAMSUNG SV0802N [..]

(Çekirdek 2.6.32-31 kullanarak)


Bu sadece harika, bu mükemmel cevap için çok teşekkür ederim ...
stuartc

@stuarte, rica ederim - btw, cks , mevcut Linux sistemlerindeki SATA cihazlarının tüm farklı adlandırma şemaları hakkında bir yazı yazdı . AtaX tanımlayıcıları ile ilgili olarak şöyle yazar: 'Bu adlar
sysfs'de

1
Hmm. Bunu doğrulamakla ilgili sorunum, genellikle aynı modelin 8+ diskine sahip olduğumdur, bu nedenle üretici kontrolleri o kadar değerli değildir.
drescherjm

1
@ drescherjm, cevabımı güncelledim. Yeni yöntem sağlam olmalı ve böylece satıcı kontrolü ihtiyacını ortadan kaldırmalıdır.
maxschlepzig

Ben gelişmiş bir sysfs komut dosyası olduğunu düşünüyorum; özellikle çift haneli ata numaralarını işler (/ ata [0-9] / ata10 ile eşleşmez) ve ayrıca sd * (örneğin sr0) adında olmayan sata aygıtlarını bulur: in / sys / class / ata_port / ata * için ; printf '% s \ t% s \ n' "$ (taban adı" $ a ")" "$ (" $ a / device / "-iname 'block' -exec ls {} \;)" bulun; bitti
Jason

2

İşte benim versiyonum, yukarıdan değiştirilmiş. Sistemin önyüklendiği kesin tarihi bilmediğim için (bunu test etmek için 27 gün önce) ve hangi kern.log dosyasının ihtiyacım olan verileri içerdiğini bilmiyorum (bazıları gzippedsistemimde olabilir), kullanıyorum uptimeve dateyaklaşık sistem önyükleme tarihini hesaplamak için (yine de güne), daha sonra kullanılabilir zgreptüm kern.log dosyalarında arama yapmak için kullanın .

İkinci grepifadeyi de biraz değiştirdim , çünkü artık ATAPI CD / DVD sürücüsünün yanı sıra ATA- * sürücülerini de gösterecek.

Yine de iyileştirmeyi kullanabilir (yani sistem çalışma süresi bir yıldan fazla ise), ancak şimdilik düzgün çalışmalıdır.

#!/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); }'

1

Aynı sorunu yaşadım ve hoşunuza gidebilecek başka bir çözüm buldum.

Lsscsi aracı, SCSI aygıtlarını (veya ana bilgisayarlarını) ve özniteliklerini listeler.

Lsscsi ile ata adını ve cihaz adını alırsınız.

Buna benzer:

$ 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

Ubuntu'da lsscsi'yi

$ sudo apt-get install lsscsi

2
hm ve çıktıdaki ataXhangi bölüme nasıl harita lsscsi?
maxschlepzig

1
@maxschlepzig Dörtlü içindeki ilk sayı ataX ile aynıdır; lsscsi'nin çıktısı 0-indekslenir ve ataZ 1-indekslenir; yani [2: 0: 0: 0] uzun uykunun yayınladığı çıkışta / dev / sda olan ata3 olurdu
Jason

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

@Jason doğrudan erişen bir alternatif de benim güncellenmiş cevaba bakınız /sys/devicesolmadan lsscsi.
maxschlepzig

0

Yukarıdaki cevapların hiçbiri benim için işe yaramadı ve SCSI veri yolu numaraları ile ATA numaraları arasındaki tutarsızlıklar nedeniyle lsscsi yaklaşımı aslında yanlış cevap verdi. 21 diskli bir sistemde, ATA18 (HSM ihlalleri) ile ilgili sorunlar hakkında birçok sistem günlüğü raporu aldım. Hangi disk bu hatalara neden oluyordu? Bazıları şeyleri daha kafa karıştırıcı yapan usb sürücülerdi. Her bir SCSI sürücüsünün sisteme nasıl bağlandığına dair bir muhasebeye ihtiyacım vardı ve ATA veya USB'den bağımsız olarak tüm SCSI diskleri (/ dev / s [dr]?) İçin sekmeli listeler veren komut dosyasını aşağıda yazdım.

Daha sonra, tüm disk sürücüleri tam olarak hesaba katıldığında, ATA hatalarımın disk sürücülerimin hiçbiriyle ilgisi olmadığını görünce şaşırdım . Yanlış soruyu soruyordum ve sanırım başkaları da aynı tuzağa düşebilir, bu yüzden burada bahsediyorum. Daha sonra HSM ihlali mesajlarını oluşturan donanımı tanımlayan ikinci bir yaklaşım kullandım.

#!/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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.