Add unmountTree to utils.

Bug: 111890351
Test: builds without any errors
Change-Id: I62a94c9e8d101756b686b402774f08a1d71cf875
This commit is contained in:
Sudheer Shanka 2018-09-25 14:22:07 -07:00
parent a2a227e382
commit 89ddf99119
3 changed files with 33 additions and 24 deletions

View file

@ -31,6 +31,8 @@
#include <dirent.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <mntent.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <sys/stat.h>
@ -38,6 +40,7 @@
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <list>
#include <mutex>
#ifndef UMOUNT_NOFOLLOW
@ -758,5 +761,32 @@ bool IsRunningInEmulator() {
return android::base::GetBoolProperty("ro.kernel.qemu", false);
}
status_t UnmountTree(const std::string& prefix) {
FILE* fp = setmntent("/proc/mounts", "r");
if (fp == NULL) {
PLOG(ERROR) << "Failed to open /proc/mounts";
return -errno;
}
// Some volumes can be stacked on each other, so force unmount in
// reverse order to give us the best chance of success.
std::list<std::string> toUnmount;
mntent* mentry;
while ((mentry = getmntent(fp)) != NULL) {
auto test = std::string(mentry->mnt_dir) + "/";
if (android::base::StartsWith(test, prefix)) {
toUnmount.push_front(test);
}
}
endmntent(fp);
for (const auto& path : toUnmount) {
if (umount2(path.c_str(), MNT_DETACH)) {
PLOG(ERROR) << "Failed to unmount " << path;
}
}
return OK;
}
} // namespace vold
} // namespace android

View file

@ -130,6 +130,8 @@ bool Readlinkat(int dirfd, const std::string& path, std::string* result);
/* Checks if Android is running in QEMU */
bool IsRunningInEmulator();
status_t UnmountTree(const std::string& prefix);
} // namespace vold
} // namespace android

View file

@ -411,30 +411,7 @@ int VolumeManager::setPrimary(const std::shared_ptr<android::vold::VolumeBase>&
}
static int unmount_tree(const std::string& prefix) {
FILE* fp = setmntent("/proc/mounts", "r");
if (fp == NULL) {
PLOG(ERROR) << "Failed to open /proc/mounts";
return -errno;
}
// Some volumes can be stacked on each other, so force unmount in
// reverse order to give us the best chance of success.
std::list<std::string> toUnmount;
mntent* mentry;
while ((mentry = getmntent(fp)) != NULL) {
auto test = std::string(mentry->mnt_dir) + "/";
if (android::base::StartsWith(test, prefix)) {
toUnmount.push_front(test);
}
}
endmntent(fp);
for (const auto& path : toUnmount) {
if (umount2(path.c_str(), MNT_DETACH)) {
PLOG(ERROR) << "Failed to unmount " << path;
}
}
return 0;
return android::vold::UnmountTree(prefix);
}
int VolumeManager::remountUid(uid_t uid, const std::string& mode) {