Когда блок Linux получает ошибку ATA, он заносит его в журнал сообщением, идентифицирующим диск как «ata% d.00». Как мне перевести это на имя устройства (например /dev/sdb
)? Я чувствую, что это должно быть тривиально, но я не могу понять это.
Когда блок Linux получает ошибку ATA, он заносит его в журнал сообщением, идентифицирующим диск как «ata% d.00». Как мне перевести это на имя устройства (например /dev/sdb
)? Я чувствую, что это должно быть тривиально, но я не могу понять это.
Ответы:
Питер вдохновил меня написать расширенный сценарий (пусть), который может даже обнаруживать флешки USB (вместо вывода глупых вещей вроде «ata0.00»). В отличие от сценария Питера, вы также получите дополнительный номер (как в 4.01), если у вас более одного устройства на одном контроллере, соответственно. канал. Вывод будет точно таким, каким вы его получили syslog
. Проверено. Очень хорошо работает на моей коробке Debian, хотя всегда есть много улучшений (например, слишком неуклюжие регулярные выражения). Но держи его! Казалось бы, слишком большое число экранированных символов, которые вы можете найти в моих регулярных выражениях, просто из соображений совместимости! Вы не можете использовать GNU sed
со всеми, поэтому я специально сделал это без расширенных регулярных выражений.
ОБНОВЛЕНИЯ
(1) больше не будет анализировать ls
вывод. (упс!) Так как вы все знаете: не разбирайте 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"
Посмотрите /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
ID 0 scsi0 - это sda и ata1.00, id 0 scsi1 - это sdb и ata2.00 и т. д.
Также посмотрите /var/log/dmesg
, что показывает информацию о загрузке драйвера ata и немного прояснит ситуацию. Ищите строку, начинающуюся с «libata».
Я предпочитаю сценарии вместо длинных объяснений. Это работает на моей коробке 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
ls -l /sys/block/sd* | sed -e 's@.*-> \.\..*/ata@/ata@' -e 's@/host@ @' -e 's@/target.*/@ @'
Это на самом деле довольно сложно. Хотя можно с уверенностью предположить, что «идентификатор 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
это:
найти идентификатор PCI контроллера SATA
# lspci | grep -i sata
00:1f.2 SATA controller: Intel Corporation 631xESB/632xESB SATA AHCI Controller (rev 09)
найти соответствующий уникальный идентификатор:
# 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
так что это 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
вот наше устройство, мы можем (необязательно) найти серийный номер, чтобы вывести это устройство (или проверить кабельные соединения или что-то еще), прежде чем наш RAID-массив полностью выйдет из строя:
# hdparm -i /dev/sdd | grep Serial
Model=ST3250310NS, FwRev=SN06, SerialNo=9SF19GYA
И вы сделали!
Попробуй это:
# 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 указаны.
У меня была та же проблема, и я смог определить диски, проверив dmesg. Там вы можете увидеть идентификатор контроллера (правильный термин ??) и модель диска. Затем используйте ls -l / dev / disk / by-id, чтобы сопоставить номер модели с / dev / sda (или любым другим). Кроме того, мне нравится Дисковая утилита для этой информации. Примечание: это работает, только если у ваших дисков разные номера моделей, иначе вы не сможете различить их.
>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
Самый простой способ - просмотреть журнал ядра при загрузке, поскольку имена устройств дисков смешаны из разных источников (например, USB-накопителей) или назначаются в зависимости от типа устройства (т. Е. Вместо этого cdrom может быть scdX, и все есть sgX. ). На практике, если вы не смешали разные типы шин (например, SATA + USB), устройство с самым низким номером ata будет sda, если это не устройство cdrom.
В зависимости от вашей системы, это может быть предсказано блужданием по sysfs. В моей системе ls -l /sys/dev/block
показывается, что 8:0
(major: minor from / dev entry) указывает на /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, я подозреваю, что если бы я использовал множитель порта, мои диски получили бы 0,01, 0,02, 0,03 и т. Д. При просмотре журналов других пользователей контроллеры PATA используют 0,00 и 0,01 для главного и подчиненного устройств. и на основе их журналов, если у вас есть ataX.01, .01 должен быть сопоставлен с «ID» в папке host: channel: ID: LUN из /sys/dev/block/
списка. Если у вас есть несколько папок ataX/
и hostY/
папок в одной папке устройства PCI, то я подозреваю, что папка ataX с наименьшим номером соответствует папке hostY с наименьшим номером.
В /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
Сценарий ниже даст вам хорошее резюме, как это:
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 отвечает на устройство чтения карт памяти SD 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)
Сценарий для поиска этой информации и многое другое можно найти по адресу https://www.av8n.com/computer/disk-hw-host-bus-id.
Это похоже на сценарий, предоставленный Mr. Syntaxerror, но причудливее. - Работает как с USB-накопителями, так и с ATA-накопителями. - В нем указывается марка привода, модель и серийный номер, - и, конечно, точка крепления. - Это более простой, читаемый и поддерживаемый.