android 存储系统学习

参考资料:

android存储系统的历史变更

app开发角度看存储系统

vold处理流程

Android M 外部存储剖析

《Android外部存储》


路径链接关系:

/sdcard ---> /storage/self/primary
/mnt/sdcard ---> /storage/self/primary
/storage/self/primary ---> /mnt/user/0/primary
/mnt/runtime/default/self/primary ---> /mnt/user/0/primary
/mnt/user/0/primary ---> /storage/emulated/0

因此最终是链接到/storage/emulated/0目录,/storage/emulated是通过fuse系统挂载的/data/media

/dev/fuse on /storage/emulated type fuse (rw,nosuid,nodev,noexec,noatime,user_id=1023,group_id=1023,default_permissions,allow_other)

storage默认开机在init.rc中挂载的是/mnt/runtime/default

# Mount default storage into root namespace
mount none /mnt/runtime/default /storage slave bind rec

重新挂载动作在EmulatedVolume::doMount()@EmulatedVolume.cpp中完成。

因此/storage/emulated/0和/data/media/0目录内容是相同的,区别在于权限:

rk3399_firefly_edp_box:/storage/emulated # ls -l
drwxrwx--x 19 root sdcard_rw 4096 2013-01-20 13:41 0

rk3399_firefly_edp_box:/data/media # ls -l                    
drwxrwx--- 19 media_rw media_rw 4096 2013-01-20 13:41 0

/mnt/runtime各个目录意义: 
/mnt/runtime/default - 对所有的应用、root命名空间(adb和其他系统组件)可见,而无需任何权限. 
/mnt/runtime/read - 对有READ_EXTERNAL_STORAGE权限的应用可见。 
/mnt/runtime/write - 对有WRITE_EXTERNAL_STORAGE权限的应用可见。

出现这三个不同权限目录的原因是控制不同权限app访问。然后利用挂载命名空间实现了挂载点的隔离,在不同挂载命名空间的进程,看到的目录层次不同。 
实现是通过在zygote fork app 时,为每个运行中的应用创建一个 mount 名字空间。在MountEmulatedStorage()@com_android_internal_os_Zygote.cpp

static bool MountEmulatedStorage(uid_t uid, jint mount_mode,
        bool force_mount_namespace) {
    // See storage config details at http://source.android.com/tech/storage/

    // Create a second private mount namespace for our process
    if (unshare(CLONE_NEWNS) == -1) {
        ALOGW("Failed to unshare(): %s", strerror(errno));
        return false;
    }

    String8 storageSource;
    if (mount_mode == MOUNT_EXTERNAL_DEFAULT) {
        storageSource = "/mnt/runtime/default";
    } else if (mount_mode == MOUNT_EXTERNAL_READ) {
        storageSource = "/mnt/runtime/read";
    } else if (mount_mode == MOUNT_EXTERNAL_WRITE) {
        storageSource = "/mnt/runtime/write";
    } else {
        // Sane default of no storage visible
        return true;
    }
    if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage",
            NULL, MS_BIND | MS_REC | MS_SLAVE, NULL)) == -1) {
        ALOGW("Failed to mount %s to /storage: %s", storageSource.string(), strerror(errno));
        return false;
    }

    // Mount user-specific symlink helper into place
    userid_t user_id = multiuser_get_user_id(uid);
    const String8 userSource(String8::format("/mnt/user/%d", user_id));
    if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) {
        return false;
    }
    if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self",
            NULL, MS_BIND, NULL)) == -1) {
        ALOGW("Failed to mount %s to /storage/self: %s", userSource.string(), strerror(errno));
        return false;
    }

    return true;
}

存储目录:

文件夹中的文件又分为两类,一类是公有目录,还有一类是私有目录,其中的公有目录有DCIM、DOWNLOAD等,私有目录就是Android这个文件夹,这里边有许多包名组成的文件夹。


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值