当前位置: 首页 > news >正文

Android 14 vold 分析(2)VolumeManager 和 NetlinkManger

3.  VolumeManager::Instance() 和 VolumeManager::start()
    system/vold/VolumeManager.cpp  
    3.1 Instance()没啥好说的 非常简单
 
    112  VolumeManager* VolumeManager::Instance() {113      if (!sInstance) sInstance = new VolumeManager();114      return sInstance;115  }116  117  VolumeManager::VolumeManager() {118      mDebug = false;119      mNextObbId = 0;120      mNextStubId = 0;121      // For security reasons, assume that a secure keyguard is122      // showing until we hear otherwise123      mSecureKeyguardShowing = true;124  }
    3.2 VolumeManager::start()
 
    174  int VolumeManager::start() {175      ATRACE_NAME("VolumeManager::start");176  177      // Always start from a clean slate by unmounting everything in178      // directories that we own, in case we crashed.179      unmountAll();           -----> 全部 unmount , 这里的unmount似乎并不是全部所有分区, 全部的话那还了得180  181      Loop::destroyAll();182  183      // Assume that we always have an emulated volume on internal184      // storage; the framework will decide if it should be mounted.185      CHECK(mInternalEmulatedVolumes.empty());186  187      auto vol = std::shared_ptr<android::vold::VolumeBase>(188              new android::vold::EmulatedVolume("/data/media", 0));  ---> 创建 EmulatedVolume189      vol->setMountUserId(0);190      vol->create();191      mInternalEmulatedVolumes.push_back(vol);192  193      // Consider creating a virtual disk194      updateVirtualDisk();195  196      return 0;197  }

4.  NetlinkManger::Instance() 和 NetlinkManger::start()
    system/vold/NetlinkManager.cpp
    4.1 NetlinkManger::Instance() 很简单 不需要赘述
 
    36  NetlinkManager* NetlinkManager::Instance() {37      if (!sInstance) sInstance = new NetlinkManager();38      return sInstance;39  }40  41  NetlinkManager::NetlinkManager() {42      mBroadcaster = NULL;43  }

    4.2 NetlinkManger::start()
    
47  int NetlinkManager::start() {48      struct sockaddr_nl nladdr;49      int sz = 64 * 1024;50      int on = 1;51  52      memset(&nladdr, 0, sizeof(nladdr));53      nladdr.nl_family = AF_NETLINK;54      nladdr.nl_pid = getpid();55      nladdr.nl_groups = 0xffffffff;56  57      if ((mSock = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT)) < 0) {   ---> 创建socket client58          PLOG(ERROR) << "Unable to create uevent socket";59          return -1;60      }61  62      // When running in a net/user namespace, SO_RCVBUFFORCE will fail because63      // it will check for the CAP_NET_ADMIN capability in the root namespace.64      // Try using SO_RCVBUF if that fails.65      if ((setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) &&66          (setsockopt(mSock, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz)) < 0)) {67          PLOG(ERROR) << "Unable to set uevent socket SO_RCVBUF/SO_RCVBUFFORCE option";68          goto out;69      }70  71      if (setsockopt(mSock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {72          PLOG(ERROR) << "Unable to set uevent socket SO_PASSCRED option";73          goto out;74      }75  76      if (bind(mSock, (struct sockaddr*)&nladdr, sizeof(nladdr)) < 0) {  --> socket bind77          PLOG(ERROR) << "Unable to bind uevent socket";78          goto out;79      }80  81      mHandler = new NetlinkHandler(mSock);    --> 创建 new NetlinkHandler82      if (mHandler->start()) {     --> 创建 new NetlinkHandler.start() 见4.383          PLOG(ERROR) << "Unable to start NetlinkHandler";84          goto out;85      }86  87      return 0;88  89  out:90      close(mSock);91      return -1;92  }

        4.3 new NetlinkHandler and start()

        这有个继承关系NetlinkHandler : NetlinkListener : SocketListener
 

    2  int NetlinkHandler::start() {33      return this->startListener();       ------> 实际就是SocketListener poll监听,是否有POLLIN 产生, onDataAvailable -> onEvent34  }35  36  void NetlinkHandler::onEvent(NetlinkEvent* evt) {  ---> 收到了uevent37      VolumeManager* vm = VolumeManager::Instance();38      const char* subsys = evt->getSubsystem();39  40      if (!subsys) {41          LOG(WARNING) << "No subsystem found in netlink event";42          return;43      }44  45      if (std::string(subsys) == "block") {   ------> 只有uevent的subsys是block才会处理的46          vm->handleBlockEvent(evt);       ------> VolumeManager处理 block device uevent  见 4.447      }48  }

        4.4 VolumeManager::handleBlockEvent()
    
199  void VolumeManager::handleBlockEvent(NetlinkEvent* evt) {200      std::lock_guard<std::mutex> lock(mLock);201  202      if (mDebug) {203          LOG(DEBUG) << "----------------";204          LOG(DEBUG) << "handleBlockEvent with action " << (int)evt->getAction();  ---> 这里是vold.debug控制的,打印具体的action205          evt->dump();206      }207  208      std::string eventPath(evt->findParam("DEVPATH") ? evt->findParam("DEVPATH") : "");209      std::string devType(evt->findParam("DEVTYPE") ? evt->findParam("DEVTYPE") : "");210  211      if (devType != "disk") return;    --->  devType不是disk还不处理, 真是牛逼哄哄212   213      int major = std::stoi(evt->findParam("MAJOR"));214      int minor = std::stoi(evt->findParam("MINOR"));215      dev_t device = makedev(major, minor);   ---> 创建block device组合216  217      switch (evt->getAction()) {218          case NetlinkEvent::Action::kAdd: {     ---> uevent action为add 具体见4.5219              for (const auto& source : mDiskSources) {  ---> 之前添加的两个disksource,还记得吗,只支持sd卡和U盘220                  if (source->matches(eventPath)) {221                      // For now, assume that MMC and virtio-blk (the latter is222                      // specific to virtual platforms; see Utils.cpp for details)223                      // devices are SD, and that everything else is USB224                      int flags = source->getFlags();225                      if (major == kMajorBlockMmc || IsVirtioBlkDevice(major)) {226                          flags |= android::vold::Disk::Flags::kSd;  ---> SD卡227                      } else {228                          flags |= android::vold::Disk::Flags::kUsb; ---> usb storage, 通过otg插入的229                      }230  231                      auto disk =232                          new android::vold::Disk(eventPath, device, source->getNickname(), flags);  ---> 创建一个disk设备节点mknod233                      handleDiskAdded(std::shared_ptr<android::vold::Disk>(disk)); --> 真正的处理234                      break;235                  }236              }237              break;238          }239          case NetlinkEvent::Action::kChange: {  --> uevent action为add 具体见4.6240              LOG(VERBOSE) << "Disk at " << major << ":" << minor << " changed";241              handleDiskChanged(device);242              break;243          }244          case NetlinkEvent::Action::kRemove: { --> uevent action为add 具体见4.7245              handleDiskRemoved(device);246              break;247          }248          default: {249              LOG(WARNING) << "Unexpected block event action " << (int)evt->getAction();250              break;251          }252      }253  }
    4.5 new android::vold::Disk()和handleDiskAdded()
        system/vold/model/Disk.cpp
   4.5.1 new android::vold::Disk()
        
Disk::Disk(const std::string& eventPath, dev_t device, const std::string& nickname, int flags)95      : mDevice(device),96        mSize(-1),97        mNickname(nickname),98        mFlags(flags),99        mCreated(false),100        mJustPartitioned(false) {101      mId = StringPrintf("disk:%u,%u", major(device), minor(device));102      mEventPath = eventPath;103      mSysPath = StringPrintf("/sys/%s", eventPath.c_str());104      mDevPath = StringPrintf("/dev/block/vold/%s", mId.c_str());105      CreateDeviceNode(mDevPath, mDevice);  ---------> 创建block device 的设备节点mknod106  }
        4.5.2 handleDiskAdded()
        
255  void VolumeManager::handleDiskAdded(const std::shared_ptr<android::vold::Disk>& disk) {256      // For security reasons, if secure keyguard is showing, wait257      // until the user unlocks the device to actually touch it258      // Additionally, wait until user 0 is actually started, since we need259      // the user to be up before we can mount a FUSE daemon to handle the disk.260      bool userZeroStarted = mStartedUsers.find(0) != mStartedUsers.end();261      if (mSecureKeyguardShowing) {262          LOG(INFO) << "Found disk at " << disk->getEventPath()263                    << " but delaying scan due to secure keyguard";264          mPendingDisks.push_back(disk);265      } else if (!userZeroStarted) {266          LOG(INFO) << "Found disk at " << disk->getEventPath()267                    << " but delaying scan due to user zero not having started";268          mPendingDisks.push_back(disk);269      } else {270          disk->create();        ---------> disk->create()271          mDisks.push_back(disk);272      }273  }146  status_t Disk::create() {147      CHECK(!mCreated);148      mCreated = true;149  150      auto listener = VolumeManager::Instance()->getListener();   ---------> StorageManaerService通信151      if (listener) listener->onDiskCreated(getId(), mFlags);  ------> StorageManaerService->onDiskCreated()152  153      if (isStub()) {154          createStubVolume();155          return OK;156      }157      readMetadata();  -------->  listener->onDiskMetadataChanged(getId(), mSize, mLabel, mSysPath);158      readPartitions();  --------> Disk::createPublicVolume()  listener->onVolumeCreated()and listener->onDiskScanned()159      return OK;160  }

思考, vold比mount service启动的早,那开机时vold获取到的listener为空,也就是说虽然disk创建了但是不会mount,那什么时候才会mount呢? 我们下一篇文章解答

相关文章:

Android 14 vold 分析(2)VolumeManager 和 NetlinkManger

3. VolumeManager::Instance() 和 VolumeManager::start() system/vold/VolumeManager.cpp 3.1 Instance()没啥好说的 非常简单 112 VolumeManager* VolumeManager::Instance() {113 if (!sInstance) sInstance new VolumeManager();114 return sInst…...

《黑马点评》Redis高并发项目实战笔记(上)P1~P45

P1 Redis企业实战课程介绍 P2 短信登录 导入黑马点评项目 首先在数据库连接下新建一个数据库hmdp&#xff0c;然后右键hmdp下的表&#xff0c;选择运行SQL文件&#xff0c;然后指定运行文件hmdp.sql即可&#xff08;建议MySQL的版本在5.7及以上&#xff09;&#xff1a; 下面这…...

pytorch车牌识别

目录 使用pytorch库中CNN模型进行图像识别收集数据集定义CNN模型卷积层池化层全连接层 CNN模型代码使用模型 使用pytorch库中CNN模型进行图像识别 收集数据集 可以去找开源的数据集或者自己手做一个 最终整合成 类别分类的图片文件 定义CNN模型 卷积层 功能&#xff1a;提…...

【C++入门】内联函数、auto与基于范围的for循环

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…...

服务器停用,备份服务文件。

文章目录 引言I 文件备份1.1 数据库文件/证书1.2 redis1.3 nacosII JAVA流水线备份2.1 java构建2.2 镜像构建2.3 docker 部署2.4 子模块构建2.5 Dockerfile_prodIII VUE项目流水线备份3.1 Node.js 构建3.2 Dockerfile_prod...

基于Python的深度学习的中文情感分析系统(V2.0),附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…...

使用Postman发送跨域请求实验

使用Postman发送跨域请求 1 跨域是什么&#xff1f;2 何为同源呢?3 跨域请求是如何被检测到的&#xff1f;4 Postman跨域请求测试4.1 后端准备4.2 测试用例4.2.1 后端未配置跨域请求(1) 前端不跨域&#xff08;2&#xff09;前端跨域 4.2.2 后端配置跨域信息&#xff08;1&…...

4、jvm-垃圾收集算法与垃圾收集器

垃圾收集算法 分代收集理论 当前虚拟机的垃圾收集都采用分代收集算法&#xff0c;这种算法没有什么新的思想&#xff0c;只是根据对象存活周期的不同将内存分为几块。一般将java堆分为新生代和老年代&#xff0c;这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。 比如…...

[Excel]如何限制儲存格輸入格式? 以“字首為英文字母大寫,其餘為數字,共15碼“為範例

[Excel]如何限制儲存格輸入格式 需求: 當一個excel表格需要由多位使用者來輸入資料時&#xff0c;難免會出現資料輸入錯誤問題&#xff0c;尤其是料號&#xff0c;品號或是訂單號的長類型編碼。若是問題屬於輸入錯誤"資料"但格式未錯誤&#xff0c;則可能需要讓exce…...

错题记录-华为海思

华为 海思数字芯片 参考 &#xff1a;FPGA开发/数字IC笔试系列(5) 华为海思IC笔试解析 FPGA开发/数字IC笔试系列(6) 华为海思IC笔试解析 SystemVerilog Function与Task的区别 $readmemh与$readmemb这两个系统任务是用来从指定文件中读取数据到寄存器数组或者RAM、ROM中。除了…...

rspack 使用构建vue3脚手架

基于 Rust 的高性能 Web 构建工具。rspack 主要适配 webpack 生态&#xff0c;对于绝大多数 webpack 工具库都是支持的。 启动速度快&#xff1b;增量热更新快。兼容 webpack 生态&#xff1b;内置了 ts、jsx、css、css modules 等开箱即用。生产优化&#xff0c;tree shaking…...

maven之pom中的build标签

1、build标签分类 1.1、全局配置&#xff08;project build&#xff09; 针对整个项目的所有情况都有效。 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"htt…...

Cesium.js--》探秘Cesium背后的3D模型魔力—加载纽约模型

今天简单实现一个Cesium.js的小Demo&#xff0c;加强自己对Cesium知识的掌握与学习&#xff0c;先简单对这个开源库进行一个简单的介绍吧&#xff01; Cesium 是一个开源的地理空间可视化引擎&#xff0c;用于创建基于 Web 的三维地球应用程序。它允许开发人员在网页上呈现高度…...

.NET i18n 多语言支持与国际化

环境 WIN10 VS2022 .NET8 1.&#x1f44b;创建项目 2.&#x1f440;创建Resources Controllers HomeController.en.resx HomeController.fr.resx HomeController.zh.resx 3.&#x1f331;Program.cs添加国际化支持 // 添加国际化支持 builder.Services.AddLocalization(…...

基于Pytorch实现图像分类——基于jupyter

分类任务 网络基本构建与训练方法&#xff0c;常用函数解torch.nn.functional模块nn.Module模块 MNIST数据集下载 from pathlib import Path import requestsDATA_PATH Path("data") PATH DATA_PATH / "mnist"PATH.mkdir(parentsTrue, exist_okTrue)U…...

如何将CSDN的文章以PDF文件形式保存到本地

1.F12 打开开发者工具窗口 2.console下输入命令 (function(){$("#side").remove();$("#comment_title, #comment_list, #comment_bar, #comment_form, .announce, #ad_cen, #ad_bot").remove();$(".nav_top_2011, #header, #navigator").remove…...

面试经典150题——删除有序数组中的重复项

面试经典150题 day3 题目来源我的题解方法一 双指针 题目来源 力扣每日一题&#xff1b;题序&#xff1a;26 我的题解 方法一 双指针 使用两个指针分别指向相同元素的左右边界&#xff0c;再利用一个count记录最终需要的数组长度。 时间复杂度&#xff1a;O(n) 空间复杂度&a…...

Unity3D知识点精华浓缩

一、细节 1、类与组件的关系 2、Time.deltaTime的含义 3、怎么表示一帧的移动距离 4、Update和LateUpdate的区别和适用场景 5、找游戏对象的方式&#xff08;别的对象 / 当前对象的子对象&#xff09; 6、组件1调用组件2中方法的方式 7、在面板中获取外部数据的方法 8、序列化属…...

HTML的文档说明

1.告诉浏览器当前网页的版本 2.写法&#xff1a; &#xff01;以前的写法&#xff1a;要依据网页的HTML的版本去确定&#xff0c;紫萼发油很多很多。 具体的写法可以参考&#xff1a;W3C官网的文档说明 &#xff01;新写法&#xff1a;W3C都推荐用h5的写法 <DOCTYPE ht…...

ubuntu 更新或更改GCC/G++

最近遇到一些问题&#xff0c;需要用到gcc-9/g-9&#xff0c;但是我自带的ubuntu18.04是gcc-7.5/g-7.5&#xff0c;所以升级一下&#xff0c;奈何文章太多而且很多无效&#xff0c;所以在此记录一下&#xff1a; 参考&#xff1a;https://stackoverflow.com/questions/19836858…...

Java --- Java语言基础

这个Java可是个好东西&#xff0c;是一门面对对象的程序设计语言&#xff0c;其语法很类似C&#xff0c;所以学过C的伙伴们就很好上手&#xff0c;另外Java对C进行了简化与提高&#xff0c;这个在后期学习会感受到&#xff0c;Java还有很多的类库API文档以及第三方开发包。 这…...

【C++算法竞赛 · 图论】图的存储

前言 图的存储 邻接矩阵 方法 复杂度 应用 例题 题解 邻接表 方法 复杂度 应用 前言 上一篇文章中&#xff08;【C算法竞赛 图论】图论基础&#xff09;&#xff0c;介绍了图论相关的概念和一种图的存储的方法&#xff0c;这篇文章将会介绍剩下的两种方法&#xff…...

Spring AOP IOC

spring的优缺点 IOC集中管理对象&#xff0c;对象之间解耦&#xff0c;方便维护对象AOP在不修改原代码的情况下&#xff0c;实现一些拦截提供众多辅助类&#xff0c;方便开发方便集成各种优秀框架 紧耦合和松耦合 松耦合可以使用单一职责原则、接口分离原则、依赖倒置原则 …...

Linux ARM平台开发系列讲解(QEMU篇) 1.1 编译QEMU 构建RISC-V64架构 运行Linux kernel

1. 概述 QEMU可以模拟很多架构的CPU(ARM,RISC-V等),重点是免费,用来学Linux简直太适合不过了,所以,我打算开一章节来教QEMU的使用,这样也方便环境统一调试,本章节就讲解如何在Ubuntu搭建QEMU,我的环境是全新的Ubuntu22,QEMU下载的9.0,kernel下载的6.0. 2. 源码下载…...

Day19-【Java SE进阶】网络编程

一、网络编程 1.概述 可以让设备中的程序与网络上其他设备中的程序进行数据交互(实现网络通信的)。java.net,*包下提供了网络编程的解决方案! 基本的通信架构 基本的通信架构有2种形式:CS架构(Client客户端/Server服务端)、BS架构(Browser浏览器/Server服务端)。 网络通信的…...

pyqt写个星三角降压启动方式2

星三角降压启动用可以用类进行封装&#xff0c;就像博图FB块那样。把逻辑都在类里完成&#xff0c;和外界需要交互的暴露出接口。测试过程中&#xff0c;发现类中直接用定时器QTimer会出现问题。然后就把定时器放到外面了。然后测试功能正常。 from PySide6.QtWidgets import …...

js可视化爬取数据生成当前热点词汇图

功能 可以爬取到很多数据&#xff0c;并且生成当前的热点词汇图&#xff0c;词越大越热门&#xff08;词云图&#xff09; 这里以b站某个评论区的数据为例&#xff0c;爬取63448条数据生成这样的图片 让我们能够更加直观的看到当前的热点 git地址 可以直接使用&#xff0c;中文…...

研发岗-面临统信UOS系统配置总结

第一步 获取root权限 配置环境等都需要用到root权限&#xff0c;所以我们先获取到root权限&#xff0c;方便下面的操作 下载软件 在UOS应用商店下载的所需应用 版本都比较低 安装node 官网下载了【arm64】的包&#xff0c;解压到指定文件夹&#xff0c;设置链接&#xff0…...

【STL详解 —— list的介绍及使用】

STL详解 —— list的介绍及使用 list的介绍list的介绍使用list的构造list iterator的使用list capacitylist element accesslist modifiers 示例list的迭代器失效 list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭…...

cocos creator开发中遇到的问题和解决方案

前言 总结一下使用cocos开发遇到的坑&#xff0c;不定期更新。 问题汇总 代码修改Position坐标不生效 首先要通过打log或者断点排除下是不是逻辑上的问题&#xff0c;还有是不是有动画相关把位置修改了。我遇到的问题是坐标修改被widget组件覆盖了。 纹理压缩包体变大 co…...

短租房网站哪家做最好/鞋子软文推广300字

传送门: http://blog.csdn.net/BlueEffie/article/details/50971665...

唐县做网站/公司网站搭建流程

转眼间&#xff0c;2019就到了末尾&#xff0c;回首这一年&#xff0c;一半颓废&#xff0c;一半努力。上半年过的滋滋润润的&#xff0c;而下半年却为了找工作找到了高考的感觉&#xff0c;基本上&#xff0c;果然出来混都是要还的。 回想起来大学四年&#xff0c;感觉也就大…...

电商app制作开发/京东关键词优化技巧

历经300多个日夜&#xff0c;2021年8月&#xff0c;基于国产企业级分布式数据库腾讯云TDSQL打造的昆山农商银行新一代核心系统成功投产上线。它采用“微服务应用国产分布式数据库”架构&#xff0c;该架构在同类银行中尚属首次。 新核心系统整体处理能力可以达到6300TPS&#x…...

营销手机网站制作/推广软文200字

#!/bin/sh#这个脚本用来判断后面的参数的种类(非数字&#xff0c;奇数&#xff0c;偶数&#xff0c;浮点数)。#用法&#xff1a;Usag&#xff1a; [参数列表]# checknum.sh#检测参数个数是否合法if test $# -lt 1 #当参数个数小于2时&#xff0c;也就是没有整数输入&#x…...

卖货到海外的免费平台/小时seo

1 传统API2 简化API 3 点对点 传统 4 发布订阅传统传统API简化API点对点域特定API发布订阅域特定APIConnection FactoryConnection FactoryQueueConnection FactoryTopicConnection FactoryConnectionJMSContextQueueConnectionTopicConnectionSessionJMSContextQueueSessionTo…...

深圳旅游网站建设/seo网络优化师就业前景

我们通常会用屏&#xff08;Screen&#xff09;来称呼一个页面&#xff08;Page&#xff09;&#xff0c;一个完整的App应该是有多个Page组成的。 在之前的案例&#xff08;豆瓣&#xff09;中&#xff0c;我们通过IndexedStack来管理了首页中的Page切换&#xff1a; 首页-书影…...