Kill apps using storage through bind mounts.

am: 89f74fbf25

* commit '89f74fbf2529d708534c041d2b711af0f1feff9f':
  Kill apps using storage through bind mounts.
gugelfrei
Jeff Sharkey 9 years ago committed by android-build-merger
commit 71ac649c1d

@ -113,6 +113,7 @@ status_t EmulatedVolume::doUnmount() {
mFusePid = 0;
}
KillProcessesUsingPath(getPath());
ForceUnmount(mFuseDefault);
ForceUnmount(mFuseRead);
ForceUnmount(mFuseWrite);

@ -177,13 +177,14 @@ extern "C" void vold_killProcessesWithOpenFiles(const char *path, int signal) {
/*
* 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 @@ void Process::killProcessesWithOpenFiles(const char *path, int signal) {
if (signal != 0) {
SLOGW("Sending %s to process %d", strsignal(signal), pid);
kill(pid, signal);
count++;
}
}
closedir(dir);
return count;
}

@ -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);

@ -123,35 +123,57 @@ status_t ForceUnmount(const std::string& path) {
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);
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);
sleep(5);
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
PLOG(WARNING) << "Failed to unmount " << path;
sleep(5);
Process::killProcessesWithOpenFiles(cpath, SIGKILL);
sleep(5);
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
PLOG(ERROR) << "Failed to unmount " << path;
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;

@ -49,6 +49,9 @@ status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid);
/* 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);

Loading…
Cancel
Save