android存储1--初始化.清理环境

android版本:android-11.0.0_r21
http://aospxref.com/android-11.0.0_r21/

android存储初始化工作分为3个阶段:

1)清理环境。因为android支持多用户,解锁后登录的可能是另一个用户,需要把之前用户执行的一些信息清理干净。

2)启动存储服务(mount、vold、storaged这些service)。

3)挂载emulated存储(存储涉及的东西很多,这系列文章只分析emulated存储)。

这篇文章分析第1阶段“清理环境”。

一、start primary user

开机后kernel启动第一个用户态进程init,init进程fork出zygote进程。zygote又fork出system server进程。下面是zygote创建system server进程的代码。
http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#920

832      public static void main(String argv[]) {
833          ZygoteServer zygoteServer = null;
834  
             ……
916  
917              zygoteServer = new ZygoteServer(isPrimaryZygote);
918  
919              if (startSystemServer) {
920                  Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
921  
922                  // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
923                  // child (system_server) process.
924                  if (r != null) {
925                      r.run();
926                      return;
927                  }
928              }

920行,fork system server进程,925行运行子进程system server。system server入口代码如下:

http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/java/com/android/server/SystemServer.java#main

410      /**
411       * The main entry point from zygote.
412       */
413      public static void main(String[] args) {
414          new SystemServer().run();
415      }

SystemServer().run()会启动各种service:
http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/java/com/android/server/SystemServer.java#run


436      private void run() {
             ……
592  
593          // Start services.
594          try {
595              t.traceBegin("StartServices");
596              startBootstrapServices(t);
597              startCoreServices(t);
598              startOtherServices(t);
599          } catch (Throwable ex) {
600              Slog.e("System", "******************************************");
601              Slog.e("System", "************ Failure starting system services", ex);
602              throw ex;
603          } finally {
604              t.traceEnd(); // StartServices
605          }

596行启动的service如下:
http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/java/com/android/server/SystemServer.java#startBootstrapServices


710      private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
             ……
760  
761          // Activity manager runs the show.
762          t.traceBegin("StartActivityManager");
763          // TODO: Might need to move after migration to WM.
764          ActivityTaskManagerService atm = mSystemServiceManager.startService(
765                  ActivityTaskManagerService.Lifecycle.class).getService();
766          mActivityManagerService = ActivityManagerService.Lifecycle.startService(
767                  mSystemServiceManager, atm);
768          mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
769          mActivityManagerService.setInstaller(installer);

在启动 ActivityManagerService 时,SystemServer 会等待 ActivityManagerService 初始化完成并绑定到系统服务中心(System Service Manager)。然后,SystemServer 会调用 ActivityManagerService 的 systemReady() 方法:
http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java#systemReady

9515      public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
               ……
9640          // headless-user start logic to UserManager-land
9641          final boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM;
9642  
9643          if (bootingSystemUser) {
9644              mSystemServiceManager.startUser(t, currentUserId);
9645          }

9644行执行SystemServiceManager::startUser
http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java#startUser

254      /**
255       * Starts the given user.
256       */
257      public void startUser(final @NonNull TimingsTraceAndSlog t, final @UserIdInt int userHandle) {
258          onUser(t, START, userHandle);
259      }

上面代码就是start一个用户,对于power键开机流程来说,就是start primary user。

258行,会发送START消息,系统中的多个模块会接收并处理该消息,包括Zygote、PackageManagerService和ActivityManagerService本身等。其中,Zygote进程会根据用户ID创建新的应用程序进程;PackageManagerService会根据用户信息和应用程序信息初始化和加载应用程序;而ActivityManagerService则会负责协调和管理用户进程的生命周期。

当primary user和各种service启动后,SystemServiceManager发送H_BOOT_COMPLETED消息,这个消息的处理见第二部分。

二、处理H_BOOT_COMPLETED消息

接着,StorageManagerService收到开机广播消息H_BOOT_COMPLETED,按时间顺序完成以下4件事情:

  • init用户目录的加密状态
  • reset external storage service
  • reset vold service
  • 添加用户

代码整体逻辑如下:

1,init用户目录的加密状态

代码路径:StorageManagerServiceHandler::handleMessage --> handleBootCompleted --> initIfBootedAndConnected

分两种情况:
1)用户目录采用硬件加解密(native encryption),此阶段什么事也不做,函数直接返回
2)用户目录采用软件加解密(enmulated encryption),执行lock  encryption key(用户目录已加密的情况)或者unlock encryption key(用户目录未加密的情况)

