DO NOT MERGE Fix deadlock in MountService
It is not safe to call into vold with a lock held on mVolumeStates since we will receive events back from vold on a different thread. So in the boot completed handler we make a copy of the volume list and then call vold to mount volumes after releasing the lock Change-Id: Iaadfb1b8be5567c8e228a8fbc69d4d483c8dc987 Signed-off-by: Mike Lockwood <lockwood@android.com>
This commit is contained in:
@ -444,31 +444,46 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC
|
|||||||
* to make the media scanner run.
|
* to make the media scanner run.
|
||||||
*/
|
*/
|
||||||
if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
|
if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
|
||||||
notifyVolumeStateChange(null, "/sdcard", VolumeState.NoMedia, VolumeState.Mounted);
|
notifyVolumeStateChange(null, "/sdcard", VolumeState.NoMedia,
|
||||||
|
VolumeState.Mounted);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new Thread() {
|
new Thread() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
// it is not safe to call vold with mVolumeStates locked
|
||||||
|
// so we make a copy of the paths and states and process them
|
||||||
|
// outside the lock
|
||||||
|
String[] paths, states;
|
||||||
|
int count;
|
||||||
synchronized (mVolumeStates) {
|
synchronized (mVolumeStates) {
|
||||||
for (String path : mVolumeStates.keySet()) {
|
Set<String> keys = mVolumeStates.keySet();
|
||||||
String state = mVolumeStates.get(path);
|
count = keys.size();
|
||||||
|
paths = (String[])keys.toArray(new String[count]);
|
||||||
|
states = new String[count];
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
states[i] = mVolumeStates.get(paths[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (state.equals(Environment.MEDIA_UNMOUNTED)) {
|
for (int i = 0; i < count; i++) {
|
||||||
int rc = doMountVolume(path);
|
String path = paths[i];
|
||||||
if (rc != StorageResultCode.OperationSucceeded) {
|
String state = states[i];
|
||||||
Slog.e(TAG, String.format("Boot-time mount failed (%d)",
|
|
||||||
rc));
|
if (state.equals(Environment.MEDIA_UNMOUNTED)) {
|
||||||
}
|
int rc = doMountVolume(path);
|
||||||
} else if (state.equals(Environment.MEDIA_SHARED)) {
|
if (rc != StorageResultCode.OperationSucceeded) {
|
||||||
/*
|
Slog.e(TAG, String.format("Boot-time mount failed (%d)",
|
||||||
* Bootstrap UMS enabled state since vold indicates
|
rc));
|
||||||
* the volume is shared (runtime restart while ums enabled)
|
|
||||||
*/
|
|
||||||
notifyVolumeStateChange(null, path, VolumeState.NoMedia,
|
|
||||||
VolumeState.Shared);
|
|
||||||
}
|
}
|
||||||
|
} else if (state.equals(Environment.MEDIA_SHARED)) {
|
||||||
|
/*
|
||||||
|
* Bootstrap UMS enabled state since vold indicates
|
||||||
|
* the volume is shared (runtime restart while ums enabled)
|
||||||
|
*/
|
||||||
|
notifyVolumeStateChange(null, path, VolumeState.NoMedia,
|
||||||
|
VolumeState.Shared);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user