Lorsqu'une boîte Linux reçoit une erreur ATA, elle l'enregistre dans le syslog avec un message identifiant le disque comme "ata%d.00". Comment traduire ce message en un nom de périphérique (par ex. /dev/sdb
) ? J'ai l'impression que cela devrait être trivial, mais je n'y arrive pas.
Réponses
Trop de publicités?Peter m'a inspiré pour écrire un script(let) avancé, qui peut même détecter les clés USB (au lieu de sortir des choses stupides comme "ata0.00"). Contrairement au script de Peter, vous obtiendrez également le sous-numéro (comme dans 4.01) si vous avez plus d'un périphérique sur le même contrôleur ou canal. La sortie sera exactement comme vous l'obtenez dans syslog
. Testé. Fonctionne très bien sur ma Debian, bien qu'il y ait toujours beaucoup d'améliorations à apporter (par exemple des regexps trop maladroites). Mais attention ! Le nombre apparemment trop élevé de caractères échappés que vous pouvez trouver dans mes regexps est juste pour des raisons de compatibilité ! Vous ne pouvez pas supposer que GNU sed
avec tout le monde, c'est pourquoi j'ai volontairement renoncé aux regexps étendues.
MISE À JOUR
(1) N'analysera plus ls
de la production. (oops !) Comme vous le savez tous : Ne pas analyser ls.
(2) Fonctionne désormais également dans les environnements en lecture seule.
(3) Inspiré par une suggestion de ce bavardage aquí J'ai réussi à rendre les déclarations sed beaucoup moins compliquées.
#!/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"
Regarder /proc/scsi/scsi
qui ressemblera à quelque chose comme ceci :
$ 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 est sda et ata1.00, scsi1 id 0 est sdb et ata2.00, etc.
Voir aussi /var/log/dmesg
qui affiche les informations de chargement du pilote ata et rendra les choses un peu plus claires. Cherchez la ligne commençant par "libata".
Je préfère les scripts aux longues explications. Cela fonctionne sur ma machine Ubuntu. Ajoutez des commentaires à votre convenance :
# 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
Essayez ceci :
# find -L /sys/bus/pci/devices/*/ata*/host*/target* -maxdepth 3 -name "sd*" 2>/dev/null | egrep block |egrep --colour '(ata[0-9]*)|(sd.*)'
Je n'ai jamais compris le dmesg - certaines lignes concernent "ata4", d'autres "scsi" ou sdc, mais personne n'attribue "ata4 . . . sdc" la commande affichée trouve le chemin /sys/bus/, où ata4 et sdc sont spécifiés.
Seulement si votre système udev le crée, vous pouvez simplement taper :
# ls -l /dev/disk/by-path/
lrwxrwxrwx 1 root root 2020-06-17 12:01 pci-0000:00:1d.7-usb-0:3:1.0-scsi-0:0:0:0 -> ../../sdc
lrwxrwxrwx 1 root root 2020-06-17 12:07 pci-0000:00:1f.2-ata-1 -> ../../sda
lrwxrwxrwx 1 root root 2020-06-17 12:07 pci-0000:00:1f.2-ata-1-part1 -> ../../sda1
lrwxrwxrwx 1 root root 2020-06-17 12:07 pci-0000:00:1f.2-ata-2 -> ../../sdb
Le résultat contient tous les dispositifs de bas niveau et les dispositifs de bloc correspondants sur la même ligne.
Il s'agit en fait d'une question assez délicate. Bien qu'il soit prudent de supposer que "l'ID scsi" est "l'ID SATA moins un", je préfère être vraiment prudent et inspecter l'ID unique_id
que je suppose (sur la base de ce poste ) est l'identifiant SATA.
Mon erreur était la suivante :
[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
Je me suis donc efforcé de trouver ce que ata4
est :
-
trouver l'identifiant PCI du contrôleur SATA
# lspci | grep -i sata 00:1f.2 SATA controller: Intel Corporation 631xESB/632xESB SATA AHCI Controller (rev 09)
-
trouver l'identifiant unique correspondant :
# 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
-
donc c'est parti
scsi_host/host3
que l'on peut traduire par3:x:x:x
que nous pouvons rechercher dansdmesg
pour en savoir plus :# 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
-
voici notre appareil, nous pouvons (éventuellement) trouver le numéro de série pour sortir cet appareil de là (ou vérifier le câblage ou autre) avant que notre réseau RAID ne tombe totalement en panne :
# hdparm -i /dev/sdd | grep Serial Model=ST3250310NS, FwRev=SN06, SerialNo=9SF19GYA
Et le tour est joué !
- Réponses précédentes
- Plus de réponses