StorageManagerService.java中的mVold.mount

news/2024/5/17 16:14:29/文章来源:https://blog.csdn.net/geshifei/article/details/130005917

android源码:android-11.0.0_r21(网址:Search (aospxref.com))

一、问题

2243行mVold.mount执行的是哪个mount函数?

2239      private void mount(VolumeInfo vol) {
2240          try {
2241              // TODO(b/135341433): Remove paranoid logging when FUSE is stable
2242              Slog.i(TAG, "Mounting volume " + vol);
2243              mVold.mount(vol.id, vol.mountFlags, vol.mountUserId, new IVoldMountCallback.Stub() {
2244                  @Override
2245                  public boolean onVolumeChecking(FileDescriptor fd, String path,
2246                          String internalPath) {
2247                      vol.path = path;
2248                      vol.internalPath = internalPath;
2249                      ParcelFileDescriptor pfd = new ParcelFileDescriptor(fd);
2250                      try {
2251                          mStorageSessionController.onVolumeMount(pfd, vol);
2252                          return true;
2253                      } catch (ExternalStorageServiceException e) {
2254                          Slog.e(TAG, "Failed to mount volume " + vol, e);
2255  
2256                          int nextResetSeconds = FAILED_MOUNT_RESET_TIMEOUT_SECONDS;
2257                          Slog.i(TAG, "Scheduling reset in " + nextResetSeconds + "s");
2258                          mHandler.removeMessages(H_RESET);
2259                          mHandler.sendMessageDelayed(mHandler.obtainMessage(H_RESET),
2260                                  TimeUnit.SECONDS.toMillis(nextResetSeconds));
2261                          return false;
2262                      } finally {
2263                          try {
2264                              pfd.close();
2265                          } catch (Exception e) {
2266                              Slog.e(TAG, "Failed to close FUSE device fd", e);
2267                          }
2268                      }
2269                  }
2270              });
2271              Slog.i(TAG, "Mounted volume " + vol);
2272          } catch (Exception e) {
2273              Slog.wtf(TAG, e);
2274          }
2275      }

二、分析过程

1,找到mVold变量

http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/core/java/com/android/server/StorageManagerService.java#mVold

569      private volatile IVold mVold;

2,找到Ivold类型

http://aospxref.com/android-11.0.0_r21/xref/system/vold/binder/android/os/IVold.aidl

 这是个aidl文件(Android Interface Definition Language,即Android接口定义语言),说明该文件将会定义一些函数,用于多进程间远程调用。

aidl文件经过编译后,会生成.java文件,我们可以在android编译的out目录中找到IVold.java(如果没有这个文件,也可以找到IVold.class,class反编译后得到IVold.java),IVold.java文件部分内容如下:

public interface IVold
extends IInterface {……static final int TRANSACTION_addSandboxIds = 11;static final int TRANSACTION_onSecureKeyguardStateChanged = 12;static final int TRANSACTION_partition = 13;static final int TRANSACTION_forgetPartition = 14;static final int TRANSACTION_mount = 15;public void onSecureKeyguardStateChanged(boolean var1) throws RemoteException;public void partition(String var1, int var2, int var3) throws RemoteException;public void forgetPartition(String var1, String var2) throws RemoteException;public void mount(String var1, int var2, int var3, IVoldMountCallback var4) throws RemoteException;……public static abstract class Stubextends Binderimplements IVold {public static IVold asInterface(IBinder obj) {if (obj == null) {return null;}IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (iin != null && iin instanceof IVold) {return (IVold)iin;}return new Proxy(obj);}……
}

从上面代码片段可以得到如下信息:
1)IVold是个接口,继承自IInterface 
2)IVold.java中定义了很多函数,与IVold.aidl中的函数对应,并且每个函数都有唯一的编号
3)IVold接口中有个Stub内部类,Stub.asInterface根据进程间通信的binder对象,找到对应的interface。举例来说,A进程实现了aidl中mount函数,B进程与A进程通过Binder-x通信,那么在B进程执行:

private volatile IVold mVold;
//根据binder找到对应的aidl interface
mVold = IVold.Stub.asInterface(Binder-x)

B进程中就可以通过mVold.mount来执行A的mount函数了。

3,IVold赋值

http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/core/java/com/android/server/StorageManagerService.java#1928

