diff options
-rw-r--r-- | VoldNativeService.cpp | 8 | ||||
-rw-r--r-- | VoldNativeService.h | 1 | ||||
-rw-r--r-- | VolumeManager.cpp | 29 | ||||
-rw-r--r-- | VolumeManager.h | 9 | ||||
-rw-r--r-- | binder/android/os/IVold.aidl | 1 |
5 files changed, 45 insertions, 3 deletions
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp index 674a7211..864a6f01 100644 --- a/VoldNativeService.cpp +++ b/VoldNativeService.cpp @@ -394,6 +394,14 @@ binder::Status VoldNativeService::setupAppDir(const std::string& path, int32_t a 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 390e9fc1..0a55af44 100644 --- a/VoldNativeService.h +++ b/VoldNativeService.h @@ -67,6 +67,7 @@ class VoldNativeService : public BinderService<VoldNativeService>, public os::Bn 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 f0fc3887..714122d2 100644 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -984,7 +984,25 @@ int VolumeManager::unmountAll() { 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 @@ int VolumeManager::setupAppDir(const std::string& path, int32_t appUid, bool fix 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 54a24433..932b81c6 100644 --- a/VolumeManager.h +++ b/VolumeManager.h @@ -165,12 +165,16 @@ class VolumeManager { * 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 @@ class VolumeManager { */ 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 bb284b83..ef4f89aa 100644 --- a/binder/android/os/IVold.aidl +++ b/binder/android/os/IVold.aidl @@ -57,6 +57,7 @@ interface IVold { 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); |