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…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...

(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...