Android 14 vold 分析(3)vold和mount service通信

vold和mount service都是binder service,并不是mount service只调用vold,vold也会调用mount service,这是双向的,这里解答上一章的问题

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

这里通过mount service 的分析解释上面的问题
1. mount service在SystemServer->startOtherServices() 可以看出这个service对android来说不是至关重要的,至少他不是bootstrap、core service
 
frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
.....
1788                      mSystemServiceManager.startService(STORAGE_MANAGER_SERVICE_CLASS);
1789                      storageManager = IStorageManager.Stub.asInterface(
1790                              ServiceManager.getService("mount"));

2. onStart()
 
frameworks/base/services/core/java/com/android/server/StorageManagerService.java#231
231          public void onStart() {
232              mStorageManagerService = new StorageManagerService(getContext());  ----> 创建StorageManagerService实例
233              publishBinderService("mount", mStorageManagerService);   -----> 添加mount到ServiceManager里
234              mStorageManagerService.start();   -
235          }
3. 两件事: connectStoraged() 和 connectVold()
 
1926      private void start() {
1927          connectStoraged();
1928          connectVold();
1929      }
1930  
1931      private void connectStoraged() {
1932          IBinder binder = ServiceManager.getService("storaged");
1933          if (binder != null) {
1934              try {
1935                  binder.linkToDeath(new DeathRecipient() {
1936                      @Override
1937                      public void binderDied() {
1938                          Slog.w(TAG, "storaged died; reconnecting");
1939                          mStoraged = null;
1940                          connectStoraged();
1941                      }
1942                  }, 0);
1943              } catch (RemoteException e) {
1944                  binder = null;
1945              }
1946          }
1947  
1948          if (binder != null) {
1949              mStoraged = IStoraged.Stub.asInterface(binder);
1950          } else {
1951              Slog.w(TAG, "storaged not found; trying again");
1952          }
1953  
1954          if (mStoraged == null) {
1955              BackgroundThread.getHandler().postDelayed(() -> {
1956                  connectStoraged();
1957              }, DateUtils.SECOND_IN_MILLIS);
1958          } else {
1959              onDaemonConnected();
1960          }
1961      }
1962  
1963      private void connectVold() {
1964          IBinder binder = ServiceManager.getService("vold");
1965          if (binder != null) {
1966              try {
1967                  binder.linkToDeath(new DeathRecipient() {
1968                      @Override
1969                      public void binderDied() {
1970                          Slog.w(TAG, "vold died; reconnecting");
1971                          mVold = null;
1972                          connectVold();
1973                      }
1974                  }, 0);
1975              } catch (RemoteException e) {
1976                  binder = null;
1977              }
1978          }
1979  
1980          if (binder != null) {
1981              mVold = IVold.Stub.asInterface(binder);
1982              try {
1983                  mVold.setListener(mListener);   ---------->  连上vold 后把listener设置到了vold中
1984              } catch (RemoteException e) {
1985                  mVold = null;
1986                  Slog.w(TAG, "vold listener rejected; trying again", e);
1987              }
1988          } else {
1989              Slog.w(TAG, "vold not found; trying again");
1990          }
1991  
1992          if (mVold == null) {
1993              BackgroundThread.getHandler().postDelayed(() -> {
1994                  connectVold();
1995              }, DateUtils.SECOND_IN_MILLIS);
1996          } else {
1997              restoreLocalUnlockedUsers();
1998              onDaemonConnected();
1999          }
2000      }
3. onDaemonConnected()
1313      public void onDaemonConnected() {
1314          mDaemonConnected = true;
1315          mHandler.obtainMessage(H_DAEMON_CONNECTED).sendToTarget();
1316      }
1317  
1318      private void handleDaemonConnected() {
1319          resetIfBootedAndConnected();
1320      }

4. resetIfBootedAndConnected() 这里就是上一章提出的问题的原因函数
 
