Android 14 vold 分析(1)启动

2024-04-10 07:52
文章标签 分析 android 启动 14 vold

本文主要是介绍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)启动的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/890477

相关文章

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间

springboot3打包成war包,用tomcat8启动

1、在pom中,将打包类型改为war <packaging>war</packaging> 2、pom中排除SpringBoot内置的Tomcat容器并添加Tomcat依赖,用于编译和测试,         *依赖时一定设置 scope 为 provided (相当于 tomcat 依赖只在本地运行和测试的时候有效,         打包的时候会排除这个依赖)<scope>provided

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

用命令行的方式启动.netcore webapi

用命令行的方式启动.netcore web项目 进入指定的项目文件夹,比如我发布后的代码放在下面文件夹中 在此地址栏中输入“cmd”,打开命令提示符,进入到发布代码目录 命令行启动.netcore项目的命令为:  dotnet 项目启动文件.dll --urls="http://*:对外端口" --ip="本机ip" --port=项目内部端口 例: dotnet Imagine.M

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57