在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