android /system/vold源码分析(7)

本文分析了process_config函数如何解析fstab配置文件,并通过DirectVolume类实例化来初始化VolumeManager。此外,还介绍了NetlinkHandler如何处理来自block子系统的uevent。

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

process_config()分析:

process_config函数用来解析/ fstab.xxx的配置文件.

这个函数还初始化了VolumeManage和DirectVolume。
有关VolumeManage的初始化基本是这个函数内进行,除此函数,VolumeManage的初始化工作做得很少。
process_config()的代码如下:

static int process_config(VolumeManager *vm)
{
    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
    char propbuf[PROPERTY_VALUE_MAX];
    int i;
    int ret = -1;
    int flags;

    property_get("ro.hardware", propbuf, "");
    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);

    fstab = fs_mgr_read_fstab(fstab_filename);
    if (!fstab) {
        SLOGE("failed to open %s\n", fstab_filename);
        return -1;
    }

    /* Loop through entries looking for ones that vold manages */
    for (i = 0; i < fstab->num_entries; i++) {
        if (fs_mgr_is_voldmanaged(&fstab->recs[i])) {
            DirectVolume *dv = NULL;
            flags = 0;

            /* Set any flags that might be set for this volume */
            if (fs_mgr_is_nonremovable(&fstab->recs[i])) {
                flags |= VOL_NONREMOVABLE;
            }
            if (fs_mgr_is_encryptable(&fstab->recs[i])) {
                flags |= VOL_ENCRYPTABLE;
            }
            /* Only set this flag if there is not an emulated sd card */
            if (fs_mgr_is_noemulatedsd(&fstab->recs[i]) &&
                !strcmp(fstab->recs[i].fs_type, "vfat")) {
                flags |= VOL_PROVIDES_ASEC;
            }
            dv = new DirectVolume(vm, &(fstab->recs[i]), flags);

            if (dv->addPath(fstab->recs[i].blk_device)) {
                SLOGE("Failed to add devpath %s to volume %s",
                      fstab->recs[i].blk_device, fstab->recs[i].label);
                goto out_fail;
            }

            vm->addVolume(dv);
        }
    }

    ret = 0;

out_fail:
    return ret;
}

/fstab.xxx文件格式为:
<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
例如:
/dev/block/platform/dw_mmc.2/by-num/p2  /system  ext4  ro  wait
/dev/block/platform/dw_mmc.2/by-num/p3 /cache ext4   noatime,nosuid,nodev,nomblk_io_submit,errors=panic    wait,check
/dev/block/platform/dw_mmc.2/by-num/p4 /data  ext4   noatime,nosuid,nodev,nomblk_io_submit,errors=panic    wait,check
/devices/platform/dw_mmc.0/mmc_host/mmc0/mmc0  /storage/sdcard1 auto defaults  voldmanaged=sdcard1:auto,noemulatedsd

fs_mgr_read_fstab(fstab_filename);的作用即是解析fstab文件的每行并返回fstab结构体:

struct fstab {
    int num_entries;   //fstab文件中每行(除空行和注释外)解析出一个fstab_rec结构体。
    struct fstab_rec *recs;
    char *fstab_filename;  //即fstab文件名
};

struct fstab_rec {
    char *blk_device;
    char *mount_point;
    char *fs_type;
    unsigned long flags;
    char *fs_options;
    int fs_mgr_flags;
    char *key_loc;
    char *verity_loc;
    long long length;
    char *label;
    int partnum;
    int swap_prio;
    unsigned int zram_size;
};

下面的代码根据每个fstab_rec生成一个DirectVolume类, 并执行:
vm->addVolume(dv);
即对VolumeManager做了初始化工作。注意DirectVolume是Volume的子类。

分析一些多余的代码,当NetlinkHandler接收到来自block子系统的uevent时:

void NetlinkHandler::onEvent(NetlinkEvent *evt) {
    VolumeManager *vm = VolumeManager::Instance();
    const char *subsys = evt->getSubsystem();

    if (!subsys) {
        SLOGW("No subsystem found in netlink event");
        return;
    }

    if (!strcmp(subsys, "block")) {
        vm->handleBlockEvent(evt);
    }
}

执行VolumeManager:: handleBlockEvent(evt):

void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
    const char *devpath = evt->findParam("DEVPATH");

    /* Lookup a volume to handle this device */
    VolumeCollection::iterator it;
    bool hit = false;
    for (it = mVolumes->begin(); it != mVolumes->end(); ++it) {
        if (!(*it)->handleBlockEvent(evt)) {
#ifdef NETLINK_DEBUG
            SLOGD("Device '%s' event handled by volume %s\n", devpath, (*it)->getLabel());
#endif
            hit = true;
            break;
        }
    }

    if (!hit) {
#ifdef NETLINK_DEBUG
        SLOGW("No volumes handled block event for '%s'", devpath);
#endif
    }
}

在VolumeManager::handleBlockEvent遍历所有Volume,并执行Volume:: handleBlockEvent(),实际上是跳转到了DirectVolume::handleBlockEvent。为什么是这里,前面已经说过,DirectVolume是Volume的子类。


