在vold执行mount命令时,挂载完之后会起来一个Service,我们今天来分析下其作用:
int Volume::mountVol() {
dev_t deviceNodes[4];
int n, i, rc = 0;
char errmsg[255];
int flags = getFlags();
bool providesAsec = (flags & VOL_PROVIDES_ASEC) != 0;
.............
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;
}
errno = 0;
int gid;
if (Fat::doMount(devicePath, getMountpoint(), false, false, false,//挂载
AID_MEDIA_RW, AID_MEDIA_RW, 0007, true)) {
SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno));
continue;
}
extractMetadata(devicePath);
if (providesAsec && mountAsecExternal() != 0) {
SLOGE("Failed to mount secure area (%s)", strerror(errno));
umount(getMountpoint());
setState(Volume::State_Idle);
return -1;
}
char service[64];
snprintf(service, 64, "fuse_%s", getLabel());
property_set("ctl.start", service);//设置系统属性起Service
setState(Volume::State_Mounted);
mCurrentlyMountedKdev = deviceNodes[i];
return 0;
}
SLOGE("Volume %s found no suitable devices for mounting :(\n", getLabel());
setState(Volume::State_Idle);
return -1;
}
接下来我们来看下init.rc,我们看/mnt/media_rw/sdcard1是外置sd卡挂载的路径,之后其自己才有权限因为是0700,而我们通常外置sd卡的操作路径是/storage/sdcard1,正是上面起的这个Service起的作用,fuse_sdcard1 这个Service,传入参数和media_rw 这个uid,原理利用fuse将/storage/sdcard1用户也是media_rw ,并且去操作这个/mnt/media_rw/sdcard1路径,最后才有/mnt/media_rw/sdcard1所有权限。
而/mnt/media_rw/usbotg 也是类似,起的Service是fuse_usbotg
内置的sd卡的路径是/mnt/shell/emulated 权限也是0700,并且做了很多软链接。而且还有一个Service sdcard也是用fuse将/data/media 拥有/mnt/shell/emulated 的权限。
on init
# See storage config details at http://source.android.com/tech/storage/
mkdir /mnt/shell/emulated 0700 shell shell
mkdir /storage/emulated 0555 root root
mkdir /storage/sdcard1 0000 system system
mkdir /storage/usbotg 0700 system system
mkdir /mnt/media_rw/usbotg 0700 media_rw media_rw
mkdir /mnt/media_rw/sdcard1 0700 media_rw media_rw
.......
# Support legacy paths
symlink /storage/emulated/legacy /sdcard
symlink /storage/emulated/legacy /mnt/sdcard
symlink /mnt/shell/emulated/0 /storage/emulated/legacy
symlink /storage/emulated/legacy /storage/sdcard0
...........
# virtual sdcard daemon running as media_rw (1023)
service sdcard /system/bin/sdcard -u 1023 -g 1023 -l /data/media /mnt/shell/emulated
class late_start
chown system system /data/etc/storage.config
# fusewrapped external sdcard daemon running as media_rw (1023)
service fuse_sdcard1 /system/bin/sdcard -u 1023 -g 1023 -w 1023 -d /mnt/media_rw/sdcard1 /storage/sdcard1
class late_start
service fuse_usbotg /system/bin/sdcard -u 1023 -g 1023 -d /mnt/media_rw/usbotg /storage/usbotg
class late_start