Помилки ATA Linux: Переклад на ім’я пристрою?


36

Коли вікно Linux отримує помилку ATA, він аналізує його повідомленням, що ідентифікує диск як "ata% d.00". Як перевести це на ім'я пристрою (наприклад /dev/sdb)? Я відчуваю, що це має бути тривіально, але я не можу цього зрозуміти.


1
Дивіться також мою відповідь на подібне запитання щодо Unix-SE: unix.stackexchange.com/a/13988/1131
maxschlepzig

Відповіді:


28

Пітер надихнув мене написати розширений сценарій (нехай), який навіть може виявити USB-палички (замість того, щоб виводити дурні речі типу "ata0.00"). Всупереч сценарію Петра, ви також отримаєте під-номер (як у 4.01), якщо у вас є більше одного пристрою на одному контролері, відповідно. канал. Вихід буде точно таким, яким ви його отримаєте syslog. Випробуваний. Я дуже добре працюю над моєю скринькою Debian, хоча вдосконалення завжди багато (наприклад, занадто незграбні регулярні виразки). Але ДІЙТЕ ЇЇ! На вигляд, занадто велика кількість символів, що втекли, які ви можете знайти в моїх регулярних виразах - це лише з міркувань сумісності! Ви не можете припустити GNU sedз усіма, саме тому я обходився без розширених регулярних виразів.

ОНОВЛЕННЯ
(1) Більше не буде аналізувати lsвихід. (ой!) Оскільки ви всі знаєте: Не розбирайте лс.
(2) Тепер також працює в середовищах, доступних лише для читання.
(3) Навіяно пропозицією від цієї балаканини тут мені вдалося знову отримати цей аналіз заяву шляху менш складним.

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

Просто нагадування, що сценарій може не відображати пристрої, які мають проблеми. У мене помилка Ata6 з програмою softreset не вдалася (1-й FIS не вдався) (Незначні випуски) перераховані пристрої, і його не було. якщо ви знаєте, що у вас є 4 диски на ПК, і лише 3 з'являються, це може бути причиною.
Кендрік

1
@Kendrick Ну, я б не звинувачував сценарій у цій справі. Бо якщо ви знаєте, як працюють драйвери ядра, вам це стане більш ніж зрозумілим :) Драйвери підсистеми ядра, як відомо, відмовляються, коли «проблеми» будуть досить серйозними. Звідси випливає, що для приводу, що підтримує UDMA, він може викликати декілька скидів диска та (зрештою) спробувати операцію диска в режимі PIO. Однак якщо це виявиться занадто нестабільним (різні помилки в часі тощо), драйвер скаже «піти» на диск. Для старих дисків PATA це означає, що холодне перезавантаження буде обов’язковим для того, щоб накопичувач знову з’явився.
синтаксисхор

Не мій намір означати вину за сценарій. лише нагадування про те, чому це може бути відсутнє :) дурна пластівка пластівчастого диспетчера принесла біль, щоб зрозуміти, що відбувається.
Кендрік

@Kendrick Ти мені кажеш, людина. :) Ну, в моїй книзі Seagate ніколи не повинен був купувати Samsung. Полюбили останні накопичувачі (коли Samsung ще займався масовим зберіганням), а також відмінну службу підтримки. Зараз Seagate взяла на себе все це ... і ... о-о.
синтаксисхор

11

Подивіться /proc/scsi/scsi, що буде виглядати приблизно так:

$ 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 і ata1.00, scsi1 id 0 - sdb і ata2.00 тощо.

Також подивіться /var/log/dmesg, що показує інформацію про завантаження драйвера ата та зробить речі трохи зрозумілішими. Шукайте лінію, що починається з "лібата".


8
Можливо, вам також знадобиться використовувати "lsscsi" - що дає дещо більш сприятливий для людини вихід - наприклад [0: 0: 0: 0] cd / dvd TSSTcorp CDDVDW SH-S202H SB00 / dev / sr0 [2: 0: 0: 0 ] диск ATA ST3500630AS 3.AA / dev / sda [3: 0: 0: 0] диск ATA WDC WD5000AAKS-0 01.0 / dev / sdb (На цьому сервері працює ядро ​​3.2.x, немає / proc / scsi *) (Вибачте, я не можу зрозуміти, як ввести будь-яке форматування у вищезазначене, щоб зробити його читабельним)
Девід Гудвін

1
Це повинна бути відповідь, а не коментар. Корисно, швидко та легко читати з однієї машини та набирати на іншій проблему.
Старійшина Гік

10

Я вважаю за краще сценарії замість тривалих пояснень. Це працює на моїй коробці Ubuntu. Додати коментарі на свій смак:

# 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

Ваш сценарій трохи менш страшний, ніж відповідь, здебільшого тому, що я бачу всю справу.
isaaclw

1
Трохи спрощення (працює для мене на Centos)ls -l /sys/block/sd* | sed -e 's@.*-> \.\..*/ata@/ata@' -e 's@/host@ @' -e 's@/target.*/@ @'
Ширкер

9

