Linux ATA hataları: Bir aygıt adına mı çevriliyor?


36

Bir Linux kutusu bir ATA hatası aldığında, diski "ata% d.00" olarak tanımlayan bir mesajla syslog'lar. Bunu bir cihaz adına (örneğin /dev/sdb) nasıl çevirebilirim ? Bunun önemsiz olması gerektiğini düşünüyorum ama çözemiyorum.


1
Ayrıca bkz. Unix-SE'de benzer bir soruya verdiğim yanıtı: unix.stackexchange.com/a/13988/1131
maxschlepzig

Yanıtlar:


28

Peter, USB çubukları bile ("ata0.00" gibi aptalca şeyler çıkarmak yerine) algılayabilen gelişmiş bir senaryo yazmam için bana ilham verdi. Peter'ın senaryosunun aksine, aynı denetleyicide birden fazla cihazınız varsa, alt numarayı (4.01'deki gibi) alırsınız. kanal. Çıktı tam olarak girdiğiniz şekilde olacaktır syslog. Test edilmiştir. Debian kutumda çok iyi çalışıyoruz, ancak her zaman çok fazla gelişme olsa da (ör: çok düzenli regexps). Ancak HOLD IT! Regexps'imde bulabileceğiniz görünüşte çok fazla sayıda kaçan karakter var sadece uyumluluk nedenlerinden dolayı! GNU’yu sedherkesle birlikte üstlenemezsiniz , bu yüzden bilerek düzenli regexps yapmadan yaptım.

GÜNCELLEME
(1) Artık lsçıktıyı ayrıştırmaz . (ayy!) Hepinizin bildiğinden beri: ls'yi ayrıştırmayın.
(2) Artık salt okunur ortamlarda da çalışıyor.
(3) Buradaki sohbetten yapılan bir öneriden esinlenerek, yine baştan aşağı ifadeleri daha az karmaşık hale getirmeyi başardım.

#!/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"

Sadece bir komut dosyası sorunlu cihazları göstermeyebileceğini hatırlatmak için. Softreset başarısız ata6 hata vardı (1 FIS başarısız oldu) (Küçük Sorunlar) dvices listelenen ve mevcut değildi. PC'de 4 diskiniz olduğunu ve sadece 3 şovunuz olduğunu biliyorsanız bunun nedeni bu olabilir.
Kendrick

1
@Kendrick Peki, bu durumda senaryoyu suçlamam. Çünkü çekirdekli sürücülerin nasıl çalıştığını biliyorsanız, bu sizin için daha net olacaktır. :) Çekirdek alt sistem sürücülerinin "sorunlar" yeterince ciddi olduğunda vazgeçtiği bilinmektedir . Bu, UDMA özellikli bir sürücü için, çoklu sürücü sıfırlamalarını indükleyebileceğini ve (sonunda) PIO modunda bir sürücü çalışmasını deneyebileceğini okur. Ancak, bunun da çok dengesiz olduğu kanıtlanırsa (çeşitli zamanlama hataları vb.), Sürücü sürücüye "git" diyecektir. Eski PATA sürücüler için bu, sürücünün tekrar gösterilmesi için soğuk yeniden başlatmanın zorunlu olacağı anlamına gelir .
sözdizimi

Senaryoyu suçlama demek istemedim. neden eksik olabileceğine dair sadece bir hatırlatma :) aptal lapa lapa seagate kontrol panosu ne olup bittiğini anlamak için acı verdi.
Kendrick

@Kendrick Bana söylüyorsun dostum. :) Benim kitabımda, Seagate asla Samsung'u satın almamalıydı . İkinci sürücüleri (Samsung hala yığın depolama alanında iken) ve mükemmel destek ekiplerini sevdi. Şimdi Seagate bütün bunları ele geçirdi ... ve ... ah-ah.
sözdizimi

11

Şuna bak /proc/scsi/scsi, ki buna benzeyecek:

$ 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 kimliği 0 sda ve ata1.00, scsi1 kimliği 0 sdb ve ata2.00, vb.

Ayrıca /var/log/dmesgata sürücünün yükleme bilgisini gösteren ve işleri biraz daha netleştirecek olana bakın. "Libata" ile başlayan satırı bulun.


8
Ayrıca biraz daha insan dostu çıktı veren 'lsscsi' kullanmanız gerekebilir - örneğin [0: 0: 0: 0] cd / dvd TSSTcorp CDDVDW SH-S202H SB00 / dev / sr0 [2: 0: 0: 0 ] disk ATA ST3500630AS 3.AA / dev / sda [3: 0: 0: 0] ATA WDC WD5000AAKS-0 01.0 / dev / sdb diski (Bu sunucuda, 3.2.x bir çekirdek çalıştırıldığında, / proc / scsi yok) *) (Üzgünüm, yukarıdakileri nasıl biçimlendireceğimi, okunaklı hale getirmek için nasıl yapabileceğimi çözemiyorum)
David Goodwin

1
Bu bir yorum yerine bir cevap olmalıdır. Bir makineden okunması kolay, hızlı ve kolaydır, başka konulara da yazın.
Elder Geek

10

Uzun açıklamalar yerine script'leri tercih ederim. Bu Ubuntu kutumda çalışıyor. Beğeninize yorum ekleyin:

# 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

Senaryonuz cevaptan biraz daha az korkutucu, çünkü çoğunlukla her şeyi görebiliyorum.
isaaclw

