Khi hộp Linux gặp lỗi ATA, nó sẽ ghi lại thông báo xác định đĩa là "ata% d.00". Làm cách nào để dịch nó sang tên thiết bị (ví dụ /dev/sdb
)? Tôi cảm thấy như thế này là tầm thường, nhưng tôi không thể tìm ra nó.
Khi hộp Linux gặp lỗi ATA, nó sẽ ghi lại thông báo xác định đĩa là "ata% d.00". Làm cách nào để dịch nó sang tên thiết bị (ví dụ /dev/sdb
)? Tôi cảm thấy như thế này là tầm thường, nhưng tôi không thể tìm ra nó.
Câu trả lời:
Peter đã truyền cảm hứng cho tôi để viết một kịch bản nâng cao (cho phép), thậm chí có thể phát hiện ra các thanh USB (thay vì xuất ra những thứ ngớ ngẩn như "ata0.00"). Ngược lại với tập lệnh của Peter, bạn cũng sẽ nhận được số phụ (như trong 4.01) nếu bạn có nhiều hơn một thiết bị ở cùng một bộ điều khiển. kênh. Đầu ra sẽ chính xác như bạn nhận được syslog
. Thử nghiệm. Hoạt động rất tốt trên hộp Debian của tôi, mặc dù luôn có rất nhiều cải tiến (ví dụ: các biểu thức quá vụng về). Nhưng GIỮ NÓ! Số lượng nhân vật thoát được dường như quá cao mà bạn có thể tìm thấy trong biểu thức chính tả của tôi chỉ vì lý do tương thích! Bạn không thể giả sử GNU sed
với mọi người, đó là lý do tại sao tôi đã làm mà không có mục đích mở rộng.
CẬP NHẬT
(1) Sẽ không còn phân tích ls
đầu ra. (Rất tiếc!) Vì tất cả các bạn đều biết: Đừng phân tích ls.
(2) Bây giờ cũng hoạt động trên môi trường chỉ đọc.
(3) Lấy cảm hứng từ một gợi ý từ cuộc trò chuyện này ở đây, tôi đã quản lý để một lần nữa nhận được các tuyên bố sed ít phức tạp hơn.
#!/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"
Nhìn vào /proc/scsi/scsi
, nó sẽ trông giống như thế này:
$ 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 là sda và ata1.00, scsi1 id 0 là sdb và ata2.00, v.v.
Cũng nhìn vào /var/log/dmesg
, cho thấy thông tin tải trình điều khiển ata và sẽ làm cho mọi thứ rõ ràng hơn một chút. Tìm dòng bắt đầu "libata".
Tôi thích scriptlets thay vì giải thích lenghty. Điều này hoạt động trên hộp Ubuntu của tôi. Thêm ý kiến theo ý thích của bạn:
# 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
ls -l /sys/block/sd* | sed -e 's@.*-> \.\..*/ata@/ata@' -e 's@/host@ @' -e 's@/target.*/@ @'
Điều này thực sự khá khó khăn. Mặc dù an toàn khi cho rằng "ID scsi" là "ID ID trừ đi một", tôi thích thực sự an toàn và kiểm tra cái unique_id
mà tôi giả sử (dựa trên bài đăng này ) là định danh SATA.
Lỗi của tôi là:
[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
Vì vậy, thủ tục của tôi để tìm hiểu những gì ata4
là:
tìm id PCI của bộ điều khiển SATA
# lspci | grep -i sata
00:1f.2 SATA controller: Intel Corporation 631xESB/632xESB SATA AHCI Controller (rev 09)
tìm ID duy nhất phù hợp:
# 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
vì vậy nó là scsi_host/host3
cái mà chúng ta có thể dịch sang 3:x:x:x
, cái mà chúng ta có thể grep dmesg
để tìm hiểu thêm:
# 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
Đây là thiết bị của chúng tôi, chúng tôi có thể (tùy chọn) tìm số sê-ri để đưa thiết bị đó ra khỏi đó (hoặc kiểm tra hệ thống cáp hoặc bất cứ thứ gì) trước khi mảng RAID của chúng tôi hoàn toàn thất bại:
# hdparm -i /dev/sdd | grep Serial
Model=ST3250310NS, FwRev=SN06, SerialNo=9SF19GYA
Và bạn đã hoàn thành!
Thử đi:
# find -L /sys/bus/pci/devices/*/ata*/host*/target* -maxdepth 3 -name "sd*" 2>/dev/null | egrep block |egrep --colour '(ata[0-9]*)|(sd.*)'
Tôi chưa bao giờ hiểu dmesg - một số hàng nói về "ata4" một số hàng khác về "scsi" hoặc sdc, nhưng không ai gán "ata4 .. sdc" lệnh hiển thị tìm thấy / sys / bus / path, trong đó cả ata4 và sdc Được xác định.
Tôi có cùng một vấn đề và có thể xác định các ổ đĩa bằng cách kiểm tra dmesg. Ở đó bạn có thể thấy định danh bộ điều khiển (thuật ngữ chính xác ??) và mô hình của đĩa. Sau đó sử dụng ls -l / dev / đĩa / by-id để khớp số mô hình với / dev / sda (hoặc bất cứ điều gì). Ngoài ra, tôi thích Disk Utility cho thông tin này. Lưu ý: điều này chỉ hoạt động nếu các đĩa của bạn có số mô hình khác nhau, nếu không bạn không thể phân biệt giữa hai.
>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
Cách dễ nhất là xem lại nhật ký kernel từ boot, vì tên thiết bị ổ đĩa được trộn từ nhiều nguồn khác nhau (ví dụ: ổ USB) hoặc được chỉ định dựa trên loại thiết bị (ví dụ: cdrom có thể là scdX và mọi thứ đều có sgX ). Trong thực tế, trừ khi bạn đã trộn lẫn các loại xe buýt khác nhau (ví dụ: SATA + USB), thiết bị ata được đánh số thấp nhất sẽ là sda trừ khi đó là thiết bị cdrom.
Tùy thuộc vào hệ thống của bạn, nó có thể được đoán bằng cách đi lang thang xung quanh sysfs. Trên hệ thống của tôi ls -l /sys/dev/block
cho thấy rằng 8:0
(chính: phụ từ / dev entry) trỏ đến /sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
Tương tự, ls -l /sys/class/ata_port
cho thấy ata1
các điểm /sys/devices/pci0000:00/0000:00:1f.2/ata1/ata_port/ata1
trên cùng một thiết bị phụ PCI.
Vì tôi sử dụng SATA và chỉ có một ổ đĩa trên mỗi cổng nên tôi có thể suy ra rằng ata1.00 = sda. Tất cả các ổ đĩa của tôi là 0,00, tôi nghi ngờ rằng nếu tôi sử dụng hệ số nhân cổng, các ổ đĩa của tôi sẽ được cung cấp .01, .02, .03, v.v. Nhìn vào nhật ký của người khác, bộ điều khiển PATA sử dụng 0,00 và 0,01 cho chủ và nô lệ và dựa trên nhật ký của họ nếu bạn có ataX.01, .01 sẽ được ánh xạ tới "ID" trong máy chủ: channel: ID: LUN từ /sys/dev/block/
danh sách. Nếu bạn có nhiều ataX/
và hostY/
thư mục trong cùng một thư mục thiết bị PCI, thì tôi nghi ngờ rằng thư mục ataX được đánh số thấp nhất khớp với thư mục hostY được đánh số thấp nhất.
Trong /sys/class/ata_port/ata${n}/device/
, bạn có thể thấy một host${x}
thư mục. Ví dụ, trên máy của tôi:
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
Các ${x}
trong host${x}
đề cập đến số đầu tiên trong [0:0:0:0]
. Vì vậy, đối với tôi ata1
đề cập đến host0
cũng có thể được biểu diễn dưới dạng SCSI như 0:*
:
gibby ~ # lsscsi 0:\*
[0:0:0:0] disk ATA WDC WD1002FAEX-0 1D05 /dev/sda
Kịch bản dưới đây sẽ cung cấp cho bạn một bản tóm tắt hay như thế này:
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
Vì vậy, trong một dòng cho mỗi ổ đĩa bạn có sdX tên thiết bị, kích thước , mô hình , s / n và pci và ata số. Các sdc ở trên lõi đến đầu đọc thẻ USB SD không có thẻ được lắp vào. Do đó ---- thay cho thông tin thực sự.
#!/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
(chỉ được thử nghiệm trên Ubuntu 12.04 / 14.04 và CentOS 6)
Có thể tìm thấy tập lệnh để tìm thông tin này và hơn thế nữa tại https://www.av8n.com/computer/disk-hw-host-bus-id
Nó tương tự như kịch bản được cung cấp bởi ông Syntaxerror, nhưng fancier. - Nó hoạt động cho các ổ USB cũng như ổ ATA. - Nó cung cấp ổ đĩa tạo và mô hình và số sê-ri, - và tất nhiên là điểm đính kèm. - Nó đơn giản hơn, dễ đọc và dễ bảo trì hơn.