Device Mapper Multipath(DM-Multipath)

Device Mapper Multipath(DM-Multipath)可以将服务器节点和存储阵列之间的多条I/O链路配置为一个单独的设备。这些I/O链路是由不同的线缆、交换机、控制器组成的SAN物理链路。Multipath将这些链路聚合在一起,生成一个单独的新的设备。

 1.DM-Multipath概览:

(1)数据冗余

DM-Multipath可以实现在active/passive模式下的灾难转移。在active/passive模式下,只有一半的链路在工作,如果链路上的某一部分(线缆、交换机、控制器)出现故障,DM-Multipath就会切换到另一半链路上。

(2)提高性能

DM-Multipath也可以配置为active/active模式,从而I/O任务以round-robin的方式分布到所有的链路上去。通过配置,DM-Multipath还可以检测链路上的负载情况,动态地进行负载均衡。

DM-Multipath的存储阵列的支持情况可以查看multipath.conf.default。对于支持列表中没有的存储,可以在multipath的配置文件multipath.conf中自行添加。

2.DM-Multipath的组成:

(1)dm-multipath内核模块实现I/O重定向、支持failover以及链路的聚合

(2)mutilpath命令查看和配置multipath设备。它一般由/etc/rc.sysinit启动,也会在系统发现新的块设备时由udev启动,或者由initramfs在系统启动时执行。

(3)multipathd后台进程监控链路。当链路失效或者恢复时,它会发起链路组的切换。它实现了对multipath设备的动态修改。不过multipath.conf修改后,它需要重新启动。

(4)kpartx命令根据设备上分区表创建device mapper设备。当需要在DM-MP设备上使用基于DOS的分区时,这个命令是必须。

不使用DM-Multipath,每一条从服务器到存储的链路都被系统识别为一个单独的设备。DM-Multipath可以在这些底层的设备之上创建一个单一的multipath设备,实现对这些链路的组织和管理。

3.Multipath设备的标志符

每一个multipath设备都有一个WWID(World Wide Identifier),这个id是全球唯一而且不可更改的。默认情况下,multipath设备的名称被设置为它的WWID。不过也可以在配置文件中使用_friendly_names选项,为设备取一个别名,别名为mpath[n]。

例如,一台服务器节点有2块HBA卡,通过一台没有划分zone的交换机,连接到2个磁盘阵列控制器,服务器系统中会发现4个设备:/dev/sda、/dev/sdb、/dev/sdc、/dev/sdd。DM-Multipath会按照配置文件在这些底层设备上创建一个拥有一个唯一WWID号的multipath设备。如果配置文件中_friendly_names选项被设置为yes,则这个multipath设备会被命名为mpath[n]。

当新的设备被DM-Multipath接管之后,新的设备文件会在/dev/目录下3个不同的地方出现:/dev/mapper/mpath[n]、/dev/mpath/mpath[n]、/dev/dm-[n]。

(1)/dev/mapper/目录下的文件,是早在系统启动的过程中就创建了。访问multipath设备时就使用这些文件,例如创建lvm;

(2)/dev/mpath/目录下的文件,是为了可以方便的在同一个目录下查看所有的multipath设备。这个文件由udev创建。如果系统在启动过程中需要访问multipath设备,不要使用这些文件。不用在这些设备文件上建立lvm;

(3)/dev/dm-[n]只为了内部使用目的,永远不要对这些文件进行操作。

4.统一multipath设备的命名

当配置文件中_friendly_names被设置为yes,在该服务器节点上这个设备名是唯一而且确定的,但是不能保证在使用这些链路的其它服务器节点上的multipath设备的名称能够相互保持一致。如果只是建立lvm,那么这个问题不会有什么影响。但是如果希望不同服务器节点上的multipath设备的名称能够统一,必须使用下面其中一种方法:

(1)在配置文件中的multipaths段使用alias选项为设备设置别名,并在不同的服务器上保持一致;

(2)如果希望不同服务器上multipath设备的user-friendly名称保持一致,首先在一台服务器上建立所有multipath设备,然后把bindings文件拷贝到所有其它系统统一命名的服务器。binds文件的位置是/var/lib/multipath/bindings。在配置文件可以使用bindings_file参数修改bindings文件的位置。

5.Multipath设备上建立lv

创建multipath设备之后,可以像使用物理设备文件一样在multipath设备上建立pv。例如,假定multipath设备为/dev/mapper/mpath0,使用

       pvscreate /dev/mapper/mpath0

即可将mpath0建立为物理卷。同样可以继续建立卷族和逻辑卷。

