android /system/vold源码分析(7)
2016-06-13 22:55
344 查看
process_config()分析:
process_config函数用来解析/ fstab.xxx的配置文件.
这个函数还初始化了VolumeManage和DirectVolume。
有关VolumeManage的初始化基本是这个函数内进行,除此函数,VolumeManage的初始化工作做得很少。
process_config()的代码如下:
static int process_config(VolumeManager *vm)
{
char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
char propbuf[PROPERTY_VALUE_MAX];
int i;
int ret = -1;
int flags;
property_get("ro.hardware", propbuf, "");
snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
fstab = fs_mgr_read_fstab(fstab_filename);
if (!fstab) {
SLOGE("failed to open %s\n", fstab_filename);
return -1;
}
/* Loop through entries looking for ones that vold manages */
for (i = 0; i < fstab->num_entries; i++) {
if (fs_mgr_is_voldmanaged(&fstab->recs[i])) {
DirectVolume *dv = NULL;
flags = 0;
/* Set any flags that might be set for this volume */
if (fs_mgr_is_nonremovable(&fstab->recs[i])) {
flags |= VOL_NONREMOVABLE;
}
if (fs_mgr_is_encryptable(&fstab->recs[i])) {
flags |= VOL_ENCRYPTABLE;
}
/* Only set this flag if there is not an emulated sd card */
if (fs_mgr_is_noemulatedsd(&fstab->recs[i]) &&
!strcmp(fstab->recs[i].fs_type, "vfat")) {
flags |= VOL_PROVIDES_ASEC;
}
dv = new DirectVolume(vm, &(fstab->recs[i]), flags);
if (dv->addPath(fstab->recs[i].blk_device)) {
SLOGE("Failed to add devpath %s to volume %s",
fstab->recs[i].blk_device, fstab->recs[i].label);
goto out_fail;
}
vm->addVolume(dv);
}
}
ret = 0;
out_fail:
return ret;
}
/fstab.xxx文件格式为:
<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
例如:
fs_mgr_read_fstab(fstab_filename);的作用即是解析fstab文件的每行并返回fstab结构体:struct fstab {
int num_entries; //fstab文件中每行(除空行和注释外)解析出一个fstab_rec结构体。
struct fstab_rec *recs;
char *fstab_filename; //即fstab文件名
};
struct fstab_rec {
char *blk_device;
char *mount_point;
char *fs_type;
unsigned long flags;
char *fs_options;
int fs_mgr_flags;
char *key_loc;
char *verity_loc;
long long length;
char *label;
int partnum;
int swap_prio;
unsigned int zram_size;
};
下面的代码根据每个fstab_rec生成一个DirectVolume类, 并执行:
vm->addVolume(dv);
即对VolumeManager做了初始化工作。注意DirectVolume是Volume的子类。
分析一些多余的代码,当NetlinkHandler接收到来自block子系统的uevent时:
执行VolumeManager:: handleBlockEvent(evt):void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
const char *devpath = evt->findParam("DEVPATH");
/* Lookup a volume to handle this device */
VolumeCollection::iterator it;
bool hit = false;
for (it = mVolumes->begin(); it != mVolumes->end(); ++it) {
if (!(*it)->handleBlockEvent(evt)) {
#ifdef NETLINK_DEBUG
SLOGD("Device '%s' event handled by volume %s\n", devpath, (*it)->getLabel());
#endif
hit = true;
break;
}
}
if (!hit) {
#ifdef NETLINK_DEBUG
SLOGW("No volumes handled block event for '%s'", devpath);
#endif
}
}
在VolumeManager::handleBlockEvent遍历所有Volume,并执行Volume:: handleBlockEvent(),实际上是跳转到了DirectVolume::handleBlockEvent。为什么是这里,前面已经说过,DirectVolume是Volume的子类。
process_config函数用来解析/ fstab.xxx的配置文件.
这个函数还初始化了VolumeManage和DirectVolume。
有关VolumeManage的初始化基本是这个函数内进行,除此函数,VolumeManage的初始化工作做得很少。
process_config()的代码如下:
static int process_config(VolumeManager *vm)
{
char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
char propbuf[PROPERTY_VALUE_MAX];
int i;
int ret = -1;
int flags;
property_get("ro.hardware", propbuf, "");
snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
fstab = fs_mgr_read_fstab(fstab_filename);
if (!fstab) {
SLOGE("failed to open %s\n", fstab_filename);
return -1;
}
/* Loop through entries looking for ones that vold manages */
for (i = 0; i < fstab->num_entries; i++) {
if (fs_mgr_is_voldmanaged(&fstab->recs[i])) {
DirectVolume *dv = NULL;
flags = 0;
/* Set any flags that might be set for this volume */
if (fs_mgr_is_nonremovable(&fstab->recs[i])) {
flags |= VOL_NONREMOVABLE;
}
if (fs_mgr_is_encryptable(&fstab->recs[i])) {
flags |= VOL_ENCRYPTABLE;
}
/* Only set this flag if there is not an emulated sd card */
if (fs_mgr_is_noemulatedsd(&fstab->recs[i]) &&
!strcmp(fstab->recs[i].fs_type, "vfat")) {
flags |= VOL_PROVIDES_ASEC;
}
dv = new DirectVolume(vm, &(fstab->recs[i]), flags);
if (dv->addPath(fstab->recs[i].blk_device)) {
SLOGE("Failed to add devpath %s to volume %s",
fstab->recs[i].blk_device, fstab->recs[i].label);
goto out_fail;
}
vm->addVolume(dv);
}
}
ret = 0;
out_fail:
return ret;
}
/fstab.xxx文件格式为:
<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
例如:
/dev/block/platform/dw_mmc.2/by-num/p2 /system ext4 ro wait /dev/block/platform/dw_mmc.2/by-num/p3 /cache ext4 noatime,nosuid,nodev,nomblk_io_submit,errors=panic wait,check /dev/block/platform/dw_mmc.2/by-num/p4 /data ext4 noatime,nosuid,nodev,nomblk_io_submit,errors=panic wait,check /devices/platform/dw_mmc.0/mmc_host/mmc0/mmc0 /storage/sdcard1 auto defaults voldmanaged=sdcard1:auto,noemulatedsd
fs_mgr_read_fstab(fstab_filename);的作用即是解析fstab文件的每行并返回fstab结构体:struct fstab {
int num_entries; //fstab文件中每行(除空行和注释外)解析出一个fstab_rec结构体。
struct fstab_rec *recs;
char *fstab_filename; //即fstab文件名
};
struct fstab_rec {
char *blk_device;
char *mount_point;
char *fs_type;
unsigned long flags;
char *fs_options;
int fs_mgr_flags;
char *key_loc;
char *verity_loc;
long long length;
char *label;
int partnum;
int swap_prio;
unsigned int zram_size;
};
下面的代码根据每个fstab_rec生成一个DirectVolume类, 并执行:
vm->addVolume(dv);
即对VolumeManager做了初始化工作。注意DirectVolume是Volume的子类。
分析一些多余的代码,当NetlinkHandler接收到来自block子系统的uevent时:
void NetlinkHandler::onEvent(NetlinkEvent *evt) { VolumeManager *vm = VolumeManager::Instance(); const char *subsys = evt->getSubsystem(); if (!subsys) { SLOGW("No subsystem found in netlink event"); return; } if (!strcmp(subsys, "block")) { vm->handleBlockEvent(evt); } }
执行VolumeManager:: handleBlockEvent(evt):void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
const char *devpath = evt->findParam("DEVPATH");
/* Lookup a volume to handle this device */
VolumeCollection::iterator it;
bool hit = false;
for (it = mVolumes->begin(); it != mVolumes->end(); ++it) {
if (!(*it)->handleBlockEvent(evt)) {
#ifdef NETLINK_DEBUG
SLOGD("Device '%s' event handled by volume %s\n", devpath, (*it)->getLabel());
#endif
hit = true;
break;
}
}
if (!hit) {
#ifdef NETLINK_DEBUG
SLOGW("No volumes handled block event for '%s'", devpath);
#endif
}
}
在VolumeManager::handleBlockEvent遍历所有Volume,并执行Volume:: handleBlockEvent(),实际上是跳转到了DirectVolume::handleBlockEvent。为什么是这里,前面已经说过,DirectVolume是Volume的子类。
相关文章推荐
- Android中的性能优化
- Android 视频通话 AnyChat
- 用Androidstudio的Terminal安装卸载应用
- Android模拟器访问本地的localhost失败及解决方案
- Android自定义控件实战——水流波动效果的实现WaveView
- 改变窗口所在的进程:android:process属性解析
- Android静默安装
- ListView的点击事件
- Android简单计算器
- android操作系统详细目录结构
- Android 多媒体之实现语音聊天界面
- 【Android】直播必备之YUV使用总结 —— Android常用的几种格式:NV21/NV12/YV12/YUV420P的区别
- 2016年6月至2017年3月学习计划
- Android 动画基础——视图动画(View Animation)
- 尝试写款小游戏吧
- Android学习笔记--基础知识
- Android综合项目乐学成语
- android中的消息机制--浅谈Handler的原理及使用
- Android入门-SayHello实现页面跳转
- android之文件权限问题