深入解析MountService、vold(三)--fuse_sdcard1(and5.1)

在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




你可能感兴趣的:(深入解析MountService、vold(三)--fuse_sdcard1(and5.1))