当在配置为active/passive模式的multipath设备上建立逻辑卷时,需要在lvm的配置文件lvm.conf中增加过滤器,将multipath设备下层的设备添加到过滤列表中。这时因为DM-Multipath会自动切换数据链路,当遇到failover和failback的情况时,如果下层的设备没有在配置文件中过滤,lvm会扫描这些passive状态下的数据链路。Passive状态的链路改变到active状态需要执行一些命令,所以lvm就会在这个时候报错。

为了过滤所有的SCSI设备,在lvm.conf中的devices段,添加下面的配置:

filter = [ "r/disk/", "r/sd.*/", "a/.*/"

6.部署DM-Multipath

       6.1开始部署

       (1)编辑/etc/multipath.conf,注释掉下面几行:

              devnode_blacklist {

                      devnode "*"

              }

       (2)multipath的默认配置已经集成在系统之中,不需要在/etc/multipath.conf中重新配置。

       path_grouping_policy的默认值为failover。在原始配置中default段设置了multipath设备的默认名称是mpath[n]的形式,如果没有这一段配置(即_friendly_names=yes),设备的默认名称是它的WWID号。

       (3)保存配置文件并退出。

       (4)执行下列命令:

              modprobe dm-multipath

              sevice multipathd start

              multipath -v2

       注:multipath -v2会打印出已经聚合的数据链路。

       (5)使用 chkconfig multipathd on,让multipath服务开机自动启动。

       6.2排除本地scsi磁盘

       很多系统都安装有本地scsi磁盘,DM-Multipath是不建议在这些磁盘上使用的。可以按照下面的步骤取消对本地scsi磁盘的映射。

       (1)使用 multipath -v2 确认本地磁盘的信息。如下面的示例(sda为本地scsi磁盘):

       [root@localhost ~]# multipath -v2

       create: SIBM-ESXSST336732LC____F3ET0EP0Q000072428BX1

       [size=33 GB][features="0"][hwhandler="0"]

       \_ round-robin 0

         \_ 0:0:0:0 sda  8:0    [---------

        device-mapper ioctl cmd 9 failed: Invalid argument

        device-mapper ioctl cmd 14 failed: No such device or address

        create: 3600a0b80001327d80000006d43621677

        [size=12 GB][features="0"][hwhandler="0"]

        \_ round-robin 0

          \_ 2:0:0:0 sdb  8:16    

            \_ 3:0:0:0 sdf  8:80    

        create: 3600 a0b80001327510000009a436215ec

        [size=12 GB][features="0"][hwhandler="0"]

        \_ round-robin 0

          \_ 2:0:0:1 sdc  8:32    

            \_ 3:0:0:1 sdg  8:96    

        create: 3600a0b80001327d800000070436216b3

        [size=12 GB][features="0"][hwhandler="0"]

        \_ round-robin 0

          \_ 2:0:0:2 sdd  8:48    

            \_ 3:0:0:2 sdh  8:112   

        create: 3600a0b80001327510000009b4362163e

        [size=12 GB][features="0"][hwhandler="0"]

        \_ round-robin 0

            \_ 2:0:0:3 sde  8:64    

            \_ 3:0:0:3 sdi  8:128

        (2)为了防止DM-Multipath对/dev/sda做映射,编辑/etc/multipath.conf中的devnode_blacklist段。可以使用devnode的方式过滤sda,不过系统中sda的命名不一定是固定的,所以最好使用wwid的方式。从上面的输出中可以看到/dev/sda的wwid为“SIBM-ESXSST336732LC____F3ET0EP0Q000072428BX1”,在配置文件添加:

        devnode_blacklist{

              wwid SIBM-ESXSST336732LC____F3ET0EP0Q000072428BX1

        }

        (3)执行下面的命令使配置生效,并重新打印multipath设备列表。

              multipath -F

              multipath -v2

       6.3在DM-Multipath中增加新的设备类型

       DM-Multipath支持大部分的存储阵列。默认的配置,可以查看multipath.conf.default文件。

       如果希望添加默认不支持的存储设备,可以在/etc/multipath.conf中添加相应的信息。例如在配置为鉴中添加HP Open-V:

              devices {

                     device {

                            vendor "HP"

                            product "OPEN-V"

                            getuid_callout "/sbin/scsi_id -g -u -p0x80 -s /block/%n"

                     }

              }

 7.DM-Multipath配置文件

       7.1概览

       DM-Multipath的配置文件分为以下几个部分:

       devnode_blacklist

           不使用DM-Multipath的设备列表。默认的情况下,所有的设备都在列表中。启用DM-Multipath的时候一般会将devnote_blacklist段注释掉; 

       defaults

           DM-Multipath的默认通用配置;

       multipaths

           单独配置每一个multipath设备的属性。这些配置会覆盖在defaults段和devices段的配置;

       devices

           单独配置每一个存储控制器。这些配置会覆盖defaults段的配置。如果使用的存储控制器不被DM-Multipath支持,那么就需要为这种类型的控制器加一个devices subsection。

       DM-Multipath确定multipath设备的属性时,会首先使用multipaths段的内容,然后是devices段,最好读取defaults段。

       7.2 配置 blacklist

       devnode_blacklist指定了系统在配置multipath设备时不使用的设备,默认情况所有的设备都在这个列表中。注释掉默认的一行之后,可以在列表中加入某一种类型的设备或者某一特定的设备。禁用设备有2种方法:

           (1)使用wwid:

           可以使用wwid指定特定的设备,如:

           blacklist {

               wwid 26353900f02796769

           }

           (2)使用设备名:

           如:

           devnode_blacklist {

               devnode "^sd[a-z]"

           }

           这一段配置会禁用所有的SCSI磁盘设备。虽然可以使用这种方法禁用单一特定的设备,但是并不建议这样做。因为除非是使用了udev固定了设备的设备名,则设备的名称在每次重启之后是有可能发生变化的。

           因为一些设备并不支持DM-Multipath,所以下面列出的设备是默认禁用的:

           blacklist {

               devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"

                devnode "^hd[a-z]"

                devnode "^cciss!c[0-9]d[0-9]*"

           }



_________________________---------------------------------------------------------------------------------------------------

device-mapper-multipathing,需要完全的升级操作系统。早期的红帽企业Linux 4
不包含这个功能。编辑文件/etc/multipath.conf。在文件头部注释掉如下内容:
devnode_blacklist {
        devnode "*"
}
如下例:
# devnode_blacklist {
#        devnode "*"
# }
取消文件 /etc/multipath.conf中这段的注释,这段内容能让 device-mapper multipathing 不用扫描所有的设备。 etc/multipath.conf file:
defaults {
      multipath_tool  "/sbin/multipath -v0"
      udev_dir        /dev
      polling_interval 10
      default_selector        "round-robin 0"
      default_path_grouping_policy    multibus
      default_getuid_callout  "/sbin/scsi_id -g -u -s /block/%n"
      default_prio_callout    "/bin/true"
      default_features        "0"
      rr_wmin_io              100
      failback                immediate
}
devnode_blacklist {
      wwid 26353900f02796769
      devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
      devnode "^hd[a-z][[0-9]*]"
      devnode "^cciss!c[0-9]d[0-9]*[p[0-9]*]"
}
这段设置了默认的 device-mapper 的动作,并且去出了通常不会有多路径的设备,如IDE硬盘和软盘。默认的hd*设备的黑名单存在这一个排印错误。需要修改。
devnode "^hd[a-z][[0-9]*]"
把上行修改为如下:
devnode "^hd[a-z][0-9]*"
为了实现简单的failover功能,下例中,defaults 组中的默认的 default_path_grouping_policy 选项被设置成为 failover。
defaults {
      multipath_tool  "/sbin/multipath -v0"
      udev_dir        /dev
      polling_interval 10
      default_selector        "round-robin 0"
      default_path_grouping_policy    failover
      default_getuid_callout  "/sbin/scsi_id -g -u -s /block/%n"
      default_prio_callout    "/bin/true"
      default_features        "0"
      rr_wmin_io              100
      failback                immediate
}
退出编辑并保存设置,执行如下命令
modprobe dm-multipath
modprobe dm-round-robin
service multipathd start
multipath -v2
命令 multipath -v2 能显示多路径,从而能知道那些设备工作在多路径下。如果没有所有输出,确认所有的SAN连接被正确的设置,系统有没有正确的开启多路径功能。执行如下命令确认多路径服务有无启动。
chkconfig multipathd on
设备的设备名会被生成,/dev/dm-#,#指代的是多路径组,如果/dev/sda是唯一的多路径设备,/dev/dm-0将会是
/dev/sda和/dev/sdb的多路径设备。注意:fdisk不能用于设备/dev/dm-#,使用fdisk只能操作基础磁盘,要在设备映射多路
径映射设备上创建/dev/dm-#分区的操作. 执行一下命令。
kpartx -a /dev/dm-#
注意: dmsetup ls ?target=multipath
是个协助侦测系统上多路径设备的命令。如果在多路径设备数据库中没有发现硬件,请查看文章“How can I add moreproducts
into the mutipathing database?” 


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Linux系统内核中的Device Mapper机制

发布时间:2008-04-07 10:55:26  来源:linuxfans  作者:linuxfans  点击:228

本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍。Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机制下,用户可以很方便的根据自己的需要制定实现存储资源的管理策略,当前比较流行的 Linux 下的逻辑卷管理器如 LVM2(Linux Volume Manager 2 version)、EVMS(Enterprise Volume Management System)、dmraid(Device Mapper Raid Tool)等都是基于该机制实现的。理解该机制是进一步分析、理解这些卷管理器的实现及设计的基础。通过本文也可以进一步理解 Linux 系统块一级 IO的设计和实现。

Device Mapper 是 Linux2.6 内核中支持逻辑卷管理的通用设备映射机制,它为实现用于存储资源管理的块设备驱动提供了一个高度模块化的内核架构,如图


在内核中它通过一个一个模块化的 target driver 插件实现对 IO 请求的过滤或者重新定向等工作,当前已经实现的 target driver 插件包括软 raid、软加密、逻辑卷条带、多路径、镜像、快照等,图中 linear、mirror、snapshot、multipath 表示的就是这些 target driver。Device mapper 进一步体现了在 Linux 内核设计中策略和机制分离的原则,将所有与策略相关的工作放到用户空间完成,内核中主要提供完成这些策略所需要的机制。Device mapper 用户空间相关部分主要负责配置具体的策略和控制逻辑,比如逻辑设备和哪些物理设备建立映射,怎么建立这些映射关系等等,而具体过滤和重定向 IO 请求的工作由内核中相关代码完成。因此整个 device mapper 机制由两部分组成--内核空间的 device mapper 驱动、用户空间的device mapper 库以及它提供的 dmsetup 工具。在下文中,我们分内核和用户空间两部分进行介绍。

内核部分

Device mapper 的内核相关代码已经作为 Linux 2.6 内核发布版的一部分集成到内核源码中了,相关代码在内核源码的 driver/md/ 目录中,其代码文件可以划分为实现 device mapper 内核中基本架构的文件和实现具体映射工作的 target driver 插件文件两部分。文章下面的分析结果主要是基于上述源码文件得到的。

重要概念

Device mapper 在内核中作为一个块设备驱动被注册的,它包含三个重要的对象概念,mapped device、映射表、target device。Mapped device 是一个逻辑抽象,可以理解成为内核向外提供的逻辑设备,它通过映射表描述的映射关系和 target device 建立映射。从 Mapped device 到一个 target device 的映射表由一个多元组表示,该多元组由表示 mapped device 逻辑的起始地址、范围、和表示在 target device 所在物理设备的地址偏移量以及target 类型等变量组成(这些地址和偏移量都是以磁盘的扇区为单位的,即 512 个字节大小)。Target device 表示的是 mapped device 所映射的物理空间段,对 mapped device 所表示的逻辑设备来说,就是该逻辑设备映射到的一个物理设备。Device mapper 中这三个对象和 target driver 插件一起构成了一个可迭代的设备树。在该树型结构中的顶层根节点是最终作为逻辑设备向外提供的 mapped device,叶子节点是 target device 所表示的底层物理设备。最小的设备树由单个 mapped device 和 target device 组成。每个 target device 都是被mapped device 独占的,只能被一个 mapped device 使用。一个 mapped device 可以映射到一个或者多个 target device 上,而一个 mapped device 又可以作为它上层 mapped device的 target device 被使用,该层次在理论上可以在 device mapper 架构下无限迭代下去。 Device mapper 内核中各对象的层次关系:




在图 中我们可以看到 mapped device1 通过映射表和 a、b、c 三个 target device 建立了映射关系,而 target device a 又是通过 mapped device 2 演化过来,mapped device 2 通过映射表和 target device d 建立映射关系。


我们进一步看一下上述三个对象在代码中的具体实现,dm.c 文件定义的 mapped_device 结构用于表示 mapped device,它主要包括该 mapped device 相关的锁,注册的请求队列和一些内存池以及指向它所对应映射表的指针等域。Mapped device 对应的映射表是由 dm_table.c 文件中定义的 dm_table 结构表示的,该结构中包含一个 dm_target结构数组,dm_target 结构具体描述了 mapped_device 到它某个 target device 的映射关系。而在 dm_table 结构中将这些 dm_target 按照 B 树的方式组织起来方便 IO 请求映射时的查找操作。Dm_target 结构具体记录该结构对应 target device 所映射的 mapped device 逻辑区域的开始地址和范围,同时还包含指向具体 target device 相关操作的 target_type 结构的指针。Target_type 结构主要包含了 target device 对应的 target driver 插件的名字、定义的构建和删除该类型target device的方法、该类target device对应的IO请求重映射和结束IO的方法等。而表示具体的target device的域是dm_target中的private域,该指针指向mapped device所映射的具体target device对应的结构。表示target device的具体结构由于不同的target 类型而不同,比如最简单的线性映射target类型对应target device的结构是dm-linear.c文件中定义的linear_c结构。其定义如下:

代码:
struct linear_c {

 struct dm_dev *dev;

 sector_t start;

};


该target device的定义相当简单,就只包括了表示对应物理设备的dm_dev结构指针和在该物理设备中以扇区为单位的偏移地址start。上述几个数据结构关系如图:




内核中建立过程

在下面我们结合具体的代码简要介绍下在内核中创建一个mapped device的过程:

1、 根据内核向用户空间提供的ioctl 接口传来的参数,用dm-ioctl.c文件中的dev_create函数创建相应的mapped device结构。这个过程很简单,主要是向内核申请必要的内存资源,包括mapped device和为进行IO操作预申请的内存池,通过内核提供的blk_queue_make_request函数注册该mapped device对应的请求队列dm_request。并将该mapped device作为磁盘块设备注册到内核中。

2、 调用dm_hash_insert将创建好的mapped device插入到device mapper中的一个全局hash表中,该表中保存了内核中当前创建的所有mapped device。

3、 用户空间命令通过ioctl调用table_load函数,该函数根据用户空间传来的参数构建指定mapped device的映射表和所映射的target device。该函数先构建相应的dm_table、dm_target结构,再调用dm-table.c中的dm_table_add_target函数根据用户传入的参数初始化这些结构,并且根据参数所指定的target类型,调用相应的target类型的构建函数ctr在内存中构建target device对应的结构,然后再根据所建立的dm_target结构更新dm_table中维护的B树。上述过程完毕后,再将建立好的dm_table添加到mapped device的全局hash表对应的hash_cell结构中。

4、 最后通过ioctl调用do_resume函数建立mapped device和映射表之间的绑定关系,事实上该过程就是通过dm_swap_table函数将当前dm_table结构指针值赋予 mapped_device相应的map域中,然后再修改mapped_device表示当前状态的域。

通过上述的4个主要步骤,device mapper在内核中就建立一个可以提供给用户使用的mapped device逻辑块设备。

IO流

Device mapper本质功能就是根据映射关系和target driver描述的IO处理规则,将IO请求从逻辑设备mapped device转发相应的target device上。Device mapper处理所有从内核中块一级IO子系统的generic_make_request和submit_bio接口,定向到mapped device的所有块读写IO请求。IO请求在device mapper的设备树中通过请求转发从上到下地进行处理。当一个bio请求在设备树中的mapped deivce向下层转发时,一个或者多个bio的克隆被创建并发送给下层target device。然后相同的过程在设备树的每一个层次上重复,只要设备树足够大理论上这种转发过程可以无限进行下去。在设备树上某个层次中,target driver结束某个bio请求后,将表示结束该bio请求的事件上报给它上层的mapped device,该过程在各个层次上进行直到该事件最终上传到根mapped device的为止,然后device mapper结束根mapped device上原始bio请求,结束整个IO请求过程。
Bio在device mapper的设备树进行逐层的转发时,最终转发到一个或多个叶子target节点终止。因为一个bio请求不可以跨多个target device(亦即物理空间段), 因此在每一个层次上,device mapper根据用户预先告知的mapped device 的target映射信息克隆一个或者多个bio,将bio进行拆分后转发到对应的target device上。这些克隆的bio先交给mapped device上对应的target driver上进行处理,根据target driver中定义的IO处理规则进行IO请求的过滤等处理,然后再提交给target device完成。上述过程在dm.c文件中的dm_request函数中完成。Target driver可以对这些bio做如下处理:

1、 将这些bio在本驱动内部排队等待以后进行处理;
2、 将bio重新定向到一个或多个target device上或者每个target device上的不同扇区;
3、 向device mapper返回error 状态。
IO请求就按照上文中描述的过程在图2中所示的设备树中逐层进行处理,直到IO请求结束。

小结

Device mapper在内核中向外提供了一个从逻辑设备到物理设备的映射架构,只要用户在用户空间制定好映射策略,按照自己的需要编写处理具体IO请求的 target driver插件,就可以很方便的实现一个类似LVM的逻辑卷管理器。Device mapper以ioctl的方式向外提供接口,用户通过用户空间的device mapper库,向device mapper的字符设备发送ioctl命令,完成向内的通信。它还通过ioctl提供向往的事件通知机制,允许target driver将IO相关的某些事件传送到用户空间。

用户空间部分

Device mapper在用户空间相对简单,主要包括device mapper库和dmsetup工具。Device mapper库就是对ioctl、用户空间创建删除device mapper逻辑设备所需必要操作的封装,dmsetup是一个提供给用户直接可用的创建删除device mapper设备的命令行工具。因为它们的功能和流程相对简单,在本文中对它们的细节就不介绍了,用户空间主要负责如下工作:

1、 发现每个mapped device相关的target device;
2、 根据配置信息创建映射表;
3、 将用户空间构建好的映射表传入内核,让内核构建该mapped device对应的dm_table结构;
4、 保存当前的映射信息,以便未来重新构建。

以下我们主要通过实例来说明dmsetup的使用,同时进一步说明device mapper这种映射机制。用户空间中最主要的工作就是构建并保存映射表,下面给出一些映射表的例子:

代码:
1)
0 1024 linear /dev/sda 204
1024 512 linear /dev/sdb 766

1536 128 linear /dev/sdc 0
2) 0 2048 striped 2 64 /dev/sda 1024 /dev/sdb 0

