附錄 A. 裝置映射(Device Mapper)設備

Device Mapper 是一個提供了卷冊管理架構的 kernel 驅動程式。它提供了建立映射裝置的一般方式,並且該映射裝置可被用來作為邏輯卷冊。它並不確切地清楚卷冊群組或 metadata 的格式為何。
Device Mapper 提供了幾個高層級技術上的基礎。除了 LVM 之外,Device-Mapper multipath 和 dmraid 指令亦使用 Device Mapper。Device Mapper 的應用程式介面為 ioctl system call。dmsetup 指令則為用戶介面。
LVM 邏輯卷冊可藉由使用 Device Mapper 啟用。所有邏輯卷冊皆會被轉換為映射裝置。所有區段皆會被轉換為一列位於描述裝置之映射表格當中的行列。Device Mapper 支援各種映射目標,其中包含了 linear mapping、striped mapping,以及 error mapping。比方說,兩個磁碟可透過一對線性映射(一個磁碟一個)來被序連為一個單獨的邏輯卷冊。當 LVM 建立了一個卷冊時,它會建立一個可透過 dmsetup 指令來查詢的基本 device-mapper 裝置。欲取得更多有關於映射表格當中的裝置格式上的相關資訊,請參閱〈節 A.1, “裝置表格映射”〉。如需取得使用 dmsetup 指令來查詢某個裝置上的相關資訊,請參閱〈節 A.2, “dmsetup 指令”〉。

A.1. 裝置表格映射

映射裝置是由一個透過受支援的裝置表格(Device Table)映射,來指定如何映射邏輯磁區(logical sector)的各個範圍的表格來定義的。映射裝置的表格是由一列具有下列格式的行列所構成的:
start length mapping [mapping_parameters...]
在 Device Mapper 表格的第一個行列中,start 這個參數必須等於 0。一個行列上的 start + length 參數必須等於下個行列上的 start。指定於映射表格行列中的映射參數,取決於該行列上所指定的 mapping
Device Mapper 中的大小總是以磁區來指定(512 位元組)。
當某個裝置被指定為 Device Mapper 中的映射參數時,它可被檔案系統中的裝置名稱(例如 /dev/hda)參照,或是被格式為 major:minor 的 major 和 minor 數字參照。我們建議使用 major:minor 這個格式因為它避免了路徑名稱搜尋。
以下顯示了一個裝置的映射表格範例。在此表格中有四個 linear 目標:
0 35258368 linear 8:48 65920
35258368 35258368 linear 8:32 65920
70516736 17694720 linear 8:16 17694976
88211456 17694720 linear 8:16 256
各個行列的前兩個參數都是區段的起始區塊以及區塊的長度。下個關鍵字為映射目標,在此範例中的所有情況下都是 linear。行列剩下的部份則包含著 linear 目標的參數。
下列部份中描述了以下映射的格式:
  • linear
  • striped
  • mirror
  • snapshot 和 snapshot-origin
  • error
  • zero
  • multipath
  • crypt

A.1.1. Linear 映射目標

Linear 映射目標會將一個連續範圍的區塊映射至另一個區塊裝置上。Linear 目標的格式如下:
start length linear device offset
start
在虛擬裝置中啟用區塊
length
此區段的長度
device
區塊裝置,被檔案系統中的裝置名稱所參照,或是被格式為 major:minor 的 major 和 minor 數字所參照
offset
在裝置上啟用映射的偏差值(offset)
下列範例顯示了一個起始區塊於虛擬裝置 0 中、區段長度為 1638400、major:minor 數字配對為 8:2,以及裝置起始偏差值為 41146992 的 linear 目標。
0 16384000 linear 8:2 41156992
下列範例顯示了一個裝置參數指定為 /dev/hda 這個裝置的 linear 目標。
0 20971520 linear /dev/hda 384

A.1.2. 等量映射目標

等量映射目標(striped Mapping Target)支援實體裝置上的 striping。它會取等量磁碟數量和 striping chunk size 為引數以及一列裝置名稱與磁區的配對。等量目標的格式如下
start length striped #stripes chunk_size device1 offset1 ... deviceN offsetN
各個等量磁碟都有一組 deviceoffset 參數。
start
在虛擬裝置中啟用區塊
length
此區段的長度
#stripes
虛擬裝置的等量磁碟數量
chunk_size
切換至下一個等量磁碟之前可寫至各個等量磁碟的磁區數量;必須至少和 kernel page 大小的 2 的 n 次方一樣大
device
區塊裝置,被檔案系統中的裝置名稱所參照,或是被格式為 major:minor 的 major 和 minor 數字所參照。
offset
在裝置上啟用映射的偏差值(offset)
下列範例顯示了一個等量目標以及三個等量磁碟和大小為 128 的 chunk size:
0 73728 striped 3 128 8:9 384 8:8 384 8:7 9789824
0
在虛擬裝置中啟用區塊
73728
此區段的長度
striped 3 128
跨越了三個裝置的 stripe 以及大小為 128 block 的 chunk size
8:9
第一個裝置的 major:minor 數字
384
第一個裝置上的映射的起始偏差值
8:8
第二個裝置上的 major:minor 數字
384
第二個裝置上的映射的起始偏差值
8:7
第三個裝置上的 major:minor 數字
9789824
第三個裝置上的映射的起始偏差值
下列範例顯示了一個擁有兩個 256 KiB chunk 的等量磁碟的等量目標,並且裝置參數是由檔案系統中的裝置名稱來指定的,而不是以 major 和 minor 數字來指定。
0 65536 striped 2 512 /dev/hda 0 /dev/hdb 0

