Kill apps using storage through bind mounts. am: 89f74fbf25
am: 71ac649c1d
* commit '71ac649c1d179a8d97db6fd1862f8b0d992a6751':
Kill apps using storage through bind mounts.
diff --git a/EmulatedVolume.cpp b/EmulatedVolume.cpp
index 6e440cc..80ef3e2 100644
--- a/EmulatedVolume.cpp
+++ b/EmulatedVolume.cpp
@@ -113,6 +113,7 @@
mFusePid = 0;
}
+ KillProcessesUsingPath(getPath());
ForceUnmount(mFuseDefault);
ForceUnmount(mFuseRead);
ForceUnmount(mFuseWrite);
diff --git a/Process.cpp b/Process.cpp
index a6f0cc6..962a460 100644
--- a/Process.cpp
+++ b/Process.cpp
@@ -177,13 +177,14 @@
/*
* Hunt down processes that have files open at the given mount point.
*/
-void Process::killProcessesWithOpenFiles(const char *path, int signal) {
- DIR* dir;
+int Process::killProcessesWithOpenFiles(const char *path, int signal) {
+ int count = 0;
+ DIR* dir;
struct dirent* de;
if (!(dir = opendir("/proc"))) {
SLOGE("opendir failed (%s)", strerror(errno));
- return;
+ return count;
}
while ((de = readdir(dir))) {
@@ -213,7 +214,9 @@
if (signal != 0) {
SLOGW("Sending %s to process %d", strsignal(signal), pid);
kill(pid, signal);
+ count++;
}
}
closedir(dir);
+ return count;
}
diff --git a/Process.h b/Process.h
index 81b5f18..62a9313 100644
--- a/Process.h
+++ b/Process.h
@@ -21,7 +21,7 @@
class Process {
public:
- static void killProcessesWithOpenFiles(const char *path, int signal);
+ static int killProcessesWithOpenFiles(const char *path, int signal);
static int getPid(const char *s);
static int checkSymLink(int pid, const char *path, const char *name);
static int checkFileMaps(int pid, const char *path);
diff --git a/Utils.cpp b/Utils.cpp
index 51ef4c4..279c990 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -123,35 +123,57 @@
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
- PLOG(WARNING) << "Failed to unmount " << path;
-
+ // Apps might still be handling eject request, so wait before
+ // we start sending signals
sleep(5);
+
Process::killProcessesWithOpenFiles(cpath, SIGINT);
-
+ sleep(5);
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
- PLOG(WARNING) << "Failed to unmount " << path;
- sleep(5);
Process::killProcessesWithOpenFiles(cpath, SIGTERM);
-
- if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
- return OK;
- }
- PLOG(WARNING) << "Failed to unmount " << path;
-
sleep(5);
- Process::killProcessesWithOpenFiles(cpath, SIGKILL);
-
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
- PLOG(ERROR) << "Failed to unmount " << path;
+
+ Process::killProcessesWithOpenFiles(cpath, SIGKILL);
+ sleep(5);
+ if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
+ return OK;
+ }
return -errno;
}
+status_t KillProcessesUsingPath(const std::string& path) {
+ const char* cpath = path.c_str();
+ if (Process::killProcessesWithOpenFiles(cpath, SIGINT) == 0) {
+ return OK;
+ }
+ sleep(5);
+
+ if (Process::killProcessesWithOpenFiles(cpath, SIGTERM) == 0) {
+ return OK;
+ }
+ sleep(5);
+
+ if (Process::killProcessesWithOpenFiles(cpath, SIGKILL) == 0) {
+ return OK;
+ }
+ sleep(5);
+
+ // Send SIGKILL a second time to determine if we've
+ // actually killed everyone with open files
+ if (Process::killProcessesWithOpenFiles(cpath, SIGKILL) == 0) {
+ return OK;
+ }
+ PLOG(ERROR) << "Failed to kill processes using " << path;
+ return -EBUSY;
+}
+
status_t BindMount(const std::string& source, const std::string& target) {
if (::mount(source.c_str(), target.c_str(), "", MS_BIND, NULL)) {
PLOG(ERROR) << "Failed to bind mount " << source << " to " << target;
diff --git a/Utils.h b/Utils.h
index f33a379..228727a 100644
--- a/Utils.h
+++ b/Utils.h
@@ -49,6 +49,9 @@
/* Really unmounts the path, killing active processes along the way */
status_t ForceUnmount(const std::string& path);
+/* Kills any processes using given path */
+status_t KillProcessesUsingPath(const std::string& path);
+
/* Creates bind mount from source to target */
status_t BindMount(const std::string& source, const std::string& target);