3) 0 4711 mirror core 2 64 nosync 2 /dev/sda 2048 /dev/sdb 1024


例子1中将逻辑设备0~1023扇区、1024~1535扇区以及1536~1663三个地址范围分别以线形映射的方式映射到/dev/sda设备第204号扇区、/dev/sdb设备第766号扇区和/dev/sdc设备的第0号扇区开始的区域。

例子2中将逻辑设备从0号扇区开始的,长度为2048个扇区的段以条带的方式映射的到/dev/sda设备的第1024号扇区以及/dev/sdb设备的第0号扇区开始的区域。同时告诉内核这个条带类型的target driver存在2个条带设备与逻辑设备做映射,并且条带的大小是64个扇区,使得驱动可以该值来拆分跨设备的IO请求。

例子3中将逻辑设备从0号扇区开始的,长度为4711个扇区的段以镜像的方式映射到/dev/sda设备的第2048个扇区以及/dev/sdb设备的第1024号扇区开始的区域。

映射表确定后,创建、删除逻辑设备的操作就相对简单,通过dmsetup如下命令就可以完成相应的操作。

代码:
dmsetup create 设备名 映射表文件 /* 根据指定的映射表创建一个逻辑设备 */

dmsetup reload 设备名 映射表文件 /* 为指定设备从磁盘中读取映射文件,重新构建映射关系 */