A.1.3. 鏡像映射目標

鏡像映射目標(mirror mapping target)支援鏡像邏輯卷冊的映射。鏡像目標的格式如下:
start length mirror log_type #logargs logarg1 ... logargN #devs device1 offset1 ... deviceN offsetN
start
在虛擬裝置中啟用區塊
length
此區段的長度
log_type
各種可能的日誌類型與它們的引數如下:
core
鏡像位於本機,並且鏡像日誌(mirror log)存放在核心記憶體(core memory)中。此日誌類型接受 1 到 3 個引數:
regionsize [[no]sync] [block_on_error]
disk
鏡像位於本機,並且鏡像日誌存放在磁碟上。此日誌類型接受 2 到 4 個引數:
logdevice regionsize [[no]sync] [block_on_error]
clustered_core
鏡像已被叢集連結,並且鏡像日誌存放在核心記憶體中。此日誌類型接受 2 到 4 個引數:
regionsize UUID [[no]sync] [block_on_error]
clustered_disk
鏡像已被叢集連結,並且鏡像日誌存放在磁碟上。此日誌類型接受 3 到 5 個引數:
logdevice regionsize UUID [[no]sync] [block_on_error]
LVM 會保存一個小型的日誌,它會使用該日誌來追蹤哪些區域已和鏡像同步化。regionsize 這個引數能指定這些區域的大小。
在一個叢集環境中,UUID 這個引數是個和鏡像日誌裝置相聯的唯一識別碼(unique identifier),日誌狀態可從而在叢集環境下被保留。
[no]sync 這個可選的引數可被用來將鏡像指定為「in-sync」或是「out-of-sync」。block_on_error 這個引數可用來使鏡像針對於錯誤進行回應而不是將它們忽略掉。
#log_args
將會被指定在映射中的日誌引數數量
logargs
鏡像的日誌引數;日誌引數的數量是透過 #log-args 參數來指定的,並且有效的日誌引數則是透過 log_type 參數來判斷出的。
#devs
鏡像中的 leg 數量;各個 leg 皆被指定了一個裝置和偏差值。
device
各個鏡像 leg 的區塊裝置,由檔案系統中的裝置名稱參照,或由格式為 major:minor 的 major 和 minor 數字參照。如 #devs 參數所顯示,各個鏡像 leg 都會被指定一個區塊裝置和偏差值。
offset
裝置上的映射的起始偏差值。如 #devs 參數所顯示,各個鏡像 leg 都會被指定一個區塊裝置和偏差值。
下列範例顯示了一個叢集鏡像的鏡像映射目標,並且該叢集鏡像的鏡像日誌被存放在磁碟上。
0 52428800 mirror clustered_disk 4 253:2 1024 UUID block_on_error 3 253:3 0 253:4 0 253:5 0
0
在虛擬裝置中啟用區塊
52428800
此區段的長度
mirror clustered_disk
含有一個指定了鏡像已被叢集連結並且鏡像日誌存放在磁碟上的鏡像目標
4
會有四個鏡像日誌
253:2
日誌裝置的 major:minor 數字
1024
鏡像日誌使用來追蹤已同步化之鏡像的區域大小
UUID
用來在叢集環境下保留日誌資訊的鏡像日誌裝置 UUID
block_on_error
鏡像應針對於錯誤做出回應
3
鏡像中的 leg 數量
253:3 0 253:4 0 253:5 0
構成各個鏡像 leg 的裝置的 major:minor 數字和偏差值

A.1.4. 快照和 snapshot-origin 映射目標

當您建立了卷冊的第一個 LVM 快照時,會有四個 Device Mapper 裝置被使用到:
  1. 一個含有 linear 映射的裝置,並且該映射包含著來源卷冊的原始映射表格。
  2. 一個含有 linear 映射的裝置,它會被用來作為來源卷冊的寫入即複製(copy-on-write,COW)的裝置;針對於各個寫入動作,原始資料都會被儲存在各個 snapshot 的 COW 裝置中,如此一來它的可見內容便不會遭到更改(直到 COW 裝置滿出)。
  3. 一個含有 snapshot 映射的裝置,它結合了 #1 與 #2,也就是可見的快照卷冊。
  4. 「原始」卷冊(它使用了原始來源卷冊所使用的裝置號碼),它的表格已被替換為一個來自於裝置 #1 的「snapshot-origin」映射。
