kern.log 오류 메시지의 ataX.0 식별자를 실제 / dev / sdY 장치에 매핑하는 방법은 무엇입니까?


11

다음 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장치 이름을 어떻게 찾을 수 있습니까?

답변:


11

/sys트리 를 탐색하여 해당 / dev / sdY 장치를 찾을 수 있습니다 .

$ 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에서 시작합니다.

Syslog

아무것도 작동하지 않으면 syslog / journal을보고 매핑을 파생시킬 수 있습니다.

/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.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 사용)


이것은 정말 대단합니다.이 훌륭한 답장을
보내

@stuarte, 당신은 환영합니다-btw, cks현재 Linux 시스템에서 SATA 장치의 모든 다른 명명 체계에 대한 글을 썼습니다 . ataX 식별자를 그가 쓰기에 관한 '이 이름은 최대한 멀리 볼 수 전혀 sysfs에 나타나지 않습니다'
maxschlepzig

1
흠. 이것의 검증 작업에 대한 내 문제는 일반적으로 정확히 동일한 모델의 8 개 이상의 디스크가 있으므로 제조업체 검사가 그렇게 중요하지 않다는 것입니다.
drescherjm

1
@ drescherjm, 나는 대답을 업데이트했습니다. 새로운 방법은 강력해야하므로 공급 업체 확인이 필요 없습니다.
maxschlepzig 13:14에

개선 된 sysfs 스크립트라고 생각합니다. 특히 두 자리 숫자 ata 번호 (/ ata [0-9] / ata10과 일치하지 않음)를 처리하고 sd * (예 : sr0)가 아닌 sata 장치를 찾습니다. / sys / class / ata_port / ata * ; printf '% s \ t % s \ n' "$ (기본 이름"$ a ")" "$ ("$ a / device / "-iname 'block'-exec ls {} \;)"; 완료
Jason

2

여기 위에서 수정 한 내 버전이 있습니다. 시스템이 부팅 된 정확한 날짜를 알지 못하기 때문에 (27 일 전에 테스트 했으므로) 어떤 kern.log에 필요한 데이터가 포함되어 있는지 (일부는 gzipped시스템에 있을 수 있음) 알지 못합니다. uptimedate(어쨌든, 하루) 대략적인 시스템 부팅 날짜를 계산하기 위해, 다음 사용 zgrep가능한 모든 kern.log 파일을 검색 할 수 있습니다.

또한 grepATAPI CD / DVD 드라이브와 ATA- * 드라이브도 표시하므로 두 번째 구문 도 약간 수정했습니다 .

여전히 구체화를 사용할 수 있지만 (즉, 시스템 가동 시간이 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); }'

1

이 같은 문제가 있었고 다른 솔루션을 찾았습니다.

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

우분투에서 간단하게 lsscsi를 설치할 수 있습니다

$ sudo apt-get install lsscsi

2
흠, 그리고 출력 ataX에서 어떤 부분으로 매핑 lsscsi합니까?
maxschlepzig

1
@maxschlepzig : quads의 첫 번째 숫자는 ataX와 동일하지만 한 가지 중요한 차이점이 있습니다. lsscsi의 출력은 0 인덱싱되고 ataZ는 1 인덱싱됩니다. 그래서 [2 : 0 : 0 : 0]은 ata3이됩니다. 이것은 longsleep이 게시 한 출력에서 ​​/ dev / sda입니다
Jason

좋아, @ 제이슨, 여기에 한 줄은 다음과 같습니다lsscsi | sed 's@^\[\([^:]\+\).\+\(/dev/.\+\)$@\1,\2@' | awk -F, '{ printf("ata%d => %s\n", $1+1, $2) }'
maxschlepzig

@Jason, 님 /sys/devices없이 직접 액세스하는 대안에 대한 업데이트 된 답변을 참조하십시오 lsscsi.
maxschlepzig 13:14에

0

위의 답변 중 어느 것도 나를 위해 효과가 없었으며 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.