dmsetup remove 设备名 /* 删除指定的逻辑设备 */




上图根据例子1中映射表在内核中建立的逻辑设备

当用户空间根据映射表下达创建逻辑设备命令后,device mapper在内核中就根据传入的参数和映射关系建立逻辑地址到物理地址的映射关系。根据映射表例子1中的映射关系建立的设备如图4所示,图中的下半部分就抽象地描绘出了按照该映射表在内核中建立的逻辑地址到物理地址的映射关系。

Device mapper的用户空间部分对开发者要实现自己的存储管理工具来说是可选的,事实上,很多我们常见的逻辑卷管理器,比如LVM2、dmraid等工具都利用device mapper的提供的device mapper用户空间库,根据自己的管理需求建立独立的一套管理工具,而并没有使用它提供的dmsetup工具,甚至IBM的开源项目企业级的逻辑卷管理系统-EVMS,在实现中都没有采用device mapper的用户空间库,完全根据内核中的ioctl定义实现了一套自己的函数库。

Target Driver

Device mapper提供了一个统一的架构,通过target driver 插件的方式允许用户根据实际的需要指定自己的IO处理规则,因此target driver充分体现了device mapper的灵活性。在上文中我们已经不止一次的提到过target driver,也描述过target driver的功能,在这里我们结合最简单的linear target driver具体介绍target driver的实现。
Target driver主要定义对IO请求的处理规则,在device mapper中对target driver的操作已定义好了统一的接口,在实现中该接口由我们上文提到的target_type结构中定义,它定义了以下target driver的方法:

1、 构建target device 的方法;
2、 删除target device 的方法;
3、 Target的映射IO请求的方法;
4、 Target结束IO请求的方法;
5、 暂停target device读写的方法;
6、 恢复target device读写的访问;
7、 获取当前target device状态的访问;
8、 Target 处理用户消息的方法;

用户可以根据具体需求选择性地实现上述方法,但一般最少要实现前3种方法,否则在device mapper下不能够正常的工作。linear target driver就只实现了前3种方法和方法7,它完成逻辑地址空间到物理地址空间的线性映射,可以将多个物理设备以线性连接的方式组成一个逻辑设备,就如图 4中描述的那样,通过linear target driver将/dev/sda、/dev/sdb、/dev/sdc的三段连续空间组成了一个大的逻辑块设备。Linear target的实现很简单,它的创建和删除方法主要完成申请和释放描述linear target device所用结构的内存资源;IO映射处理方法的实现更是简单,如下代码所示:

代码:
static int linear_map(struct dm_target *ti, struct bio *bio,

        union map_info *map_context)

{

 struct linear_c *lc = (struct linear_c *) ti->private;

 bio->bi_bdev = lc->dev->bdev;

 bio->bi_sector = lc->start + (bio->bi_sector - ti->begin);

 return 1;

}
 


该映射方法就是将发送给逻辑设备mapped device的bio请求,根据映射关系以线性的方式重新定向到linear target device所表示物理设备的相应位置,如代码所示具体实现方法就是修改bio的bi_bdev设备指针为target device对应的设备指针,并根据target device的起始地址和该bio请求在mapped device设备上的偏移值改变IO请求开始的扇区号bi_sector,从而完成IO请求的重定向。其他target driver的实现也都大同小异,按照device mapper所定义的接口规范,结合自己需要的功能进行实现即可,这里就不一一介绍了,有兴趣的读者可以看内核中具体的target driver代码。


dmsetup help [-c|-C|--columns]
dmsetup create
device_name [-u uuid] [--notable | --table <table> | table_file]
dmsetup remove
[-f|--force] device_name
dmsetup remove_all
[-f|--force]
dmsetup suspend
[--nolockfs] [--noflush] device_name
dmsetup resume
device_name
dmsetup load
device_name [--table <table> | table_file]
dmsetup clear
device_name
dmsetup reload
device_name [--table <table> | table_file]
dmsetup rename
device_name new_name
dmsetup message
device_name sector message
dmsetup ls
[--target target_type] [--exec command] [--tree [-o options]]
dmsetup info
[device_name]
dmsetup info -c|-C|--columns
[--noheadings] [--separator separator] [-o fields] [-O|--sort sort_fields] [device_name]
dmsetup deps
[device_name]
dmsetup status
[--target target_type] [device_name]
dmsetup table
[--target target_type] [device_name]
dmsetup wait
device_name [event_nr]
dmsetup mknodes
[device_name]
dmsetup targets
dmsetup version
dmsetup setgeometry
device_name cyl head sect start

