Skip to content

Commit

Permalink
Add a method in vold to unmount app data and obb dir for testing
Browse files Browse the repository at this point in the history
This new method will be used in new sm command.
Tests can use this so data and obb dirs are unmounted, and won't
be killed when volume is unmounted.

Bug: 148049767
Test: New sm command able to unmount app's data and obb dirs
Change-Id: Ifbc661ca510e996abd4b7ce1fb195aaa7afc37ad
  • Loading branch information
Ricky Wai committed Jan 18, 2021
1 parent 610eba0 commit a2ca11e
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 12 deletions.
12 changes: 11 additions & 1 deletion VoldNativeService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,17 @@ binder::Status VoldNativeService::remountAppStorageDirs(int uid, int pid,
ENFORCE_SYSTEM_OR_ROOT;
ACQUIRE_LOCK;

return translate(VolumeManager::Instance()->remountAppStorageDirs(uid, pid, packageNames));
return translate(VolumeManager::Instance()->handleAppStorageDirs(uid, pid,
false /* doUnmount */, packageNames));
}

binder::Status VoldNativeService::unmountAppStorageDirs(int uid, int pid,
const std::vector<std::string>& packageNames) {
ENFORCE_SYSTEM_OR_ROOT;
ACQUIRE_LOCK;

return translate(VolumeManager::Instance()->handleAppStorageDirs(uid, pid,
true /* doUnmount */, packageNames));
}

binder::Status VoldNativeService::setupAppDir(const std::string& path, int32_t appUid) {
Expand Down
2 changes: 2 additions & 0 deletions VoldNativeService.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ class VoldNativeService : public BinderService<VoldNativeService>, public os::Bn
binder::Status remountUid(int32_t uid, int32_t remountMode);
binder::Status remountAppStorageDirs(int uid, int pid,
const std::vector<std::string>& packageNames);
binder::Status unmountAppStorageDirs(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);
Expand Down
64 changes: 55 additions & 9 deletions VolumeManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,43 @@ bool scanProcProcesses(uid_t uid, userid_t userId, ScanProcCallback callback, vo
return true;
}

// In each app's namespace, unmount obb and data dirs
static bool umountStorageDirs(int nsFd, const char* android_data_dir, const char* android_obb_dir,
int uid, const char* targets[], int size) {
// This code is executed after a fork so it's very important that the set of
// methods we call here is strictly limited.
if (setns(nsFd, CLONE_NEWNS) != 0) {
async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to setns %s", strerror(errno));
return false;
}

// Unmount of Android/data/foo needs to be done before Android/data below.
bool result = true;
for (int i = 0; i < size; i++) {
if (TEMP_FAILURE_RETRY(umount2(targets[i], MNT_DETACH)) < 0 && errno != EINVAL &&
errno != ENOENT) {
async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to umount %s: %s",
targets[i], strerror(errno));
result = false;
}
}

// Mount tmpfs on Android/data and Android/obb
if (TEMP_FAILURE_RETRY(umount2(android_data_dir, MNT_DETACH)) < 0 && errno != EINVAL &&
errno != ENOENT) {
async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to umount %s :%s",
android_data_dir, strerror(errno));
result = false;
}
if (TEMP_FAILURE_RETRY(umount2(android_obb_dir, MNT_DETACH)) < 0 && errno != EINVAL &&
errno != ENOENT) {
async_safe_format_log(ANDROID_LOG_ERROR, "vold", "Failed to umount %s :%s",
android_obb_dir, strerror(errno));
result = false;
}
return result;
}

// In each app's namespace, mount tmpfs on obb and data dir, and bind mount obb and data
// package dirs.
static bool remountStorageDirs(int nsFd, const char* android_data_dir, const char* android_obb_dir,
Expand Down Expand Up @@ -741,8 +778,8 @@ static std::string getStorageDirTarget(userid_t userId, std::string dirName,
userId, dirName.c_str(), packageName.c_str());
}

// Fork the process and remount storage
bool VolumeManager::forkAndRemountStorage(int uid, int pid,
// Fork the process and remount / unmount app data and obb dirs
bool VolumeManager::forkAndRemountStorage(int uid, int pid, bool doUnmount,
const std::vector<std::string>& packageNames) {
userid_t userId = multiuser_get_user_id(uid);
std::string mnt_path = StringPrintf("/proc/%d/ns/mnt", pid);
Expand Down Expand Up @@ -798,11 +835,20 @@ bool VolumeManager::forkAndRemountStorage(int uid, int pid,
// Fork a child to mount Android/obb android Android/data dirs, as we don't want it to affect
// original vold process mount namespace.
if (!(child = fork())) {
if (remountStorageDirs(nsFd, android_data_dir, android_obb_dir, uid,
sources_cstr, targets_cstr, size)) {
_exit(0);
if (doUnmount) {
if (umountStorageDirs(nsFd, android_data_dir, android_obb_dir, uid,
targets_cstr, size)) {
_exit(0);
} else {
_exit(1);
}
} else {
_exit(1);
if (remountStorageDirs(nsFd, android_data_dir, android_obb_dir, uid,
sources_cstr, targets_cstr, size)) {
_exit(0);
} else {
_exit(1);
}
}
}

Expand All @@ -827,8 +873,8 @@ bool VolumeManager::forkAndRemountStorage(int uid, int pid,
return true;
}

int VolumeManager::remountAppStorageDirs(int uid, int pid,
const std::vector<std::string>& packageNames) {
int VolumeManager::handleAppStorageDirs(int uid, int pid,
bool doUnmount, const std::vector<std::string>& packageNames) {
// Only run the remount if fuse is mounted for that user.
userid_t userId = multiuser_get_user_id(uid);
bool fuseMounted = false;
Expand All @@ -842,7 +888,7 @@ int VolumeManager::remountAppStorageDirs(int uid, int pid,
}
}
if (fuseMounted) {
forkAndRemountStorage(uid, pid, packageNames);
forkAndRemountStorage(uid, pid, doUnmount, packageNames);
}
return 0;
}
Expand Down
6 changes: 4 additions & 2 deletions VolumeManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ class VolumeManager {
int onSecureKeyguardStateChanged(bool isShowing);

int remountUid(uid_t uid, int32_t remountMode) { return 0; }
int remountAppStorageDirs(int uid, int pid, const std::vector<std::string>& packageNames);
int handleAppStorageDirs(int uid, int pid,
bool doUnmount, const std::vector<std::string>& packageNames);

/* Aborts all FUSE filesystems, in case the FUSE daemon is no longer up. */
int abortFuse();
Expand All @@ -129,7 +130,8 @@ class VolumeManager {
int updateVirtualDisk();
int setDebug(bool enable);

bool forkAndRemountStorage(int uid, int pid, const std::vector<std::string>& packageNames);
bool forkAndRemountStorage(int uid, int pid, bool doUnmount,
const std::vector<std::string>& packageNames);

static VolumeManager* Instance();

Expand Down
1 change: 1 addition & 0 deletions binder/android/os/IVold.aidl
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ interface IVold {

void remountUid(int uid, int remountMode);
void remountAppStorageDirs(int uid, int pid, in @utf8InCpp String[] packageNames);
void unmountAppStorageDirs(int uid, int pid, in @utf8InCpp String[] packageNames);

void setupAppDir(@utf8InCpp String path, int appUid);
void fixupAppDir(@utf8InCpp String path, int appUid);
Expand Down

0 comments on commit a2ca11e

Please sign in to comment.