Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab0c7403 authored by Martijn Coenen's avatar Martijn Coenen
Browse files

Increase timeout waiting for ExternalStorageService to bind.

We've observed occasions where it can take a long time for the
system_server main thread to come around to handling the bind of the
service, for example because it's handling long-running jobs:

06-04 08:19:27.544  1000  1532  1532 W Looper  : Slow dispatch took
2044ms main h=com.android.server.job.JobSchedulerService$JobHandler
c=null m=1

Delays like this can cause us to fail binding to the external storage
service for a user, and reset the whole storage stack, leading to
unexpected results, especially if we timed out for trying to mount user
10, while user 0 has already been successfully mounted.

Increase the timeout to 20 seconds; this gives us a lot more time to
complete the bind. At the same time, we want to avoid risking holding
the vold lock for too and/or any deadlocks.

Add a WTF for when we do hit the timeout, to get a better grasp on how
common this is.

Bug: 158452122
Test: Boot device
Change-Id: Ia8f6f121448f6b5e484fd3e8cca845fdd89afc23
parent 475cf183
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -52,7 +52,6 @@ import static com.android.internal.util.XmlUtils.readStringAttribute;
import static com.android.internal.util.XmlUtils.writeIntAttribute;
import static com.android.internal.util.XmlUtils.writeIntAttribute;
import static com.android.internal.util.XmlUtils.writeLongAttribute;
import static com.android.internal.util.XmlUtils.writeLongAttribute;
import static com.android.internal.util.XmlUtils.writeStringAttribute;
import static com.android.internal.util.XmlUtils.writeStringAttribute;
import static com.android.server.storage.StorageUserConnection.REMOTE_TIMEOUT_SECONDS;


import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -224,6 +223,9 @@ class StorageManagerService extends IStorageManager.Stub
    private static final String ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY =
    private static final String ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY =
            "persist.sys.vold_app_data_isolation_enabled";
            "persist.sys.vold_app_data_isolation_enabled";


    // How long we wait to reset storage, if we failed to call onMount on the
    // external storage service.
    public static final int FAILED_MOUNT_RESET_TIMEOUT_SECONDS = 10;
    /**
    /**
     * If {@code 1}, enables the isolated storage feature. If {@code -1},
     * If {@code 1}, enables the isolated storage feature. If {@code -1},
     * disables the isolated storage feature. If {@code 0}, uses the default
     * disables the isolated storage feature. If {@code 0}, uses the default
@@ -2202,7 +2204,7 @@ class StorageManagerService extends IStorageManager.Stub
                    } catch (ExternalStorageServiceException e) {
                    } catch (ExternalStorageServiceException e) {
                        Slog.e(TAG, "Failed to mount volume " + vol, e);
                        Slog.e(TAG, "Failed to mount volume " + vol, e);


                        int nextResetSeconds = REMOTE_TIMEOUT_SECONDS * 2;
                        int nextResetSeconds = FAILED_MOUNT_RESET_TIMEOUT_SECONDS;
                        Slog.i(TAG, "Scheduling reset in " + nextResetSeconds + "s");
                        Slog.i(TAG, "Scheduling reset in " + nextResetSeconds + "s");
                        mHandler.removeMessages(H_RESET);
                        mHandler.removeMessages(H_RESET);
                        mHandler.sendMessageDelayed(mHandler.obtainMessage(H_RESET),
                        mHandler.sendMessageDelayed(mHandler.obtainMessage(H_RESET),
+2 −1
Original line number Original line Diff line number Diff line
@@ -62,7 +62,7 @@ import java.util.concurrent.TimeoutException;
public final class StorageUserConnection {
public final class StorageUserConnection {
    private static final String TAG = "StorageUserConnection";
    private static final String TAG = "StorageUserConnection";


    public static final int REMOTE_TIMEOUT_SECONDS = 5;
    public static final int REMOTE_TIMEOUT_SECONDS = 20;


    private final Object mLock = new Object();
    private final Object mLock = new Object();
    private final Context mContext;
    private final Context mContext;
@@ -202,6 +202,7 @@ public final class StorageUserConnection {
        try {
        try {
            if (!latch.await(REMOTE_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
            if (!latch.await(REMOTE_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
                // TODO(b/140025078): Call ActivityManager ANR API?
                // TODO(b/140025078): Call ActivityManager ANR API?
                Slog.wtf(TAG, "Failed to bind to the ExternalStorageService for user " + mUserId);
                throw new TimeoutException("Latch wait for " + reason + " elapsed");
                throw new TimeoutException("Latch wait for " + reason + " elapsed");
            }
            }
        } catch (InterruptedException e) {
        } catch (InterruptedException e) {