devmap_name major minor
devmap_name
major:minor

Description

dmsetup manages logical devices that use the device-mapper driver. Devices are created by loading a table that specifies a target for each sector (512 bytes) in the logical device.

The first argument to dmsetup is a command. The second argument is the logical device name or uuid.

Invoking the command as devmap_name is equivalent to
dmsetup info -c --noheadings -j
major -m minor.

Options

-c|-C|--columns

Display output in columns rather than as Field: Value lines.
-j|--major major
Specify the major number.
-m|--minor minor
Specify the minor number.
-n|--noheadings
Suppress the headings line when using columnar output.
--noopencount
Tell the kernel not to supply the open reference count for the device.
--notable
When creating a device, don't load any table.
-o|--options
Specify which fields to display.
-r|--readonly
Set the table being loaded read-only.
--table <table>
Specify a one-line table directly on the command line.
-u|--uuid
Specify the uuid.
-v|--verbose [-v|--verbose]
Produce additional output.
--version
Display the library and kernel driver version.

Commands

create

device_name [-u uuid] [--notable | --table <table> | table_file]

Creates a device with the given name. If table_file or <table> is supplied, the table is loaded and made live. Otherwise a table is read from standard input unless --notable is used. The optional uuid can be used in place of device_name in subsequent dmsetup commands. If successful a device will appear as /dev/device-mapper/<device-name>. See below for information on the table format.
deps

[device_name]

Outputs a list of (major, minor) pairs for devices referenced by the live table for the specified device.
help

[-c|-C|--columns]

Outputs a summary of the commands available, optionally including the list of report fields.
info

[device_name]

Outputs some brief information about the device in the form:
State: SUSPENDED|ACTIVE, READ-ONLY
Tables present: LIVE and/or INACTIVE
Open reference count
Last event sequence number (used by wait)
Major and minor device number
Number of targets in the live table
UUID
info

