android6存储,Android存储系统之源码篇(6)

当前主线程发送消息H_DAEMON_CONNECTED给线程“MountService”,该线程收到消息后调用MountServiceHandler的handleMessage()相应分支后,进而调用handleDaemonConnected()方法。

private void handleDaemonConnected() {

synchronized (mLock) {

resetIfReadyAndConnectedLocked();

}

//类型为CountDownLatch,用于多线程同步,阻塞await()直到计数器为零

mConnectedSignal.countDown();

if (mConnectedSignal.getCount() != 0) {

return;

}

//调用PMS来加载ASECs

mPms.scanAvailableAsecs();

//用于通知ASEC扫描已完成

mAsecsScanned.countDown();

}

这里的PMS.scanAvailableAsecs()经过层层调用,最终核心工作还是通过MountService.getSecureContainerList。

[-> MountService.java]

public String[] getSecureContainerList() {

enforcePermission(android.Manifest.permission.ASEC_ACCESS);

//等待mConnectedSignal计数锁达到零

waitForReady();

//当没有挂载Primary卷设备,则弹出警告

warnOnNotMounted();

try {

//向vold进程发送asec list命令

return NativeDaemonEvent.filterMessageList(

mConnector.executeForList("asec", "list"), VoldResponseCode.AsecListResult);

} catch (NativeDaemonConnectorException e) {

return new String[0];

}

}

三、Vold

Vold是由开机过程中解析init.rc时启动:

on post-fs-data

start vold

Vold的service定义如下:

service vold /system/bin/vold

class core

socket vold stream 0660 root mount

socket cryptd stream 0660 root mount

ioprio be 2

接下来便进入main()方法:

3.1 main

[-> system/vold/Main.cpp]

int main(int argc, char** argv) {

setenv("ANDROID_LOG_TAGS", "*:v", 1);

android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));

VolumeManager *vm;

CommandListener *cl;

CryptCommandListener *ccl;

NetlinkManager *nm;

//解析参数,设置contenxt

parse_args(argc, argv);

...

fcntl(android_get_control_socket("vold"), F_SETFD, FD_CLOEXEC);

fcntl(android_get_control_socket("cryptd"), F_SETFD, FD_CLOEXEC);

mkdir("/dev/block/vold", 0755);

//用于cryptfs检查,并mount加密的文件系统

klog_set_level(6);

//创建单例对象VolumeManager 【见小节3.2.1】

if (!(vm = VolumeManager::Instance())) {

exit(1);

}

//创建单例对象NetlinkManager 【见小节3.3.1】

if (!(nm = NetlinkManager::Instance())) {

exit(1);

}

if (property_get_bool("vold.debug", false)) {

vm->setDebug(true);

}

// 创建CommandListener对象 【见小节3.4.1】

cl = new CommandListener();

// 创建CryptCommandListener对象 【见小节3.5.1】

ccl = new CryptCommandListener();

//【见小节3.2.2】

vm->setBroadcaster((SocketListener *) cl);

//【见小节3.3.2】

nm->setBroadcaster((SocketListener *) cl);

if (vm->start()) { //【见小节3.2.3】

exit(1);

}

process_config(vm); //【见小节3.2.4】

if (nm->start()) { //【见小节3.3.3】

exit(1);

}

coldboot("/sys/block");

//启动响应命令的监听器 //【见小节3.4.2】

if (cl->startListener()) {

exit(1);

}

if (ccl->startListener()) {

exit(1);

}

//Vold成为监听线程

while(1) {

sleep(1000);

}

exit(0);

}

该方法的主要功能是创建下面4个对象并启动

VolumeManager

NetlinkManager (NetlinkHandler)

CommandListener

CryptCommandListener

接下来分别说说几个类:

3.2 VolumeManager

3.2.1 创建

[-> VolumeManager.cpp]

VolumeManager *VolumeManager::Instance() {

if (!sInstance)

sInstance = new VolumeManager();

return sInstance;

}

创建单例模式的VolumeManager对象

VolumeManager::VolumeManager() {

mDebug = false;

mActiveContainers = new AsecIdCollection();

mBroadcaster = NULL;

mUmsSharingCount = 0;

mSavedDirtyRatio = -1;

//当UMS获取时,则设置dirty ratio为0

mUmsDirtyRatio = 0;

}

3.2.2 vm->setBroadcaster

void setBroadcaster(SocketListener *sl) {

mBroadcaster = sl;

}

将新创建的 CommandListener 对象sl赋值给vm对象的成员变量 mBroadcaster

3.2.3 vm->start

int VolumeManager::start() {

//卸载所有设备,以提供最干净的环境

unmountAll();

//创建Emulated内部存储

mInternalEmulated = std::shared_ptr<:vold::volumebase>(

new android::vold::EmulatedVolume("/data/media"));

mInternalEmulated->create();

return 0;

}

mInternalEmulated的据类型为 EmulatedVolume ,设备路径为 /data/media ,id和label为“emulated”,mMountFlags=0。 EmulatedVolume 继承于 VolumeBase

3.2.3.1 unmountAll

int VolumeManager::unmountAll() {

std::lock_guard<:mutex> lock(mLock);

//卸载内部存储

if (mInternalEmulated != nullptr) {

mInternalEmulated->unmount();

}

//卸载外部存储

for (auto disk : mDisks) {

disk->unmountAll();

}

FILE* fp = setmntent("/proc/mounts", "r");

if (fp == NULL) {

return -errno;

}

std::list<:string> toUnmount;

mntent* mentry;

while ((mentry = getmntent(fp)) != NULL) {

if (strncmp(mentry->mnt_dir, "/mnt/", 5) == 0

|| strncmp(mentry->mnt_dir, "/storage/", 9) == 0) {

toUnmount.push_front(std::string(mentry->mnt_dir));

}

}

endmntent(fp);

for (auto path : toUnmount) {

//强制卸载

android::vold::ForceUnmount(path);

}

return 0;

}

此处打开的”/proc/mounts”每一行内容依次是文件名,目录,类型,操作。例如:

/dev/fuse /mnt/runtime/default/emulated fuse rw,nosuid,nodev,...

该方法的主要工作是卸载:

内部存储mInternalEmulated;

外部存储mDisks,比如sdcard等;

“/proc/mounts”中目录包含mnt或者storage的路径;

(责任编辑:ioter)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值