一、 device-mapper基本原理介绍
1.1 dm工作原理
1.2 dm实现动态卷(逻辑分区)功能介绍(dm-linear)
1.3 dm 实现完整性校验功能介绍(dm-verity)
1.4 元数据加密(default-key)
1.5 dm实现快照功能介绍(snapshot,snapshot-origin,dm-snapshot-merge,bow)
二、vold介绍
2.1 vold结构总览
2.2 encryptFstab(元数据加解密)
2.3 mountFstab(挂载分区)
2.4 fbeEnable(使能fbe加密)
2.5 initUser0
三、分区挂载流程介绍
3.1 分区挂载顺序总览
3.2 metadata分区挂载流程
3.3 system分区挂载流程
3.4 userdata分区挂载流程
四、 常见问题汇总
4.1 set_policy_failed问题
4.2 init_user0_failed问题
4.3 enablefilecrypto_failed问题
4.4 userdata挂载失败问题
4.5 关机时ServiceManager crash导致vold shutdown超时死机重启
前言:
还没开始深入了解分区挂载原理时,觉得分区挂载涉及的内容应该不会很多。就是在分区表中找到对应的物理块,然后直接mount就完成了,最多就是需要了解一些流程顺序上的内容。
当真正开始走读分区挂载流程代码时,才发现之前的想法太天真了。如果要深入了解分区挂载原理,需要了解的内容很多。
在远古android时期,挂载真的如上面描述的,仅仅是一个挂载(一个物理分区由文件系统管理起来)
但是随着对分区使用效率,安全等提出了越来越多的要求,分区挂载涉及的内容也越来越多。
例如:为了解决system和vender等分区size不能动态调整的问题引入动态分区概念(逻辑分区),将system,vendor等分区打包放在了super分区下;system等关键分区为了防止篡改,在挂载或使用时,需要这些分区进行完整性校验;为了用户数据的安全,对userdata分区中的数据需要加密,加密方式也有较早的FDE( Full-disk encryption全盘加密),发展到现在更精细化的FBE(File-based Encryption文件级加密),并且针对userdata还增加了 metadata(元数据)级别的加密;系统分区也有之前的单分区进recovery下升级,到A/B分区到recovery下升级,再到现在的VAB分区架构,借用snapshot(快照)技术完成升级及回滚等等。
如果要对分区挂载有一个完整系统的了解,上面提到的那些技术都是绕不开的。但是每一项技术深入到代码细节介绍的话是不现实的,而且也不是我们这篇文章的重点。
所以下面我们先对用到的技术做一些原理介绍,了解他们是怎么工作的,不深入代码。对这些技术有基本的了解后,我们对整个分区挂载逻辑深入到代码级别去分析。
一、device-mapper基本原理介绍
1.1 dm工作原理
device-mapper是linux块设备映射技术框架。我们挂载用到的动态卷(逻辑分区),完整性校验(dm-verity),vab升级用到snapshot(快照)技术都离不开它。
它是在块设备上的一层映射,对外来看,它也是一个块设备(虚拟块设备)。它有三个重要概念,映射设备(mapped device),映射表(map table),目标设备(traget device)。这样说可能比较抽象。
我们可以类别成图书馆场景来了解一下它的工作原理。
图书馆中摆着一排排书,每一本书就像是我们块设备中的物理块。一排书架可以看做是一个块设备(由一个个物理块组成)。我们在存放书时,按照书的特性进行分类存放,例如经济类的书存放在一个书架,人文历史的书存放在另一个书架。这样的好处就是我们可以根据我们要拿书的种类去快速找到我们需要的书。
但是某一天图书馆的领导换了,他觉得根据书种类搜索的方法太单一了,还希望能通过书名首字母方式快速找到需要的书。这应该怎么解决呢?有一个办法就是再建一个图书馆,买一模一样的书。然后书架上按照首字母的方式排列。这样你想按首字母找也行,想按类型找也行,显然是不可能的。
这时候有一种解决方案就是建立了一个虚拟书架(虚拟块设备),这个虚拟书架对外来看,和其他书架没有区别,但是实际上面摆放的只是一张张小卡片,这些小卡片上面写的书名以及这本书真正摆放的物理位置(映射表),并且是按照拼音首字母排序的。当我们去这个书架上拿书的时候,图书管理员(device mapper驱动)会根据卡片上的内容,快速到这本书真正摆放的位置(目标设备),拿到真正的书,并给到我们。对我们来说,我们也可以在这个虚拟书架上拿到真正的书,所以用起来和其他实际的物理书架也没有什么区别。这个就是device-mapper的工作原理。
所以我们看到device-mapper工作只是增加了一层映射,对外来看它也是一个块设备,在实际访问时,device-mapper的区别会根据映射表,去真正块设备(目标设备)上的物理块上帮我们拿到需要的数据返回给我们。
Device-mapper使用起来也比较灵活
一个虚拟书架的目标设备也可以是另一个虚拟书架,这也很好理解,因为对外来看,虚拟书架和物理书架使用起来并没有什么区别。
也可以只映射一个物理分区的部分块,同样也可以将两个物理分区中的内容映射到同一个虚拟块设备中。后面的章节会介绍这种特性的使用。
dmctl list targets
可以查看dm设备支持的不同类型,后面章节介绍的一些功能其实都是不同dm设备类型的应用。dmctl list targets可以看到手机中支持的不同targets
手机中的dm设备及targets列表如下
dm设备名 |
target |
my_engineering_a |
linear |
my_heytap_a |
linear |
system_ext_a |
linear |
userdata |
default-key |
vendor_dlkm-verity |
verity |
odm_a |
linear |
system_a |
linear |
vendor-verity |
verity |
vendor_dlkm_a |
linear |
vendor_a |
linear |
system_ext-verity |
verity |