Check if storage app data and obb directories exist in vold
As storage is not mounted in system server, we use vold
to check if storage app data and obb directories exist instead.
We add a method in vold so it only creates app data and obb dirs
if dirs do not exist to speed up app starting time.
Bug: 160336374
Test: Data and obb directories are created when a new app is started
Change-Id: I1bd784d9c9e05463f71433fc782ac4e0c831cbf1
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index 674a721..864a6f0 100644
--- a/VoldNativeService.cpp
+++ b/VoldNativeService.cpp
@@ -394,6 +394,14 @@
return translate(VolumeManager::Instance()->setupAppDir(path, appUid));
}
+binder::Status VoldNativeService::ensureAppDirsCreated(const std::vector<std::string>& paths,
+ int32_t appUid) {
+ ENFORCE_SYSTEM_OR_ROOT;
+ ACQUIRE_LOCK;
+
+ return translate(VolumeManager::Instance()->ensureAppDirsCreated(paths, appUid));
+}
+
binder::Status VoldNativeService::fixupAppDir(const std::string& path, int32_t appUid) {
ENFORCE_SYSTEM_OR_ROOT;
CHECK_ARGUMENT_PATH(path);
diff --git a/VoldNativeService.h b/VoldNativeService.h
index 390e9fc..0a55af4 100644
--- a/VoldNativeService.h
+++ b/VoldNativeService.h
@@ -67,6 +67,7 @@
binder::Status remountAppStorageDirs(int uid, int pid,
const std::vector<std::string>& packageNames);
+ binder::Status ensureAppDirsCreated(const std::vector<std::string>& paths, int32_t appUid);
binder::Status setupAppDir(const std::string& path, int32_t appUid);
binder::Status fixupAppDir(const std::string& path, int32_t appUid);
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index f0fc388..714122d 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -984,7 +984,25 @@
return 0;
}
-int VolumeManager::setupAppDir(const std::string& path, int32_t appUid, bool fixupExistingOnly) {
+int VolumeManager::ensureAppDirsCreated(const std::vector<std::string>& paths, int32_t appUid) {
+ if (IsSdcardfsUsed()) {
+ // sdcardfs magically does this for us
+ return OK;
+ }
+
+ int size = paths.size();
+ for (int i = 0; i < size; i++) {
+ int result = setupAppDir(paths[i], appUid, false /* fixupExistingOnly */,
+ true /* skipIfDirExists */);
+ if (result != OK) {
+ return result;
+ }
+ }
+ return OK;
+}
+
+int VolumeManager::setupAppDir(const std::string& path, int32_t appUid, bool fixupExistingOnly,
+ bool skipIfDirExists) {
// Only offer to create directories for paths managed by vold
if (!StartsWith(path, "/storage/")) {
LOG(ERROR) << "Failed to find mounted volume for " << path;
@@ -1029,11 +1047,18 @@
const std::string volumeRoot = volume->getRootPath(); // eg /data/media/0
- if (fixupExistingOnly && (access(lowerPath.c_str(), F_OK) != 0)) {
+ const int access_result = access(lowerPath.c_str(), F_OK);
+ if (fixupExistingOnly && access_result != 0) {
// Nothing to fixup
return OK;
}
+ if (skipIfDirExists && access_result == 0) {
+ // It's safe to assume it's ok as it will be used for zygote to bind mount dir only,
+ // which the dir doesn't need to have correct permission for now yet.
+ return OK;
+ }
+
if (volume->getType() == VolumeBase::Type::kPublic) {
// On public volumes, we don't need to setup permissions, as everything goes through
// FUSE; just create the dirs and be done with it.
diff --git a/VolumeManager.h b/VolumeManager.h
index 54a2443..932b81c 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -165,12 +165,16 @@
* files in the passed in path, but only if that path exists; if it doesn't
* exist, this function doesn't create them.
*
+ * If skipIfDirExists is set, we will not fix any existing dirs, we will
+ * only create app dirs if it doesn't exist.
+ *
* Validates that given paths are absolute and that they contain no relative
* "." or ".." paths or symlinks. Last path segment is treated as filename
* and ignored, unless the path ends with "/". Also ensures that path
* belongs to a volume managed by vold.
*/
- int setupAppDir(const std::string& path, int32_t appUid, bool fixupExistingOnly = false);
+ int setupAppDir(const std::string& path, int32_t appUid, bool fixupExistingOnly = false,
+ bool skipIfDirExists = false);
/**
* Fixes up an existing application directory, as if it was created with
@@ -179,6 +183,9 @@
*/
int fixupAppDir(const std::string& path, int32_t appUid);
+ // Called before zygote starts to ensure dir exists so zygote can bind mount them.
+ int ensureAppDirsCreated(const std::vector<std::string>& paths, int32_t appUid);
+
int createObb(const std::string& path, const std::string& key, int32_t ownerGid,
std::string* outVolId);
int destroyObb(const std::string& volId);
diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl
index bb284b8..ef4f89a 100644
--- a/binder/android/os/IVold.aidl
+++ b/binder/android/os/IVold.aidl
@@ -57,6 +57,7 @@
void setupAppDir(@utf8InCpp String path, int appUid);
void fixupAppDir(@utf8InCpp String path, int appUid);
+ void ensureAppDirsCreated(in @utf8InCpp String[] paths, int appUid);
@utf8InCpp String createObb(@utf8InCpp String sourcePath, @utf8InCpp String sourceKey,
int ownerGid);