kern.log 오류 메시지의 ataX.0 식별자를 실제 /dev/sdY 장치에 어떻게 매핑합니까?

kern.log 오류 메시지의 ataX.0 식별자를 실제 /dev/sdY 장치에 어떻게 매핑합니까?

다음 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/sdYataX 식별자가 열거되는 순서와 동일한 순서로 생성되며 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.loggrep을 수행합니다 .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 파일을 검색하는 데 사용됩니다.

또한 이제 두 번째 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 오류가 다음과 관련이 있다는 사실에 놀랐습니다.어느내 디스크 드라이브. 나는 잘못된 질문을 해왔고 다른 사람들도 같은 함정에 빠지기 쉽다고 생각하므로 여기서 언급합니다. 그런 다음 두 번째 방법을 사용하여 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

관련 정보