您的位置:首页 > 移动开发 > Android开发

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>
例如:
/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的子类。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: