summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSan Mehat <san@google.com>2010-02-18 09:00:18 -0800
committerSan Mehat <san@google.com>2010-02-18 11:48:49 -0800
commit4ba8948dc16463053e21cda5744f519a555080d0 (patch)
treeb033c6371d77569f490bf0b4a2a7e64dbac58882
parentd31e380bd9689dd9629b510ffe324707e261b439 (diff)
downloadsystem_vold-4ba8948dc16463053e21cda5744f519a555080d0.tar.gz
system_vold-4ba8948dc16463053e21cda5744f519a555080d0.tar.bz2
system_vold-4ba8948dc16463053e21cda5744f519a555080d0.zip
vold: Add 'force' option to anything that can cause an unmount
Signed-off-by: San Mehat <san@google.com>
-rw-r--r--CommandListener.cpp27
-rw-r--r--DirectVolume.cpp2
-rw-r--r--Volume.cpp22
-rw-r--r--Volume.h2
-rw-r--r--VolumeManager.cpp32
-rw-r--r--VolumeManager.h6
6 files changed, 53 insertions, 38 deletions
diff --git a/CommandListener.cpp b/CommandListener.cpp
index b25728f..c87198e 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -59,7 +59,11 @@ int CommandListener::VolumeCmd::runCommand(SocketClient *cli,
} else if (!strcmp(argv[1], "mount")) {
rc = vm->mountVolume(argv[2]);
} else if (!strcmp(argv[1], "unmount")) {
- rc = vm->unmountVolume(argv[2]);
+ bool force = false;
+ if (argc >= 4 && !strcmp(argv[3], "force")) {
+ force = true;
+ }
+ rc = vm->unmountVolume(argv[2], force);
} else if (!strcmp(argv[1], "format")) {
rc = vm->formatVolume(argv[2]);
} else if (!strcmp(argv[1], "share")) {
@@ -244,11 +248,15 @@ int CommandListener::AsecCmd::runCommand(SocketClient *cli,
cli->sendMsg(ResponseCode::CommandOkay, "Container finalized", false);
}
} else if (!strcmp(argv[1], "destroy")) {
- if (argc != 3) {
- cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec destroy <container-id>", false);
+ if (argc < 3) {
+ cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec destroy <container-id> [force]", false);
return 0;
}
- if (vm->destroyAsec(argv[2])) {
+ bool force = false;
+ if (argc > 3 && !strcmp(argv[3], "force")) {
+ force = true;
+ }
+ if (vm->destroyAsec(argv[2], force)) {
cli->sendMsg(ResponseCode::OperationFailed, "Container destroy failed", true);
} else {
cli->sendMsg(ResponseCode::CommandOkay, "Container destroyed", false);
@@ -267,13 +275,16 @@ int CommandListener::AsecCmd::runCommand(SocketClient *cli,
} else {
cli->sendMsg(ResponseCode::CommandOkay, "Mount succeeded", false);
}
-
} else if (!strcmp(argv[1], "unmount")) {
- if (argc != 3) {
- cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec unmount <container-id>", false);
+ if (argc < 3) {
+ cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec unmount <container-id> [force]", false);
return 0;
}
- if (vm->unmountAsec(argv[2])) {
+ bool force = false;
+ if (argc > 3 && !strcmp(argv[3], "force")) {
+ force = true;
+ }
+ if (vm->unmountAsec(argv[2], force)) {
cli->sendMsg(ResponseCode::OperationFailed, "Container unmount failed", true);
} else {
cli->sendMsg(ResponseCode::CommandOkay, "Container unmounted", false);
diff --git a/DirectVolume.cpp b/DirectVolume.cpp
index 68a6fcd..dcb1a05 100644
--- a/DirectVolume.cpp
+++ b/DirectVolume.cpp
@@ -274,7 +274,7 @@ void DirectVolume::handlePartitionRemoved(const char *devpath, NetlinkEvent *evt
getLabel(), getMountpoint(), major, minor);
mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeBadRemoval,
msg, false);
- if (Volume::unmountVol()) {
+ if (Volume::unmountVol(true)) {
LOGE("Failed to unmount volume on bad removal (%s)",
strerror(errno));
// XXX: At this point we're screwed for now
diff --git a/Volume.cpp b/Volume.cpp
index 529975a..cce2fc1 100644
--- a/Volume.cpp
+++ b/Volume.cpp
@@ -275,7 +275,7 @@ int Volume::mountVol() {
return -1;
}
-int Volume::unmountVol() {
+int Volume::unmountVol(bool force) {
int i, rc;
if (getState() != Volume::State_Mounted) {
@@ -285,7 +285,7 @@ int Volume::unmountVol() {
}
setState(Volume::State_Unmounting);
- usleep(1000 * 200); // Give the framework some time to react
+ usleep(1000 * 1000); // Give the framework some time to react
for (i = 1; i <= 10; i++) {
rc = umount(getMountpoint());
if (!rc)
@@ -299,17 +299,18 @@ int Volume::unmountVol() {
LOGW("Volume %s unmount attempt %d failed (%s)",
getLabel(), i, strerror(errno));
- int action;
+ int action = 0;
- if (i > 8) {
- action = 2; // SIGKILL
- } else if (i > 7) {
- action = 1; // SIGHUP
- } else
- action = 0; // just complain
+ if (force) {
+ if (i > 8) {
+ action = 2; // SIGKILL
+ } else if (i > 7) {
+ action = 1; // SIGHUP
+ }
+ }
Process::killProcessesWithOpenFiles(getMountpoint(), action);
- usleep(1000*250);
+ usleep(1000*1000);
}
if (!rc) {
@@ -319,6 +320,7 @@ int Volume::unmountVol() {
return 0;
}
+ errno = EBUSY;
LOGE("Volume %s failed to unmount (%s)\n", getLabel(), strerror(errno));
setState(Volume::State_Mounted);
return -1;
diff --git a/Volume.h b/Volume.h
index 7306e4e..9bf0f0a 100644
--- a/Volume.h
+++ b/Volume.h
@@ -53,7 +53,7 @@ public:
virtual ~Volume();
int mountVol();
- int unmountVol();
+ int unmountVol(bool force);
int formatVol();
const char *getLabel() { return mLabel; }
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 251e11c..72ec3da 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -325,8 +325,8 @@ out_err:
return -1;
}
-#define ASEC_UNMOUNT_RETRIES 10
-int VolumeManager::unmountAsec(const char *id) {
+#define ASEC_UNMOUNT_RETRIES 5
+int VolumeManager::unmountAsec(const char *id, bool force) {
char asecFileName[255];
char mountPoint[255];
@@ -353,20 +353,22 @@ int VolumeManager::unmountAsec(const char *id) {
LOGW("ASEC %s unmount attempt %d failed (%s)",
id, i, strerror(errno));
- int action;
- if (i > (ASEC_UNMOUNT_RETRIES - 2))
- action = 2; // SIGKILL
- else if (i > (ASEC_UNMOUNT_RETRIES - 3))
- action = 1; // SIGHUP
- else
- action = 0; // Just complain
+ int action = 0; // default is to just complain
+
+ if (force) {
+ if (i > (ASEC_UNMOUNT_RETRIES - 2))
+ action = 2; // SIGKILL
+ else if (i > (ASEC_UNMOUNT_RETRIES - 3))
+ action = 1; // SIGHUP
+ }
Process::killProcessesWithOpenFiles(mountPoint, action);
usleep(1000 * 1000);
}
if (rc) {
- LOGE("Failed to unmount ASEC %s", id);
+ errno = EBUSY;
+ LOGE("Failed to unmount container %s (%s)", id, strerror(errno));
return -1;
}
@@ -397,7 +399,7 @@ int VolumeManager::unmountAsec(const char *id) {
return 0;
}
-int VolumeManager::destroyAsec(const char *id) {
+int VolumeManager::destroyAsec(const char *id, bool force) {
char asecFileName[255];
char mountPoint[255];
@@ -407,7 +409,7 @@ int VolumeManager::destroyAsec(const char *id) {
if (isMountpointMounted(mountPoint)) {
LOGD("Unmounting container before destroy");
- if (unmountAsec(id)) {
+ if (unmountAsec(id, force)) {
LOGE("Failed to unmount asec %s for destroy (%s)", id, strerror(errno));
return -1;
}
@@ -675,7 +677,7 @@ int VolumeManager::unshareVolume(const char *label, const char *method) {
return 0;
}
-int VolumeManager::unmountVolume(const char *label) {
+int VolumeManager::unmountVolume(const char *label, bool force) {
Volume *v = lookupVolume(label);
if (!v) {
@@ -698,13 +700,13 @@ int VolumeManager::unmountVolume(const char *label) {
while(mActiveContainers->size()) {
AsecIdCollection::iterator it = mActiveContainers->begin();
LOGI("Unmounting ASEC %s (dependant on %s)", *it, v->getMountpoint());
- if (unmountAsec(*it)) {
+ if (unmountAsec(*it, force)) {
LOGE("Failed to unmount ASEC %s (%s) - unmount of %s may fail!", *it,
strerror(errno), v->getMountpoint());
}
}
- return v->unmountVol();
+ return v->unmountVol(force);
}
/*
diff --git a/VolumeManager.h b/VolumeManager.h
index f989cdb..5ed6f21 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -52,7 +52,7 @@ public:
int listVolumes(SocketClient *cli);
int mountVolume(const char *label);
- int unmountVolume(const char *label);
+ int unmountVolume(const char *label, bool force);
int shareVolume(const char *label, const char *method);
int unshareVolume(const char *label, const char *method);
int shareAvailable(const char *method, bool *avail);
@@ -62,9 +62,9 @@ public:
int createAsec(const char *id, unsigned numSectors, const char *fstype,
const char *key, int ownerUid);
int finalizeAsec(const char *id);
- int destroyAsec(const char *id);
+ int destroyAsec(const char *id, bool force);
int mountAsec(const char *id, const char *key, int ownerUid);
- int unmountAsec(const char *id);
+ int unmountAsec(const char *id, bool force);
int renameAsec(const char *id1, const char *id2);
int getAsecMountPath(const char *id, char *buffer, int maxlen);