1056      private void resetIfBootedAndConnected() {
1057          Slog.d(TAG, "Thinking about reset, mBootCompleted=" + mBootCompleted
1058                  + ", mDaemonConnected=" + mDaemonConnected);
1059          if (mBootCompleted && mDaemonConnected) {              -------->  只有两个条件同时满足,才会执行reset操作
1060              final UserManager userManager = mContext.getSystemService(UserManager.class);
1061              final List<UserInfo> users = userManager.getUsers();
1062  
1063              mStorageSessionController.onReset(mVold, () -> {
1064                  mHandler.removeCallbacksAndMessages(null);
1065              });
1066  
1067              final int[] systemUnlockedUsers;
1068              synchronized (mLock) {
1069                  // make copy as sorting can change order
1070                  systemUnlockedUsers = Arrays.copyOf(mSystemUnlockedUsers,
1071                          mSystemUnlockedUsers.length);
1072  
1073                  mDisks.clear();
1074                  mVolumes.clear();
1075  
1076                  addInternalVolumeLocked();
1077              }
1078  
1079              try {
1080                  // Reset vold to tear down existing disks/volumes and start from
1081                  // a clean state.  Exception: already-unlocked user storage will
1082                  // remain unlocked and is not affected by the reset.
1083                  //
1084                  // TODO(b/135341433): Remove cautious logging when FUSE is stable
1085                  Slog.i(TAG, "Resetting vold...");
1086                  mVold.reset();                            ----------->>>>>>>>>> 根源在这里
1087                  Slog.i(TAG, "Reset vold");
1088  
1089                  // Tell vold about all existing and started users
1090                  for (UserInfo user : users) {
1091                      if (user.isCloneProfile()) {
1092                          mVold.onUserAdded(user.id, user.serialNumber, user.profileGroupId);
1093                      } else {
1094                          mVold.onUserAdded(user.id, user.serialNumber, -1);
1095                      }
1096                  }
1097                  for (int userId : systemUnlockedUsers) {
1098                      mVold.onUserStarted(userId);
1099                      mStoraged.onUserStarted(userId);
1100                  }
1101                  restoreSystemUnlockedUsers(userManager, users, systemUnlockedUsers);
1102                  mVold.onSecureKeyguardStateChanged(mSecureKeyguardShowing);
1103                  mStorageManagerInternal.onReset(mVold);
1104              } catch (Exception e) {
1105                  Slog.wtf(TAG, e);
1106              }
1107          }
1108      }

5.bootCompleted() 这里才会真正的执行到reset
238          public void onBootPhase(int phase) {
239              if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
240                  mStorageManagerService.servicesReady();
241              } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
242                  mStorageManagerService.systemReady();
243              } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
244                  mStorageManagerService.bootCompleted();
245              }2088      private void bootCompleted() {
2089          mBootCompleted = true;
2090          mHandler.obtainMessage(H_BOOT_COMPLETED).sendToTarget();
2091      }2093      private void handleBootCompleted() {
2094          resetIfBootedAndConnected();
2095      }

log: 第三次才会执行reset
 

04-09 15:27:35.006  2112  3684 D StorageManagerService: Thinking about reset, mBootCompleted=false, mDaemonConnected=true
04-09 15:27:35.012  2112  3684 D StorageManagerService: Thinking about reset, mBootCompleted=false, mDaemonConnected=true
04-09 15:27:37.854  2112  3684 D StorageManagerService: Thinking about reset, mBootCompleted=true, mDaemonConnected=true

6. vold reset 就是执行的是VolumeManager::reset() 这里就不赘述了
 
904  int VolumeManager::reset() {
905      // Tear down all existing disks/volumes and start from a blank slate so
906      // newly connected framework hears all events.
907      for (const auto& vol : mInternalEmulatedVolumes) {
908          vol->destroy();
909      }
910      mInternalEmulatedVolumes.clear();                      
911  
912      // Destroy and recreate all disks except that StubVolume disks are just
913      // destroyed and removed from both mDisks and mPendingDisks.
914      // StubVolumes are managed from outside Android (e.g. from Chrome OS) and
915      // their disk recreation on reset events should be handled from outside by
916      // calling createStubVolume() again.
917      for (const auto& disk : mDisks) {
918          disk->destroy();
919          if (!disk->isStub()) {
920              disk->create();    -------------> 所有的disks 重新create一遍, 这回listener不会为空了
921          }
922      }
923      const auto isStub = [](const auto& disk) { return disk->isStub(); };
924      mDisks.remove_if(isStub);
925      mPendingDisks.remove_if(isStub);
926  
927      updateVirtualDisk();
928      mAddedUsers.clear();
929      mStartedUsers.clear();
930      mSharedStorageUser.clear();
931  
932      // Abort all FUSE connections to avoid deadlocks if the FUSE daemon was killed
933      // with FUSE fds open.
934      abortFuse();
935      return 0;
936  }


7. onVolumeCreated()
 
system/vold/model/VolumeBase.cpp
181  status_t VolumeBase::create() {
182      CHECK(!mCreated);
183  
184      mCreated = true;
185      status_t res = doCreate();
186  
187      auto listener = getListener();
188      if (listener) {
189          listener->onVolumeCreated(getId(), static_cast<int32_t>(mType), mDiskId, mPartGuid,
190                                    mMountUserId);
191      }
192  
193      setState(State::kUnmounted);
194      return res;
195  }