有個使用來建立這些裝置的固定命名方案。比方說,您可能會使用下列指令來建立一個名為 base 的 LVM 卷冊以及一個基於該卷冊、名為 snap 的快照卷冊。
# lvcreate -L 1G -n base volumeGroup
# lvcreate -L 100M --snapshot -n snap volumeGroup/base
這會產生四個裝置,並且您可透過下列指令來檢視這些裝置:
# dmsetup table|grep volumeGroup
volumeGroup-base-real: 0 2097152 linear 8:19 384
volumeGroup-snap-cow: 0 204800 linear 8:19 2097536
volumeGroup-snap: 0 2097152 snapshot 254:11 254:12 P 16
volumeGroup-base: 0 2097152 snapshot-origin 254:11

# ls -lL /dev/mapper/volumeGroup-*
brw-------  1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real
brw-------  1 root root 254, 12 29 ago 18:15 /dev/mapper/volumeGroup-snap-cow
brw-------  1 root root 254, 13 29 ago 18:15 /dev/mapper/volumeGroup-snap
brw-------  1 root root 254, 10 29 ago 18:14 /dev/mapper/volumeGroup-base
snapshot-origin 目標的格式如下:
start length snapshot-origin origin
start
在虛擬裝置中啟用區塊
length
此區段的長度
origin
快照的基本卷冊
snapshot-origin 通常會有一個或是更多個基於它的快照。讀取動作會直接被映射至 backing device。針對於各個寫入動作,原始資料都會被儲存在各個快照的 COW 裝置中來保存它的可見內容直到 COW 裝置填滿。
snapshot 目標的格式如下:
start length snapshot origin COW-device P|N chunksize
start
在虛擬裝置中啟用區塊
length
此區段的長度
origin
快照的基本卷冊
COW-device
遭到更改的資料區塊所被儲存至的裝置
P|N
P(Persistent〔一致性〕)或是 N(Not persistent〔非一致性〕);顯示了快照在系統重新啟動後是否還會存在。針對於暫時性的快照(N),磁碟上必須要儲存較少 metadata;它們可被 kernel 保存在記憶體中。
chunksize
被存放在 COW 裝置上、遭到更改的資料區塊大小(以磁區為單位)
下列範例顯示了一個原始裝置為 254:11 的 snapshot-origin 目標。
0 2097152 snapshot-origin 254:11
下列範例顯示了一個原始裝置為 254:11 並且 COW 裝置為 254:12 的 snapshot 目標。這個快照裝置經過了系統重新啟動後將依然有效,並且儲存在 COW 裝置上的資料的區塊大小為 16 個磁區。
0 2097152 snapshot 254:11 254:12 P 16

A.1.5. error 映射目標

若使用了 error 映射目標的話,任何針對於映射的磁區的 I/O 作業都會失敗。
error 映射目標可用來進行測試。若要測試某個裝置在錯誤的情況下會有什麼特性,您可建立一個裝置映射,並且在該裝置中間含有個錯誤的磁區,或是您可將鏡像的一個 leg 替換為另一個 error 目標。
一個 error 目標可被用來取代一個發生錯誤的裝置,這是個避免在實際的裝置上逾時和進行重新嘗試的方式。它可被用來作為一個當您在發生錯誤,而進行 LVM metadata 重整時的媒介目標。
error 映射目標除了 startlength 這兩個參數之外不接受額外的參數。
下列範例顯示了一個 error 目標。
0 65536 error

A.1.6. zero 映射目標

zero 映射目標是個相當於 /dev/zero 的區塊裝置。對於此映射所進行的讀取作業會回傳一些零的區塊。寫至此映射的資料將會被丟棄,不過寫入作業會成功。zero 映射目標不接受 startlength 參數以外的額外參數。
下列範例顯示了一個 16Tb 裝置的 zero 目標。
0 65536 zero

A.1.7. multipath 映射目標

