diff options
| author | Ricky Wai <rickywai@google.com> | 2020-02-28 16:37:07 +0000 |
|---|---|---|
| committer | Ricky Wai <rickywai@google.com> | 2020-03-12 19:36:26 +0000 |
| commit | 486d760e6bc791db3f449c6fc4c205e86cd4f2d5 (patch) | |
| tree | 341ba0baf9e69e313bde481cd9cd0ae6beb32d0b /core/java/android | |
| parent | a8375cc9f85380254d18ae48b59e8954c0b7886e (diff) | |
Pass bind mount storage data decision from java to zygote
Before we used store dirty data in system property to record
if FUSE for a user is mounted, and zygote uses it to determine
if storage mount is needed. It introduces performance issues and
not reliable.
This CL does the following changes:
- System server determines if storage dirs mount are needed, and store
the record inside system server.
- It passes the verdict to zygote so zygote just need to follow the
input.
- When emulated storage is mounted / unmounted, it will record if
FUSE for that user is ready to use, and will be used for determining
if storage dirs mount are needed when a new process starts.
- After emulated storage is mounted, it will create an async thread
to remount all storage dirs for existing app processes. As we have a
record of pids that storage dirs are not mounted yet, we can use it
directly without scanning the whole /proc in vold.
Bug: 149548518
Test: After flag is enabled, AdoptableHostTest still pass.
Change-Id: Ic99d027d42b2b9a1c7fd03070b36c44882c6e7c5
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/ActivityManagerInternal.java | 7 | ||||
| -rw-r--r-- | core/java/android/os/Process.java | 6 | ||||
| -rw-r--r-- | core/java/android/os/ZygoteProcess.java | 14 | ||||
| -rw-r--r-- | core/java/android/os/storage/StorageManagerInternal.java | 7 |
4 files changed, 27 insertions, 7 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index ec110435d95c..489a0de0518e 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -34,6 +34,7 @@ import android.os.TransactionTooLargeException; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * Activity manager local system service interface. @@ -124,6 +125,12 @@ public abstract class ActivityManagerInternal { public abstract int getUidProcessState(int uid); /** + * Get a map of pid and package name that process of that pid Android/data and Android/obb + * directory is not mounted to lowerfs. + */ + public abstract Map<Integer, String> getProcessesWithPendingBindMounts(int userId); + + /** * @return {@code true} if system is ready, {@code false} otherwise. */ public abstract boolean isSystemReady(); diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index d7af1b9faa97..a557bd994c13 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -607,6 +607,7 @@ public class Process { * started. * @param pkgDataInfoMap Map from related package names to private data directory * volume UUID and inode number. + * @param bindMountAppStorageDirs whether zygote needs to mount Android/obb and Android/data. * @param zygoteArgs Additional arguments to supply to the zygote process. * @return An object that describes the result of the attempt to start the process. * @throws RuntimeException on fatal start failure @@ -630,12 +631,13 @@ public class Process { @Nullable long[] disabledCompatChanges, @Nullable Map<String, Pair<String, Long>> pkgDataInfoMap, + boolean bindMountAppStorageDirs, @Nullable String[] zygoteArgs) { return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges, - pkgDataInfoMap, zygoteArgs); + pkgDataInfoMap, bindMountAppStorageDirs, zygoteArgs); } /** @hide */ @@ -659,7 +661,7 @@ public class Process { runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, packageName, /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, /*isTopApp=*/ false, - disabledCompatChanges, /* pkgDataInfoMap */ null, zygoteArgs); + disabledCompatChanges, /* pkgDataInfoMap */ null, false, zygoteArgs); } /** diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index 34cec061edcd..5f3f14facd75 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -333,6 +333,7 @@ public class ZygoteProcess { * started. * @param pkgDataInfoMap Map from related package names to private data directory * volume UUID and inode number. + * @param bindMountAppStorageDirs whether zygote needs to mount Android/obb and Android/data. * * @param zygoteArgs Additional arguments to supply to the Zygote process. * @return An object that describes the result of the attempt to start the process. @@ -354,6 +355,7 @@ public class ZygoteProcess { @Nullable long[] disabledCompatChanges, @Nullable Map<String, Pair<String, Long>> pkgDataInfoMap, + boolean bindMountAppStorageDirs, @Nullable String[] zygoteArgs) { // TODO (chriswailes): Is there a better place to check this value? if (fetchUsapPoolEnabledPropWithMinInterval()) { @@ -365,7 +367,7 @@ public class ZygoteProcess { runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false, packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges, - pkgDataInfoMap, zygoteArgs); + pkgDataInfoMap, bindMountAppStorageDirs, zygoteArgs); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); @@ -606,6 +608,7 @@ public class ZygoteProcess { * @param disabledCompatChanges a list of disabled compat changes for the process being started. * @param pkgDataInfoMap Map from related package names to private data directory volume UUID * and inode number. + * @param bindMountAppStorageDirs whether zygote needs to mount Android/obb and Android/data. * @param extraArgs Additional arguments to supply to the zygote process. * @return An object that describes the result of the attempt to start the process. * @throws ZygoteStartFailedEx if process start failed for any reason @@ -628,6 +631,7 @@ public class ZygoteProcess { @Nullable long[] disabledCompatChanges, @Nullable Map<String, Pair<String, Long>> pkgDataInfoMap, + boolean bindMountAppStorageDirs, @Nullable String[] extraArgs) throws ZygoteStartFailedEx { ArrayList<String> argsForZygote = new ArrayList<>(); @@ -725,6 +729,10 @@ public class ZygoteProcess { argsForZygote.add(sb.toString()); } + if (bindMountAppStorageDirs) { + argsForZygote.add(Zygote.BIND_MOUNT_APP_STORAGE_DIRS); + } + if (disabledCompatChanges != null && disabledCompatChanges.length > 0) { StringBuilder sb = new StringBuilder(); sb.append("--disabled-compat-changes="); @@ -1282,7 +1290,9 @@ public class ZygoteProcess { abi, instructionSet, null /* appDataDir */, null /* invokeWith */, true /* startChildZygote */, null /* packageName */, ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS /* zygotePolicyFlags */, false /* isTopApp */, - null /* disabledCompatChanges */, null /* pkgDataInfoMap */, extraArgs); + null /* disabledCompatChanges */, null /* pkgDataInfoMap */, + /* bindMountAppStorageDirs */ false, extraArgs); + } catch (ZygoteStartFailedEx ex) { throw new RuntimeException("Starting child-zygote through Zygote failed", ex); } diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java index a2def7fff2d2..f43a2523b5b3 100644 --- a/core/java/android/os/storage/StorageManagerInternal.java +++ b/core/java/android/os/storage/StorageManagerInternal.java @@ -100,10 +100,11 @@ public abstract class StorageManagerInternal { } /** - * Check if fuse is running in target user, if it's running then setup its obb directories. - * TODO: System server should store a list of active pids that obb is not mounted and use it. + * Create storage directories if it does not exist. + * Return true if the directories were setup correctly, otherwise false. */ - public abstract void prepareObbDirs(int userId, Set<String> packageList, String processName); + public abstract boolean prepareStorageDirs(int userId, Set<String> packageList, + String processName); /** * Add a listener to listen to reset event in StorageManagerService. |