8. onVolumeCreatedLocked()
 

1373          public void onVolumeCreated(String volId, int type, String diskId, String partGuid,
1374                  int userId) {
1375              synchronized (mLock) {
1376                  final DiskInfo disk = mDisks.get(diskId);
1377                  final VolumeInfo vol = new VolumeInfo(volId, type, disk, partGuid);
1378                  vol.mountUserId = userId;
1379                  mVolumes.put(volId, vol);
1380                  onVolumeCreatedLocked(vol);
1381              }
1382          }


9. onVolumeCreatedLocked()
.....
1523          } else if (vol.type == VolumeInfo.TYPE_PUBLIC) {
1524              // TODO: only look at first public partition
1525              if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, mPrimaryStorageUuid)
1526                      && vol.disk.isDefaultPrimary()) {
1527                  Slog.v(TAG, "Found primary storage at " + vol);
1528                  vol.mountFlags |= VolumeInfo.MOUNT_FLAG_PRIMARY;
1529                  vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE_FOR_WRITE;
1530              }
1531  
1532              // Adoptable public disks are visible to apps, since they meet
1533              // public API requirement of being in a stable location.
1534              // If FBE is enabled, sdcard is no longer considered adoptable,
1535              // make sdcard visible.
1536              if (vol.disk.isAdoptable() || (vol.disk.isSd() && !vol.disk.label.equals("Virtual"))) {
1537                  vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE_FOR_WRITE;
1538              }
1539  
1540              vol.mountUserId = mCurrentUserId;
1541              mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget();  ------->  执行mount
1542  
1543          }....
740                  case H_VOLUME_MOUNT: {
741                      final VolumeInfo vol = (VolumeInfo) msg.obj;
742                      if (isMountDisallowed(vol)) {
743                          Slog.i(TAG, "Ignoring mount " + vol.getId() + " due to policy");
744                          break;
745                      }
746  
747                      mount(vol);
748                      brea

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

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

相关文章

FME学习之旅---day21

我们付出一些成本&#xff0c;时间的或者其他&#xff0c;最终总能收获一些什么。 教程&#xff1a;AutoCAD 变换 相关的文章 为您的 DWG 赋予一些样式&#xff1a;使用 DWGStyler、模板文件、块等 FME数据检查器在显示行的方式上受到限制。它只能显示线条颜色&#xff0c;而…

Leetcode 374. 猜数字大小

猜数字游戏的规则如下&#xff1a; 每轮游戏&#xff0c;我都会从 1 到 n 随机选择一个数字。 请你猜选出的是哪个数字。 如果你猜错了&#xff0c;我会告诉你&#xff0c;你猜测的数字比我选出的数字是大了还是小了。 你可以通过调用一个预先定义好的接口 int guess(int num)…

电商行业网络安全不可小视,如何保障网商平台的稳定

随着互联网的全面普及&#xff0c;基于互联网的电子商务也应运而生&#xff0c;并在近年来获得了巨大的发展&#xff0c;成为一种全新的商务模式&#xff0c;被许多经济专家认为是新的经济增长点。 作为一种全新的商务模式&#xff0c;它有很大的发展前途&#xff0c;同时&…

为什么pdf拆分出几页之后大小几乎没有变化

PDF 文件的大小在拆分出几页之后几乎没有变化可能有几个原因&#xff1a; 图像压缩: 如果 PDF 文件中包含图像&#xff0c;而这些图像已经被压缩过&#xff0c;拆分后的页面依然会保留这些压缩设置&#xff0c;因此文件大小可能不会显著变化。 文本和矢量图形: PDF 文件中的文…

基于Java+SpringBoot+vue3+uniapp口红销售/商城管理系统设计与实现

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

java错误记录

文章目录 javaslf4j中log不存在 maven编译出现Non-resolvable import POM: Failure to find类找不到jdk版本不对 java slf4j中log不存在 解决方法&#xff1a;再idea中安装lombok插件。 离线下载地址 https://github.com/mplushnikov/lombok-intellij-plugin/releases&#x…

【二分查找】Leetcode 点名

题目解析 LCR 173. 点名 算法讲解 1. 哈希表 class Solution { public:int takeAttendance(vector<int>& nums) {map<int, int> Hash;for(auto n : nums) Hash[n];for(int i 0; i < nums[nums.size() - 1]; i){if(Hash[i] 0)return i;}return nums.si…

实验模拟gfs 五大逻辑卷

目录 一 实验环境 二 4台服务端准备工作 1&#xff0c;66,77,88,99 四台机器加4块磁盘 2&#xff0c; scan 刷新磁盘供电接口 并查看 3&#xff0c;改主机名&#xff0c;方便后续操作 4&#xff0c;为加快访问速度 写hosts文件 做映射&#xff08;55客户机也写&…

Google Cookie意见征求底部弹窗

关于欧盟 Cookie 通知 根据2024年欧盟的《通用数据保护条例》以及其他相关法规&#xff0c;要求google cookie的使用必须征求用户的同意&#xff0c;才能进行收集用户数据信息&#xff0c;因此跨境独立站&#xff0c;如果做欧洲市场&#xff0c;就必须弹出cookie收集数据弹窗&a…

【MATLAB源码-第183期】基于matlab的图像处理GUI很全面包括滤波,灰度,边缘提取,RGB亮度调节,二值化等。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1. RGB颜色亮度调整 1.1 RGB颜色模型 RGB颜色模型是一种加色模型&#xff0c;使用红色&#xff08;R&#xff09;、绿色&#xff08;G&#xff09;、蓝色&#xff08;B&#xff09;三种颜色的不同组合来表示各种颜色。每种…

svn 使用记录

还原某个文件到指定版本 svn export -r 10520 resanaly.lua --force 设置忽略指定后缀文件&#xff0c; 例如忽略 .lc 后缀的文件, -R 是递归文件夹&#xff0c;path 为指定的起始目录 svn propset svn:ignore -R “*.lc” path svn propget svn:ignore -R 查看忽略设置 设置后…

第9章 文件和内容管理

思维导图 9.1 引言 文件和内容管理是指针对存储在关系型数据库之外的数据和信息的采集、存储、访问和使用过程的管理。它的重点在于保持文件和其他非结构化或半结构化信息的完整性&#xff0c;并使这些信息能够被访问。文件和非结构化内容也应是安全且高质量的。 确保文件和内容…

题目:学习使用按位取反~。

题目&#xff1a;学习使用按位取反~。  There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence. The blog content is all parallel goods. Those who are worried about being cheated should leav…

Paper Reading

使用diffusion mode生成synthetic images&#xff0c;用于enhance traning data: 1. FreeMask: Synthetic Images with Dense Annotations Make Stronger Segmentation Models (NurIPS 2024) Challenges: Generating in-domain imagesGenerating high-quality imagesGenera…

【零基础学数据结构】顺序表

目录 1.了解数据结构 什么是数据结构&#xff1f; 为什么要进行数据管理&#xff1f; 2.顺序表 顺序表概要解析&#xff1a; ​编辑顺序表的分类&#xff1a; 差别和使用优先度&#xff1a; 1.创建顺序表 1.1顺序表分为静态顺序表和动态顺序表 1.2顺序表的初始化…

Ps 滤镜:查找边缘

Ps菜单&#xff1a;滤镜/风格化/查找边缘 Filter/Stylize/Find Edges 查找边缘 Find Edges滤镜能够突出图像中的边缘&#xff0c;同时保留原图的颜色信息。 “查找边缘”滤镜通过分析图像的色彩和亮度变化来识别边缘。 这种处理方式使得图像的主要轮廓以一种艺术化的线条形式被…

本地部署google大模型并编写程序调用流式输出

目录 ollamagemma客户端调用 ollama 本地安装ollama gemma 下载并部署模型 本机资源有限&#xff0c;可以下个2b的相对较小的模型 执行命令 ollama run gemma:2b客户端调用 import requests import jsondata {"model": "gemma:2b","messages&quo…

虚拟机网络配置

1. 为什么要配置&#xff1f; 当我们创建好一个虚拟机并在网络方面未作更改由虚拟机自动生成ip地址时&#xff0c;虚拟机的ip地址是处于动态变化的&#xff0c;每次开启都会再随机生成一个新的ip&#xff1b;这不利于我们通过其他设备远程连接该虚拟机&#xff0c;这时候需要我…

C++(13): 智能指针shared_ptr

1. 概述 shared_ptr智能指针&#xff0c;本质是“离开作用域会自动调整(减小)引用计数&#xff0c;如果引用计数为0&#xff0c;则会调用析构函数”。这样一来&#xff0c;就进化成类似于int、float等的一种会被自动释放的类型。 2. 初始化智能指针 初始化一个智能指针的方式比…

1.Spring的核心思想 —— IOC和DI

1. Spring是什么&#xff1f; 简单的说&#xff0c;Spring其实指的是Spring Framework&#xff08;Spring框架&#xff09;&#xff0c;是一个开源框架。 如果要用一句话概括&#xff1a;它是包含众多工具方法的IOC&#xff08;Inverse of Control控制反转&#xff09;容器。…