LinuxボックスがATAエラーを受け取ると、ディスクを「ata%d.00」として識別するメッセージでsyslogします。それをデバイス名に変換するにはどうすればよいですか(例:/dev/sdb
)?これは些細なことのように思えますが、理解できません。
ピーターは、(「ata0.00」のような馬鹿げたものを出力する代わりに)USBスティックを検出することさえできる高度なスクリプト(let)を書くように私にインスピレーションを与えました。 Peterのスクリプトとは逆に、同じコントローラレスポンスに複数のデバイスがある場合は、サブ番号も取得します(4.01と同様)。チャネル。出力は、syslog
で取得したとおりになります。テスト済み。私のDebianボックスでは非常にうまく機能していますが、常に多くの改善があります(例:不格好な正規表現)。しかし、それを保持してください!私の正規表現で見つかるエスケープ文字の数が多すぎるように見えるのは、互換性の理由だけです!すべての人がGNU sed
と仮定することはできません。そのため、拡張正規表現を使用せずに意図的に行いました。
[〜#〜]更新[〜#〜]
(1)ls
出力を解析しなくなります。 (おっと!)ご存知のとおり: lsを解析しないでください。
(2)読み取り専用環境でも動作するようになりました。
(3)このおしゃべりからの示唆に触発 ここ 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"
次のような/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
も参照してください。これは、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
これは実際にはかなりトリッキーです。 「scsi ID」が「SATA ID-1」であると仮定するのは安全ですが、私は本当に安全であり、私が仮定するunique_id
を検査することを好みます( this post に基づいて) 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
が何であるかを見つけるための私の手順:
sATAコントローラのPCI IDを見つける
# lspci | grep -i sata
00:1f.2 SATA controller: Intel Corporation 631xESB/632xESB SATA AHCI Controller (rev 09)
一致する一意のIDを見つけます。
# 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
でgrepして詳細を確認できます。
# 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 /パスを見つけません。ここで、ata4とsdcの両方指定されています。
同じ問題があり、dmesgをチェックすることでドライブを識別できました。コントローラの識別子(正しい用語??)とディスクのモデルが表示されます。次に、ls -l/dev/disk/by-idを使用して、モデル番号を/ dev/sda(またはその他)に一致させます。あるいは、この情報のためにディスクユーティリティが好きです。注:これは、ディスクのモデル番号が異なる場合にのみ機能します。それ以外の場合、2つを区別することはできません。
>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
/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
ドライブのデバイス名がさまざまなソース(USBドライブなど)から混在しているため、またはデバイスのタイプに基づいて割り当てられているため(つまり、代わりにcdromがscdXである可能性があるため)、ブートからカーネルログを確認するのが最も簡単な方法ですすべてにはsgXがあります)。実際には、異なる種類のバス(SATA + USBなど)を混在させていない限り、デバイスの最小番号はcdromデバイスでない限りsdaになります。
お使いのシステムによっては、sysfsをさまようことでそれがわかるかもしれません。私のシステムでは、ls -l /sys/dev/block
は8:0
(/ devエントリからのメジャー:マイナー)が/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
が同じPCIサブデバイス上の/sys/devices/pci0000:00/0000:00:1f.2/ata1/ata_port/ata1
を指していることを示します。
私はSATAを使用しており、各ポートにドライブが1つしかないので、ata1.00 = sdaと推定できます。私のドライブはすべて.00です。ポートマルチプライヤーを使用した場合、ドライブには.01、.02、.03などが与えられると思います。他の人のログを見ると、PATAコントローラーはマスターとスレーブに.00と.01を使用しています。 、およびataX.01がある場合はログに基づいて、.01を/sys/dev/block/
リストのHost:channel:ID:LUNフォルダーの「ID」にマッピングする必要があります。同じPCIデバイスフォルダー内に複数のataX/
フォルダーとhostY/
フォルダーがある場合、I suspectは、最小番号のataXフォルダーが最小番号のhostYフォルダーと一致することを示します。
以下のスクリプトは、次のような素晴らしい要約を提供します。
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
したがって、ドライブごとに1行にsdXデバイス名、size、model、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でのみテスト済み)
この情報を見つけるためのスクリプトなどは https://www.av8n.com/computer/disk-hw-Host-bus-id にあります。
Syntaxerror氏が提供するスクリプトに似ていますが、より洗練されています。 -USBドライブおよびATAドライブで動作します。 -ドライブのメーカー、モデル、シリアル番号、およびもちろんアタッチメントポイントを提供します。 -わかりやすく、読みやすく、保守が容易です。