Linux ATAエラー:デバイス名への変換?


36

LinuxボックスでATAエラーが発生すると、ディスクを「ata%d.00」として識別するメッセージでsyslogに記録されます。これをデバイス名(例:)に変換するにはどうすればよい/dev/sdbですか?これは些細なことだと思いますが、理解できません。


1
Unix-SEでの同様の質問に対する私の答えも参照してください:unix.stackexchange.com/a/13988/1131
maxschlepzig

回答:


28

Peterは、「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"

スクリプトに問題があるデバイスが表示されない場合があることを思い出してください。ソフトリセットに失敗したata6エラーが発生しました(最初のFISが失敗しました)(マイナーな問題)がリストされたデバイスで、存在しませんでした。PCに4つのディスクがあり、3つしか表示されないことがわかっている場合は、その理由が考えられます。
ケンドリック

1
@Kendrickまあ、私はこの場合、スクリプトを非難しません。カーネルドライバーがどのように機能するかを知っている場合、これは明確になります:)カーネルサブシステムドライバーは、「問題」が十分に深刻になると放棄することがわかっています。これは、UDMA対応ドライブの場合、複数のドライブリセットを誘発し、(最終的に)PIOモードでドライブ操作を試行する可能性があることを示しています。ただし、これも不安定すぎる場合(さまざまなタイミングエラーなど)、ドライバーはドライブに「ゴーアウェイ」と言います。古いPATAドライブの場合、これは、ドライブが再び表示されるためにコールドリブートが必須であることを意味します。
構文エラー

スクリプトを非難するつもりはありません。なぜそれが欠落しているのかを思い出させるために:)愚かなフレークシーゲイトコントローラーボードは、何が起こっているのかを理解するのが苦痛になりました。
ケンドリック

@Kendrickあなたは私に男を言っています。:)さて、私の本の中で、シーゲイトは決してサムスンを買収すべきでありませんでした。サムスンがまだ大容量ストレージビジネスを営んでいた頃の後者のドライブと、優れたサポートチームを気に入っていました。現在、シーゲイトはこのすべてを引き継いでいます...そして...あーあ。
構文エラー

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。これは、ataドライバのロード情報を示しており、物事を少し明確にします。「libata」で始まる行を探します。


8
また、「lsscsi」を使用する必要がある場合があります-これはやや人間に優しい出力を提供します-例[0:0:0:0] cd / dvd TSSTcorp CDDVDW SH-S202H SB00 / dev / sr0 [2:0:0:0 ] disk ATA ST3500630AS 3.AA / dev / sda [3:0:0:0] disk ATA WDC WD5000AAKS-0 01.0 / dev / sdb(3.2.xカーネルを実行しているこのサーバーでは、/ proc / scsiはありません。 *)(申し訳ありませんが、私はそれを読みやすくするために、任意の上記に書式を取得する方法を見つけ出すように見えることはできません)
デヴィッド・グッドウィン

1
これは、コメントではなく答えでなければなりません。便利で、素早く、簡単に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
少し簡素化(ls -l /sys/block/sd* | sed -e 's@.*-> \.\..*/ata@/ata@' -e 's@/host@ @' -e 's@/target.*/@ @'
Centosで

9

これは実際には非常に注意が必要です。「scsi ID」が「SATA ID-1」で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. SATAコントローラーのPCI IDを見つける

    # lspci | grep -i sata
    00:1f.2 SATA controller: Intel Corporation 631xESB/632xESB SATA AHCI Controller (rev 09)
    
  2. 一致する一意の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
    
  3. それはon scsi_host/host3であり、これはに翻訳できます3:x:x:x。これをgrepし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」を割り当てる人はいません。指定されます。


5

同じ問題があり、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

2

最も簡単な方法は、ブートからカーネルログを確認することです。ドライブデバイス名はさまざまなソース(USBドライブなど)から混合されるか、デバイスのタイプに基づいて割り当てられます(つまり、cdromがscdXで、すべてがsgX )。実際には、異なる種類のバス(たとえば、SATA + USB)を混在させていない限り、cdromデバイスでない限り、最小番号のataデバイスはsdaになります。

システムによっては、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いることを明らかにし、同じPCIサブデバイス上にあるata1ポイントを明らかにして/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」にマッピングされる必要があります。あなたは複数持っている場合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]。だから私にとってata1host0、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

したがって、ドライブごとに1行で、sdXデバイス名、サイズモデルs / npciおよび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つの異なるホストでテストしたので、上記のスクリプトにataへの参照が含まれていないHWを見つけました。dmesg | grep "ata [0-9]"が決して私を失敗させたことはないことを指摘しておくべきです。
ndemou

0

この情報などを見つけるためのスクリプトは、 https://www.av8n.com/computer/disk-hw-host-bus-idにあります。

これは、Mr。Syntaxerrorが提供するスクリプトに似ていますが、より洗練されています。-USBドライブおよびATAドライブで機能します。-ドライブのメーカーとモデル、シリアル番号、そしてもちろん接続ポイントを提供します。-より簡単で、読みやすく、保守しやすい。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.