附录 A. 设备映射器(Device Mapper)

Device Mapper 是一个为卷管理提供构架的内核驱动程序。它提供一个创建映射设备的通用方法,该设备可作为逻辑卷使用。它并不具体了解卷组或者元数据格式。
Device Mapper 是很多高级技术的基础。除 LVM 外,Device Mapper 多路径和 dmraid 命令也使用 Device Mapper。Device Mapper 的应用程序界面是 ioctl 系统调用。用户界面是 dmsetup 命令。
LVM 逻辑卷是使用 Device Mapper 激活的。每个逻辑卷都会被转换成映射的设备,每个片段都会被转换成映射列表中描述设备的一行。Device Mapper 支持各种映射目标,包括线性映射、条带映射和错误映射。例如:两张磁盘可连成一个带一对线性映射的逻辑卷,每个映射对应一个磁盘。当 LVM 创建卷时,它会生成一个底层 device-mapper 设备,使用 dmsetup 命令可对其进行查询。有关映射列表中设备格式的详情,请参考 第 A.1 节 “设备表映射”。有关使用 dmsetup 命令查询某个设备的详情,请参考 第 A.2 节 “dmsetup 命令”

A.1. 设备表映射

映射设备是根据指定如何使用支持的设备表映射映射设备的每个逻辑扇区的表格定义。映射设备表由以下格式行组成:
start length mapping [mapping_parameters...]
在设备映射表的第一行中,start 参数必须等于 0。每行中的 start + length 参数必须与下一行的 start 相等。在映射表中指定哪个映射参数取决于在该行中指定的 mapping 类型。
Device Mapper 的大小总是以扇区(512 字节)为单位指定。
将某个设备指定为 Device Mapper 的映射参数后,就可以在该文件系统(比如 /dev/hda)中根据其设备名称进行参考,或者在使用 major:minor 格式时根据主要号码和次要号码进行参考。首选 major:minor 格式,因为这样可避免查找路径名。
以下显示了某设备的映像表示例。在这个表中有四个线性目标:
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 目标的参数组成。
下面的小节描述了以下映射的格式:
  • 线性映射
  • 条带映射
  • 镜像映射
  • 快照和原始快照映射
  • 错误映射
  • 零映射
  • 多路径映射
  • 加密映射

A.1.1. 线性映射目标

线性映射目标将块的连续行映射到另一个块设备中。线性目标的格式如下:
start length linear device offset
start
虚拟设备中的起始块
length
这个片段的长度
device
块设备,被该文件系统中的设备名称或者主号码和副号码以 major:minor 的格式参考
offset
该设备中映射的起始偏移
以下示例显示了起始块位于虚拟设备 0,片段长度为 1638400,major:minor 号码对为 8:2,起始偏移为 41146992 的线性目标。
0 16384000 linear 8:2 41156992
以下示例演示了将设备参数指定为 /dev/hda 的线性目标。
0 20971520 linear /dev/hda 384

A.1.2. 条带映射目标

条带映射目标支持所有跨物理设备的条带。它使用条带数目和成条的组集大小以及设备名称和扇区对作为参数。条状目标的格式如下:
start length striped #stripes chunk_size device1 offset1 ... deviceN offsetN
每个条块都有一组 deviceoffset 参数。
start
虚拟设备中的起始块
length
这个片段的长度
#stripes
虚拟设备的条数
chunk_size
切换到下一个条之前写入每个条的扇区数,必须至少是内核页面大小的两倍
device
块设备,可被该文件系统中的设备名称或者主号码和副号码以格式 major:minor 参考。
offset
该设备中映射的起始偏移
以下示例显示了一个有三个条,且组集大小为 128 的条状目标:
0 73728 striped 3 128 8:9 384 8:8 384 8:7 9789824
0
虚拟设备中的起始块
73728
这个片段的长度
striped 3 128
三个设备中组集大小为 128 块的条带
8:9
第一个设备的 major:minor 号码
384
第一个设备中映射的起始偏移
8:8
第二个设备的 major:minor 号码
384
第二个设备中映射的起始偏移
8:7
第三个设备的 major:minor 号码
9789824
第三个设备中映射的起始偏移
以下示例显示了含有两个 256KiB 条,使用文件系统中的设备名称而不是主号码和副号码指定设备参数的条状目标。
0 65536 striped 2 512 /dev/hda 0 /dev/hdb 0

