Merge fuse unmount paths to reduce fuse unmount total time
Previously, we were waiting unnecessarily for long times trying to unmount
different fuse paths with no luck at the end. Made sure that we merge
these unmount flows so that we don't sleep separately for each unmount.
Additionally, added polling logic to not sleep the whole duration
without trying to unmount. Further more, made sure that we try to kill
apps using storage/emulated when unmounting fuse paths.
More details about the change can be found here go/mount-performance-improvement
Test: atest AdoptableHostTest, atest StorageManagerTest
Bug: 318335297
Bug: 402367661
Bug: 369519866
Flag: android.vold.flags.enhance_fuse_unmount
Change-Id: Id8af00fd1bff1de4078e4acd148a918738b4cea6
diff --git a/Process.cpp b/Process.cpp
index 426a425..0115fb1 100644
--- a/Process.cpp
+++ b/Process.cpp
@@ -46,7 +46,7 @@
namespace android {
namespace vold {
-static bool checkMaps(const std::string& path, const std::string& prefix) {
+static bool checkMaps(const std::string& path, const std::vector<std::string>& prefixes) {
bool found = false;
auto file = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
if (!file) {
@@ -60,9 +60,14 @@
std::string::size_type pos = line.find('/');
if (pos != std::string::npos) {
line = line.substr(pos);
- if (android::base::StartsWith(line, prefix)) {
- LOG(WARNING) << "Found map " << path << " referencing " << line;
- found = true;
+ for (const auto& prefix : prefixes) {
+ if (android::base::StartsWith(line, prefix)) {
+ LOG(WARNING) << "Found map " << path << " referencing " << line;
+ found = true;
+ break;
+ }
+ }
+ if (found) {
break;
}
}
@@ -72,12 +77,14 @@
return found;
}
-static bool checkSymlink(const std::string& path, const std::string& prefix) {
+static bool checkSymlink(const std::string& path, const std::vector<std::string>& prefixes) {
std::string res;
if (android::base::Readlink(path, &res)) {
- if (android::base::StartsWith(res, prefix)) {
- LOG(WARNING) << "Found symlink " << path << " referencing " << res;
- return true;
+ for (const auto& prefix : prefixes) {
+ if (android::base::StartsWith(res, prefix)) {
+ LOG(WARNING) << "Found symlink " << path << " referencing " << res;
+ return true;
+ }
}
}
return false;
@@ -129,7 +136,8 @@
return pids.size();
}
-int KillProcessesWithOpenFiles(const std::string& prefix, int signal, bool killFuseDaemon) {
+int KillProcessesWithOpenFiles(const std::vector<std::string>& prefixes, int signal,
+ bool killFuseDaemon) {
std::unordered_set<pid_t> pids;
auto proc_d = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/proc"), closedir);
@@ -148,10 +156,10 @@
// Look for references to prefix
bool found = false;
auto path = StringPrintf("/proc/%d", pid);
- found |= checkMaps(path + "/maps", prefix);
- found |= checkSymlink(path + "/cwd", prefix);
- found |= checkSymlink(path + "/root", prefix);
- found |= checkSymlink(path + "/exe", prefix);
+ found |= checkMaps(path + "/maps", prefixes);
+ found |= checkSymlink(path + "/cwd", prefixes);
+ found |= checkSymlink(path + "/root", prefixes);
+ found |= checkSymlink(path + "/exe", prefixes);
auto fd_path = path + "/fd";
auto fd_d = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(fd_path.c_str()), closedir);
@@ -161,7 +169,7 @@
struct dirent* fd_de;
while ((fd_de = readdir(fd_d.get())) != nullptr) {
if (fd_de->d_type != DT_LNK) continue;
- found |= checkSymlink(fd_path + "/" + fd_de->d_name, prefix);
+ found |= checkSymlink(fd_path + "/" + fd_de->d_name, prefixes);
}
}
@@ -198,5 +206,10 @@
return totalKilledPids;
}
+int KillProcessesWithOpenFiles(const std::string& prefix, int signal, bool killFuseDaemon) {
+ return KillProcessesWithOpenFiles(std::vector<std::string>(1, prefix), signal,
+ killFuseDaemon);
+}
+
} // namespace vold
} // namespace android