Це насправді досить складно. Хоча з упевненістю можна припустити, що "ідентифікатор scsi" є "ідентифікатором SATA мінус один", я вважаю за краще бути справді безпечним і перевіряти, unique_idщо я припускаю (виходячи з цього повідомлення ) є ідентифікатором SATA.

Моя помилка:

[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

Тож моя процедура з'ясувати, що ata4таке:

  1. знайти ідентифікатор PCI контролера SATA

    # lspci | grep -i sata
    00:1f.2 SATA controller: Intel Corporation 631xESB/632xESB SATA AHCI Controller (rev 09)
    
  2. знайти унікальний ідентифікатор, що відповідає:

    # 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. тож увімкнено scsi_host/host3, на що ми можемо перекласти 3:x:x:x, на що ми можемо простувати, 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. ось наш пристрій, ми можемо (необов'язково) знайти серійний номер, щоб вивезти цей пристрій звідти (або перевірити кабельне чи інше), перш ніж наш RAID-масив повністю вийде з ладу:

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

І ви закінчили!


7

Спробуйте це:

# 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 - деякі рядки про "ata4", деякі інші про "scsi" або sdc, але ніхто не призначає "ata4 ... sdc", показана команда знаходить / sys / bus / path, де і ata4, і sdc уточнюються.


5

У мене була така ж проблема, і я зміг визначити диски, перевіривши dmesg. Там ви можете побачити ідентифікатор контролера (правильний термін ??) та модель диска. Потім використовуйте ls -l / dev / disk / by-id, щоб відповідати номеру моделі / / dev / sda (або що завгодно). Крім того, мені подобається Disk Utility для цієї інформації. Примітка. Це працює лише в тому випадку, якщо ваші диски мають різні номери моделей, інакше ви не можете їх розрізнити.

>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

Найпростіший спосіб - переглянути журнал ядра з завантаження, оскільки назви пристроїв накопичувачів змішуються з різних джерел (наприклад, USB-накопичувачів) або призначаються залежно від типу пристрою (наприклад, cdrom може бути scdX, і все має sgX ). На практиці, якщо ви не змішали різні типи шин (наприклад, SATA + USB), найменшим номером ata-пристрою буде sda, якщо це не пристрій cdrom.

Залежно від вашої системи, це може бути визначено, блукаючи навколо sysfs. У моїй системі ls -l /sys/dev/blockвиявляється, що 8:0(основний: мінор з / дев. Запис) вказує на /sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda Аналогічно, ls -l /sys/class/ata_portвиявляє, що ata1вказує на те, /sys/devices/pci0000:00/0000:00:1f.2/ata1/ata_port/ata1що знаходиться на тому ж підрозділі PCI.

Оскільки я використовую SATA, і на кожному порту є лише один накопичувач, я можу визначити, що ata1.00 = sda. Усі мої накопичувачі - .00, я підозрюю, що якби я використовував помножувач порту, мої накопичувачі отримали б .01, .02, .03 і т. Д. Переглядаючи журнали інших людей, контролери PATA використовують .00 та .01 для головного та веденого , і на основі їхніх журналів, якщо у вас є ataX.01, .01 має бути відображено до "ідентифікатора" у хості: channel: ID: папка LUN зі /sys/dev/block/списку. Якщо у вас є кілька ataX/і hostY/папки в тій же папці пристрою PCI, то я підозрюю , що з найменшим номером папки ATAX збігається з найменшим номером папки Hosty.


2

У ньому /sys/class/ata_port/ata${n}/device/можна побачити host${x}папку. Наприклад, на моїй машині:

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

${x}У host${x}ставиться до цього першого номера в [0:0:0:0]. Тож для мене ata1йдеться про те, host0яке також може бути представлене у формі SCSI як 0:*:

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

0

Сценарій, поданий нижче, дасть вам приємне резюме, як це:

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

Отже, в одному рядку на диск ви маєте назву пристрою sdX , розмір , модель , s / n та номери pci та ata . SDC вище відповідає пристрою зчитування USB SD-карт, в якому не вставлена ​​карта. Звідси ---- замість реальної інформації.

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

(тестується лише на ubuntu 12.04 / 14.04 та CentOS 6)


Як це дорівнює, щоб показати вам, що, наприклад, ATA 4.01?
Edward_178118

У вихідному прикладі ви бачите sda: ... ata1 ... і sdb: ... ata3 .... І справді sda був у ata1, а sdb в ata2. Оскільки я написав його і протестував його на 4 різних хостах, я виявив HW, де вищевказаний скрипт не містить посилання на ата. Я мушу зазначити, що dmesg | grep "ata [0-9]" ніколи не підводив мене.
ndemou

0

Сценарій для пошуку цієї інформації та іншого можна знайти на веб- сайті https://www.av8n.com/computer/disk-hw-host-bus-id

Він схожий на сценарій, наданий містером Syntaxerror, але більш фантазійний. - Він працює як для USB-накопичувачів, так і для ATA-накопичувачів. - Він забезпечує марку приводу, модель та серійний номер, - і звичайно точку кріплення. - Це більш просто, читабельно і доглянуто.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.