1928	private void connectVold() {
1929          IBinder binder = ServiceManager.getService("vold");
1930          if (binder != null) {
1931              try {
1932                  binder.linkToDeath(new DeathRecipient() {
1933                      @Override
1934                      public void binderDied() {
1935                          Slog.w(TAG, "vold died; reconnecting");
1936                          mVold = null;
1937                          connectVold();
1938                      }
1939                  }, 0);
1940              } catch (RemoteException e) {
1941                  binder = null;
1942              }
1943          }
1944  
1945          if (binder != null) {
1946              mVold = IVold.Stub.asInterface(binder);
1947              try {
1948                  mVold.setListener(mListener);
1949              } catch (RemoteException e) {
1950                  mVold = null;
1951                  Slog.w(TAG, "vold listener rejected; trying again", e);
1952              }
1953          } else {
1954              Slog.w(TAG, "vold not found; trying again");
1955          }
1956  
1957          if (mVold == null) {
1958              BackgroundThread.getHandler().postDelayed(() -> {
1959                  connectVold();
1960              }, DateUtils.SECOND_IN_MILLIS);
1961          } else {
1962              onDaemonConnected();
1963          }
1964      }

1929行获取vold service,找到对应的binder,1946行根据binder找到对应的aidl接口mVold,找到mVold后,就可以调用其他地方实现的具体的方法了,比如mVold.mount。总结就是,找到了vold service就能找到具体的函数实现了,所以现在的问题是vold service在哪、是什么?

4,vold service是什么

如果没看过vold的启动流程,在茫茫大海的android代码里搜vold service还是比较困难的,现在直接给答案,后面再简单描述vold的启动流程。

http://aospxref.com/android-11.0.0_r21/xref/system/vold/VoldNativeService.h#31

 可以看到VoldNativeService.h文件中定义了VoldNativeService类。这个类有很多函数定义,我们重点看getServiceName方法。VoldNativeService.getServiceName返回的就是“vold”,所以VoldNativeService类中的函数就是aidl接口中各个函数的具体实现。比如mVold.mount的具体实现就是VoldNativeService::mount(见VoldNativeService.cpp)。

三、vold进程的启动及vold service的注册

vold的源头在 /etc/init/hw/init.rc,系统开机后会执行这个文件,启动vold进程。init.rc对应的源码路径为: http://aospxref.com/android-11.0.0_r21/xref/system/vold/vold.rc

文件内容:

1 service vold /system/bin/vold \
2         --blkid_context=u:r:blkid:s0 --blkid_untrusted_context=u:r:blkid_untrusted:s0 \
3         --fsck_context=u:r:fsck:s0 --fsck_untrusted_context=u:r:fsck_untrusted:s0
4     class core
5     ioprio be 2
6     writepid /dev/cpuset/foreground/tasks
7     shutdown critical
8     group root reserved_disk
vold相关的源码在system/vold目录下,/system/bin/vold是从http://aospxref.com/android-11.0.0_r21/xref/system/vold/main.cpp的main函数开始执行的。
主要关注vold进程向ServiceManager注册service的过程。
54  int main(int argc, char** argv) {……113      ATRACE_BEGIN("VoldNativeService::start");
114      if (android::vold::VoldNativeService::start() != android::OK) {
115          LOG(ERROR) << "Unable to start VoldNativeService";
116          exit(1);
117      }……

114行VoldNativeService::start()启动VoldNativeService,并将其注册到ServiceManager中。


http://aospxref.com/android-11.0.0_r21/xref/system/vold/VoldNativeService.cpp#120

120  status_t VoldNativeService::start() {
121      IPCThreadState::self()->disableBackgroundScheduling(true);
122      status_t ret = BinderService<VoldNativeService>::publish();
123      if (ret != android::OK) {
124          return ret;
125      }
126      sp<ProcessState> ps(ProcessState::self());
127      ps->startThreadPool();
128      ps->giveThreadPoolName();
129      return android::OK;
130  }

122行BinderService<VoldNativeService>::publish()执行具体的注册操作。

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/include/binder/BinderService.h#34

33  template<typename SERVICE>
34  class BinderService
35  {
36  public:
37      static status_t publish(bool allowIsolated = false,
38                              int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
39          sp<IServiceManager> sm(defaultServiceManager());
40          return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
41                                dumpFlags);

根据33行typename SERVICE及 VoldNativeService::start()中122行BinderService<VoldNativeService>::publish(),可以知道SERVICE就是VoldNativeService,所以SERVICE::getServiceName()就是VoldNativeService::getServiceName()。通过第二节第4段【vold service是什么】可知getServiceName()将返回字符串“vold”。总结就是,VoldNativeService以“vold”名称注册到ServiceManager中,VoldNativeService类中实现了很多函数,这些函数就是跨进程调用的具体函数,比如mVold.mount。

四、mVold.mount是什么

在第二节第3段【IVold赋值】,1929行ServiceManager.getService("vold")获取vold service关联的binder,也就是VoldNativeService了,然后1946行mVold = IVold.Stub.asInterface(binder)获取binder对象关联的aidl接口,也就是VoldNativeService中定义的一系列接口函数了,比如mVold.mount在http://aospxref.com/android-11.0.0_r21/xref/system/vold/VoldNativeService.cpp#mount

262  binder::Status VoldNativeService::mount(
263          const std::string& volId, int32_t mountFlags, int32_t mountUserId,
264          const android::sp<android::os::IVoldMountCallback>& callback) {
265      ENFORCE_SYSTEM_OR_ROOT;
266      CHECK_ARGUMENT_ID(volId);
267      ACQUIRE_LOCK;
268  
269      auto vol = VolumeManager::Instance()->findVolume(volId);
270      if (vol == nullptr) {
271          return error("Failed to find volume " + volId);
272      }
273  
274      vol->setMountFlags(mountFlags);
275      vol->setMountUserId(mountUserId);
276  
277      vol->setMountCallback(callback);
278      int res = vol->mount();
279      vol->setMountCallback(nullptr);
280  
281      if (res != OK) {
282          return translate(res);
283      }
284  
285      if ((mountFlags & MOUNT_FLAG_PRIMARY) != 0) {
286          res = VolumeManager::Instance()->setPrimary(vol);
287          if (res != OK) {
288              return translate(res);
289          }
290      }
291      return translate(OK);
292  }

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

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

相关文章

【LeetCode】-- 108. 将有序数组转换为二叉搜索树

1. 题目 108. 将有序数组转换为二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 给你一个整数数组 nums &#xff0c;其中元素已经按升序排列&#xff0c;请你将其转换为一棵高度平衡二叉搜索树。高度平衡二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 …

mysql在CentOS7.x环境安装

查看当前环境的yum源 ls -l /etc/yum.repos.d/ 可以看到当前环境是没有下载mysql对应的yum源的, 所以需要去官网下载对应的yum源. 找mysql的yum源并安装 http://repo.mysql.com/ 在选择对应yum源之前, 需要看一下自己系统的版本: 进入官网后, 鼠标右击进入查看页面源代码, 因为…

Leetcode.463 岛屿的周长

题目链接 Leetcode.463 岛屿的周长 easy 题目描述 给定一个 row x col的二维网格地图 grid&#xff0c;其中&#xff1a;grid[i][j] 1表示陆地&#xff0c; grid[i][j] 0表示水域。 网格中的格子 水平和垂直 方向相连&#xff08;对角线方向不相连&#xff09;。整个网格被…

如何从功能测试转型到自动化测试:我三年的学习经历

前言 在软件测试的领域里&#xff0c;自动化测试已经成为了不可或缺的一部分。 与传统的手工测试相比&#xff0c;自动化测试具有更高的效率和精确度&#xff0c;能够有效地减少测试时间和成本&#xff0c;同时提高测试质量。作为一个从事软件测试的人员&#xff0c;如果你想…

Oracle JDK 和 OpenJDK 有什么区别?

可能在看这个问题之前很多人和我一样并没有接触和使用过 OpenJDK 。那么 Oracle JDK 和 OpenJDK 之间是否存在重大差异&#xff1f;下面我通过收集到的一些资料&#xff0c;为你解答这个被很多人忽视的问题。 首先&#xff0c;2006 年 SUN 公司将 Java 开源&#xff0c;也就有…

智慧方政务云顶层设计与建设方案(ppt)

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除 对一网统管总体架构的理解物联网生态中的业务定位物联网产品与解决方案概览智联物联网管理平台总体方案智联物联网管理平台总体架构智联联连接平台(HLINK)应用架构智慧社区基于…

Linux--进程信号

前言 无人问津也好&#xff0c;技不如人也罢&#xff0c;你都要试着安静下来&#xff0c;去做自己该做的事情&#xff0c;而不是让烦恼和焦虑毁掉你不就不多的热情和定力。心可以碎&#xff0c;手不能停&#xff0c;该干什么干什么&#xff0c;在崩溃中继续努力前行&#xff0c…

export、export default 和import

&#x1f468; 作者简介&#xff1a;大家好&#xff0c;我是Taro&#xff0c;前端领域创作者 ✒️ 个人主页&#xff1a;唐璜Taro &#x1f680; 支持我&#xff1a;点赞&#x1f44d;&#x1f4dd; 评论 ⭐️收藏 文章目录前言一、export default 和 import &#xff1f;1. e…

【教学类-29-03】20230409《门牌号-黏贴版(5层*5间)灰底下划线》-(中班《我爱我家》偏数学)

作品样式&#xff1a; 背景需求 在门牌号黏贴版教学实践中&#xff0c;发现90%的幼儿都不会做 1、空格没有平均分布&#xff1a; 从5*630的门牌号中&#xff0c;随机抽取5个空格&#xff0c;有80%的概率出现“一行2个空、3行1个空”的情况。但幼儿第一次做&#xff0c;楼层都…

软考总结条款(2023-05-28系统分析师)

Raid0、 Raid1、 Raid5、 Raid10的原理、特点、性能区别 - 2023-04-07 指令集 - 2023-04-07 RISC全称Reduced Instruction Set Compute&#xff0c;精简指令集计算机。 CISC全称Complex Instruction Set Computers&#xff0c;复杂指令集计算机。 CISC既有简单指令也有复杂指…

【协议项目之 I2C】(一) 基本时序与实现

一、基本介绍 I2C协议&#xff08;集成电路总线&#xff09;使用两根线SDA和SCL实现数据传输&#xff0c;其连接如下图所示&#xff0c;总线上通过上拉电阻可以挂载各种低速外设,例如EEPROM 24C02,传感器等。   使用I2C&#xff0c;可以将多个从机&#xff08;Slave&#xf…

upload-labs pass6-pass10

1.pass-6黑名单 空格绕过 直接上传肯定不可以 这个地方配置文件虽然只过滤了.htaccess&#xff0c;.user.ini也是不可用的&#xff0c;因为这里进行了重命名&#xff0c;通过代码审计可以发现空格没有过滤&#xff0c;这是利用windows的一个特性&#xff0c;后缀后面有空格和…

EasyCVR在公共资源交易中心监控视频汇聚项目中的场景应用方案

一、背景分析 2019年5月&#xff0c;国务院办公厅印发了《国务院办公厅转发国家发展改革委关于深化公共资源交易平台整合共享实施意见的通知》&#xff08;国办函〔2019〕41号&#xff09;&#xff0c;明确深化公共资源平台整合共享&#xff0c;要求地方各级人民政府制度细化落…

1.8 函数的连续与间断

我的理解&#xff1a; 注意&#xff1a; 在处理连续性问题时&#xff0c;需要注意以下几点&#xff1a; 连续函数在一段区间内的取值具有稳定性和连续性&#xff0c;因此可以使用它们来刻画某个过程的规律。 如果一个函数在某个点处不连续&#xff0c;那么这个点就是一个间断…

C语言预处理命令(宏定义和条件编译)

C语言预处理命令&#xff08;宏定义和条件编译&#xff09; 前言 在编译和链接之前&#xff0c;还需要对源文件进行一些文本方面的操作&#xff0c;比如文本替换、文件包含、删除部分代码等&#xff0c;这个过程叫做预处理&#xff0c;由预处理程序完成。 较之其他编程语言&am…

图像复原论文阅读:GRL算法笔记

标题&#xff1a;Efficient and Explicit Modelling of Image Hierarchies for Image Restoration 会议&#xff1a;CVPR2023 论文地址&#xff1a;http://arxiv.org/abs/2303.00748 官方代码&#xff1a;https://github.com/ofsoundof/GRL-Image-Restoration 作者单位&#xf…

国产化复旦微电子 FMQL45T900 替代Xilinx ZYNQ ARM+FPGA 7045方案(评论区有联系方式)

FM4550国产化开发板 功能接口 - - 系统框图 - - 对应参数 - 1.主要参数 系统1&#xff1a; FPGA型号&#xff1a;FMQL45T900 PS内核&#xff1a;四核ARM Cortex-A7&#xff0c;主频800MHz PS端内存&#xff1a;1GB DDR3,数据速率1066Mbps&#xff0c;32bit PL端内存&…

vagrant无剩余磁盘空间,无法连接Mysql

vagrant无剩余磁盘空间&#xff0c;无法连接Mysql 参考博客1 参考博客2 1.报错&#xff1a;设备上没有剩余空间 C:/HashiCorp/Vagrant/embedded/gems/2.2.19/gems/net-scp-3.0.0/lib/net/scp.rb:398:in await_response_state: \x01scp: /tmp/vagrant-network-entry-eth1-1680…

工业树莓派如何保障电气安全?

一、应用背景 电气系统主要用于传输和分配电力&#xff0c;是工业生产过程中不可或缺的组成部分&#xff0c;广泛应用于工业自动化控制、机器人、电动汽车等领域。因此&#xff0c;实时监测电气系统具有重要意义。 电流是电气系统中最基本的参数之一&#xff0c;实时监测电气…

[Linux]管理文件基本操作

​⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;输出优质文章 ⭐作者主页&#xff1a;逐梦苍穹 ⭐所属专栏&#xff1a;Linux基础操作。本文主要是分享一些Linux系统常用操作&#xff0c;内容主要来源是学校作业&#xff0c;分享出来的…