Erros Linux ATA: Traduzindo para um nome de dispositivo?

30

Quando uma caixa do Linux recebe um erro do ATA, o syslog faz uma mensagem identificando o disco como "ata% d.00". Como faço para traduzir isso para um nome de dispositivo (por exemplo, /dev/sdb )? Eu sinto que isso deve ser trivial, mas eu não consigo descobrir.

    
por nelhage 09.03.2011 / 00:00

10 respostas

26

Peter me inspirou a escrever um script avançado (let), que pode até detectar pendrives (em vez de gerar coisas bobas como "ata0.00"). Ao contrário do roteiro de Pedro, você também obterá o subnúmero (como em 4.01) se tiver mais de um dispositivo no mesmo controlador resp. canal. A saída será exatamente como você obtém em syslog . Testado. Funcionando muito bem na minha caixa Debian, embora sempre haja muitas melhorias (por exemplo, regexps muito desajeitados). Mas mantenha isso! O número aparentemente alto de caracteres de escape que você pode encontrar nos meus regexps é apenas por razões de compatibilidade! Você não pode assumir o GNU sed com todos, e é por isso que fiz sem regexps estendidos de propósito.

ATUALIZAÇÕES
(1) não irá mais analisar ls output. (oops!) Já que todos vocês sabem: Não analisam ls.
(2) Agora também funciona em ambientes somente leitura.
(3) Inspirado por uma sugestão desse bate-papo aqui eu consegui novamente fazer com que as instruções sed sejam menos complicadas.

#!/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"
    
por 12.09.2012 / 03:15
11

Veja /proc/scsi/scsi , que será algo assim:

$ 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 é sda e ata1.00, scsi1 id 0 é sdb e ata2.00, etc.

Veja também /var/log/dmesg , que mostra as informações de carregamento do driver de ata e tornará as coisas um pouco mais claras. Procure a linha que começa com "libata".

    
por 09.03.2011 / 01:22
10

Eu prefiro scriptlets em vez de explicações extensas. Isso funciona na minha caixa do Ubuntu. Adicione comentários ao seu gosto:

# 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
    
por 01.08.2012 / 14:42
8

Isso é bem complicado. Embora seja seguro assumir que "o scsi ID" é "o SATA ID menos um", prefiro ser realmente seguro e inspecionar o unique_id que eu suponho (com base em esta postagem ) é o identificador SATA.

Meu erro foi:

[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

Então, meu procedimento para descobrir o que é ata4 :

  1. encontre o ID PCI do controlador SATA

    # lspci | grep -i sata
    00:1f.2 SATA controller: Intel Corporation 631xESB/632xESB SATA AHCI Controller (rev 09)
    
  2. encontre o ID exclusivo correspondente:

    # 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. , por isso, é em scsi_host/host3 , que podemos traduzir para 3:x:x:x , que podemos encontrar em dmesg para saber mais:

    # 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. aqui está o nosso dispositivo, podemos (opcionalmente) encontrar o número de série para tirar o dispositivo de lá (ou verificar o cabeamento ou qualquer outro) antes que nosso array RAID falhe totalmente:

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

E pronto!

    
por 20.06.2013 / 19:12
5

Eu tive o mesmo problema e consegui identificar unidades verificando o dmesg. Lá você pode ver o identificador do controlador (termo correto) e o modelo do disco. Em seguida, use ls -l / dev / disk / by-id para corresponder ao número do modelo para / dev / sda (ou qualquer outro). Como alternativa, gosto do Utilitário de Disco para essa informação. Nota: isto só funciona se os seus discos tiverem números de modelo diferentes, caso contrário você não poderá distinguir entre os dois.

>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
    
por 18.02.2013 / 19:31
3

Tente isto:

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

Eu nunca entendi o dmesg - algumas linhas são sobre "ata4" algumas outras sobre "scsi" ou sdc, mas ninguém atribui "ata4 ... sdc" o comando mostrado encontra o caminho / sys / bus /, onde ambos, ata4 e sdc, são especificados.

J.

    
por 16.08.2017 / 13:46
2

A maneira mais fácil é revisar o log do kernel desde a inicialização, desde que os nomes dos dispositivos da unidade sejam misturados de várias origens (por exemplo, unidades USB) ou atribuídos com base no tipo de dispositivo (por exemplo, cdrom pode ser scdX e < em> tudo tem um sgX). Na prática, a menos que você tenha misturado diferentes tipos de barramentos (por exemplo, SATA + USB), o dispositivo ata com numeração mais baixa será sda, a menos que seja um dispositivo de cdrom.

Dependendo do seu sistema, pode ser adivinhado vagando pelo sysfs. No meu sistema ls -l /sys/dev/block revela que 8:0 (maior: menor da entrada / dev) aponta para /sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda Da mesma forma, ls -l /sys/class/ata_port revela que ata1 aponta para /sys/devices/pci0000:00/0000:00:1f.2/ata1/ata_port/ata1 que está no mesmo sub-dispositivo PCI.

Como eu uso SATA, e apenas uma unidade está em cada porta, posso deduzir que ata1.00 = sda. Todas as minhas unidades são .00, suspeito que se eu usasse um multiplicador de porta, minhas unidades receberiam .01, .02, .03 etc. Olhando para os logs de outras pessoas, os controladores PATA usam .00 e .01 para mestre e escravo e, com base em seus logs, se você tiver ataX.01, o .01 deverá ser mapeado para o "ID" na pasta host: channel: ID: LUN na listagem /sys/dev/block/ . Se você tiver várias pastas ataX/ e hostY/ na mesma pasta do dispositivo PCI, então suspeito de que a pasta ataX com o número mais baixo corresponda à pasta hostY com o número mais baixo.

    
por 09.03.2011 / 02:16
0

O script abaixo lhe dará um bom resumo como este:

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

Portanto, em uma linha por unidade, você tem o sdX nome do dispositivo, tamanho , modelo , s / n e os números pci e ata . O sdc acima corresponde a um leitor de cartões SD USB sem cartão inserido. Daí o ---- no lugar da informação real.

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

(testado apenas no Ubuntu 12.04 / 14.04 e no CentOS 6)

    
por 06.10.2014 / 22:55
0

Em /sys/class/ata_port/ata${n}/device/ , você pode ver uma pasta host${x} . Por exemplo, na minha máquina:

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

O ${x} em host${x} refere-se ao primeiro número no [0:0:0:0] . Então, para mim, ata1 refere-se a host0 , que também pode ser representado no formato SCSI como 0:* :

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

Um script para encontrar essas informações, e mais, pode ser encontrado em    link

É semelhante ao script fornecido pelo Sr. Syntaxerror, mas mais chique.  - Funciona para drives USB e drives ATA.  - Fornece a marca e o modelo do inversor e o número de série,  - e, claro, o ponto de fixação.  - É mais simples, legível e sustentável.

    
por 06.12.2016 / 19:11