From ef63921f81118ea71049f8ff36fa035c54ea5ecd Mon Sep 17 00:00:00 2001 From: Ricky Wai Date: Tue, 7 Apr 2020 13:43:20 +0100 Subject: [PATCH] Bind mount install and android writable DATA and OBB dirs To improvement performance, and also making them able to list the dirs. This should also be fine under b/151055432, as the whole obb directory is mounted, renameTo() from installer to apps should be a move not copy. Bug: 153422990 Bug: 153540919 Test: atest AdoptableHostTest Change-Id: Ia18fd4393db14a0f11d6e5b947dd716515bdeeef --- VolumeManager.cpp | 2 +- model/EmulatedVolume.cpp | 68 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/VolumeManager.cpp b/VolumeManager.cpp index e4e5781..eac020f 100644 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -947,7 +947,7 @@ int VolumeManager::unmountAll() { !StartsWith(test, "/mnt/scratch") && #endif !StartsWith(test, "/mnt/vendor") && !StartsWith(test, "/mnt/product") && - !StartsWith(test, "/mnt/installer")) || + !StartsWith(test, "/mnt/installer") && !StartsWith(test, "/mnt/androidwritable")) || StartsWith(test, "/storage/")) { toUnmount.push_front(test); } diff --git a/model/EmulatedVolume.cpp b/model/EmulatedVolume.cpp index e411b33..e7cd36e 100644 --- a/model/EmulatedVolume.cpp +++ b/model/EmulatedVolume.cpp @@ -141,12 +141,49 @@ status_t EmulatedVolume::mountFuseBindMounts() { // a special bind mount, since app-private and OBB dirs share the same GID, but we // only want to give access to the latter. if (mUseSdcardFs) { - std::string installerSource( - StringPrintf("/mnt/runtime/write/%s/%d/Android/obb", label.c_str(), userId)); - std::string installerTarget( - StringPrintf("/mnt/installer/%d/%s/%d/Android/obb", userId, label.c_str(), userId)); + std::string obbSource(StringPrintf("/mnt/runtime/write/%s/%d/Android/obb", + label.c_str(), userId)); + std::string obbInstallerTarget(StringPrintf("/mnt/installer/%d/%s/%d/Android/obb", + userId, label.c_str(), userId)); - status = doFuseBindMount(installerSource, installerTarget, pathsToUnmount); + status = doFuseBindMount(obbSource, obbInstallerTarget, pathsToUnmount); + if (status != OK) { + return status; + } + } else if (mAppDataIsolationEnabled) { + std::string obbSource(StringPrintf("%s/obb", androidSource.c_str())); + std::string obbInstallerTarget(StringPrintf("/mnt/installer/%d/%s/%d/Android/obb", + userId, label.c_str(), userId)); + + status = doFuseBindMount(obbSource, obbInstallerTarget, pathsToUnmount); + if (status != OK) { + return status; + } + } + + // /mnt/androidwriteable is similar to /mnt/installer, but it's for + // MOUNT_EXTERNAL_ANDROID_WRITABLE apps and it can also access DATA (Android/data) dirs. + if (mAppDataIsolationEnabled) { + std::string obbSource = mUseSdcardFs ? + StringPrintf("/mnt/runtime/write/%s/%d/Android/obb", label.c_str(), userId) + : StringPrintf("%s/obb", androidSource.c_str()); + + std::string obbAndroidWritableTarget( + StringPrintf("/mnt/androidwritable/%d/%s/%d/Android/obb", + userId, label.c_str(), userId)); + + status = doFuseBindMount(obbSource, obbAndroidWritableTarget, pathsToUnmount); + if (status != OK) { + return status; + } + + std::string dataSource = mUseSdcardFs ? + StringPrintf("/mnt/runtime/write/%s/%d/Android/data", label.c_str(), userId) + : StringPrintf("%s/data", androidSource.c_str()); + std::string dataTarget(StringPrintf("/mnt/androidwritable/%d/%s/%d/Android/data", + userId, label.c_str(), userId)); + + status = doFuseBindMount(dataSource, dataTarget, pathsToUnmount); if (status != OK) { return status; } @@ -159,7 +196,7 @@ status_t EmulatedVolume::unmountFuseBindMounts() { std::string label = getLabel(); int userId = getMountUserId(); - if (mUseSdcardFs) { + if (mUseSdcardFs || mAppDataIsolationEnabled) { std::string installerTarget( StringPrintf("/mnt/installer/%d/%s/%d/Android/obb", userId, label.c_str(), userId)); LOG(INFO) << "Unmounting " << installerTarget; @@ -169,6 +206,25 @@ status_t EmulatedVolume::unmountFuseBindMounts() { // Intentional continue to try to unmount the other bind mount } } + if (mAppDataIsolationEnabled) { + std::string obbTarget( StringPrintf("/mnt/androidwritable/%d/%s/%d/Android/obb", + userId, label.c_str(), userId)); + LOG(INFO) << "Unmounting " << obbTarget; + auto status = UnmountTree(obbTarget); + if (status != OK) { + LOG(ERROR) << "Failed to unmount " << obbTarget; + // Intentional continue to try to unmount the other bind mount + } + std::string dataTarget(StringPrintf("/mnt/androidwritable/%d/%s/%d/Android/data", + userId, label.c_str(), userId)); + LOG(INFO) << "Unmounting " << dataTarget; + status = UnmountTree(dataTarget); + if (status != OK) { + LOG(ERROR) << "Failed to unmount " << dataTarget; + // Intentional continue to try to unmount the other bind mount + } + } + // When app data isolation is enabled, kill all apps that obb/ is mounted, otherwise we should // umount the whole Android/ dir. if (mAppDataIsolationEnabled) {