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
This commit is contained in:
Ricky Wai 2020-12-03 15:32:52 +00:00
parent e8838a862d
commit bbfb6ea1ac
5 changed files with 45 additions and 3 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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.

View file

@ -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);

View file

@ -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);