次のkern.log
スニペットを検討してください。
ata4.00: failed command: WRITE FPDMA QUEUED
ata4.00: cmd 61/00:78:40:1e:6c/04:00:f0:00:00/40 tag 15 ncq 524288 out
res 41/04:00:00:00:00/04:00:00:00:00/00 Emask 0x1 (device error)
ata4.00: status: { DRDY ERR }
ata4.00: error: { ABRT }
ata4: hard resetting link
ata4: nv: skipping hardreset on occupied port
ata4: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
ata4.00: configured for UDMA/133
ata4: EH complete
カーネルが実際にどのハードドライブを参照しているかをどのように確認できますかata4.00
?
その/dev/sdY
デバイス名を見つけるには?
答え1
対応する/ dev / sdYデバイスはツリーを参照して見つけることができます/sys
。
$ find /sys/devices | grep '/ata[0-9]\+/.*/block/s[^/]\+$' \
| sed 's@^.\+/\(ata[0-9]\+\)/.\+/block/\(.\+\)$@\1 => /dev/\2@'
より効率的な/sys
巡回を通して(参照lsata.sh):
$ echo /sys/class/ata_port/ata*/../../host*/target*/*/block/s* | tr ' ' '\n' \
| awk -F/ '{printf("%s => /dev/%s\n", $5, $NF)}'
2ディスクシステムのサンプル出力:
ata1 => /dev/sda
ata2 => /dev/sdb
その後、物理ハードウェアを確実に識別するには、/ dev / sdYをシリアル番号にマップする必要があります。例:
$ ls /dev/disk/by-id -l | grep 'ata.*sd[a-zA-Z]$'
LSSCI
このlssci
ユーティリティは、マッピングのエクスポートにも使用できます。
$ lsscsi | sed 's@^\[\([^:]\+\).\+\(/dev/.\+\)$@\1,\2@' \
| awk -F, '{ printf("ata%d => %s\n", $1+1, $2) }'
関連するlsscsi列挙は0から始まり、ata列挙は0から始まります。
システムログ
他の方法がない場合は、システムログ/ログを確認してマッピングをエクスポートできます。
デバイスは、/dev/sdY
ataX識別子がリストされている順序と同じ順序で作成され、kern.log
非ディスクデバイス(ATAPI)と未接続リンクは無視されます。
したがって、次のコマンドはマッピングを表示します。
$ grep '^May 28 2' /var/log/kern.log.0 | \
grep 'ata[0-9]\+.[0-9][0-9]: ATA-' | \
sed 's/^.*\] ata//' | \
sort -n | sed 's/:.*//' | \
awk ' { a="ata" $1; printf("%10s is /dev/sd%c\n", a, 96+NR); }'
ata1.00 is /dev/sda
ata3.00 is /dev/sdb
ata5.00 is /dev/sdc
ata7.00 is /dev/sdd
ata8.00 is /dev/sde
ata10.00 is /dev/sdf
(上記のログメッセージは他のシステムで発生したものなので、ata4は表示されません。)
スタートメッセージが循環したため、/var/log/kern.log.0
代わりに使用しています。これが最後のブート時間であり、前のメッセージを無視したいので、/var/log/kern.log
grepを実行します。May 28 2
マッピングを確認するには、次の出力を表示していくつかのチェックを実行できます。
$ grep '^May 28 2' /var/log/kern.log.0 | \
grep 'ata[0-9]\+.[0-9][0-9]: ATA-'
May 28 20:43:26 hn kernel: [ 1.260488] ata1.00: ATA-7: SAMSUNG SV0802N, max UDMA/100
May 28 20:43:26 hn kernel: [ 1.676400] ata5.00: ATA-5: ST380021A, 3.19, max UDMA/10
[..]
この出力を次の出力とhdparm
比較できます。
$ hdparm -i /dev/sda
/dev/sda:
Model=SAMSUNG SV0802N [..]
(カーネル2.6.32-31を使用)
答え2
これは上記で修正された私のバージョンです。システムが開始された正確な日付(テストの場合は27日前)がわからず、どのkern.logに必要なデータが含まれているか(一部はgzipped
私のシステムに存在する可能性があります)、わからないので、次のように使用してuptime
計算date
します。おおよそのシステム開始日(とにかく現在の日付まで)は、zgrep
使用可能なすべてのkern.logファイルを検索するために使用されます。
また、2番目のgrep
説明ではATA-*ドライブだけでなく、ATAPI CD/DVDドライブも表示されるので、少し修正しました。
それでも改善が可能ですが(つまり、システムの稼働時間が1年以上の場合)、現在はうまく機能します。
#!/bin/bash
uptime=$(uptime | awk -F' ' '{ print $3" "$4 }' | sed s/,//)
date=$(date -d "$uptime ago" | awk '{print $2" "$3 }')
zgrep "$date" /var/log/kern.log* | \
grep 'ata[0-9]\+.[0-9][0-9]: ATA' | \
sed 's/^.*\] ata//' | \
sort -n | sed 's/:.*//' | \
awk ' { a="ata" $1; printf("%10s is /dev/sd%c\n", a, 96+NR); }'
答え3
同じ問題が発生し、目的の別の解決策を見つけました。
lsscsiツールは、SCSIデバイス(またはホスト)とその属性を一覧表示します。
lsscsi を使用して ata 名とデバイス名を取得します。
次のようになります。
$ lsscsi --long
[0:0:1:0] cd/dvd MATSHITA DVD-ROM UJDA780 1.50 /dev/sr0
state=running queue_depth=1 scsi_level=6 type=5 device_blocked=0 timeout=30
[2:0:0:0] disk ATA WDC WD3000FYYZ-0 01.0 /dev/sda
state=running queue_depth=1 scsi_level=6 type=0 device_blocked=0 timeout=30
[3:0:0:0] disk ATA WDC WD1002FBYS-0 03.0 /dev/sdb
state=running queue_depth=1 scsi_level=6 type=0 device_blocked=0 timeout=30
[4:0:0:0] disk ATA WDC WD1002FBYS-0 03.0 /dev/sdc
state=running queue_depth=1 scsi_level=6 type=0 device_blocked=0 timeout=30
[5:0:0:0] disk ATA WDC WD1002FBYS-0 03.0 /dev/sdd
state=running queue_depth=1 scsi_level=6 type=0 device_blocked=0 timeout=30
[6:0:0:0] disk ATA WDC WD3000FYYZ-0 01.0 /dev/sde
state=running queue_depth=1 scsi_level=6 type=0 device_blocked=0 timeout=30
[7:0:0:0] disk ATA WDC WD1002FBYS-0 03.0 /dev/sdf
state=running queue_depth=1 scsi_level=6 type=0 device_blocked=0 timeout=30
Ubuntuでは、単にlsscsiをインストールできます。
$ sudo apt-get install lsscsi
答え4
上記の答えのどれも私には役に立ちませんでしたが、lsscsiメソッドは実際にSCSIバス番号とATA番号の違いによって誤った答えを生成しました。 21台のディスクシステムでATA18の問題(HSM違反)に関する多くのsyslogレポートを受け取りました。これらのエラーを引き起こすディスクは何ですか?一部はUSBドライブなので、状況はさらに混乱します。各SCSIドライブがシステムにどのように接続されているかを計算する必要があります。 ATA、USB、またはすべてのSCSIディスク(/ dev / s [dr]?)のテーブル形式のリストを生成するために、次のスクリプトを作成しました。
その後、すべてのディスクドライブを念頭に置いて、私のATAエラーが次のように関連していることに驚きました。どの私のディスクドライブ。私は間違った質問をしてきたし、他の人も同じ落とし穴に陥りやすいと思うので、ここで言及します。次に、2番目の方法を使用して、HSM違反メッセージを生成したハードウェアを識別しました。この内容は、以下のスクリプトに表示されるドキュメントにも詳しく説明されています。
#!/bin/bash
## This script lists the ata and usb bus numbers, as well as the
## overall "host" numbers, of each scsi disk. The same information
## appears formatted four ways, redundantly, for ease of lookup by (1)
## device lettername, (2) ata bus, (3) usb bus, or (4) overall "host"
## number.
#######################################################
## Q: What if you're looking for an ATA bus number, e.g. ata18, that
## isn't listed by this script?
## (1) Well, it's probably not a SCSI disk, at least not one that's
## operating.
## (2) Somewhere in /sys you can find a mapping from the ATA bus
## number to some overall host number, such as host17. For example,
## if you're looking for ata18, you can use a find command...
## find /sys -type l -exec bash -c 'link=`readlink "$0"`; if [[ "$link" =~ /ata18/ ]] ; then echo $link ; fi' {} \;
## ...which, after some delay, might yield output something like this:
## ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/ata_port/ata18
## ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/scsi_generic/sg5
## ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/link18/dev18.0/ata_device/dev18.0
## ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/scsi_host/host17
## ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/link18/ata_link/link18
## ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/bsg/17:0:0:0
## ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/scsi_device/17:0:0:0
## ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/scsi_generic/sg5
## ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/bsg/17:0:0:0
## ../../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0
## ../../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17
## ../../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0
## Then you might notice the "/host17/" or "scsi_device/17:0:0:0"
## in the above output lines, and look in the output of...
## lshw
## .. for "scsi17" or "17:0" or such, and discover, somewhere in it ...
## ...
## *-scsi:5
## physical id: 8
## logical name: scsi17
## capabilities: emulated
## *-processor UNCLAIMED
## description: SCSI Processor
## product: 91xx Config
## vendor: Marvell
## physical id: 0.0.0
## bus info: scsi@17:0.0.0
## version: 1.01
## capabilities: removable
## configuration: ansiversion=5
## ...
## ...thus learning that ata18 corresponds to an unclaimed device (but
## not actually a disk). Q.E.D.
## P.S. the lsscsi command yields the following, which might lead
## one to think that the problem was being caused by a CD-ROM drive
## (SCSI18:0) rather than emanating from the Marvell (SCSI17:0):
## [17:0:0:0] process Marvell 91xx Config 1.01 -
## [18:0:0:0] cd/dvd HL-DT-ST DVDRAM GH22NS90 HN00 /dev/sr0
## ... but ATA != SCSI, and 17 != 18. The CD/DVD drive was ATA19,
## actually. You can still use lsscsi, but
## bear in mind that what you're seeing in the left column
## is *not* ATA numbers but rather SCSI bus numbers, and the two
## are not to be confused.
#######################################################
blockDevsDir=/sys/dev/block
declare -A scsiDevLetters
declare -A hostNumbers
declare -A ataNumbers
declare -A usbNumbers
scsiDevLetterRE='/s(d[a-z]|r[0-9])$'
hostNumberRE='/host([0-9]+)/'
ataNumberRE='/ata([0-9]+)/'
usbNumberRE='/usb([0-9]+)/'
cd "$blockDevsDir"
for busid in `ls -1` ; do
linkval=`readlink "$busid" `
if [[ "$linkval" =~ $scsiDevLetterRE ]] ; then
scsiDevLetter="${BASH_REMATCH[1]}"
if [[ "$linkval" =~ $hostNumberRE ]] ; then
hostNumber="${BASH_REMATCH[1]}"
if [[ "$linkval" =~ $ataNumberRE ]] ; then
ataNumber="${BASH_REMATCH[1]}"
scsiDevLetters[$scsiDevLetter]=`printf 'ata%-2.2s host%-2.2s' "${ataNumber}" "${hostNumber}"`
hostNumbers[${hostNumber}]=`printf '/dev/sd%s ata%-2.2s' "${scsiDevLetter}" "${ataNumber}"`
ataNumbers[${ataNumber}]=`printf '/dev/sd%s host%-2.2s' "${scsiDevLetter}" "${hostNumber}"`
elif [[ "$linkval" =~ $usbNumberRE ]] ; then
usbNumber="${BASH_REMATCH[1]}"
scsiDevLetters[$scsiDevLetter]=`printf 'usb%-2.2s host%-2.2s' "${usbNumber}" "${hostNumber}"`
hostNumbers[${hostNumber}]=`printf '/dev/sd%s usb%-2.2s' "${scsiDevLetter}" "${usbNumber}"`
existingUsbValue="${usbNumbers[${usbNumber}]}"
addedUsbValue=`printf '/dev/sd%s host%-2.2s' "${scsiDevLetter}" "${hostNumber}"`
if [ -n "$existingUsbValue" ] ; then
usbNumbers[${usbNumber}]="$existingUsbValue | $addedUsbValue"
else
usbNumbers[${usbNumber}]="$addedUsbValue"
fi
else
echo "Neither ata nor usb: /dev/sd${scsiDevLetter} (host${hostNumber}) !"
fi
else
echo "No host number for /dev/sd${scsiDevLetter}"
fi
fi
done
echo '/dev/sd?'
echo '--------'
for scsiDevLetter in `echo "${!scsiDevLetters[*]}" | tr ' ' '\n' | sort` ; do
echo "/dev/sd${scsiDevLetter} ${scsiDevLetters[$scsiDevLetter]}"
done
echo
echo 'ataNN'
echo '-----'
for ataNumber in `echo "${!ataNumbers[*]}" | tr ' ' '\n' | sort -n` ; do
printf 'ata%-2.2s %s\n' "$ataNumber" "${ataNumbers[$ataNumber]}"
done
echo
echo 'usbNN'
echo '-----'
for usbNumber in `echo "${!usbNumbers[*]}" | tr ' ' '\n' | sort -n` ; do
printf 'usb%-2.2s %s\n' "$usbNumber" "${usbNumbers[$usbNumber]}"
done
echo
echo 'hostNN'
echo '------'
for hostNumber in `echo "${!hostNumbers[*]}" | tr ' ' '\n' | sort -n` ; do
printf 'host%-2.2s %s\n' "$hostNumber" "${hostNumbers[$hostNumber]}"
done