注: 此系列文章基于Android11,写于2021年,原本发布于公司wiki. Android12之后多了passthrough
Fuse 系列内容简介:
- 核心原理概述
- mount篇
- App进程创建篇 --- bindmount
- FuseDeamon启动---loop
- 以 open 为例子概述内核fuse流程
- passthrough 方案
内容涉及知识点:
-
vold 服务进程 VoldNativeService.cpp
-
mount 服务进程 StorageManagerService.java
-
mount挂载
- bind mount挂载
- 命名空间mount挂载
-
Linux内核空间-用户空间
-
系统调用与中断
-
Linux文件系统 以及 文件与进程之间的权限关系
-
Zygote进程---App进程创建流程 bind mount挂载
-
繁琐,复杂,冗余,杂乱,恶心,非人类,反人性的 sdcard 目录
^
讲解目标
理解这些目录为什么都是相同内容:
底层目录:/data/media/0
上层目录:storage/emulated/0
挂载目录:/mnt/user/0/emulated/0
/mnt/pass_through/0/emulated/0
/mnt/installer/0/emulated/0
链接: /sdcard
Android Fuse 的难点就是 各个目录之间的挂载关系很复杂:
理解这些目录为什么都是相同内容:
底层目录:/data/media/ 真实文件所在目录
挂载目录:
/mnt/user/0/ vold服务代码中把目录 /mnt/user/0/emulated 挂载为 fuse 文件系统 /mnt/pass_through/0/ vold服务代码中通过bindmount 指向 /data/media/
上层目录:
/storage/ init.rc 文件中,通过bindmount 指向 /mnt/user/0
因此对于普通进程而言,访问 /storage 目录就是访问 /mnt/user/0/ 目录。
/mnt/user/0/ 目录为Fuse文件系统,因此其访问请求被Fuse系统内核转发到用户空间FuseDaemon所在的 MediaProvider 进程处理。
命名空间moun目录:
对于 MediaProvider 进程: 在进程创建过程中把 /storage 通过命名空间bindmount 指向 /mnt/pass_through/0 目录。
又因为/mnt/pass_through/0 指向 /data/media/ ,
因此,MediaProvider 接收到内核转发的文件请求,再去访问文件时,是访问的文件真实所在的目录 /data/media/
链接: /sdcard 链接到 /storage/self/primary,/storage/self/primary 又链接到 /storage/emulated/0