Android Vold简介(三)

本文深入探讨Android Vold如何处理内置存储(EmulatedVolume)和外置存储(PublicVolume)的挂载过程。EmulatedVolume主要负责内置存储,通过创建特定目录并使用sdcardfs进行权限控制。PublicVolume则处理外接存储,根据文件系统类型挂载到/storage下。在Android Q之后,Vold开始使用Fuse,并移除kernel中的sdcardfs实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
之前两篇主要介绍了Vold的架构以及运行机制,本篇主要来介绍下Vold是内置存储和外置存储的mount流程。前面已经介绍过,无论什么存储,最终都会调用doMount()这个虚函数,对于不同类型的则会有不同的mount流程(即挂在到不同的文件系统下);对于内置存储,使用EmulatedVolume类来处理,而外接sd卡或者OTG设备则基本上都使用PublicVolume类来处理,因此uevent传递上来的消息会通知到vold到底这个存储介质属于什么类型。
 
首先来看下EmulatedVolume处理流程,首先会判断Primary标志,表明是内置主要的存储,一般都会跑进这个逻辑,因为只有data分区下的存储才会走这边;接着创建/mnt/runtime/default/emulated等四个目录,这个是Google针对sdcardfs添加的用来处理app之间相互的访问权限。拥有不同权限的app会bind mount到对应的目录,例如只有读权限的app则会bind到/mnt/runtime/read/emulated。

status_t EmulatedVolume::doMount() {
   
    // We could have migrated storage to an adopted private volume, so always
    // call primary storage "emulated" to avoid media rescans.
    std::string label = mLabel;  //存储介质的卷名
    if (getMountFlags() & MountFlags::kPrimary) {
   
        label = "emulated";
    }

    mFuseDefault = StringPrintf("/mnt/runtime/default/%s", label.c_str()); //默认权限,一般是只读权限;
    mFuseRead = StringPrintf("/mnt/runtime/read/%s", label.c_str());    //读权限
    mFuseWrite = StringPrintf("/mnt/runtime/write/%s", label.c_str()); //写权限
    mFuseFull = StringPrintf("/mnt/runtime/full/%s", label.c_str());  //所有权限

    setInternalPath(mRawPath);
    setPath(StringPrintf("/storage/%s", label.c_str()));

    //创建对应的四个目录
    if (fs_prepare_dir(mFuseDefault.c_str(), 0700, AID_ROOT, AID_ROOT) ||
        fs_prepare_dir(mFuseRead.c_str(), 0700, AID_ROOT, AID_ROOT) ||
        fs_prepare_dir(mFuseWrite.c_str(), 0700, AID_ROOT, AID_ROOT) ||
        fs_prepare_dir(mFuseFull.c_str(), 0700, AID_ROOT, AID_ROOT)) {
   
        PLOG(ERROR) << getId() << " failed to create mount points";
        return -errno;
    }

    dev_t before = GetDevice(mFuseFull);

    //创建子进程,启动sdcard进程来处理具体的挂在流程;
    if (!(mFusePid = fork())) {
   
        // clang-format off
        if (execl(kFusePath, kFusePath,      //执行sdcard进程
                "-u", "1023", // AID_MEDIA_RW  挂载使用的uid
                "-g", "1023", // AID_MEDIA_RW  挂载使用的gid
                "-m",
                "-w",
                "-G",
                "-i",
                "-o",
                mRawPath.c_str(),
                label.c_str(),
                NULL)) {
   
            // clang-format on
            PLOG(ERROR) << "Failed to exec";
        }

        LOG(ERROR) << "FUSE exiting";
        _exit(1);
    }

    if (mFusePid == -1) {
   
        PLOG(ERROR) << getId() << " failed to fork";
        return -errno;
    }

    nsecs_t start = systemTime(SYSTEM_TIME_BOOTTIME);
    while (before == GetDevice
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值