A.1.3. 镜像映射目标

镜像映射目标支持镜像逻辑设备映像。镜像目标格式如下:
start length mirror log_type #logargs logarg1 ... logargN #devs device1 offset1 ... deviceN offsetN
start
虚拟设备中的起始块
length
这个片段的长度
log_type
可能的日志类型及其参数如下:
core
镜像是本地的,镜像日志保存在核内存中。这个日志类型有 1-3 个参数:
regionsize [[no]sync] [block_on_error]
disk
镜像是本地的,镜像日志保存在磁盘中。这个日志类型可附加 2-4 个参数:
logdevice regionsize [[no]sync] [block_on_error]
clustered_core
镜像是集群的,镜像日志保存在 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 参数是与镜像日志设备关联的特定识别符,以便可通过该集群维护日志状态。
可使用自选的 [no]sync 参数将镜像指定为 "in-sync" 或者 "out-of-sync"。block_on_error 参数是用来让镜像对错误做出响应,而不是忽略它们。
#log_args
将在映射中指定的日志参数数目
logargs
镜像的日志参数;提供的日志参数数目是由 #log-args 参数指定的,且有效日志参数由 log_type 参数决定。
#devs
镜像中的分支数目;为每个分支指定一个设备和一个偏移
device
每个镜像分支的块设备,使用该文件系统中的设备名称或者主号码和副号码以 major:minor 的格式参考。每个镜像分支都有一个块设备和误差,如 #devs 参数中所示。
offset
设备中映射的起始偏移。每个镜像分支都有一个块设备和偏移,如 #devs 参数中所示。
下面的示例演示了集群映像的镜像映像目标,并将该映像的映像日志保存在磁盘中。
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
附带 4 个镜像日志参数
253:2
日志设备的 major:minor 号码
1024
镜像日志用来跟踪进行同步的区域大小
UUID
镜像日志设备的 UUID,该设备上用来维护集群吞吐量信息。
block_on_error
镜像应该对错误进行响应
3
镜像中的分支数
253:3 0 253:4 0 253:5 0
构成镜像每个分支的设备的 major:minor 号码和偏移

A.1.4. 快照和原始快照映射目标

创建某个卷的第一个 LVM 快照时,使用了四个 Device Mapper 设备:
  1. 包含源卷原始映射表的线性映射设备。
  2. 作为源卷即写即拷(copy-on-write,COW)设备使用的有线性映射的设备;每次写入时,会将原始数据保存在每个快照的 COW 设备中以便保持不更改可见内容(直到 COW 设备写满为止)。
  3. 附带快照映射及 #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 通常有一个或者多个基于它的快照。会将读取操作直接与后备设备映射。每次写入时,会将原始数据保存在每个快照的 COW 设备中以便使其不更改可见内容(直到 COW 设备写满为止)。
快照目标的格式如下:
start length snapshot origin COW-device P|N chunksize
start
虚拟设备中的起始块
length
这个片段的长度
origin
快照基础卷
COW-device
保存更改组集数据的设备
P|N
P(持久)或者N(不持久);表示是否可在重启后保留快照。对于瞬时快照(N)必须将 less metadata 保存在磁盘中;内核可将其保存在内存中。
chunksize
将保存到 COW 设备中的有数据块更改的扇区大小
以下示例显示了起始设备为 254:11 的 snapshot-origin 目标。
0 2097152 snapshot-origin 254:11
以下示例显示了起始设备为 254:11、COW 设备为 254:12 的 snapshot-origin 目标。这个快照设备在重启后仍然保留,且保存在 COW 设备中的数据块大小为 16 个扇区。
0 2097152 snapshot 254:11 254:12 P 16

A.1.5. 错误映射目标

如果有错误映射目标,任何对映射的扇区的 I/O 操作会失败。
错误映射可用来进行测试。要测试某个设备在失败后如何动作,可以创建一个有坏扇区的设备映射,或者您可以换出一个镜像分支并用错误目标替换。
错误目标可用于出错的设备,是一种避免超时并在实际设备中重试的方法。失败后重新部署 LVM 元数据时可将其作为中间目标使用。
错误映射目标除 startlength 参数外不使用其它参数。
以下示例显示的是错误目标。
0 65536 error

