Gdy Linux otrzymuje błąd ATA, sysloguje go komunikatem identyfikującym dysk jako „ata% d.00”. Jak mam to przetłumaczyć na nazwę urządzenia (np. /dev/sdb
)? Wydaje mi się, że powinno to być trywialne, ale nie mogę tego rozgryźć.
Gdy Linux otrzymuje błąd ATA, sysloguje go komunikatem identyfikującym dysk jako „ata% d.00”. Jak mam to przetłumaczyć na nazwę urządzenia (np. /dev/sdb
)? Wydaje mi się, że powinno to być trywialne, ale nie mogę tego rozgryźć.
Odpowiedzi:
Peter zainspirował mnie do napisania zaawansowanego skryptu (let), który może nawet wykryć pamięć USB (zamiast wypisywać głupie rzeczy, takie jak „ata0.00”). W przeciwieństwie do skryptu Piotra, otrzymasz również pod-numer (jak w 4.01), jeśli masz więcej niż jedno urządzenie na tym samym kontrolerze lub. kanał. Dane wyjściowe będą dokładnie takie, jak je otrzymujesz syslog
. Przetestowany. Działa bardzo dobrze na moim pudełku Debiana, chociaż zawsze jest wiele ulepszeń (np. Zbyt niezdarne wyrażenia regularne). Ale TRZYMAJ! Pozornie zbyt duża liczba znaków ucieczki, które możesz znaleźć w moich wyrażeniach regularnych, to tylko ze względu na kompatybilność! Nie możesz założyć GNU sed
ze wszystkimi, dlatego celowo zrobiłem to bez rozszerzonych wyrażeń regularnych.
AKTUALIZACJE
(1) Nie będą już analizować ls
danych wyjściowych. (ups!) Ponieważ wszyscy wiecie: nie analizujcie ls.
(2) Teraz działa również w środowiskach tylko do odczytu.
(3) Zainspirowany sugestią z tego chit-czatu tutaj udało mi się jeszcze bardziej uprościć zdania sed.
#!/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"
Spójrz /proc/scsi/scsi
, który będzie wyglądał mniej więcej tak:
$ 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 to sda i ata1.00, scsi1 id 0 to sdb i ata2.00 itp.
Zobacz także /var/log/dmesg
, która pokazuje informacje o ładowaniu sterownika ata i sprawi, że będzie trochę jaśniej. Poszukaj linii zaczynającej się od „libata”.
Wolę skrypty zamiast długich wyjaśnień. Działa to na moim systemie Ubuntu. Dodaj komentarze do swoich upodobań:
# 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
ls -l /sys/block/sd* | sed -e 's@.*-> \.\..*/ata@/ata@' -e 's@/host@ @' -e 's@/target.*/@ @'
To jest właściwie dość trudne. Chociaż można bezpiecznie założyć, że „identyfikator scsi” to „identyfikator SATA minus jeden”, wolę być naprawdę bezpieczny i sprawdzam, unique_id
co, jak zakładam (na podstawie tego postu ), jest identyfikatorem SATA.
Mój błąd to:
[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
Więc moja procedura, aby dowiedzieć się, co ata4
to jest:
znajdź identyfikator PCI kontrolera SATA
# lspci | grep -i sata
00:1f.2 SATA controller: Intel Corporation 631xESB/632xESB SATA AHCI Controller (rev 09)
znajdź pasujący unikalny identyfikator:
# 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
więc jest włączony scsi_host/host3
, na który możemy przetłumaczyć 3:x:x:x
, na który możemy dmesg
się dowiedzieć, aby dowiedzieć się więcej:
# 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
oto nasze urządzenie, możemy (opcjonalnie) znaleźć numer seryjny, aby zabrać to urządzenie stamtąd (lub sprawdzić okablowanie lub cokolwiek innego), zanim nasza macierz RAID całkowicie zawiedzie:
# hdparm -i /dev/sdd | grep Serial
Model=ST3250310NS, FwRev=SN06, SerialNo=9SF19GYA
I jesteś skończony!
Spróbuj tego:
# find -L /sys/bus/pci/devices/*/ata*/host*/target* -maxdepth 3 -name "sd*" 2>/dev/null | egrep block |egrep --colour '(ata[0-9]*)|(sd.*)'
Nigdy nie rozumiałem dmesg - niektóre wiersze dotyczą „ata4”, inne zaś dotyczą „scsi” lub sdc, ale nikt nie przypisuje „ata4 ... sdc” pokazane polecenie znajduje ścieżkę / sys / bus / path, gdzie zarówno ata4, jak i sdc są określone.
Miałem ten sam problem i byłem w stanie zidentyfikować dyski, sprawdzając dmesg. Tam możesz zobaczyć identyfikator kontrolera (poprawny termin?) I model dysku. Następnie użyj ls -l / dev / disk / by-id, aby dopasować numer modelu do / dev / sda (lub cokolwiek innego). Alternatywnie podoba mi się Narzędzie dyskowe dla tych informacji. Uwaga: działa to tylko wtedy, gdy dyski mają różne numery modeli, w przeciwnym razie nie można ich rozróżnić.
>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
Najprostszym sposobem jest przejrzenie dziennika jądra od startu, ponieważ nazwy urządzeń napędowych są mieszane z różnych źródeł (np. Napędów USB) lub są przypisywane na podstawie typu urządzenia (np. Cdrom może być scdX zamiast tego i wszystko ma sgX ). W praktyce, chyba że masz do czynienia z różnymi rodzajami magistrali (np. SATA + USB), urządzeniem ATA o najniższym numerze będzie SDA, chyba że jest to urządzenie CDROM.
W zależności od systemu można go rozróżnić wędrując po dysfunkcjach. W moim systemie ls -l /sys/dev/block
ujawnia, że 8:0
(major: minor from / dev entry) wskazuje na /sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
Podobnie, ls -l /sys/class/ata_port
ujawnia te ata1
punkty, na /sys/devices/pci0000:00/0000:00:1f.2/ata1/ata_port/ata1
których znajduje się to samo urządzenie podrzędne PCI.
Ponieważ używam SATA i na każdym porcie jest tylko jeden dysk, mogę wywnioskować, że ata1.00 = sda. Wszystkie moje dyski mają 0,00, podejrzewam, że gdybym użył multiplikatora portów, moje dyski otrzymałyby 0,01, 0,02, 0,03 itd. Patrząc na logi innych ludzi Kontrolery PATA używają 0,00 i 0,01 dla master i slave , i na podstawie ich dzienników, jeśli masz ataX.01, .01 powinien być mapowany na „ID” w hoście: kanał: ID: folder LUN z /sys/dev/block/
listy. Jeśli masz wiele folderów ataX/
i hostY/
folderów w tym samym folderze urządzenia PCI, podejrzewam, że folder ataX o najniższym numerze odpowiada folderowi hostY o najniższym numerze.
W /sys/class/ata_port/ata${n}/device/
możesz zobaczyć host${x}
folder. Np. Na moim komputerze:
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
Symbol ${x}
in host${x}
odnosi się do tej pierwszej liczby w [0:0:0:0]
. Więc dla mnie ata1
odnosi się do, host0
który może być również reprezentowany w formie SCSI jako 0:*
:
gibby ~ # lsscsi 0:\*
[0:0:0:0] disk ATA WDC WD1002FAEX-0 1D05 /dev/sda
Poniższy skrypt da Ci takie fajne podsumowanie:
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
Tak więc w jednym wierszu na dysk masz nazwę urządzenia SDX , rozmiar , model , s / n oraz numery pci i ata . Sdc powyżej odpowiada czytnikowi kart USB SD bez włożonej karty. Stąd ---- zamiast prawdziwej informacji.
#!/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
(testowany tylko na Ubuntu 12.04 / 14.04 i CentOS 6)
Skrypt umożliwiający znalezienie tych informacji i nie tylko można znaleźć na stronie https://www.av8n.com/computer/disk-hw-host-bus-id
Jest podobny do skryptu dostarczonego przez pana Syntaxerrora, ale jest bardziej fantazyjny. - Działa zarówno z dyskami USB, jak i ATA. - Podaje markę i model napędu oraz numer seryjny, - i oczywiście punkt mocowania. - Jest prostszy, czytelniejszy i łatwiejszy w utrzymaniu.