在手机上敲一下mount命令,看到很多挂载成dm设备,它们到底是什么?背后的原理又是怎样的?以OPPO Reno3为例:
首先请看下:Linux Storage Stack Diagram存储堆栈图,其中用红色框标记的部分就是今天要说说明DeviceMapper。
Device Mapper是Linux2.6 内核中支持逻辑卷管理的通用设备映射机制,它为实现用于存储资源管理的块设备驱动提供了一个高度模块化的内核架构。
Device Mapper将所有与策略相关的工作放到用户空间完成,内核中主要提供完成这些策略所需要的机制。用户空间部分责配置具体的策略和控制逻辑,比如逻辑设备和哪些物理设备建立映射,怎么建立这些映射关系等,而具体重定向 IO 请求的工作由内核中相关代码完成。
内核中相关代码在内核源码的 kernel/driver/md/ 目录中,其代码文件可以划分为实现device mapper 内核中基本架构的文件(例如:dm.c dm_table.c等)和实现具体映射工作的 target driver 插件文件(例如:dm-bow.c dm-crypt.c dm-linear.c等)两部分。
它包含三个重要的对象概念,Mapped Device、Mapping Table、Target device。
-
Mapped Device:是一个抽象的逻辑设备,通过MappingTable描述的映射关系(Mapped Device 逻辑的起始地址、范围、和表示在 Target Device 所在物理设备的地址偏移量以及Target 类型等信息)和Target Device建立映射关系。
-
Target Device:是Mapped Device所映射的物理空间段。
-
Mapping Table:DeviceMapper在内核中通过一个一个模块化的 Target Driver 插件实现对 IO 请求的过滤或者重新定向等工作,当前已经实现的插件包括:dm-crypt、dm-linear、dm-verity、dm-bow、dm-raid等。
Device mapper 中这三个对象和 target driver 插件一起构成了一个可迭代的设备树。该层次在理论上可以在 device mapper 架构下无限迭代下去。
核心数据结构
mapped_device :在dm.c 文件中定义,该结构用于表示 mapped device,它主要包括该 mapped device 相关的锁,注册的请求队列和一些内存池以及指向它所对应映射表的指针等域。
dm_table:在文件dm_table.c 文件中定义,该结构中包含一个 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 类型而不同。
开发者可以定制device target部分,以实现自己所需要的需求功能:
三步建立dm设备的过程
通过下述的三个主要步骤,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请求过程。
总结
Android中很多特性都是使用上述的框架实现的。
使用了这些功能的分区在mount命令的看到都是dm-x(x表示数字,与创建dm设备的顺序有关)的设备。也就是说在dm设备与实际物理设备之间是有一个映射关系的,这个关系就是devicemapper中的io转发逻辑。
最后解释下第一张图中的dm设备的含义
一个思考题:
dm设备都是从数字0开始创建的,为什么androidQ以后的版本都看不到dm-0呢?
![](https://i-blog.csdnimg.cn/blog_migrate/e63873685ec1f0d97dbe1a86d8f6afe5.png)
“内核工匠”微信公众号
Linux 内核黑科技 | 技术文章 | 精选教程