A.1.6. 零映射目标

映射目标是与 /dev/zero 等同的块设备。对这个映射的读取操作会返回零块。写入这个映射的数据会被丢弃,但写入操作会成功。映射目标除 startlength 参数外没有其它参数。
以下示例显示了大小为 16Tb 设备的目标。
0 65536 zero

A.1.7. 多路径映射目标

多路径映射目标支持多路径的设备的映射。多路径目标的格式如下:
start length  multipath  #features [feature1 ... featureN] #handlerargs [handlerarg1 ... handlerargN] #pathgroups pathgroup pathgroupargs1 ... pathgroupargsN
每个路径组群都有一组 pathgroupargs 参数。
start
虚拟设备中的起始块
length
这个片段的长度
#features
在那些功能之后是多路径功能的数目。如果这个参数是 0,则没有 feature 参数,且下一个设备映射参数为 #handlerargs。目前只有一个功能可使用 multipath.conf 文件中的 features 属性设置,即 queue_if_no_path。这说明如果没有路径可用,则将这个多路经的设备设定为队列 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
路径组的数目。路径组是一组 multipathed 设备进行负载平衡的路径。每个路径组都有一组 pathgroupargs 参数。
pathgroup
下一个要尝试的路径组。
pathgroupsargs
每个路径组均由以下参数组成:
pathselector #selectorargs #paths #pathargs device1 ioreqs1 ... deviceN ioreqsN 
路径组中的每个路径都有一组路径参数。
pathselector
指定用来决定使用这个路径组中的哪个路径进行下一个 I/O 操作的算法。
#selectorargs
在多路径映射中这个参数后的路径选择程序参数的数目。目前,这个参数的值总是 0。
#paths
这个路径组中的路径数目。
#pathargs
在这个组群中为每个路径指定的路径参数数目。目前,这个数值总是 1,即 ioreqs 参数。
device
该路径的块设备,使用主号码和副号码以 major:minor 格式参考
ioreqs
切换到当前组群的下一个路径前路由到这个路径的 I/O 请求数目。
图 A.1 “多路径映射目标” 显示带两个路径组群的多路径目标格式。
多路径映射目标

图 A.1. 多路径映射目标

以下示例显示对同一个多路径设备的一个纯故障排除目标定义。在这个目标中有四个路径组,其中每个路径组只有一个路径,以便多路径的设备每次只能使用一个路径。
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
下面的示例显示为同一个多路径设备完全展开(多总线)目标定义。在这个目标中只有一个路径组,其中包含所有路径。在这个设定中,多路径将所有负载平均分配到所有路径中。
0 71014400 multipath 0 0 1 1 round-robin 0 4 1 66:112 1000 \
 67:176 1000 68:240 1000 65:48 1000
有关多路径的详情请参考《使用设备映射器多路径》文档。

A.1.8. 加密映射目标

加密目标会加密通过指定设备的所有数据。它使用内核 Crypto API。
加密目标的格式如下:
start length crypt cipher key IV-offset device offset
start
虚拟设备中的起始块
length
这个片段的长度
cipher
Cipher 包含 cipher[-chainmode]-ivmode[:iv options]
cipher
可用密码位于 /proc/crypto(例如:aes)。
chainmode
永远使用 cbc。不要使用 ebc,它不使用初始向量(IV)。
ivmode[:iv options]
IV 是一个用来区分加密法的初始向量。IV 模式是 plain或者 essiv:hash-plainivmode 使用扇区号码(加 IV 误差)作为 IV。-essivivmode 是一个改进,可避免水印弱点。
key
加密密钥,以十六进制提供
IV-offset
初始向量(IV)偏移
device
块设备,被该文件系统中的设备名称或者主号码和副号码以 major:minor 的格式参考
offset
该设备中映射的起始偏移
以下是加密目标示例。
0 2097152 crypt aes-plain 0123456789abcdef0123456789abcdef 0 /dev/hda 0