multipath 映射目標支援多路徑裝置的映射。multipath 目標的格式如下:
start length  multipath  #features [feature1 ... featureN] #handlerargs [handlerarg1 ... handlerargN] #pathgroups pathgroup pathgroupargs1 ... pathgroupargsN
各個路徑群組都有一組 pathgroupargs 參數。
start
在虛擬裝置中啟用區塊
length
此區段的長度
#features
multipath 功能的數量以及它們的功能。若此參數為零的話,那麼就不會有 feature 這個參數並且下一個裝置映射參數會是 #handlerargs。\n\n目前只有一個受支援的 multipath 功能,queue_if_no_path,可以在 multipath.conf 檔案中的 features 屬性中設定。這表示此多路徑裝置目前已設為若沒有可用路徑的話便會將 I/O 作業置於佇列中。
在以下例子裡,multipath.conf 檔案中的 no_path_retry 屬性只有在嘗試路徑數次且失敗後,並被標示為失敗時,才會被設定到佇列 I/O 操作中。在這情況下,映射就會以下列格式來顯示出,直到所有路徑檢查程式所被指定的檢查次數都已完成後。
0 71014400 multipath 1 queue_if_no_path 0 2 1 round-robin 0 2 1 66:128 \
1000 65:64 1000 round-robin 0 2 1 8:0 1000 67:192 1000
當所有路徑檢查程式所被指定的檢查次數都已完成後,映射就會以下列格式顯示出。
0 71014400 multipath 0 0 2 1 round-robin 0 2 1 66:128 1000 65:64 1000 \
round-robin 0 2 1 8:0 1000 67:192 1000
#handlerargs
硬體處理程式引數的數量以及那些引數。硬體處理程式會在切換路徑群組或是處理 I/O 錯誤時指定一個用來執行硬體特屬之動作的模組。若這被設為 0 的話,那麼下個參數便是 #pathgroups
#pathgroups
路徑群組的數量。路徑群組(path group)代表一組路徑,並且多路徑的裝置將會在這些路徑上進行負載平衡。各個路徑群組都有一組 pathgroupargs 參數。
pathgroup
下一個嘗試的路徑群組。
pathgroupsargs
各個路徑群組都包含著下列引數:
pathselector #selectorargs #paths #pathargs device1 ioreqs1 ... deviceN ioreqsN 
路徑群組中的各個路徑都都有一組路徑引數。
pathselector
可指定使用中的演算法來判斷下個 I/O 作業該使用此路徑群組中的哪個路徑。
#selectorargs
允許此引數使用於 multipath 映射的路徑選擇器引數數量。目前,這個引數的值總會是 0。
#paths
此路徑群組中的路徑數量。
#pathargs
為此群組中各個路徑所指定的路徑引數數量。目前,這個數字總會是 1,也就是 ioreqs 引數。
device
路徑的區塊裝置號碼,以格式為 major:minor 的 major 和 minor 數字來參照
ioreqs
要切換至目前群組中的下個路徑前所需要用來 route 至此路徑的 I/O 請求數量。
圖形 A.1, “Multipath 映射目標”〉顯示了含有兩個路徑群組的 multipath 目標的格式。
Multipath 映射目標

圖形 A.1. Multipath 映射目標

下列範例顯示了相同 multipath 裝置的純容錯(failover)目標定義。在此目標中有四個路徑群組,並且一個路徑群組只有一個開放的路徑,這樣一來 multipath 裝置便只會一次使用一個路徑。
0 71014400 multipath 0 0 4 1 round-robin 0 1 1 66:112 1000 \
round-robin 0 1 1 67:176 1000 round-robin 0 1 1 68:240 1000 \
round-robin 0 1 1 65:48 1000
下列範例顯示了相同 multipath 裝置的一個多重匯流排(multibus)目標定義。在此目標中只有一個路徑群組,並且它包含了所有的路徑。在此設定中,multipath 會將負載平衡地分配至所有路徑中。
0 71014400 multipath 0 0 1 1 round-robin 0 4 1 66:112 1000 \
 67:176 1000 68:240 1000 65:48 1000
如欲取得更多有關於進行 multipath 上的相關資訊,請參閱 Using Device Mapper Multipath 文件。

A.1.8. crypt 映射目標

crypt 目標會將通過指定裝置的資料加密。它使用了 kernel 的 Crypto API。
crypt 目標的格式如下:
start length crypt cipher key IV-offset device offset
start
在虛擬裝置中啟用區塊
length
此區段的長度
cipher
Cipher 包含著 cipher[-chainmode]-ivmode[:iv options]
cipher
可用的 Cipher 列在 /proc/crypto 中(比方說 aes)。
chainmode
總是使用 cbc。請勿使用 ebc;它並不使用初始向量(IV)。
ivmode[:iv options]
IV 是個使用來改變加密的初始向量。IV 模式為 plainessiv:hash-plainivmode 使用了磁區編號(加上 IV 偏差值)來作為 IV。-essivivmode 是為了避免 watermark 弱點用的。
key
加密金鑰、以十六進位提供
IV-offset
初始向量(Initial Vector,IV)偏差值
device
區塊裝置,被檔案系統中的裝置名稱所參照,或是被格式為 major:minor 的 major 和 minor 數字所參照
offset
在裝置上啟用映射的偏差值(offset)
下列為 crypt 目標的範例。
0 2097152 crypt aes-plain 0123456789abcdef0123456789abcdef 0 /dev/hda 0