Làm cách nào để ánh xạ định danh ataX.0 trong thông báo lỗi kern.log sang thiết bị thực tế / dev / sdY?


11

Xem xét kern.logđoạn trích sau :

 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

Làm thế nào tôi có thể xác định được ổ cứng mà hạt nhân thực sự có nghĩa là gì khi nó nói về ata4.00?

Làm thế nào tôi có thể tìm thấy /dev/sdYtên thiết bị tương ứng ?

Câu trả lời:


10

Bạn có thể tìm thấy thiết bị / dev / sdY tương ứng thông qua di chuyển qua /syscây:

$ find /sys/devices | grep '/ata[0-9]\+/.*/block/s[^/]\+$' \
    | sed 's@^.\+/\(ata[0-9]\+\)/.\+/block/\(.\+\)$@\1 => /dev/\2@'

Với một giao dịch hiệu quả hơn /sys(xem lsata.sh ):

$ echo /sys/class/ata_port/ata*/../../host*/target*/*/block/s* | tr ' ' '\n' \
    | awk -F/ '{printf("%s => /dev/%s\n", $5, $NF)}'

Ví dụ đầu ra từ hệ thống 2 đĩa:

ata1 => /dev/sda
ata2 => /dev/sdb

Sau đó, để xác định đáng tin cậy phần cứng thực tế, bạn cần ánh xạ / dev / sdY đến số sê-ri, ví dụ:

$ ls /dev/disk/by-id -l | grep 'ata.*sd[a-zA-Z]$'

lssci

Các lsscitiện ích cũng có thể được sử dụng để lấy các bản đồ:

$ lsscsi | sed 's@^\[\([^:]\+\).\+\(/dev/.\+\)$@\1,\2@' \
    | awk -F, '{ printf("ata%d => %s\n", $1+1, $2) }'

Lưu ý rằng phép liệt kê lsscsi có liên quan bắt đầu từ 0 trong khi phép liệt kê ata bắt đầu từ 0.

Nhật ký hệ thống

Nếu không có gì khác hoạt động, người ta có thể nhìn vào nhật ký / nhật ký để lấy bản đồ.

Các /dev/sdYthiết bị được tạo theo cùng thứ tự với số nhận dạng ataX được liệt kê trong kern.logkhi bỏ qua các thiết bị không phải đĩa (ATAPI) và các liên kết không được kết nối.

Do đó, lệnh sau sẽ hiển thị ánh xạ:

$ 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

(Lưu ý rằng ata4 không được hiển thị vì các thông báo nhật ký ở trên là từ một hệ thống khác.)

Tôi đang sử dụng /var/log/kern.log.0và không phải /var/log/kern.logvì các thông điệp khởi động đã được xoay. Tôi grep May 28 2vì đây là lần khởi động cuối cùng và tôi muốn bỏ qua các tin nhắn trước đó.

Để xác minh ánh xạ, bạn có thể thực hiện một số kiểm tra thông qua việc nhìn vào đầu ra của:

$ 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
[..]

Và bạn có thể so sánh đầu ra này với hdparmđầu ra, ví dụ:

$ hdparm -i /dev/sda

/dev/sda:

Model=SAMSUNG SV0802N [..]

(sử dụng hạt nhân 2.6.32-31)


Điều này thật tuyệt vời, cảm ơn bạn rất nhiều vì câu trả lời tuyệt vời này ...
stuartc

@stuarte, bạn được chào đón - btw, cks đã viết một bài về tất cả các sơ đồ đặt tên khác nhau của các thiết bị SATA trên các hệ thống Linux hiện tại . Về định danh ataX, ông viết: 'Những cái tên này hoàn toàn không xuất hiện trong các sysfs như tôi có thể thấy'
maxschlepzig

1
Hừm. Vấn đề của tôi với hoạt động xác minh của điều này là tôi thường có hơn 8 đĩa cùng một mô hình để kiểm tra nhà sản xuất không có giá trị.
drescherjm

1
@drescherjm, tôi đã cập nhật câu trả lời của mình. Phương pháp mới phải mạnh mẽ và do đó loại bỏ mọi nhu cầu kiểm tra nhà cung cấp.
maxschlepzig

Tôi có những gì tôi nghĩ là một kịch bản sysfs được cải thiện; đặc biệt, nó xử lý các số ata hai chữ số (/ ata [0-9] / sẽ không khớp với ata10) và cũng tìm thấy các thiết bị sata không được đặt tên là sd * (ví dụ: sr0): cho một / sys / class / ata_port / ata * ; làm printf '% s \ t% s \ n' "$ (tên cơ sở" $ a ")" "$ (tìm" $ a / device / "-iname 'block' -exec ls {} \;)"; xong
Jason

2

Đây là phiên bản của tôi, được sửa đổi từ trên. Vì tôi không biết chính xác ngày hệ thống được khởi động (để kiểm tra nó là 27 ngày trước) và tôi không biết kern.log nào chứa dữ liệu tôi cần (một số có thể có gzippedtrên hệ thống của tôi), tôi sử dụng uptimedateđể tính ngày khởi động hệ thống gần đúng (dù sao cũng là ngày), sau đó sử dụng zgrepđể tìm kiếm trong tất cả các tệp kern.log có sẵn.

Tôi cũng đã sửa đổi một chút greptuyên bố thứ hai , vì bây giờ nó cũng sẽ hiển thị ổ đĩa CD / DVD ATAPI cũng như các ổ đĩa ATA- *.

Nó vẫn có thể sử dụng sàng lọc (tức là nếu thời gian hoạt động của hệ thống lớn hơn một năm), nhưng bây giờ sẽ hoạt động tốt.

#!/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

Chỉ có vấn đề tương tự và tìm thấy một giải pháp khác mà người ta có thể thích.

Công cụ lsscsi liệt kê các thiết bị SCSI (hoặc máy chủ) và thuộc tính của chúng.

Với lsscsi người ta có được tên ata và tên thiết bị.

Trông như thế này:

$ 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

Trên Ubuntu người ta có thể cài đặt lsscsi đơn giản với

$ sudo apt-get install lsscsi

2
hm, và làm thế nào để ataXánh xạ tới phần nào trong lsscsiđầu ra?
maxschlepzig

1
@maxschlepzig Số đầu tiên trong: quads giống như ataX với một điểm khác biệt quan trọng; đầu ra của lsscsi là 0-index và ataZ là 1-index; vì vậy [2: 0: 0: 0] sẽ là ata3, đó là / dev / sda trong sản phẩm mà giấc ngủ dài được đăng
Jason

@Jason, ok, đây là một lớp lót:lsscsi | sed 's@^\[\([^:]\+\).\+\(/dev/.\+\)$@\1,\2@' | awk -F, '{ printf("ata%d => %s\n", $1+1, $2) }'
maxschlepzig

@Jason, xem thêm câu trả lời cập nhật của tôi để biết cách thay thế trực tiếp truy cập /sys/devicesmà không cần lsscsi.
maxschlepzig

0

Không có câu trả lời nào ở trên làm việc cho tôi và cách tiếp cận lsscsi thực sự mang lại câu trả lời sai, do sự khác biệt giữa số bus SCSI và số ATA. Trên hệ thống 21 đĩa, tôi đã có nhiều báo cáo nhật ký hệ thống về các vấn đề với ATA18 (vi phạm HSM). Đĩa nào gây ra những lỗi này? Một số là ổ đĩa USB, khiến mọi thứ trở nên khó hiểu hơn. Tôi cần một kế toán về cách mỗi ổ đĩa SCSI được gắn vào hệ thống và tôi đã viết tập lệnh bên dưới để đưa ra danh sách dạng bảng cho tất cả các đĩa SCSI (/ dev / s [dr]?) Bất kể ATA hay USB.

Sau đó, với tất cả các ổ đĩa được hạch toán đầy đủ, tôi rất ngạc nhiên khi thấy rằng các lỗi ATA của tôi không liên quan gì đến bất kỳ ổ đĩa nào của tôi. Tôi đã hỏi sai câu hỏi và tôi nghĩ những người khác có thể dễ dàng rơi vào cùng một cái bẫy, đó là lý do tại sao tôi đề cập đến nó ở đây. Sau đó, tôi đã sử dụng cách tiếp cận thứ hai xác định phần cứng đang tạo ra các thông báo vi phạm HSM, cũng được nêu chi tiết trong tài liệu xuất hiện trong tập lệnh bên dưới.

#!/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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.