[--noheadings] [--separator separator] [-o fields] [-O|--sort sort_fields] [device_name]

Output you can customise. Fields are comma-separated and chosen from the following list: name, major, minor, attr, open, segments, events, uuid. Attributes are: (L)ive, (I)nactive, (s)uspended, (r)ead-only, read-(w)rite. Precede the list with '+' to append to the default selection of columns instead of replacing it. Precede any sort_field with - for a reverse sort on that column.
ls

[--target target_type] [--exec command] [--tree [-o options]]

List device names. Optionally only list devices that have at least one target of the specified type. Optionally execute a command for each device. The device name is appended to the supplied command. --tree displays dependencies between devices as a tree. It accepts a comma-separate list of options. Some specify the information displayed against each node: device/nodevice; active, open, rw, uuid. Others specify how the tree is displayed: ascii, utf, vt100; compact, inverted, notrunc.
load|reload
device_name [--table <table> | table_file]
Loads <table> or table_file into the inactive table slot for device_name. If neither is supplied, reads a table from standard input.
message
device_name sector message
Send message to target. If sector not needed use 0.
mknodes
[device_name]
Ensure that the node in /dev/mapper for device_name is correct. If no device_name is supplied, ensure that all nodes in /dev/mapper correspond to mapped devices currently loaded by the device-mapper kernel driver, adding, changing or removing nodes as necessary.
remove

[-f|--force] device_name

Removes a device. It will no longer be visible to dmsetup. Open devices cannot be removed except with older kernels that contain a version of device-mapper prior to 4.8.0. In this case the device will be deleted when its open_count drops to zero. From version 4.8.0 onwards, if a device can't be removed because an uninterruptible process is waiting for I/O to return from it, adding --force will replace the table with one that fails all I/O, which might allow the process to be killed.
remove_all
[-f|--force]
Attempts to remove all device definitions i.e. reset the driver. Use with care! From version 4.8.0 onwards, if devices can't be removed because uninterruptible processess are waiting for I/O to return from them, adding --force will replace the table with one that fails all I/O, which might allow the process to be killed. This also runs mknodes afterwards.
rename

device_name new_name

Renames a device.
resume

device_name

Un-suspends a device. If an inactive table has been loaded, it becomes live. Postponed I/O then gets re-queued for processing.
setgeometry
device_name cyl head sect start
Sets the device geometry to C/H/S.
status

[--target target_type] [device_name]

Outputs status information for each of the device's targets. With --target, only information relating to the specified target type is displayed.
suspend
[--nolockfs] [--noflush] device_name
Suspends a device. Any I/O that has already been mapped by the device but has not yet completed will be flushed. Any further I/O to that device will be postponed for as long as the device is suspended. If there's a filesystem on the device which supports the operation, an attempt will be made to sync it first unless --nolockfs is specified. Some targets such as recent (October 2006) versions of multipath may support the --noflush option. This lets outstanding I/O that has not yet reached the device to remain unflushed.
table

[--target target_type] [device_name]

Outputs the current table for the device in a format that can be fed back in using the create or load commands. With --target, only information relating to the specified target type is displayed.
targets
Displays the names and versions of the currently-loaded targets.
version
Outputs version information.
wait

device_name [event_nr]

Sleeps until the event counter for device_name exceeds event_nr. Use -v to see the event number returned. To wait until the next event is triggered, use info to find the last event number.

Table Format

Each line of the table specifies a single target and is of the form:
logical_start_sector num_sectors target_type target_args

There are currently three simple target types available together with more complex optional ones that implement snapshots and mirrors.

linear

destination_device start_sector

The traditional linear mapping.
striped
num_stripes chunk_size [destination start_sector]+
Creates a striped area.
e.g. striped 2 32 /dev/hda1 0 /dev/hdb1 0 will map the first chunk (16k) as follows:
LV chunk 1 -> hda1, chunk 1
LV chunk 2 -> hdb1, chunk 1
LV chunk 3 -> hda1, chunk 2
LV chunk 4 -> hdb1, chunk 2
etc.
error
Errors any I/O that goes to this area. Useful for testing or for creating devices with holes in them.

Examples

# A table to join two disks together
0 1028160 linear /dev/hda 0
1028160 3903762 linear /dev/hdb 0

# A table to stripe across the two disks,
# and add the spare space from
# hdb to the back of the volume

0 2056320 striped 2 32 /dev/hda 0 /dev/hdb 0
2056320 2875602 linear /dev/hdb 1028160


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值