从安全性、性能角度看,硬件加解密更好。

现在的手机基本都是硬件加解密方式,通过adb shell getprop ro.crypto.state可查询手机用的是哪种加解密方式。

adb shell getprop ro.crypto.state

返回字符串

加解密方式

"encrypted"

native encryption(硬件加解密)

"unencrypted" 或 "unsupported"

enmulated encryption(软件加解密)

"default"

手机还没有加密过

handleMessage处理H_BOOT_COMPLETED:
StorageManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/StorageManagerService.java

707      class StorageManagerServiceHandler extends Handler {
713          public void handleMessage(Message msg) {
714              switch (msg.what) {
719                  case H_BOOT_COMPLETED: {
720                      handleBootCompleted();
721                      break;
722                  }

 收到H_BOOT_COMPLETED广播消息后, 执行719行分支,handleBootCompleted函数如下:

2076      private void handleBootCompleted() {
2077          initIfBootedAndConnected();
2078          resetIfBootedAndConnected();
2079      }

initIfBootedAndConnected函数处理enmulated encryption场景,如果用户目录是加密状态,那么lock encryption key,否则就unlock encryption key。
StorageManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/StorageManagerService.java

1061      private void initIfBootedAndConnected() {

1064          if (mBootCompleted && mDaemonConnected
1065                  && !StorageManager.isFileEncryptedNativeOnly()) {

1069              final boolean initLocked = StorageManager.isFileEncryptedEmulatedOnly();

1071              final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
1072              for (UserInfo user : users) {
1073                  try {
1074                      if (initLocked) {
1075                          mVold.lockUserKey(user.id);
1076                      } else {
1077                          mVold.unlockUserKey(user.id, user.serialNumber, encodeBytes(null),
            
        ……

1065行StorageManager.isFileEncryptedNativeOnly(),判断设备是不是硬件加解密。如果是硬件加解密,则什么也不做,退出函数。设备用软件加解密时,进入1066行分支处理,根据StorageManager.isFileEncryptedEmulatedOnly()获取到的用户目录加密状态,执行lock 或者unlock encryption key操作。

2,reset external service

代码路径:StorageManagerServiceHandler::handleMessage --> handleBootCompleted --> resetIfBootedAndConnected --> StorageSessionController::onReset

external storage service是一个由名为com.android.providers.media.module的package提供的服务,用于管理外部存储设备(sd卡、u盘等),服务名称为com.android.providers.media.fuse.ExternalStorageServiceImpl。ExternalStorageServiceImpl用于控制mediaprovider访问外部存储文件,源码见/packages/providers/MediaProvider/src/com/android/providers/media/fuse/ExternalStorageServiceImpl.java。

可通过adb shell dumpsys activity services com.android.providers.media.module/com.android.providers.media.fuse.ExternalStorageServiceImpl命令查看service详细信息。

reset external service主要完成2件事:
1)umount外部存储
2)关闭连接至external storage service的所有connection

一般情况下,外部存储还没有挂载成功,所以不需要卸载任何存储,也不需要关闭任何connection。不过下面还是过一下代码:

StorageManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/StorageManagerService.java

1087      private void resetIfBootedAndConnected() {

1090          if (mBootCompleted && mDaemonConnected) {
1091              final UserManager userManager = mContext.getSystemService(UserManager.class);
1092              final List<UserInfo> users = userManager.getUsers();
1093  
1094              if (mIsFuseEnabled) {
1095                  mStorageSessionController.onReset(mVold, () -> {
1096                      mHandler.removeCallbacksAndMessages(null);
1097                  });
1098              } else {
1099                  killMediaProvider(users);
1100              }
            
            ……

1095行umount外部存储并关闭connection,mStorageSessionController.onReset函数如下:
StorageSessionController.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/storage/StorageSessionController.java

240      public void onReset(IVold vold, Runnable resetHandlerRunnable) {
245          SparseArray<StorageUserConnection> connections = new SparseArray();
246          synchronized (mLock) {
247              mIsResetting = true;
248              Slog.i(TAG, "Started resetting external storage service...");
249              for (int i = 0; i < mConnections.size(); i++) {
250                  connections.put(mConnections.keyAt(i), mConnections.valueAt(i));
251              }
252          }
253  
254          for (int i = 0; i < connections.size(); i++) {
255              StorageUserConnection connection = connections.valueAt(i);
256              for (String sessionId : connection.getAllSessionIds()) {
259                 vold.unmount(sessionId);
                     ……
268                  connection.removeSessionAndWait(sessionId);
279                  connection.close();

259行vold.unmount(即VoldNativeService::mount函数,参考StorageManagerService.java中的mVold.mount_geshifei的博客-CSDN博客)卸载外部存储设备,不过,在开机流程不会执行到这个函数。

279行关闭connection。

3,reset vold service

代码路径:StorageManagerServiceHandler::handleMessage --> handleBootCompleted --> resetIfBootedAndConnected --> mVold.reset

这个阶段主要完成3件事:

  • 销毁volume
  • 重置disk对象
  • 清空用户

StorageManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/StorageManagerService.java
 

1087      private void resetIfBootedAndConnected() {

                     /* reset external service,
                      * umount外部存储并关闭external storage service所有connection
                      */
1095                  mStorageSessionController.onReset(mVold, () -> {
1096                      mHandler.removeCallbacksAndMessages(null);
1097                  });         
1101  
1115                  // TODO(b/135341433): Remove paranoid logging when FUSE is stable
1116                  Slog.i(TAG, "Resetting vold...");
1117                  mVold.reset();
1118                  Slog.i(TAG, "Reset vold");
1112              }


1117行,mVold.reset()执行VoldNativeService::reset。
VoldNativeService.cpp - OpenGrok cross reference for /system/vold/VoldNativeService.cpp
 

164  binder::Status VoldNativeService::reset() {
165      ENFORCE_SYSTEM_OR_ROOT;
166      ACQUIRE_LOCK;
167  
168      return translate(VolumeManager::Instance()->reset());
169  }

168行,执行VolumeManager::reset函数。
VolumeManager.cpp - OpenGrok cross reference for /system/vold/VolumeManager.cpp

912  int VolumeManager::reset() {
913      // Tear down all existing disks/volumes and start from a blank slate so
914      // newly connected framework hears all events.
915      for (const auto& vol : mInternalEmulatedVolumes) {
916          vol->destroy();
917      }
918      mInternalEmulatedVolumes.clear();
919  
920      for (const auto& disk : mDisks) {
921          disk->destroy();
922          disk->create();
923      }
924      updateVirtualDisk();
925      mAddedUsers.clear();
926      mStartedUsers.clear();
927      return 0;
928  }

916行销毁volume(vol->destroy --> VolumeBase::destroy --> doDestroy)。

920行如果创建了disk对象(此时一般没有创建任何disk),就重置disk(先disk->destroy --> Disk:destory销毁disk对象,再disk->create --> Disk::create创建disk对象)。

925行,清空mAddedUsers中保存的所有用户ID,即删除所有已添加的用户。

926行,清空mStartedUsers中保存的所有用户ID,即删除所有已启动的用户。

4,在mAddedUsers中记录用户信息

代码路径:StorageManagerServiceHandler::handleMessage --> handleBootCompleted --> resetIfBootedAndConnected --> mVold.onUserAdded

mAddedUsers 是 VolumeManager 用于跟踪已添加的用户信息的数据结构,当系统启动时,它会将记录在其中的用户信息发送给 vold,以确保 vold 了解系统中所有用户的存在。这样可以确保 vold 能够正确地管理卷和磁盘。android支持多用户,用户外部存储挂载点为/storage/emulated/用户id,如果某个用户在连接设备后注销了系统,VolumeManager将记录在mAddedUsers中该用户信息发送给vold,vold就可以正确地卸个载设备上的卷或文件系统。

StorageManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/StorageManagerService.java

1087      private void resetIfBootedAndConnected() {

                      /* reset external service,
                       * umount外部存储并关闭external storage service所有connection
                       */
1095                  mStorageSessionController.onReset(mVold, () -> {
1096                      mHandler.removeCallbacksAndMessages(null);
1097                  });

                      /* reset vold service,
                       * 销毁volume,重置disk,清空用户
1117                  mVold.reset();

                      /* 在mAddedUsers中 记录用户信息 */
1121                  for (UserInfo user : users) {
1122                      mVold.onUserAdded(user.id, user.serialNumber);
1123                  }
1124                  for (int userId : systemUnlockedUsers) {
1125                      mVold.onUserStarted(userId);
1126                      mStoraged.onUserStarted(userId);
1127                  }
1128                  if (mIsAutomotive) {
1129                      restoreAllUnlockedUsers(userManager, users, systemUnlockedUsers);
1130                  }
1131                  mVold.onSecureKeyguardStateChanged(mSecureKeyguardShowing);
1132                  mStorageManagerInternal.onReset(mVold);
1133             

1122行mVold.onUserAdded,调用VoldNativeService::onUserAdded,代码VoldNativeService.cpp - OpenGrok cross reference for /system/vold/VoldNativeService.cpp

185  binder::Status VoldNativeService::onUserAdded(int32_t userId, int32_t userSerial) {
186      ENFORCE_SYSTEM_OR_ROOT;
187      ACQUIRE_LOCK;
188  
189      return translate(VolumeManager::Instance()->onUserAdded(userId, userSerial));
190  }

189行执行的是VolumeManager::onUserAdded,代码VolumeManager.cpp - OpenGrok cross reference for /system/vold/VolumeManager.cpp

455  int VolumeManager::onUserAdded(userid_t userId, int userSerialNumber) {
456      LOG(INFO) << "onUserAdded: " << userId;
457  
458      mAddedUsers[userId] = userSerialNumber;
459      return 0;
460  }

458行将user信息添加到mAddedUsers中。

回到resetIfBootedAndConnected函数,看一下1124行分支:

1087      private void resetIfBootedAndConnected() {

                      /* reset external service,
                       * umount外部存储并关闭external storage service所有connection
                       */
1095                  mStorageSessionController.onReset(mVold, () -> {
1096                      mHandler.removeCallbacksAndMessages(null);
1097                  });

                      /* reset vold service,
                       * 销毁volume,重置disk,清空用户
1117                  mVold.reset();

                      /* 在mAddedUsers中 记录用户信息 */
1121                  for (UserInfo user : users) {
1122                      mVold.onUserAdded(user.id, user.serialNumber);
1123                  }
1124                  for (int userId : systemUnlockedUsers) {
1125                      mVold.onUserStarted(userId);
1126                      mStoraged.onUserStarted(userId);
1127                  }
1128                  if (mIsAutomotive) {
1129                      restoreAllUnlockedUsers(userManager, users, systemUnlockedUsers);
1130                  }
1131                  mVold.onSecureKeyguardStateChanged(mSecureKeyguardShowing);
1132                  mStorageManagerInternal.onReset(mVold);
1133             

systemUnlockedUsers"数组包含已经解锁的用户ID。当设备启动时,通常只有一个用户(User 0)被解锁,而其他用户(如果有的话)会在后续解锁后被添加到数组中。所以,对于开机流程,mVold.onUserStarted(userId)不会执行。
在某些情况下,例如设备支持多用户功能并且用户在设置中添加了一个或多个额外的用户,或者设备已经解锁并且用户在后续的操作中解锁了其他用户,则systemUnlockedUsers数组中就会包含多个用户ID。

下一篇文章分析存储相关服务(mount、vold、storaged)的启动流程。

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值