1
Biraz basitleştirici (benim için ls -l /sys/block/sd* | sed -e 's@.*-> \.\..*/ata@/ata@' -e 's@/host@ @' -e 's@/target.*/@ @'
Centos'ta

9

Bu aslında oldukça zor. "Scsi ID" nin "SATA ID eksi bir" unique_idolduğunu varsaymak güvenli olsa da, gerçekten güvenli olmayı ve hangisinin ( bu yayına dayanarak ) SATA tanımlayıcısı olduğunu kontrol etmeyi tercih ederim .

Benim hatam:

[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

Öyleyse ne ata4olduğunu bulma prosedürüm :

  1. SATA denetleyicisinin PCI kimliğini bulma

    # lspci | grep -i sata
    00:1f.2 SATA controller: Intel Corporation 631xESB/632xESB SATA AHCI Controller (rev 09)
    
  2. eşleşen benzersiz kimliği bulun:

    # 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. yani scsi_host/host3, daha fazlasını öğrenmek 3:x:x:xiçin arayabileceğimiz, çevirebileceğimiz , açık dmesg:

    # 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. işte cihazımız, RAID dizimiz tamamen bozulmadan önce o cihazı oradan çıkaracak (veya kabloları veya herhangi bir şeyi kontrol edecek) seri numarasını bulabiliriz:

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

Ve bitti!


7

Bunu dene:

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

Dmesg'i hiç anlamadım - bazı satırlar "scsi" veya sdc ile ilgili "ata4", bazıları "ata4", bazılarını da "scsi" veya sdc ile ilişkilendirir, ancak hiç kimse "ata4. .Sdc" a atamaz. belirtildi.


5

Ben de aynı problemi yaşadım ve dmesg'i kontrol ederek sürücüleri tespit edebildim. Burada denetleyici tanımlayıcısını (doğru terim ??) ve diskin modelini görebilirsiniz. Daha sonra model numarasını / dev / sda (veya her neyse) ile eşleştirmek için ls -l / dev / disk / by-id komutunu kullanın. Alternatif olarak, bu bilgi için Disk Yardımcı Programını seviyorum. Not: Bu sadece diskleriniz farklı model numaralarına sahipse çalışır, aksi halde ikisini ayırt edemezsiniz.

>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

2

En kolay yöntem, çekirdek kütüklerini önyüklemeden incelemektir; çünkü sürücü cihaz adları çeşitli kaynaklardan (örn. USB sürücüler) karıştırılır veya cihazın türüne göre atanır (örn. Cdrom yerine scdX olabilir ve her şey sgX'e sahiptir). ). Uygulamada, farklı türdeki otobüsleri karıştırmadığınız sürece (örneğin SATA + USB) en düşük numaralı ata aygıtı cdrom aygıtı olmadıkça sda olacaktır.

Sisteminize bağlı olarak, sysfs dolaşılarak bölünebilir. Benim sistem üzerinde ls -l /sys/dev/blockortaya koymaktadır 8:0: puan (majör / dev girişten minör) /sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda Aynı şekilde, ls -l /sys/class/ata_portortaya koymaktadır ata1puan /sys/devices/pci0000:00/0000:00:1f.2/ata1/ata_port/ata1aynı PCI alt cihazda olduğu.

SATA kullandığımdan ve her portta yalnızca bir sürücü olduğundan, bu ata1.00 = sda değerini çıkarabilirim. Tüm sürücülerim .00, bir port çarpanı kullanırsam, sürücülerime .01, .02, .03 vb. Verileceğinden şüpheleniyorum. Diğer insanların günlüklerine bakıldığında PATA denetleyicilerinin master ve slave için .00 ve. ve ataX.01 varsa, günlüklerine göre, .01 ana makinedeki "ID" ile eşlenmelidir: kanal: ID: LUN klasörü /sys/dev/block/listeden. Aynı PCI aygıt klasöründe birden fazla ataX/ve hostY/klasörünüz varsa, en düşük numaralı ataX klasörünün en düşük numaralı hostY klasörüyle eşleştiğinden şüpheleniyorum .


2

İçinde /sys/class/ata_port/ata${n}/device/bir host${x}klasör görebilirsiniz . Örneğin, makinemde:

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

Bu, ${x}içindeki host${x}ilk sayıyı ifade eder [0:0:0:0]. Bu yüzden benim ata1için host0hangisinin SCSI biçiminde de temsil edilebileceği belirtiliyor 0:*:

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

0

Aşağıdaki komut dosyası size şöyle güzel bir özet verecek:

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

Dolayısıyla sürücü başına bir satırda sdX cihazının adı, boyutu , modeli , s / n ve pci ve ata numaralarına sahipsiniz . Yukarıdaki sdc, kart takılı olmayan bir USB SD kart okuyucusuna karşılık gelir. Dolayısıyla, gerçek bilginin yerine ----.

#!/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

(sadece ubuntu 12.04 / 14.04 ve CentOS 6’da test edilmiştir)


Bu size, örneğin ATA 4.01'in ne olduğunu göstermeye nasıl eşittir?
Edward_178118

Örnek çıktıda sda: ... ata1 ... ve sdb: ... ata3'ü görüyorsunuz. Ve aslında sda ata1'de ve sdb ata2'de. Yazdığım ve 4 farklı ana bilgisayarda test ettiğimden beri, yukarıdaki komut dosyasının ata referansı içermediği HW öğrendim. Dmesg | grep "ata [0-9]" 'un beni asla başarısızlığa uğratmadığını belirtmeliyim.
ndemou

0

Bu bilgileri ve daha fazlasını bulmak için bir komut dosyası https://www.av8n.com/computer/disk-hw-host-bus-id adresinde bulunabilir.

Bay Syntaxerror tarafından sağlanan senaryoya benzer, ancak meraklısı. - USB sürücüler ve ATA sürücüler için çalışır. - Sürücünün marka ve model ve seri numarasını, - ve tabii ki bağlantı noktasını sağlar. - Daha basit, okunaklı ve bakımı kolay.

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.