Android -- Vold机制简要分析
- 格式:doc
- 大小:407.00 KB
- 文档页数:27
Android -- Vold机制简要分析
V old是用于管理和控制Android外部存储介质的后台进程,这里说的管控,主要包括SDK 的插拔、挂载/卸载和格式化等;它是Android平台外部存储系统的管控枢纽。
V old的整个控制模块主要由三个类模块构成:NetlinkManager、V olumeManager和CommandListener,它们的功能划分大概是:
NetlinkManager:用于从kernel中获取SD卡插拔的Uevnet消息
V olumeManager:管理模块,对NetlinkManager转发的消息做一些处理,并通过CommandListener发送给framework(MountService.java);接着framework会通过套接字下发命令,指引VolumeManager对存储设备做下一步的操作,如挂载/卸载等CommandListener:通过socket,实现MountService.java与V old之间的消息交换
NetLink是Linux下用户进程和kernel进行信息交互的一种机制,借助这种机制,用户进程(如V old/Netd)可以接收来自kernel的一些消息,同时也可以向kernel发送一些控制命令。NetlinkManager就是基于此设计的。Uevent也跟Linux系统有关,它与Linux 的设备文件系统有一定关系;这里,我们可以简单的认为,Uevent就是一个字符串,它描述了外部存储设备插入/拔出、挂载/卸载的状态信息。V old通过Netlink机制,可以得到这些信息,并进行外部存储设备的管理、控制。
由上述介绍,我们可以得到如下的V old框架图描述:
有了V old的架构描述,接下来就开始分析V old进程的整体流程及实现了。
一、V old进程的声明与创建
V old进程的声明与创建过程跟zygote一样,在init.rc中声明,在init进程创建:
[java] view plain copy 在CODE上查看代码片派生到我的代码片
service vold /system/bin/vold \
--blkid_context=u:r:blkid:s0 --blkid_untrusted_context=u:r:blkid_untrusted:s0 \
--fsck_context=u:r:fsck:s0 --fsck_untrusted_context=u:r:fsck_untrusted:s0
class core
socket vold stream 0660 root mount
socket cryptd stream 0660 root mount
ioprio be 2
在创建Vold进程时,会为它创建两个socket,用于与framework进行信息交互。其他的细节,参考之前zygote进程创建的介绍。
二、进入Vold主程序
V old的主程序在/system/vold目录中,直接看main.cpp::main()函数:
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
int main(int argc, char** argv) {
setenv("ANDROID_LOG_TAGS", "*:v", 1);
android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
LOG(INFO) << "V old 3.0 (the awakening) firing up";
LOG(VERBOSE) << "Detected support for:"
<< (android::vold::IsFilesystemSupported("ext4") ? " ext4" : "")
<< (android::vold::IsFilesystemSupported("f2fs") ? " f2fs" : "")
<< (android::vold::IsFilesystemSupported("vfat") ? " vfat" : "");
V olumeManager *vm;
CommandListener *cl;
CryptCommandListener *ccl;
NetlinkManager *nm;
parse_args(argc, argv);
sehandle = selinux_android_file_context_handle();
if (sehandle) {
selinux_android_set_sehandle(sehandle);
}
// Quickly throw a CLOEXEC on the socket we just inherited from init
fcntl(android_get_control_socket("vold"), F_SETFD, FD_CLOEXEC);//拿到init进程创建的名为vold的socket句柄,并为它设置FD_CLOEXEC标志位
fcntl(android_get_control_socket("cryptd"), F_SETFD, FD_CLOEXEC);//同上
mkdir("/dev/block/vold", 0755);//创建/dev/block/vold目录,存放所有subdisk和sdcard的挂载点信息
/* For when cryptfs checks and mounts an encrypted filesystem */
klog_set_level(6);
/* Create our singleton managers */