OSDN Git Service

Zygote: Increase wrap-pid timeout to thirty seconds
authorAndreas Gampe <agampe@google.com>
Fri, 21 Jul 2017 18:41:00 +0000 (11:41 -0700)
committerAndreas Gampe <agampe@google.com>
Tue, 25 Jul 2017 02:59:13 +0000 (19:59 -0700)
Some lowend devices under heavy instrumentation may not be able to
send the pid in the current five seconds. Drop the safety and
ignore watchdog debug builds, and move the timeout to thirty seconds.

Make the ZygoteConnection constants sharable in their own @hide class.
Add an assert into the watchdog that the wait time is less than the
watchdog time on non-debug builds.

(cherry picked from commit 27497c6dfc03242abfe7c087fcaf37e684529678)

Bug: 63904739
Bug: 63638768
Test: m
Test: manual test
Test: cts-tradefed run commandAndExit cts-dev -m CtsWrapWrapDebugTestCases
Change-Id: I80abdda54cd94e935de5a52b9f3c9192d0e31060

core/java/com/android/internal/os/ZygoteConnection.java
core/java/com/android/internal/os/ZygoteConnectionConstants.java [new file with mode: 0644]
services/core/java/com/android/server/Watchdog.java

index 1e82054..9fa3239 100644 (file)
@@ -22,6 +22,9 @@ import static android.system.OsConstants.POLLIN;
 import static android.system.OsConstants.STDERR_FILENO;
 import static android.system.OsConstants.STDIN_FILENO;
 import static android.system.OsConstants.STDOUT_FILENO;
+import static com.android.internal.os.ZygoteConnectionConstants.CONNECTION_TIMEOUT_MILLIS;
+import static com.android.internal.os.ZygoteConnectionConstants.MAX_ZYGOTE_ARGC;
+import static com.android.internal.os.ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS;
 
 import android.net.Credentials;
 import android.net.LocalSocket;
@@ -56,18 +59,6 @@ class ZygoteConnection {
     private static final int[][] intArray2d = new int[0][0];
 
     /**
-     * {@link android.net.LocalSocket#setSoTimeout} value for connections.
-     * Effectively, the amount of time a requestor has between the start of
-     * the request and the completed request. The select-loop mode Zygote
-     * doesn't have the logic to return to the select loop in the middle of
-     * a request, so we need to time out here to avoid being denial-of-serviced.
-     */
-    private static final int CONNECTION_TIMEOUT_MILLIS = 1000;
-
-    /** max number of arguments that a connection can specify */
-    private static final int MAX_ZYGOTE_ARGC = 1024;
-
-    /**
      * The command socket.
      *
      * mSocket is retained in the child process in "peer wait" mode, so
@@ -835,10 +826,6 @@ class ZygoteConnection {
             try {
                 // Do a busy loop here. We can't guarantee that a failure (and thus an exception
                 // bail) happens in a timely manner.
-                //
-                // We'll wait up to five seconds. This should give enough time for the fork to go
-                // through, but not to trigger the watchdog in the system server.
-                final int SLEEP_IN_MS = 5000;
                 final int BYTES_REQUIRED = 4;  // Bytes in an int.
 
                 StructPollfd fds[] = new StructPollfd[] {
@@ -847,7 +834,7 @@ class ZygoteConnection {
 
                 byte data[] = new byte[BYTES_REQUIRED];
 
-                int remainingSleepTime = SLEEP_IN_MS;
+                int remainingSleepTime = WRAPPED_PID_TIMEOUT_MILLIS;
                 int dataIndex = 0;
                 long startTime = System.nanoTime();
 
@@ -859,7 +846,8 @@ class ZygoteConnection {
 
                     int res = android.system.Os.poll(fds, remainingSleepTime);
                     long endTime = System.nanoTime();
-                    remainingSleepTime = SLEEP_IN_MS - (int)((endTime - startTime) / 1000000l);
+                    int elapsedTimeMs = (int)((endTime - startTime) / 1000000l);
+                    remainingSleepTime = WRAPPED_PID_TIMEOUT_MILLIS - elapsedTimeMs;
 
                     if (res > 0) {
                         if ((fds[0].revents & POLLIN) != 0) {
diff --git a/core/java/com/android/internal/os/ZygoteConnectionConstants.java b/core/java/com/android/internal/os/ZygoteConnectionConstants.java
new file mode 100644 (file)
index 0000000..506e39f
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+/**
+ * Sharable zygote constants.
+ *
+ * @hide
+ */
+public class ZygoteConnectionConstants {
+    /**
+     * {@link android.net.LocalSocket#setSoTimeout} value for connections.
+     * Effectively, the amount of time a requestor has between the start of
+     * the request and the completed request. The select-loop mode Zygote
+     * doesn't have the logic to return to the select loop in the middle of
+     * a request, so we need to time out here to avoid being denial-of-serviced.
+     */
+    public static final int CONNECTION_TIMEOUT_MILLIS = 1000;
+
+    /** max number of arguments that a connection can specify */
+    public static final int MAX_ZYGOTE_ARGC = 1024;
+
+    /**
+     * Wait time for a wrapped app to report back its pid.
+     *
+     * We'll wait up to thirty seconds. This should give enough time for the fork
+     * to go through, but not to trigger the watchdog in the system server (by default
+     * sixty seconds).
+     *
+     * WARNING: This may trigger the watchdog in debug mode. However, to support
+     *          wrapping on lower-end devices we do not have much choice.
+     */
+    public static final int WRAPPED_PID_TIMEOUT_MILLIS = 30000;
+}
index aceedf1..6a81d32 100644 (file)
@@ -19,6 +19,7 @@ package com.android.server;
 import android.app.IActivityController;
 import android.os.Binder;
 import android.os.RemoteException;
+import com.android.internal.os.ZygoteConnectionConstants;
 import com.android.server.am.ActivityManagerService;
 
 import android.content.BroadcastReceiver;
@@ -57,6 +58,11 @@ public class Watchdog extends Thread {
     // Set this to true to have the watchdog record kernel thread stacks when it fires
     static final boolean RECORD_KERNEL_THREADS = true;
 
+    // Note 1: Do not lower this value below thirty seconds without tightening the invoke-with
+    //         timeout in com.android.internal.os.ZygoteConnection, or wrapped applications
+    //         can trigger the watchdog.
+    // Note 2: The debug value is already below the wait time in ZygoteConnection. Wrapped
+    //         applications may not work with a debug build. CTS will fail.
     static final long DEFAULT_TIMEOUT = DB ? 10*1000 : 60*1000;
     static final long CHECK_INTERVAL = DEFAULT_TIMEOUT / 2;
 
@@ -262,6 +268,10 @@ public class Watchdog extends Thread {
 
         // Initialize monitor for Binder threads.
         addMonitor(new BinderThreadMonitor());
+
+        // See the notes on DEFAULT_TIMEOUT.
+        assert DB ||
+                DEFAULT_TIMEOUT > ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS;
     }
 
     public void init(Context context, ActivityManagerService activity) {