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呢? 我们下一篇文章解答

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/805376.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人脸识别业务(基于腾讯人脸识别接口)

使用腾讯云人脸识别接口&#xff0c;基于优图祖母模型。 一、准备工作 人脸识别账号 申请腾讯云服务器账号&#xff0c;生成自己的秘钥。记录秘钥和秘钥ID。 创建人员库 记下人员库id 在配置文件application.yml中添加配置。 plateocr:SecretId: 秘钥IDSecretKey: 秘钥ser…

红队内网攻防渗透:内网渗透之域内横向移动攻击技术

红队内网攻防渗透 常用windows远程连接和相关命令1.IPC1.首先建立一个IPC连接2.net use 查看当前连接3.ipc\$利用条件:4.ipc\$连接失败原因:5.常见错误号:2.ipc连接获取远程主机信息1.dir列出远程主机文件2.tasklist命令列出目标主机上运行的进程3.IPC计划任务攻击流程at命令…

Day1 省选衔接题 思路总结

Day1 省选题 思路 取数 可反悔的贪心。我们开一个双向链表记录此时每个数的前/后一个数是什么。一个简单但不一定正确的贪心策略即为&#xff1a;每次都取走当前值最大的且可取的数&#xff0c;并更新列表。考虑如何使这个贪心思路正确。 设 p r e x pre_x prex​ 表示 x x …

Path Aggregation Network for Instance Segmentation

PANet 摘要1. 引言2.相关工作3.框架 PANet 最初是为 proposal-based 实例分割框架提出来的&#xff0c;mask 是实例的掩码&#xff0c;覆盖了物体包含的所有像素&#xff0c;proposal 在目标检测领域是可能存在目标的区域。在实例分割中&#xff0c;首先利用RPN(Region Proposa…

深入理解Java中的字段与属性的区别

1、Java中的属性和字段有什么区别&#xff1f; 答&#xff1a;Java中的属性(property)&#xff0c;通常可以理解为get和set方法。 而字段(field)&#xff0c;通常叫做“类成员”&#xff0c;或 "类成员变量”&#xff0c;有时也叫“域”&#xff0c;理解为“数据成员”&…

c语言字符串函数(模拟实现)

用递归的方式完成strlen int my_len(const char* str) { static int count; assert(str);//能够判断为不为空指针 if (*str ! \0) { my_len(str); return count; } else { count 0; return count;;//真正的strlen是unsi…

练习题(2024/4/10)

1. 删除有序数组中的重复项 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元…

2022年蓝桥杯省赛——直线

目录 题目链接&#xff1a;11.直线 - 蓝桥云课 (lanqiao.cn) 题目描述 思路 代码思路如下 代码实现 坑来喽~~ 导致这个BUG的原因&#xff01;&#xff01;&#xff01; 总结 整体的 两种b的情况对比数据 题目链接&#xff1a;11.直线 - 蓝桥云课 (lanqiao.cn) 题目描…

一文搞懂计算机视觉模型

计算机视觉&#xff0c;这个曾经让科学家们望而生畏的领域&#xff0c;如今在深度学习的加持下&#xff0c;正迎来前所未有的发展。你是否好奇&#xff0c;是哪些深度学习模型让计算机拥有了“慧眼”&#xff1f;让我们一起揭开这些模型的神秘面纱。 /1 卷积神经网络 (CNNs)。…

分库,分表,分区,分片

MySQL&#xff1a; 是一个开源的关系型数据库管理系统&#xff0c;主要用于存储和管理数据。它提供了命令行接口&#xff0c; SQLyog&#xff1a; 是一个图形化的客户端软件&#xff0c;专门用于管理和操作MySQL数据库。 它提供了一个直观的用户界面&#xff0c;简化了MySQL数据…

JVM面试整理--对象的创建和堆

文章目录 对象的创建过程是怎样的?对象在内存中的结构是怎样的&#xff08;专业的叫法&#xff1a;对象的内存布局&#xff09;对象在内存分配时使用的哪种方式&#xff08;有的地方也称为&#xff1a;分配算法&#xff09;知道什么是“指针碰撞”吗&#xff1f;知道什么是“空…

LeetCode 80—— 删除有序数组中的重复项 II

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 让 index指向删除重复元素后数组的新长度&#xff1b;让 st_idx 指向重复元素的起始位置&#xff0c;而 i 指向重复元素的结束位置&#xff0c;duplicate_num代表重复元素的个数&#xff1b;一段重复元素结束后&am…

php校园活动报名系统vue+mysql

开发语言&#xff1a;php 后端框架&#xff1a;Thinkphp/Laravel 前端框架&#xff1a;vue.js 服务器&#xff1a;apache 数据库&#xff1a;mysql 运行环境:phpstudy/wamp/xammp等本选题则旨在通过标签分类管理等方式&#xff0c;管理员&#xff1b;首页、个人中心、学生管理、…

如何从零开始训练一个语言模型

如何从零开始训练一个语言模型 #mermaid-svg-gtUlIrFtNPw1oV5a {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-gtUlIrFtNPw1oV5a .error-icon{fill:#552222;}#mermaid-svg-gtUlIrFtNPw1oV5a .error-text{fill:#5522…

Redis 缓存穿透、缓存击穿、缓存雪崩区别和解决方案

缓存穿透 什么是缓存穿透&#xff1f; 缓存穿透说简单点就是大量请求的 key 是不合理的&#xff0c;根本不存在于缓存中&#xff0c;也不存在于数据库中 。这就导致这些请求直接到了数据库上&#xff0c;根本没有经过缓存这一层&#xff0c;对数据库造成了巨大的压力&#xf…

2、Qt UI控件 -- qucsdk项目使用

前言&#xff1a;上一篇文章讲了qucsdk的环境部署&#xff0c;可以在QDesigner和Qt Creator中看到qucsdk控件&#xff0c;这一篇来讲下在项目中使用qucsdk库中的控件。 一、准备材料 要想使用第三方库&#xff0c;需要三个先决条件&#xff0c; 1、控件的头文件 2、动/静态链…

【C++造神计划】定义常量

1 宏常量&#xff08;macro constants&#xff09; 使用预处理器指令 #define 可以将那些经常使用的常量定义为你自己取的名字而不需要借助于变量 编译器在遇到 #define 指令的时候&#xff0c;做的只是把任何出现这些常量名的地方替换成它们被定义为的代码 #define 指令不是…

rollup 插件架构-装饰器模式增添插件性能分析

文章目录 输入 rollup 配置根据用户配置开启插件性能分析性能分析函数实现分级输出结果装饰器模式拓展组件 输入 rollup 配置 初始化计时器&#xff0c;构建完成时输出每个阶段的耗时、内存占用等信息,会 wrapper 相应 hook 方法&#xff0c;添加计时相关功能 initialiseTime…

记录vue之npm run serve报错SET NODE_OPTIONS

> vue-antd-pro3.0.0 serve > SET NODE_OPTIONS--openssl-legacy-provider && vue-cli-service servesh: SET: command not found 一定要注意&#xff1a;将 SET NODE_OPTIONS–openssl-legacy-provider && 删除即可

17 - Games101 - 笔记 - 材质与外观

**17 **材质与外观 材质与BRDF 自然界中的材质&#xff1a;丝绸、头发、蝴蝶翅膀表面、寿司表面等等 图形学中的材质&#xff1a;同一个模型之所以渲染出不同结果的原因就是因为材质。在图形学中是给不同的物体指定不同的材质&#xff0c;知道它们如何和光线作用后就能正确的…