Linux

如何將 SATA 設備名稱映射到 RAID 系統的物理 SATA 介面

  • September 6, 2020

我有一個帶有 10 個 SATA 埠的系統,另一個 SATA 作為啟動盤。10 個 SATA 埠組成 5 個軟體 RAID1 陣列。RAID 磁碟可以在引導之間被移除,並隨時與任意空白磁碟交換。

我需要確保它/dev/sda始終是的第一個物理 SATA 埠,並且/dev/sdj始終第十個,以便 RAID1 陣列正常執行。例如,如果第一個埠中的第一個磁碟發生故障,則應將其標記為失去磁碟,因此下一個埠中的磁碟應為/dev/sdb. 目前,下一個可用磁碟被掛載為/dev/sda——完全破壞我的陣列和我的引導配置。

想像一個可怕的場景,其中所有其他磁碟都發生故障,因此每個 RAID1 陣列在其對中只有一個工作磁碟。編號為:

  • /dev/sda
  • /dev/sdc
  • /dev/sde
  • /dev/sdg
  • /dev/sdi

不是:

  • /dev/sda
  • /dev/sdb
  • /dev/sdc
  • /dev/sdd
  • /dev/sde

我已經看到udev了通過 UUID 標記特定磁碟的規則,但是由於使用者將任意熱交換磁碟,這一點都不方便。

預設情況下,Linux 將使用下一個字母字元標記下一個可用磁碟。在許多情況下,單個損壞的磁碟會破壞多個 RAID 1 陣列。

  • 如何將設備映射到特定的硬體介面?這甚至可能嗎?
  • 是否有可能在啟動時出現“失去”設備,因此後續設備不會被錯誤標記?

Debian Wiki有一個很好的條目來描述我需要什麼。在此之後,我在 /etc/udev/rules.d/20-disk-bay.rules 下制定了自己的規則。我只包括了前兩個 sata 埠映射作為範例:

# There are different DEVPATHs for major kernel versions!
# Example for SATA N:
#
# Kernel < 3 DEVPATH
# *1f.2/hostN/targetN:0:0/N:0:0:0*
#
# Kernel > 3 DEVPATH
# *1f.2/ata(N+1)/host*

########## Map SATA 0 to /dev/sdb ##############

# Kernel < 3

KERNEL=="sd?", SUBSYSTEM=="block", DEVPATH=="*1f.2/host0/target0:0:0/0:0:0:0*", NAME="sdb", RUN+="/usr/bin/logger My disk ATTR{partition}=$ATTR{partition}, DEVPATH=$devpath, ID_PATH=$ENV{ID_PATH}, ID_SERIAL=$ENV{ID_SERIAL}", GOTO="END_20_PERSISTENT_DISK"

KERNEL=="sd?*", ATTR{partition}=="1", SUBSYSTEM=="block", DEVPATH=="*1f.2/host0/target0:0:0/0:0:0:0*", NAME="sdb%n", RUN+="/usr/bin/logger My partition parent=%p number=%n, ATTR{partition}=$ATTR{partition}"

# Kernel > 3

KERNEL=="sd?", SUBSYSTEM=="block", DEVPATH=="*1f.2/ata1/host*", NAME="sdb", RUN+="/usr/bin/logger My disk ATTR{partition}=$ATTR{partition}, DEVPATH=$devpath, ID_PATH=$ENV{ID_PATH}, ID_SERIAL=$ENV{ID_SERIAL}", GOTO="END_20_PERSISTENT_DISK"

KERNEL=="sd?*", ATTR{partition}=="1", SUBSYSTEM=="block", DEVPATH=="*1f.2/ata1/host*", NAME="sdb%n", RUN+="/usr/bin/logger My partition parent=%p number=%n, ATTR{partition}=$ATTR{partition}"

########## Map SATA 1 to /dev/sdc ##############

# Kernel < 3

KERNEL=="sd?", SUBSYSTEM=="block", DEVPATH=="*1f.2/host1/target1:0:0/1:0:0:0*", NAME="sdc", RUN+="/usr/bin/logger My disk ATTR{partition}=$ATTR{partition}, DEVPATH=$devpath, ID_PATH=$ENV{ID_PATH}, ID_SERIAL=$ENV{ID_SERIAL}", GOTO="END_20_PERSISTENT_DISK"

KERNEL=="sd?*", ENV{DEVTYPE}=="partition", SUBSYSTEM=="block", DEVPATH=="*1f.2/host1/target1:0:0/1:0:0:0*", NAME="sdc%n", RUN+="/usr/bin/logger My partition parent=%p number=%n, ATTR{partition}=$ATTR{partition}"

# Kernel > 3

KERNEL=="sd?", SUBSYSTEM=="block", DEVPATH=="*1f.2/ata2/host*", NAME="sdc", RUN+="/usr/bin/logger My disk ATTR{partition}=$ATTR{partition}, DEVPATH=$devpath, ID_PATH=$ENV{ID_PATH}, ID_SERIAL=$ENV{ID_SERIAL}", GOTO="END_20_PERSISTENT_DISK"
KERNEL=="sd?*", ATTR{partition}=="1", SUBSYSTEM=="block", DEVPATH=="*1f.2/ata2/host*", NAME="sdc%n", RUN+="/usr/bin/logger My partition parent=%p number=%n, ATTR{partition}=$ATTR{partition}"

LABEL="END_20_PERSISTENT_DISK"

上述規則將始終將放置在 SATA 埠 0(我主機板上的第一個物理 SATA 埠)中的任何驅動器映射為 /dev/sdb,並將放置在 SATA 1 中的任何驅動器映射為 /dev/sdc 一致的物理埠映射在我的案例中至關重要,因為我有 5 個 RAID-1 陣列,可以在其中任意將磁碟從其物理熱插拔托架中換出。非技術使用者可以隨時更換這些磁碟,而無需處理設備 ID - 系統是完全自主的,不會在熱插拔托架中的錯誤磁碟上建構 RAID 陣列。這是一個非常具體的案例。

如果您創建一個數組:

mdadm --create --name=DATA00 --level=6 --auto=part --verbose /dev/md0 --raid-devices=6 /dev/sda1 /dev/sdb1 /dev/sdd1 /dev/sde1 /dev/sdf1 /dev/sdg1

然後做:

mdadm --detail --scan >> /etc/mdadm/mdadm.conf

你得到一個mdadm.conf像這樣的條目:

ARRAY /dev/md/DATA00 metadata=1.2 name=owl:DATA00 UUID=5eeada67:ff994361:bae3ab52:d9e8bd49

無需參考原始分區和/或驅動程序排序,因為 UUID 負責這一點。從 中可以看出啟動/重啟後哪些實際分區構成了陣列/proc/mdstat。要查看單個分區(包括其 UUID),請使用mdadm --examine /dev/sdXY

鑑於重新啟動後不需要在驅動器中設置特定順序,並且由於我的 BIOS 會根據我是否連接外部 SATA 進行切換,我很高興這無關緊要。

引用自:https://unix.stackexchange.com/questions/179453