vold and init

本文详细解析了 Android 4.1 中的存储挂载过程,包括设备节点获取、加密状态检查、分区检测及挂载流程等关键技术步骤。

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

android4.1

section.1

int Volume::mountVol() { dev_t deviceNodes[4]; int n, i, rc = 0; char errmsg[255]; const char* externalStorage = getenv("EXTERNAL_STORAGE");\\-----mnt/sdcard bool primaryStorage = externalStorage && !strcmp(getMountpoint(), externalStorage); char decrypt_state[PROPERTY_VALUE_MAX]; char crypto_state[PROPERTY_VALUE_MAX]; char encrypt_progress[PROPERTY_VALUE_MAX]; int flags; property_get("vold.decrypt", decrypt_state, "");//---参见《init》do_mount_all() property_get("vold.encrypt_progress", encrypt_progress, ""); /* Don't try to mount the volumes if we have not yet entered the disk password * or are in the process of encrypting.//-----decrypt_state=1表示磁盘没有被解密 */ if ((getState() == Volume::State_NoMedia) || ((!strcmp(decrypt_state, "1") || encrypt_progress[0]) && primaryStorage)) { snprintf(errmsg, sizeof(errmsg), "Volume %s %s mount failed - no media", getLabel(), getMountpoint()); mVm->getBroadcaster()->sendBroadcast( ResponseCode::VolumeMountFailedNoMedia, errmsg, false); errno = ENODEV; return -1; } else if (getState() != Volume::State_Idle) { errno = EBUSY; if (getState() == Volume::State_Pending) { mRetryMount = true; } return -1; } if (isMountpointMounted(getMountpoint())) { SLOGW("Volume is idle but appears to be mounted - fixing"); setState(Volume::State_Mounted); // mCurrentlyMountedKdev = XXX return 0; } n = getDeviceNodes((dev_t *) &deviceNodes, 4); if (!n) { SLOGE("Failed to get device nodes (%s)\n", strerror(errno)); return -1; } /* If we're running encrypted, and the volume is marked as encryptable and nonremovable, * and vold is asking to mount the primaryStorage device, then we need to decrypt * that partition, and update the volume object to point to it's new decrypted * block device */ property_get("ro.crypto.state", crypto_state, ""); flags = getFlags(); if (primaryStorage && ((flags & (VOL_NONREMOVABLE | VOL_ENCRYPTABLE))==(VOL_NONREMOVABLE | VOL_ENCRYPTABLE)) && !strcmp(crypto_state, "encrypted") && !isDecrypted()) {//---------还没有解密呢 char new_sys_path[MAXPATHLEN]; char nodepath[256]; int new_major, new_minor; if (n != 1) { /* We only expect one device node returned when mounting encryptable volumes */ SLOGE("Too many device nodes returned when mounting %d\n", getMountpoint()); return -1; } if (cryptfs_setup_volume(getLabel(), MAJOR(deviceNodes[0]), MINOR(deviceNodes[0]),//---解密 new_sys_path, sizeof(new_sys_path), &new_major, &new_minor)) { SLOGE("Cannot setup encryption mapping for %d\n", getMountpoint()); return -1; } /* We now have the new sysfs path for the decrypted block device, and the * majore and minor numbers for it. So, create the device, update the * path to the new sysfs path, and continue. */ snprintf(nodepath, sizeof(nodepath), "/dev/block/vold/%d:%d", new_major, new_minor); if (createDeviceNode(nodepath, new_major, new_minor)) { SLOGE("Error making device node '%s' (%s)", nodepath, strerror(errno)); } // Todo: Either create sys filename from nodepath, or pass in bogus path so // vold ignores state changes on this internal device. updateDeviceInfo(nodepath, new_major, new_minor); /* Get the device nodes again, because they just changed */ n = getDeviceNodes((dev_t *) &deviceNodes, 4); if (!n) { SLOGE("Failed to get device nodes (%s)\n", strerror(errno)); return -1; } } 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; } /* * Mount the device on our internal staging mountpoint so we can * muck with it before exposing it to non priviledged users. */ errno = 0; int gid; if (primaryStorage) {//-----external storage write access 1015 // Special case the primary SD card. // For this we grant write access to the SDCARD_RW group. gid = AID_SDCARD_RW; } else {//-------------internal media storage write access 1023 // For secondary external storage we keep things locked up. gid = AID_MEDIA_RW; } if (Fat::doMount(devicePath, "/mnt/secure/staging", false, false, false, AID_SYSTEM, gid, 0702, true)) { SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno)); continue; } SLOGI("Device %s, target %s mounted @ /mnt/secure/staging", devicePath, getMountpoint()); protectFromAutorunStupidity();//--------------阻止autorun.inf文件的自动运行 // only create android_secure on primary storage if (primaryStorage && createBindMounts()) {//--------mount -bind SLOGE("Failed to create bindmounts (%s)", strerror(errno)); umount("/mnt/secure/staging"); setState(Volume::State_Idle); return -1; } /* * Now that the bindmount trickery is done, atomically move the * whole subtree to expose it to non priviledged users. */ if (doMoveMount("/mnt/secure/staging", getMountpoint(), false)) {//-------mount --move SLOGE("Failed to move mount (%s)", strerror(errno)); umount("/mnt/secure/staging"); setState(Volume::State_Idle); return -1; } 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; }

 

03-25
<think>好的,我现在需要解决用户关于“vold android service”的问题。首先,用户提到的voldAndroid中的作用,我需要先回忆一下相关知识。 根据提供的引用资料,vold是Volume Daemon,负责管理存储设备的热插拔事件,连接内核和框架层。引用[5]提到vold的代码路径是system/vold和/system/core/libsysutils/src,这可能涉及它的实现结构。用户可能想知道vold服务是如何启动的,或者它的工作原理。 接下来,我需要检查用户给出的引用内容。例如,引用[3]提到voldinit.rc中作为服务进程启动,而init.rc在Android启动过程中有重要作用。这可能涉及vold的启动机制,由init进程启动,作为守护进程运行。 然后,用户的问题可能包括vold的功能、架构或与其他组件的交互。引用[4]说明vold管理U盘等存储设备,不同Android版本可能有差异。需要指出vold处理设备挂载、卸载,与Framework层的MountService通信。 用户提供的引用中有多个链接,但部分链接可能重复或不可访问,但根据引用内容,我需要整合这些信息,确保回答准确。例如,引用[1]和[2]都提到vold的架构和启动参数,可能需要解释其服务配置。 可能的疑问点:vold作为守护进程,如何监听内核事件?答案可能涉及Netlink套接字,用于接收内核的uevent,如引用[5]提到的处理热插拔事件。 此外,用户的问题可能涉及vold的调试或常见问题,比如存储设备无法识别,可能需要检查vold的日志或配置。不过用户当前的问题更偏向于基本功能和工作原理,所以重点应放在解释vold的角色、架构和流程上。 需要确保回答结构清晰,分点说明vold的定义、架构、工作流程、启动方式等,并引用提供的资料作为支持。同时,生成的相关问题应围绕vold的扩展知识,如与其他服务交互、调试方法、版本差异等。</think>### Android Vold 服务解析 #### 1. Vold 的定义与作用 **Vold**(Volume Daemon)是 Android 系统中负责**存储设备热插拔管理**的核心守护进程,充当**内核层与框架层之间的桥梁**。它监听来自 Linux 内核的存储设备事件(如 U 盘插入、SD 卡挂载),并通过与上层服务(如 `MountService`)通信完成设备的挂载、卸载、格式化等操作[^5]。 #### 2. Vold 的架构与组件 - **代码路径**: - 主要逻辑:`system/vold` - 基础工具库:`/system/core/libsysutils/src`[^5] - **核心模块**: - `VolumeManager`:管理存储设备生命周期 - `NetlinkManager`:通过 Netlink 套接字监听内核的 `uevent` 事件 - `CommandListener`:处理来自上层服务的指令(如 `mount`、`unmount`) #### 3. Vold 的工作流程 1. **事件监听**: Vold 通过 Netlink 接收内核发出的 `uevent`(如 `add`/`remove` 设备事件)[^5]。 2. **设备处理**: - 解析设备类型(如 U 盘、SD 卡) - 调用 `fsck` 检查文件系统完整性 3. **与上层通信**: - 通过 `Binder` 将事件通知 `MountService` - 执行来自 `MountService` 的指令(如格式化存储设备)[^4]。 #### 4. Vold 的启动方式 Vold 由 **init 进程**在系统启动时通过 `init.rc` 脚本启动,配置示例如下: ```rc service vold /system/bin/vold class core socket vold stream 0660 root mount ioprio be 2 ``` - 关键配置: - 以 `core` 类核心服务运行 - 创建名为 `vold` 的 Unix 域套接字用于进程通信[^3][^2]。 #### 5. 与其他组件的关系 - **内核层**:通过 `uevent` 获取存储设备状态变化 - **Framework 层**:通过 `Binder` 与 `MountService` 交互 - **文件系统**:调用 `mount`/`umount` 等系统调用完成实际操作[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值