Android 14 vold 分析(1)启动
1.启动
它是从rc文件中启动的,rc文件是second stage init才会解析的,也就是说vold主要作用做second stage mount,那first stage mount是怎么做的呢,第一阶段实际上直接调用的是fs_mgr进行的mount,fs_mgr_do_mount_one()
system/core/rootdir/init.rc
584 on early-fs
585 # Once metadata has been mounted, we'll need vold to deal with userdata checkpointing
586 start vold
2. vold main()分析 这里省略不中要的代码
65 int main(int argc, char** argv) {
....
74 LOG(DEBUG) << "Detected support for:" ---> 这里log输出内核支持的文件系统,结果来自/proc/filesystems见2.1
75 << (android::vold::IsFilesystemSupported("ext4") ? " ext4" : "")
76 << (android::vold::IsFilesystemSupported("f2fs") ? " f2fs" : "")
77 << (android::vold::IsFilesystemSupported("vfat") ? " vfat" : "")
78 << (android::vold::IsFilesystemSupported("texfat") ? " texfat" : "")
79 << (android::vold::IsFilesystemSupported("exfat") ? " exfat" : "");
80
81 VolumeManager* vm; ---> vold中两个主要的组件VolumeManager和NetlinkManager
82 NetlinkManager* nm; ---> VolumeManager负责volume的管理, NetlinkManager 负责block device uevent的管理
.........
93 mkdir("/dev/block/vold", 0755);
94
95 /* For when cryptfs checks and mounts an encrypted filesystem */
96 klog_set_level(6); ---> 设置kernel log输出level 默认是KLOG_INFO_LEVEL = 6
97
98 /* Create our singleton managers */
99 if (!(vm = VolumeManager::Instance())) { ---> 为 VolumeManager 创建实例
100 LOG(ERROR) << "Unable to create VolumeManager";
101 exit(1);
102 }
103
104 if (!(nm = NetlinkManager::Instance())) { ---> 为 NetlinkManager 创建实例
105 LOG(ERROR) << "Unable to create NetlinkManager";
106 exit(1);
107 }
108
109 if (android::base::GetBoolProperty("vold.debug", false)) { ---> vold.debug可以用来打开log, 用作显示block device uevent的发生
110 vm->setDebug(true);
111 }
112
113 if (vm->start()) { ---> VolumeManager 做初始化的操作
114 PLOG(ERROR) << "Unable to start VolumeManager";
115 exit(1);
116 }
117
118 VoldConfigs configs = {};
119 if (process_config(vm, &configs)) { ---> 获取volume的config信息, 其实config信息解析自fstab中的flags,见2.2
120 PLOG(ERROR) << "Error reading configuration... continuing anyways";
121 }
122
123 android::hardware::configureRpcThreadpool(1, false /* callerWillJoin */);
124
125 ATRACE_BEGIN("VoldNativeService::start"); ---> VoldNativeService是Ivold的实现,作为binder server,创建实例并加入到ServiceManager里
126 if (android::vold::VoldNativeService::start() != android::OK) {
127 LOG(ERROR) << "Unable to start VoldNativeService";
128 exit(1);
129 }
130 ATRACE_END();
131
132 LOG(DEBUG) << "VoldNativeService::start() completed OK";
133
134 ATRACE_BEGIN("NetlinkManager::start");
135 if (nm->start()) { ---> NetlinkManager 做初始化的操作
136 PLOG(ERROR) << "Unable to start NetlinkManager";
137 exit(1);
138 }
139 ATRACE_END();
140
141 // This call should go after listeners are started to avoid
142 // a deadlock between vold and init (see b/34278978 for details) ---> 从volume的config信息设置property
143 android::base::SetProperty("vold.has_adoptable", configs.has_adoptable ? "1" : "0");
144 android::base::SetProperty("vold.has_quota", configs.has_quota ? "1" : "0");
145 android::base::SetProperty("vold.has_reserved", configs.has_reserved ? "1" : "0");
146 android::base::SetProperty("vold.has_compress", configs.has_compress ? "1" : "0");
147
148 // Do coldboot here so it won't block booting,
149 // also the cold boot is needed in case we have flash drive
150 // connected before Vold launched
151 coldboot("/sys/block"); ---> 重新触发一下block device uevent和init进程的RegenerateUevents()类似,见2.3
152
153 ATRACE_END();
154
155 android::IPCThreadState::self()->joinThreadPool(); ------> 开启主线程 binder looper
156 LOG(INFO) << "vold shutting down";
157
158 exit(0);
159 }
2.1 cat proc/filesystems nodev代表vfs, 好多啊 头大 搞那么多VFS我是真的服
nodev sysfsnodev tmpfsnodev bdevnodev procnodev cgroupnodev cgroup2nodev cpusetnodev binfmt_miscnodev configfsnodev debugfsnodev tracefsnodev securityfsnodev sockfsnodev bpfnodev pipefsnodev ramfsnodev devptsext3ext2ext4vfatmsdosexfatfuseblknodev fusenodev fusectlnodev virtiofsnodev overlaynodev incremental-fsf2fserofsnodev selinuxfsnodev bindernodev pstorenodev functionfs
2.2 process_config()
229 static int process_config(VolumeManager* vm, VoldConfigs* configs) {230 ATRACE_NAME("process_config");231 232 if (!ReadDefaultFstab(&fstab_default)) { -------> 读取fstab233 PLOG(ERROR) << "Failed to open default fstab";234 return -1;235 }236 237 /* Loop through entries looking for ones that vold manages */238 configs->has_adoptable = false;239 configs->has_quota = false;240 configs->has_reserved = false;241 configs->has_compress = false;242 for (auto& entry : fstab_default) {243 if (entry.fs_mgr_flags.quota) {244 configs->has_quota = true;245 }246 if (entry.reserved_size > 0) {247 configs->has_reserved = true; --------> userdata分区是有reserved size的,所以你的手机存储满了还是可以运行的248 }249 if (entry.fs_mgr_flags.fs_compress) {250 configs->has_compress = true;251 }252 253 /* Make sure logical partitions have an updated blk_device. */254 if (entry.fs_mgr_flags.logical && !fs_mgr_update_logical_partition(&entry) &&255 !entry.fs_mgr_flags.no_fail) {256 PLOG(FATAL) << "could not find logical partition " << entry.blk_device;257 }258 259 if (entry.mount_point == "/data" && !entry.metadata_key_dir.empty()) {260 // Pre-populate userdata dm-devices since the uevents are asynchronous (b/198405417).261 android::vold::defaultkey_precreate_dm_device(); ------> 这个好像有点内容,我还没看262 }263 264 if (entry.fs_mgr_flags.vold_managed) { ----> 就两个 /storage/sdcard1 /storage/usbotg wait,voldmanaged=sdcard1:auto265 if (entry.fs_mgr_flags.nonremovable) {266 LOG(WARNING) << "nonremovable no longer supported; ignoring volume";267 continue;268 }269 270 std::string sysPattern(entry.blk_device);271 std::string nickname(entry.label);272 int flags = 0;273 274 if (entry.is_encryptable()) {275 flags |= android::vold::Disk::Flags::kAdoptable; ----> sdcard 作为adoptable storage, 能卡死..呵呵..笑了276 configs->has_adoptable = true;277 }278 if (entry.fs_mgr_flags.no_emulated_sd ||279 android::base::GetBoolProperty("vold.debug.default_primary", false)) {280 flags |= android::vold::Disk::Flags::kDefaultPrimary;281 }282 283 vm->addDiskSource(std::shared_ptr<VolumeManager::DiskSource>( ----> 申明voldmanaged的这俩,被vm添加到了mDisksource284 new VolumeManager::DiskSource(sysPattern, nickname, flags)));285 }286 }287 return 0;288 }
2.3 do_coldboot()
188 static void do_coldboot(DIR* d, int lvl) {189 struct dirent* de;190 int dfd, fd;191 192 dfd = dirfd(d);193 194 fd = openat(dfd, "uevent", O_WRONLY | O_CLOEXEC);195 if (fd >= 0) {196 write(fd, "add\n", 4); --------> 因为vold启动前就已经有block device add了,所以需要重新触发 add block device uevent197 close(fd);198 }199 200 while ((de = readdir(d))) {201 DIR* d2;202 203 if (de->d_name[0] == '.') continue;204 205 if (de->d_type != DT_DIR && lvl > 0) continue;206 207 fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);208 if (fd < 0) continue;209 210 d2 = fdopendir(fd); 211 if (d2 == 0)212 close(fd);213 else {214 do_coldboot(d2, lvl + 1); --------> sys/block/没有找到uevent文件,递归往子目录查找215 closedir(d2);216 }217 }218 }
相关文章:
Android 14 vold 分析(1)启动
1.启动 它是从rc文件中启动的,rc文件是second stage init才会解析的,也就是说vold主要作用做second stage mount,那first stage mount是怎么做的呢,第一阶段实际上直接调用的是fs_mgr进行的mount,fs_mgr_do_mount_one…...
【云计算】混合云组成、应用场景、风险挑战
混合云组成及应用场景 1.混合云组成1.1 基础网络1.2 统一的技术平台 2.混合云应用场景2.1 灾备2.2 弹性算力调度2.3 法律合规2.4 成本控制 3.风险与挑战3.1 标准缺乏3.2 网速有限3.3 技术绑定3.4 法律合规 1.混合云组成 根据混合云应用场景的不同,混合云的组件差别…...
spring bean的继承和依赖
bean的继承和依赖 spring除了提供了一般的配置bean的方式之外,还实现了java中继承的特性,设置bean的父子关系,这样对于一些重复的配置就可以进行省略 bean的继承 配置bean的父子关系,父bean有的东西,子bean全部继承过来…...
Swift中的字符串
Swift中的字符串是一个有序的字符集合,用于存储和操作文本数据。字符串由一系列的Unicode字符组成,可以包含任意的字符,包括字母、数字、符号和空格等。 在Swift中,字符串的类型是String,可以使用双引号或者三引号来表…...

MySQL基础-----约束详解
目录 一. 概述: 二.约束演示: 三.外键约束: 3.1介绍: 3.2外键约束语法: 3.3删除,更新行为: 一. 概述: 🧐🧐概念:约束是作用于表中字段上的规则,用于限制…...

【Unity】游戏场景添加后处理特效PostProcessing
添加后处理特效PostProcessing 添加雾效果后处理何为后处理?添加后处理特效 添加雾效果 依次点击Window -> Rendering -> Lighting添加Lighting面板。 点击Lighting里面的Environment,找到Other Setting 将Fog选项勾选 更改下方的颜色 调整雾的浓…...

STM32芯片软复位导致SRAM2的值被擦除话题
1. 问题描述 客户在使用 STM32L433CCY6 开发过程中,出现软件复位后 SRAM2 里的值被擦除问题。 2. 问题确认 客户用同一版软件在两块板子上的表现还不一样,一块软件复位后 SRAM2 的值不会被擦除,另一块则会被擦除,并且确认被擦除…...

【C++航海王:追寻罗杰的编程之路】异常——错误处理方式之一
目录 引言 1 -> C语言传统的处理错误的方式 2 -> C异常概念 3 -> 异常的使用 3.1 -> 异常的抛出和捕获 3.2 -> 异常的重新抛出 3.3 -> 异常规范 4 -> 自定义异常体系 5 -> C标准库的异常体系 6 -> 异常的优缺点 引言 在C编程中ÿ…...

5.2 mybatis之autoMappingBehavior作用
文章目录 1. NONE关闭自动映射2. PARTIAL非嵌套结果映射3. FULL全自动映射 众所周知mybatis中标签< resultMap >是用来处理数据库库字段与java对象属性映射的。通常java对象属性(驼峰格式)与数据库表字段(下划线形式)是一 一…...

【算法一则】做算法学数据结构 - 简化路径 - 【栈】
目录 题目栈代码题解 题目 给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 ‘/’ 开头),请你将其转化为更加简洁的规范路径。 在 Unix 风格的文件系统中,一个点(.)表…...

OpenHarmony实战开发-如何使用Web预渲染实现功能介绍。
介绍 为了便于大家在使用本案例集时能够更详细的了解各个案例,本案例基于Web预渲染实现了案例介绍功能,即应用右下角的问号icon。 效果图预览 使用说明 因为直接加载的线上README,因此本功能需联网使用点击icon,即会弹出对应案…...
三七互娱,oppo,快手25届暑期实习内推
三七互娱,oppo,快手25届暑期实习内推 ①OPPO 【内推码】:X6866447 【一键内推】:https://careers.oppo.com/university/oppo/campus/post?shareId4546 【需求岗位】软件类、AI/算法类、硬件类、设计类、产品类 ②快手 【岗位】算法、工程、游…...

InnoDB架构:内存篇
InnoDB架构:内存篇 InnoDB是MySQL数据库中默认的存储引擎,它为数据库提供了事务安全型(ACID兼容)、行级锁定和外键支持等功能。InnoDB的架构设计优化了对于读取密集和写入密集型应用的性能表现,是一个高度优化的存储系…...

8个Python高效数据分析的技巧
这篇文章介绍了8个使用Python进行数据分析的方法,不仅能够提升运行效率,还能够使代码更加“优美”。 1 一行代码定义List 定义某种列表时,写For 循环过于麻烦,幸运的是,Python有一种内置的方法可以在一行代码中解决…...

暴力破解密码自动阻断
1 re模块 re 模块是 Python 中用于正则表达式操作的模块。正则表达式(Regular Expression)是一种强大的文本处理工具,它使用一种特殊的字符序列来表示字符串中的模式,并可以通过模式匹配、查找、替换等操作对文本进行高效处理。 …...

【华为】Telnet实验配置
【华为】Telnet 实验配置 应用场景三种认证方式配置注意事项拓扑无认证(None)交换机配置顺序Telnet ServerTelnet Client测试 密码认证(Password)配置顺序Telnet ServerTelnet Client测试 AAA认证(scheme)配…...

SAM功能改进VRP-SAM论文解读VRP-SAM: SAM with Visual Reference Prompt
现已总结SAM多方面相关的论文解读,具体请参考该专栏的置顶目录篇 一、总结 1. 简介 发表时间:2024年3月30日 论文: 2402.17726.pdf (arxiv.org)https://arxiv.org/pdf/2402.17726.pdf代码: syp2ysy/VRP-SAM (github.com)htt…...
MySQL truncate table 与 delete 清空表的区别和坑
拓展阅读 MySQL View MySQL truncate table 与 delete 清空表的区别和坑 MySQL Ruler mysql 日常开发规范 MySQL datetime timestamp 以及如何自动更新,如何实现范围查询 MySQL 06 mysql 如何实现类似 oracle 的 merge into MySQL 05 MySQL入门教程࿰…...

Spring GA、PRE、SNAPSHOT 版本含义及区别
GA:General Availability: 正式发布的版本,推荐使用(主要是稳定),与maven的releases类似; PRE: 预览版,内部测试版。主要是给开发人员和测试人员测试和找BUG用的,不建议使用; SNAPSHOT: 快照…...

一文看懂标准版和Pro版的区别
在CRMEB的众多产品中,有这样两款产品经常被拿来比较,它们就是CRMEB的标准版和Pro版商城系统,今天,我们就来盘一下这两款系统之间究竟有哪些不同。 1、Pro版系统性能更卓越 CRMEB Pro版采用Tp6 SwooleRedis高性能框架开发&#x…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...