Android 的存储系统主要由
SystemServer 进程中的MountService:
为应用提供服务的Binder类,StorageManager 是 MountService的代理,在用户进程中使用。
和
Vold进程(volume daemon 是一个守护进程,负责和底层存储系统的驱动交互,管理各种存储设备,包括外置USB和SD卡设备,)中的VolumeManager:
VolumeManager 管理着系统底层所有的Volume 对象,实现各种存储相关的操作。
CommandListener 对象负责和MountService 中的 NativeDemonConnector 进行 socket通信, 而 NetlinkHandler 对象则负责监听来自驱动的 Netlink Socket消息。
NetlinkerManager 对象的主要工作主要是监听驱动发出的uevent消息,主要作用是创建3个NetlinkHandler对象。
组成。
MountService 和Vold 之间通过socket进行通信,这个通信过程是双向的,有从MountService到Vold的操作命令,也有从Vold到MountService的消息,用来通知底层硬件发生了变化。
MountService 通过vold进程查询和操作存储设备。如果外部存储设备发生变化,如插入USB,Vold将会接受到内核的UEvent消息并转发给MountService.
他们管理着系统的存储设备,执行各种操作,包括:
mount:
unmount:
format:
对存储设备的操作———MountService服务
MountService 作为 SystemServer中的一个Binder服务,他的作用是让用户进程能通过他的接口对系统的各种存储设备进行各种操作。这些是在Vold中完成的,MountService只是把命令发送到了Vold进程中。
MountService构造方法的工作是;
1.获得PackageManagerService的引用,因为底层存储系统的变化会导致PackageManagerService重新扫描存储器,因此,当存储器发生变化时,MountService收到了底层的消息会通知PackageManagerService重新扫描。
2.监听几种Itent,包括用户发生变化的Itent:ACTION_USER_ADDED, ACTION_USER_REMOVED; usb状态发生变化的Itent:ACTION_USB_STATE.以及系统空闲的Itent:ACTION_IDLE_MAINTENANCE_START.
3.创建ObbActionHandler对象,用于处理和Obb文件系统相关的消息
4.创建NativeDaemonConnector对象,用于和底层的Vold进行socket通信
5.创建一个线程,这个线程的执行函数是NativeDaemonConnector对象的run()方法。
VolumeManager 的作用——创建实例对象
vold 的main()函数中调用了VolumeManager 的Instance()函数来创建实例对象。和NetlinkManager对象一样,VolumeManager也只能创建一个对象。在main()函数中,还调用了process_config() 函数,该函数首先读取fstab.xxx文件的内容,然后根据文件中每行定义的存储器的属性来创建DirectVolume对象,所有对象都将加入到VolumeManager中。/fstab.xxx文件的后缀名是根据设备的属性值ro.hardware来确定的。例如,fstab.hammerhead。这个文件有很多行,每行都是设备中分区的5种属性:
第一个值是分区的原始位置,例如,/dev/block/platform/msm_sdcc.1/by-name/system;
第二个值是挂载点,例如/system;
第三个值是分区的类型,通常值为ext4, vfat和emmc;
第四个值是mount分区使用的标志和属性,例如ro.barrier=1;
第五个值是定义分区的属性,包括是否加密、是否能够移动等,不过大部分情况下他的值为default。
process_config()函数会使用从文件中读到的内容,每行创建一个对应的DirectVolume对象,然后把对象加入到VolumeManager对象中。
NetlinkHandler中接收到从驱动来的消息,回调用VolumeManager中各种DirectVolume对象的handleBlockEvent()函数来处理。
从驱动发送的消息有三大类:
N1ActionAdd:
handleDiskAdded: 设置DirectVolume对象的状态,让他和底层的硬件状态保持一致,这样当上层查询时,返回的结果能和硬件的实际状况一致。还能从消息中得到磁盘的分区数量,如果分区数量为0,设备的状态马上可以变成State_Idle,这样上层软件就可以使用这个设备了,如果分区数量不为0,还需要等到增加分区的消息带来后,才能让设备的状态变为State_Idle,当前只能先将设备的状态改为State_Pending.
handlePartitionAdded
N1ActionRemove:
handleDiskRemove
handlePartitionRemove
N1ActionChange:
handleDiskChange
handlePartitionChange
handleBlockEvent()函数会比较消息中的DEVPATH和DirectVolume的路径参数,相等才会处理。
底层什么时候会发送这三种消息?例如插入和移除了SD卡,就会触发驱动发送消息通知Vold模块。根据设备的类型是Disk还是Partition,最后一共有六种处理函数。
监视存储设备大小:
添加用户存储分区: