From 88108bd3bc8f6801310caa070745edc8f377c383 Mon Sep 17 00:00:00 2001 From: Daichi Hirono Date: Wed, 25 Jan 2017 13:30:34 +0900 Subject: [PATCH 1/2] Use MNT_DETACH when unmounting appfuse mount. The system server requests unmount for appfuse when all opened file on appfuse are closed. However the kernel sometimes returns EBUSY for umount2 if it's just after closing all FDs on the mount point. To avoid the case, specify MNT_DETACH to unmount. Bug: 33363856 Test: mount and unmount appfuse repeatedly and see if unmount succeed. Change-Id: I802e1c048357cc445febf3b95341999463a0ec65 --- CommandListener.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CommandListener.cpp b/CommandListener.cpp index a312af2..36249e7 100644 --- a/CommandListener.cpp +++ b/CommandListener.cpp @@ -749,7 +749,13 @@ static android::status_t runCommandInNamespace(const std::string& command, if (command == "mount") { _exit(mountInNamespace(uid, device_fd, path)); } else if (command == "unmount") { - android::vold::ForceUnmount(path); + // If it's just after all FD opened on mount point are closed, umount2 can fail with + // EBUSY. To avoid the case, specify MNT_DETACH. + if (umount2(path.c_str(), UMOUNT_NOFOLLOW | MNT_DETACH) != 0 && + errno != EINVAL && errno != ENOENT) { + PLOG(ERROR) << "Failed to unmount directory."; + _exit(-errno); + } _exit(android::OK); } else { LOG(ERROR) << "Unknown appfuse command " << command; From 95b09469a30fc8c5972b9e7a3ff65db8ec705779 Mon Sep 17 00:00:00 2001 From: Daichi Hirono Date: Wed, 25 Jan 2017 17:16:46 +0900 Subject: [PATCH 2/2] Remove appfuse mount point directory after unmounting. Bug: 34691785 Test: Check if there are directories under /mnt/appfuse after unmounting. Change-Id: I00a897dd6d60e20b5ccfdfe2faeabb8a4f489197 --- CommandListener.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CommandListener.cpp b/CommandListener.cpp index 36249e7..e80bdce 100644 --- a/CommandListener.cpp +++ b/CommandListener.cpp @@ -756,6 +756,10 @@ static android::status_t runCommandInNamespace(const std::string& command, PLOG(ERROR) << "Failed to unmount directory."; _exit(-errno); } + if (rmdir(path.c_str()) != 0) { + PLOG(ERROR) << "Failed to remove the mount directory."; + _exit(-errno); + } _exit(android::OK); } else { LOG(ERROR) << "Unknown appfuse command " << command;