<think>好的,用户之前问过关于Android设备插入U盘到挂载完成的流程,现在他接着问vold的源代码Android framework中的位置。我需要详细回答这个问题。 首先,用户可能对Android系统开发感兴趣,或者正在学习相关的知识,想要深入了解vold的实现。他们的真实需求可能是想要查看源码,了解vold的工作原理,或者进行定制开发、调试问题。比如,他们可能在开发需要处理外部存储的应用,或者在进行系统定制时遇到问题,需要参考源码。 接下来,我需要回忆voldAndroid代码中的位置。根据之前的了解,vold是Volume Daemon,属于系统底层服务,负责存储设备的管理。Android的源代码结构里,系统服务通常位于不同的目录。比如,frameworks/base/包含很多系统服务,但vold是否在那里呢? 可能需要确认一下。记得vold代码并不在frameworks/base下,因为vold是一个独立的守护进程,属于系统核心服务,但可能放在system目录下。比如,在AOSP中,许多核心服务和守护进程位于system/core或system/vold。搜索一下,确认vold代码路径应该是system/vold。例如,在AOSP源码中,vold代码确实位于system/vold目录下。 用户可能需要具体的路径,以便在源码中查找。另外,他们可能想知道如何下载或浏览这部分代码。需要给出具体的仓库链接,比如Android官方的源码仓库中的路径。比如,在线查看的话,可以在https://android.googlesource.com/platform/system/vold/ 找到。 此外,用户可能对vold的模块结构感兴趣,比如主要代码文件,如main.cpp、VolumeManager.cpp等,可以简要介绍一下目录结构中的关键文件,帮助他们定位。 还需要考虑用户可能的后续问题,比如如何编译vold,或者如何修改代码,但当前问题只涉及位置,所以不需要展开。不过可以提到相关的mk文件,比如Android.mk或Android.bp,说明构建配置的位置。 最后,确保回答清晰,结构正确,分点说明,让用户容易理解。同时检查是否有其他相关信息需要补充,比如vold与其他组件的交互,但当前问题重点在源码位置,所以保持专注。</think>### vold 源码在 Android 系统框架中的位置 在 AOSP(Android Open Source Project)中,**vold(Volume Daemon)** 的源代码位于以下目录: ``` /platform/system/vold/ ``` --- #### **关键代码路径解析** | 路径 | 功能说明 | |-------------------------------|--------------------------------------------------------------------------| | `/platform/system/vold/` | **核心代码根目录**,包含守护进程主逻辑、存储设备管理、文件系统操作等代码 | | `/vold/main.cpp` | vold 的入口函数,初始化服务并启动事件循环 | | `/vold/VolumeManager.cpp` | 管理存储卷的生命周期(挂载/卸载/格式化) | | `/vold/Disk.cpp` | 处理物理磁盘的分区检测与状态管理 | | `/vold/Ext4.cpp`/`Ntfs.cpp` | 文件系统操作实现(如挂载 NTFS/FAT32/exFAT) | | `/vold/NetlinkHandler.cpp` | 监听内核通过 Netlink 发送的 uevent 设备事件 | | `/vold/Utils.cpp` | 封装底层系统调用(如 fork/exec 执行`mount`命令) | --- #### **相关配置文件与构建脚本** | 路径 | 作用 | |-----------------------------------|----------------------------------------------------------------------| | `/platform/system/vold/Android.bp` | Blueprint 构建脚本,定义 vold 的编译规则和依赖项 | | `/platform/system/core/libcutils/` | 依赖库:提供 Android 特有的工具函数(如`android_get_control_socket`)| | `/platform/system/core/libsysutils/` | 依赖库:处理 socket 通信和事件循环 | --- ### **如何查看源码** 1. **官方 AOSP 仓库** 在线浏览地址: https://android.googlesource.com/platform/system/vold/ 2. **本地代码库** 若已下载完整 AOSP 代码,可通过以下命令定位: ```bash cd /path/to/aosp find . -name "vold" # 确认 system/vold 目录位置 ``` --- ### **代码结构示例** ``` system/vold/ ├── Android.bp # 构建配置 ├── main.cpp # 主入口 ├── VolumeManager.cpp # 卷管理 ├── Disk.cpp # 磁盘设备处理 ├── NetlinkHandler.cpp # 内核事件监听 ├── model/ # 数据模型(卷、磁盘等对象) │ ├── Volume.cpp │ └── Disk.h ├── fs/ # 文件系统支持 │ ├── Ext4.cpp │ └── Ntfs.cpp └── tests/ # 单元测试 ``` --- ### **调试与修改建议** 1. **修改 vold 代码** 需重新编译系统镜像: ```bash mmm system/vold/ # 仅编译 vold 模块 adb root && adb remount adb push out/target/product/.../system/bin/vold /system/bin/ ``` 2. **查看 vold 日志** 通过`logcat`过滤 vold 的调试信息: ```bash adb logcat -s vold ``` --- ### **与其他组件的关联** vold 通过以下接口与 Android 系统交互: - **Binder IPC**:与`StorageManagerService`通信(代码位于`frameworks/base/services/core/java/com/android/server/storage/`) - **Socket**:接收来自内核的 uevent 事件 - **FUSE/sdcardfs**:实现存储隔离(代码位于`kernel/.../fs/fuse/`或`system/core/sdcard/`) 通过分析这些代码,可以深入理解 Android 存储管理的底层机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值