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…...

腾讯云服务器价格表(腾讯云服务器报价表)
腾讯云服务器提供了多种类型的产品,以满足不同用户的需求,其价格因产品类型、配置和使用时长等因素而有所不同。以下是根据最近的信息整理的腾讯云服务器价格表概览,但请注意,实际价格可能会有所变动,建议用户在购买前…...

试试把GPT和Suno结合起来用(附免费GPT)
什么是GPT GPT(生成预训练变换器)是由OpenAI开发的一种先进的人工智能模型,它能够理解和生成人类语言。通过大量的数据训练,GPT模型不仅能够撰写文章、编写代码,还能创作诗歌和故事。而现在,这种技术已经扩…...

SpringBoot修改菜品模块开发
需求分析与设计 一:产品原型 在菜品管理列表页面点击修改按钮,跳转到修改菜品页面,在修改页面回显菜品相关信息并进行修改,最后点击保存按钮完成修改操作。 修改菜品原型: 二:接口设计 通过对上述原型图…...

Rust开发笔记 | 系统编程的守护神
在如今这个信息技术不断发展的时代,系统编程语言演进的步伐从未停歇。Rust,作为现代化的系统编程语言,正凭借其出色的性能、安全性和并发处理能力赢得编程界的广泛赞誉。有别于传统的系统编程语言,Rust在保证高性能的同时…...

dcoker+nginx解决前端本地开发跨域
步骤 docker 拉取nginx镜像跑容器 并配置数据卷nginx.conf nginx.conf文件配置 这里展示server server {listen 80;listen [::]:80;server_name localhost;#access_log /var/log/nginx/host.access.log main;location / {# 当我们访问127.0.0.1:8028就会跳转到ht…...

基于云开发和微信小程序的爱宠家系统
基于云开发和微信小程序的爱宠家系统 “Development of PetCare Home System based on Cloud Computing and WeChat Mini Program” 完整下载链接:基于云开发和微信小程序的爱宠家系统 文章目录 基于云开发和微信小程序的爱宠家系统摘要第一章 系统概述1.1 研究背景1.2 研究目…...

光场相机建模与畸变校正改进方法
摘要:光场相机作为一种新型的成像系统,可以直接从一次曝光的图像中得到三维信息。为了能够更充分有效地利用光场数据包含的角度和位置信息,完成更加精准的场景深度计算,从而提升光场相机的三维重建的精度,需要实现精确…...

面试算法-173-二叉树的直径
题目 给你一棵二叉树的根节点,返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 示例 1: 输入:root [1,2,3,4,…...

Python Typing模块
Python Typing模块 常用类型 类型说明int,long,float整型,长整形,浮点型bool,str布尔型,字符串类型List, Tuple, Dict, Set列表,元组,字典, 集合Iterable,Iterator可迭代类型,迭代器类型Generator生成器类型 后三行需要从typing…...

【鸿蒙开发】饿了么页面练习
0. 整体结构 整体划分3部分。店铺部分,购物车部分,金额统计部分。使用 Stack 把3部分堆叠 0.1 整体页面 Index.ets 修改 Index.ets ,使用堆叠布局,并居底部对齐 import { ElShop } from ../components/ElShop import { ElShopp…...