vold: Add 'force' option to anything that can cause an unmount
Signed-off-by: San Mehat <san@google.com>
This commit is contained in:
parent
d31e380bd9
commit
4ba8948dc1
6 changed files with 53 additions and 38 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
22
Volume.cpp
22
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;
|
||||
|
|
2
Volume.h
2
Volume.h
|
@ -53,7 +53,7 @@ public:
|
|||
virtual ~Volume();
|
||||
|
||||
int mountVol();
|
||||
int unmountVol();
|
||||
int unmountVol(bool force);
|
||||
int formatVol();
|
||||
|
||||
const char *getLabel() { return mLabel; }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue