在Android系统中的vold源码中,挂载sdcard的操作有以下几个:
/dev/block/vold/8:1 挂载在-> /mnt/secure/staging
/mnt/secure/staging/.android_secure 挂载在-> /mnt/secure/asec
tmpfs 挂载在-> /mnt/secure/staging/.android_secure
/mnt/secure/staging 挂载在-> /mnt/sdcard
这里涉及到好几次挂载,望各位讨论,指点指点迷津?
如果需要源码,以下就是:
int Volume::mountVol() {
dev_t deviceNodes[4];
int n, i, rc = 0;
char errmsg[255];
if (getState() == Volume::State_NoMedia) {
snprintf(errmsg, sizeof(errmsg),
"Volume %s %s mount failed - no media",
getLabel(), getMountpoint());
mVm->getBroadcaster()->sendBroadcast(
ResponseCode::VolumeMountFailedNoMedia,
errmsg, false);
errno = ENODEV;
return -1;
} else if (getState() != Volume::State_Idle) {
errno = EBUSY;
return -1;
}
if (isMountpointMounted(getMountpoint())) {
SLOGW("Volume is idle but appears to be mounted - fixing");
setState(Volume::State_Mounted);
// mCurrentlyMountedKdev = XXX
return 0;
}
n = getDeviceNodes((dev_t *) &deviceNodes, 4);
if (!n) {
SLOGE("Failed to get device nodes (%s)\n", strerror(errno));
return -1;
}
for (i = 0; i < n; i++) {
char devicePath[255];
sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(deviceNodes[i]),
MINOR(deviceNodes[i]));
SLOGI("%s being considered for volume %s\n", devicePath, getLabel());
errno = 0;
setState(Volume::State_Checking);
if (Fat::check(devicePath)) {
if (errno == ENODATA) {
SLOGW("%s does not contain a FAT filesystem\n", devicePath);
continue;
}
errno = EIO;
/* Badness - abort the mount */
SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno));
setState(Volume::State_Idle);
return -1;
}
/*
* Mount the device on our internal staging mountpoint so we can
* muck with it before exposing it to non priviledged users.
*/
errno = 0;
if (Fat::doMount(devicePath, "/mnt/secure/staging", false, false, 1000, 1015, 0702, true)) {
SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno));
continue;
}
SLOGI("Device %s, target %s mounted @ /mnt/secure/staging", devicePath, getMountpoint());
protectFromAutorunStupidity();
if (createBindMounts()) {
SLOGE("Failed to create bindmounts (%s)", strerror(errno));
umount("/mnt/secure/staging");
setState(Volume::State_Idle);
return -1;
}
/*
* Now that the bindmount trickery is done, atomically move the
* whole subtree to expose it to non priviledged users.
*/
if (doMoveMount("/mnt/secure/staging", getMountpoint(), false)) {
SLOGE("Failed to move mount (%s)", strerror(errno));
umount("/mnt/secure/staging");
setState(Volume::State_Idle);
return -1;
}
setState(Volume::State_Mounted);
mLastMountedKdev = mCurrentlyMountedKdev = deviceNodes[i];
return 0;
}
SLOGE("Volume %s found no suitable devices for mounting :(\n", getLabel());
setState(Volume::State_Idle);
return -1;
}