Megaraid 磁盤定位

原文地址: https://www.tony-yin.site/201...

mega drive

早前寫過一篇【利用Raid卡工具獲取邏輯盤是否爲SSD】的文章,大概講述瞭如何經過raid卡工具判斷一個邏輯磁盤對應物理磁盤是否爲SSD,當時主要提到了megaclisas3ircu這兩種工具,核心是如何經過raid卡工具定位到邏輯磁盤對應的物理磁盤的位置,當時的方式如今看來在有些場景會存在缺陷。php

當時的方案主要是先經過lspci獲取raid卡型號,而後找到對應的raid卡型號,緊接着經過lsscsi命令獲取邏輯磁盤的targetid,再經過raid卡工具根據targetid定位到對應的物理盤。當時的方案在多controller的場景下存在問題,可能會出現重複target id的狀況,因此這時候只能再借助controller id來定位惟一的磁盤了。總而言之,想真正定位邏輯磁盤對應的物理磁盤,就必需要獲取到磁盤的controller idenclosure idslot number,有了這三個參數,即可以獲取該磁盤的信息,或者對該物理磁盤進行點燈、響音和作raid等操做。linux

那麼,具體如何定位邏輯磁盤的物理位置呢?且看下文分析ios

獲取 raid 卡信息

經過lspci命令能夠獲取到操做系統上全部raid卡信息,咱們能夠看到每一個raid卡最前面都有一串數字,好比第一行是02:00.0,第二行是03:00.0,這裏的0203表示的是raid卡的busid,即raid卡控制器在pci總線上的idgit

[root@tony ~]# lspci | grep "LSI Logic"
02:00.0 RAID bus controller: LSI Logic / Symbios Logic MegaRAID SAS-3 3008 [Fury] (rev 02)
03:00.0 RAID bus controller: LSI Logic / Symbios Logic MegaRAID SAS-3 3108 [Invader] (rev 02)

獲取磁盤 pcipath

linux中,一切皆文件,每一個文件都有本身的惟一標識,對於磁盤而言,pcipath就是它的惟一標識,pci總線上面有不少控制器,好比scsi控制器,而磁盤又存在於scsi控制器上,因此咱們能夠在lsscsi命令獲取到的scsi設備列表中查看到操做系統上的磁盤信息。github

sda爲例,咱們能夠在/dev/disk/by-path目錄下查看到磁盤的pcipathshell

[root@tony ~]# ll /dev/disk/by-path/
total 4
lrwxrwxrwx 1 root root   9 May 11 10:30 pci-0000:02:00.0-scsi-0:2:0:0 -> ../../sda
lrwxrwxrwx 1 root root  10 May 11 10:30 pci-0000:02:00.0-scsi-0:2:0:0-part1 -> ../../sda1
lrwxrwxrwx 1 root root  10 May 11 10:30 pci-0000:02:00.0-scsi-0:2:0:0-part2 -> ../../sda2
lrwxrwxrwx 1 root root   9 May 11 16:22 pci-0000:02:00.0-scsi-0:2:1:0 -> ../../sdb
lrwxrwxrwx 1 root root   9 May 11 16:22 pci-0000:02:00.0-scsi-0:2:10:0 -> ../../sdk

因爲在linux中,udev是用戶態的設備管理,因此咱們也能夠經過udev獲取。框架

[root@tony ~]# udevadm info --query=symlink --name=sda
disk/by-id/scsi-36509a4c0ac86790022337b9105005435 disk/by-id/wwn-0x6509a4c0ac86790022337b9105005435 disk/by-path/pci-0000:02:00.0-scsi-0:2:0:0

這邊咱們能夠獲得磁盤sdapcipathpci-0000:02:00.0-scsi-0:2:0:002就是磁盤的raid卡的bus id,後面的00表示channel id,再後面的0:2:0:0就和lsscsi獲取的同樣了,其中2就表示target id工具

因此經過bud id,咱們能夠獲取到磁盤對應的raid卡型號,根據對應的raid卡工具操做磁盤。這邊咱們只討論megaraid,因此工具也就是megacli了。spa

獲取 controller id

上面咱們獲取到了磁盤的target id和對應raid卡的bus id,而對於megacli工具而言,每一個raid卡都有一個與之對應的controller操作系統

[root@tony ~]# /opt/MegaRAID/MegaCli/MegaCli64 -AdpGetPciInfo -aall -NoLog

PCI information for Controller 0
--------------------------------
Bus Number      : 2
Device Number   : 0
Function Number : 0

PCI information for Controller 1
--------------------------------
Bus Number      : 3
Device Number   : 0
Function Number : 0


Exit Code: 0x00

這邊咱們能夠看到megacli獲取到了兩個controller,也就對應上面lspci獲取到的兩張raid卡。細心的朋友能夠發現這邊有一個Bus Number,分別爲23,而咱們上面獲取到了raid卡的bus id分別爲0203,沒錯,這邊的Bus Numberbus id是對應的,只是Bus number沒有自動填補成兩位數,因此咱們能夠經過bus id獲得sda所對應的controller0

注意:
本來系統中版本 8.07.07megacli工具獲取 raid卡信息的時候會存在問題,每次 Bus Number都會變化,咱們只要升級 megacli便可,我這邊是把 megacli升級到了 8.07.14版本。

安裝包地址:https://github.com/tony-yin/M...

獲取磁盤組

此時,咱們擁有了controller id,能夠獲取該controller下全部的磁盤組信息。

[root@tony ~]# /opt/MegaRAID_new/MegaCli/MegaCli64  -LdPdInfo -a0 -NoLog
Adapter #0

Number of Virtual Disks: 13
Virtual Drive: 0 (Target Id: 0)
Name                :
RAID Level          : Primary-1, Secondary-0, RAID Level Qualifier-0
Size                : 558.375 GB
Sector Size         : 512
Is VD emulated      : No
Mirror Data         : 558.375 GB
State               : Optimal
Strip Size          : 64 KB
Number Of Drives    : 2
Span Depth          : 1
Default Cache Policy: WriteThrough, ReadAheadNone, Direct, No Write Cache if Bad BBU
Current Cache Policy: WriteThrough, ReadAheadNone, Direct, No Write Cache if Bad BBU
Default Access Policy: Read/Write
Current Access Policy: Read/Write
Disk Cache Policy   : Disk's Default
Encryption Type     : None
Default Power Savings Policy: Controller Defined
Current Power Savings Policy: None
Can spin up in 1 minute: Yes
LD has drives that support T10 power conditions: Yes
LD's IO profile supports MAX power savings with cached writes: No
Bad Blocks Exist: No
Is VD Cached: No
Number of Spans: 1
Span: 0 - Number of PDs: 2

PD: 0 Information
Enclosure Device ID: 32
Slot Number: 12
Drive's position: DiskGroup: 0, Span: 0, Arm: 0
Enclosure position: 1
Device Id: 12
WWN: 50000398181A974C
Sequence Number: 2
Media Error Count: 0
Other Error Count: 0
Predictive Failure Count: 0
Last Predictive Failure Event Seq Number: 0
PD Type: SAS
...
...

而後咱們能夠根據target id獲取對應的磁盤組信息,target id與上面的Target Id所對應,這樣咱們能夠過濾獲得惟一的磁盤組信息。這邊咱們能夠看到sda對應Target Id0的磁盤組,該raid類型爲raid1,虛擬磁盤組中有兩塊物理盤,而後咱們能夠獲取這兩塊物理盤的enclosure idslot number,這樣再加上前文的controller id,咱們就能夠完徹底全地定位到具體一塊磁盤的物理位置。

一鍵定位

針對這種需求,本人根據以上邏輯寫了一個簡單的腳本能夠一鍵獲取磁盤的定位。

[root@tony ~]# ./get_disk_location.py sda
['0:32:12', '0:32:13']

這邊0:32:12分別表示磁盤的controller idenclosure idslot number

完整代碼地址: https://github.com/tony-yin/M...

總結

以前的作法大部分場景可行,可是在一些場合偶爾會發現問題,總感受仍是不夠靠譜,身邊的人還有經過sdasdb這種排列順序來查找和megacli中顯示磁盤的對應關係的,就更不靠譜了。linux操做系統是能夠識別到具體硬件設備的,因此是確定存在方法識別硬件對應的邏輯設備的,本文經過pcipath獲取到設備的惟一標識,而後根據pcipath中的bus idmegacli中的cobtroller創建鏈接,最後經過target id鎖定惟一磁盤組中的磁盤信息。

經過這種方式,咱們不須要肉眼判斷,也不須要顧慮部分場景方案不適用,這徹底就是操做系統使用的方式,使用這種最基礎,最底層的方式實現,真是讓人豁然開朗。這跟看源碼相似,瞭解一個功能的背後具體實現,你才知道最正確的姿式,不用去碰,去湊,這種感受真好。

給你們推薦一本書《Linux設備驅動程序》,這本書詳細講解了linux中各類設備與驅動的細節,很底層也很枯燥,不過看完後應該會頗有收穫。但願你們在使用各類已有工具和框架的基礎上,多去了解背後的實現機制,這樣能夠幫助咱們更好地實現更深層次的需求。

Refer

  1. Persistent block device naming
  2. hwraid
  3. showtools
  4. Linux SCSI 子系統剖析
相關文章
相關標籤/搜索