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…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...
Linux安全加固:从攻防视角构建系统免疫
Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...
机器学习的数学基础:线性模型
线性模型 线性模型的基本形式为: f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法,得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...
TJCTF 2025
还以为是天津的。这个比较容易,虽然绕了点弯,可还是把CP AK了,不过我会的别人也会,还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...
