summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--VoldNativeService.cpp8
-rw-r--r--VoldNativeService.h1
-rw-r--r--VolumeManager.cpp29
-rw-r--r--VolumeManager.h9
-rw-r--r--binder/android/os/IVold.aidl1
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);