Mount direct boot apps obb dir after fuse is ready.
- Remove bind mounting Android/ code as we want to bind mount obb dir
for each process instead.
- Set property "vold.vold.fuse_running_users" as an array of user id
for which fuse is ready to use.
- After fuse is ready for a user, fork a background process in vold
to bind mount all direct boot apps for that user so its direct boot
apps obb dir will be mounted to lower fs for imporoved performance.
Bug: 148049767
Bug: 137890172
Test: After flag is enabled, AdoptableHostTest still pass.
Change-Id: I90079fbeed1c91f9780ca71e37b0012884680b7c
diff --git a/Utils.cpp b/Utils.cpp
index 35839ac..5c58aaf 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -82,6 +82,9 @@
static const char* kAppMediaDir = "/Android/media/";
static const char* kAppObbDir = "/Android/obb/";
+static const char* kMediaProviderCtx = "u:r:mediaprovider:";
+static const char* kMediaProviderAppCtx = "u:r:mediaprovider_app:";
+
// Lock used to protect process-level SELinux changes from racing with each
// other between multiple threads.
static std::mutex kSecurityLock;
@@ -382,6 +385,31 @@
return -errno;
}
+status_t KillProcessesWithMountPrefix(const std::string& path) {
+ if (KillProcessesWithMounts(path, SIGINT) == 0) {
+ return OK;
+ }
+ if (sSleepOnUnmount) sleep(5);
+
+ if (KillProcessesWithMounts(path, SIGTERM) == 0) {
+ return OK;
+ }
+ if (sSleepOnUnmount) sleep(5);
+
+ if (KillProcessesWithMounts(path, SIGKILL) == 0) {
+ return OK;
+ }
+ if (sSleepOnUnmount) sleep(5);
+
+ // Send SIGKILL a second time to determine if we've
+ // actually killed everyone mount
+ if (KillProcessesWithMounts(path, SIGKILL) == 0) {
+ return OK;
+ }
+ PLOG(ERROR) << "Failed to kill processes using " << path;
+ return -EBUSY;
+}
+
status_t KillProcessesUsingPath(const std::string& path) {
if (KillProcessesWithOpenFiles(path, SIGINT) == 0) {
return OK;
@@ -839,6 +867,19 @@
}
}
+// TODO: Use a better way to determine if it's media provider app.
+bool IsFuseDaemon(const pid_t pid) {
+ auto path = StringPrintf("/proc/%d/mounts", pid);
+ char* tmp;
+ if (lgetfilecon(path.c_str(), &tmp) < 0) {
+ return false;
+ }
+ bool result = android::base::StartsWith(tmp, kMediaProviderAppCtx)
+ || android::base::StartsWith(tmp, kMediaProviderCtx);
+ freecon(tmp);
+ return result;
+}
+
bool IsFilesystemSupported(const std::string& fsType) {
std::string supported;
if (!ReadFileToString(kProcFilesystems, &supported)) {
@@ -1198,6 +1239,16 @@
return true;
}
+status_t EnsureDirExists(const std::string& path, mode_t mode, uid_t uid, gid_t gid) {
+ if (access(path.c_str(), F_OK) != 0) {
+ PLOG(WARNING) << "Dir does not exist: " << path;
+ if (fs_prepare_dir(path.c_str(), mode, uid, gid) != 0) {
+ return -errno;
+ }
+ }
+ return OK;
+}
+
status_t MountUserFuse(userid_t user_id, const std::string& absolute_lower_path,
const std::string& relative_upper_path, android::base::unique_fd* fuse_fd) {
std::string pre_fuse_path(StringPrintf("/mnt/user/%d", user_id));