Revert "Adjusts the USAP pool refill mechanism."

This reverts commit 0779af6259.

Reason for revert: Breaks cts SignedConfigHostTest

Note: This CL effectively reverts commit:
54b8d7ea4d
"Make the USAP Pool refill delay configurable."

As that builds on top of the original CL being reverted. Only the
ZygoteServer portion of that change is reverted.

Test: atest SignedConfigHostTest
(on an acloud instance)
Bug: 132794985
Change-Id: I1327a22d103452bed46d191ec2bafb72a5e095ca
This commit is contained in:
Mathew Inwood
2019-05-24 14:06:10 +01:00
parent b90ec854e1
commit 154e348896
5 changed files with 160 additions and 296 deletions

View File

@@ -172,11 +172,6 @@ public final class Zygote {
*/ */
public static final int SOCKET_BUFFER_SIZE = 256; public static final int SOCKET_BUFFER_SIZE = 256;
/**
* @hide for internal use only
*/
private static final int PRIORITY_MAX = -20;
/** a prototype instance for a future List.toArray() */ /** a prototype instance for a future List.toArray() */
static final int[][] INT_ARRAY_2D = new int[0][0]; static final int[][] INT_ARRAY_2D = new int[0][0];
@@ -241,7 +236,8 @@ public final class Zygote {
int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir, int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
int targetSdkVersion) { int targetSdkVersion) {
ZygoteHooks.preFork(); ZygoteHooks.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkAndSpecialize( int pid = nativeForkAndSpecialize(
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose, uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
fdsToIgnore, startChildZygote, instructionSet, appDataDir); fdsToIgnore, startChildZygote, instructionSet, appDataDir);
@@ -253,7 +249,6 @@ public final class Zygote {
// Note that this event ends at the end of handleChildProc, // Note that this event ends at the end of handleChildProc,
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork"); Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
} }
ZygoteHooks.postForkCommon(); ZygoteHooks.postForkCommon();
return pid; return pid;
} }
@@ -340,16 +335,15 @@ public final class Zygote {
static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags, static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) { int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
ZygoteHooks.preFork(); ZygoteHooks.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkSystemServer( int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits, uid, gid, gids, runtimeFlags, rlimits,
permittedCapabilities, effectiveCapabilities); permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server. // Enable tracing as soon as we enter the system_server.
if (pid == 0) { if (pid == 0) {
Trace.setTracingEnabled(true, runtimeFlags); Trace.setTracingEnabled(true, runtimeFlags);
} }
ZygoteHooks.postForkCommon(); ZygoteHooks.postForkCommon();
return pid; return pid;
} }
@@ -467,16 +461,13 @@ public final class Zygote {
/** /**
* Fork a new unspecialized app process from the zygote * Fork a new unspecialized app process from the zygote
* *
* @param usapPoolSocket The server socket the USAP will call accept on
* @param sessionSocketRawFDs Anonymous session sockets that are currently open * @param sessionSocketRawFDs Anonymous session sockets that are currently open
* @param isPriorityFork Value controlling the process priority level until accept is called
* @return In the Zygote process this function will always return null; in unspecialized app * @return In the Zygote process this function will always return null; in unspecialized app
* processes this function will return a Runnable object representing the new * processes this function will return a Runnable object representing the new
* application that is passed up from usapMain. * application that is passed up from usapMain.
*/ */
static Runnable forkUsap(LocalServerSocket usapPoolSocket, static Runnable forkUsap(LocalServerSocket usapPoolSocket,
int[] sessionSocketRawFDs, int[] sessionSocketRawFDs) {
boolean isPriorityFork) {
FileDescriptor[] pipeFDs = null; FileDescriptor[] pipeFDs = null;
try { try {
@@ -486,8 +477,7 @@ public final class Zygote {
} }
int pid = int pid =
nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(), nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(), sessionSocketRawFDs);
sessionSocketRawFDs, isPriorityFork);
if (pid == 0) { if (pid == 0) {
IoUtils.closeQuietly(pipeFDs[0]); IoUtils.closeQuietly(pipeFDs[0]);
@@ -502,8 +492,7 @@ public final class Zygote {
private static native int nativeForkUsap(int readPipeFD, private static native int nativeForkUsap(int readPipeFD,
int writePipeFD, int writePipeFD,
int[] sessionSocketRawFDs, int[] sessionSocketRawFDs);
boolean isPriorityFork);
/** /**
* This function is used by unspecialized app processes to wait for specialization requests from * This function is used by unspecialized app processes to wait for specialization requests from
@@ -526,11 +515,6 @@ public final class Zygote {
// Load resources // Load resources
ZygoteInit.nativePreloadGraphicsDriver(); ZygoteInit.nativePreloadGraphicsDriver();
// Change the priority to max before calling accept so we can respond to new specialization
// requests as quickly as possible. This will be reverted to the default priority in the
// native specialization code.
boostUsapPriority();
while (true) { while (true) {
try { try {
sessionSocket = usapPoolSocket.accept(); sessionSocket = usapPoolSocket.accept();
@@ -633,12 +617,6 @@ public final class Zygote {
null /* classLoader */); null /* classLoader */);
} }
private static void boostUsapPriority() {
nativeBoostUsapPriority();
}
private static native void nativeBoostUsapPriority();
static void setAppProcessName(ZygoteArguments args, String loggingTag) { static void setAppProcessName(ZygoteArguments args, String loggingTag) {
if (args.mNiceName != null) { if (args.mNiceName != null) {
Process.setArgV0(args.mNiceName); Process.setArgV0(args.mNiceName);
@@ -894,6 +872,15 @@ public final class Zygote {
ZygoteHooks.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet); ZygoteHooks.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet);
} }
/**
* Resets the calling thread priority to the default value (Thread.NORM_PRIORITY
* or nice value 0). This updates both the priority value in java.lang.Thread and
* the nice value (setpriority).
*/
static void resetNicePriority() {
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
}
/** /**
* Executes "/system/bin/sh -c <command>" using the exec() system call. * Executes "/system/bin/sh -c <command>" using the exec() system call.
* This method throws a runtime exception if exec() failed, otherwise, this * This method throws a runtime exception if exec() failed, otherwise, this

View File

@@ -330,7 +330,7 @@ class ZygoteConnection {
if (zygoteServer.isUsapPoolEnabled()) { if (zygoteServer.isUsapPoolEnabled()) {
Runnable fpResult = Runnable fpResult =
zygoteServer.fillUsapPool( zygoteServer.fillUsapPool(
new int[]{mSocket.getFileDescriptor().getInt$()}, false); new int[]{mSocket.getFileDescriptor().getInt$()});
if (fpResult != null) { if (fpResult != null) {
zygoteServer.setForkChild(); zygoteServer.setForkChild();

View File

@@ -822,9 +822,6 @@ public class ZygoteInit {
public static void main(String argv[]) { public static void main(String argv[]) {
ZygoteServer zygoteServer = null; ZygoteServer zygoteServer = null;
// Set the initial thread priority to the "normal" value.
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
// Mark zygote start. This ensures that thread creation will throw // Mark zygote start. This ensures that thread creation will throw
// an error. // an error.
ZygoteHooks.startZygoteNoThreadCreation(); ZygoteHooks.startZygoteNoThreadCreation();
@@ -884,6 +881,8 @@ public class ZygoteInit {
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis()); SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
} }
// Do an initial gc to clean up after startup // Do an initial gc to clean up after startup

View File

@@ -66,12 +66,6 @@ class ZygoteServer {
/** The default value used for the USAP_POOL_SIZE_MIN device property */ /** The default value used for the USAP_POOL_SIZE_MIN device property */
private static final String USAP_POOL_SIZE_MIN_DEFAULT = "1"; private static final String USAP_POOL_SIZE_MIN_DEFAULT = "1";
/** The default value used for the USAP_REFILL_DELAY_MS device property */
private static final String USAP_POOL_REFILL_DELAY_MS_DEFAULT = "3000";
/** The "not a timestamp" value for the refill delay timestamp mechanism. */
private static final int INVALID_TIMESTAMP = -1;
/** /**
* Indicates if this Zygote server can support a unspecialized app process pool. Currently this * Indicates if this Zygote server can support a unspecialized app process pool. Currently this
* should only be true for the primary and secondary Zygotes, and not the App Zygotes or the * should only be true for the primary and secondary Zygotes, and not the App Zygotes or the
@@ -137,18 +131,6 @@ class ZygoteServer {
*/ */
private int mUsapPoolRefillThreshold = 0; private int mUsapPoolRefillThreshold = 0;
/**
* Number of milliseconds to delay before refilling the pool if it hasn't reached its
* minimum value.
*/
private int mUsapPoolRefillDelayMs = -1;
private enum UsapPoolRefillAction {
DELAYED,
IMMEDIATE,
NONE
}
ZygoteServer() { ZygoteServer() {
mUsapPoolEventFD = null; mUsapPoolEventFD = null;
mZygoteSocket = null; mZygoteSocket = null;
@@ -285,13 +267,6 @@ class ZygoteServer {
mUsapPoolSizeMax); mUsapPoolSizeMax);
} }
final String usapPoolRefillDelayMsPropString = Zygote.getConfigurationProperty(
ZygoteConfig.USAP_POOL_REFILL_DELAY_MS, USAP_POOL_REFILL_DELAY_MS_DEFAULT);
if (!usapPoolRefillDelayMsPropString.isEmpty()) {
mUsapPoolRefillDelayMs = Integer.parseInt(usapPoolRefillDelayMsPropString);
}
// Sanity check // Sanity check
if (mUsapPoolSizeMin >= mUsapPoolSizeMax) { if (mUsapPoolSizeMin >= mUsapPoolSizeMax) {
Log.w(TAG, "The max size of the USAP pool must be greater than the minimum size." Log.w(TAG, "The max size of the USAP pool must be greater than the minimum size."
@@ -318,16 +293,9 @@ class ZygoteServer {
} }
} }
private void fetchUsapPoolPolicyPropsIfUnfetched() {
if (mIsFirstPropertyCheck) {
mIsFirstPropertyCheck = false;
fetchUsapPoolPolicyProps();
}
}
/** /**
* Refill the USAP Pool to the appropriate level, determined by whether this is a priority * Checks to see if the current policy says that pool should be refilled, and spawns new USAPs
* refill event or not. * if necessary.
* *
* @param sessionSocketRawFDs Anonymous session sockets that are currently open * @param sessionSocketRawFDs Anonymous session sockets that are currently open
* @return In the Zygote process this function will always return null; in unspecialized app * @return In the Zygote process this function will always return null; in unspecialized app
@@ -335,36 +303,25 @@ class ZygoteServer {
* application that is passed up from usapMain. * application that is passed up from usapMain.
*/ */
Runnable fillUsapPool(int[] sessionSocketRawFDs, boolean isPriorityRefill) { Runnable fillUsapPool(int[] sessionSocketRawFDs) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Zygote:FillUsapPool"); Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Zygote:FillUsapPool");
// Ensure that the pool properties have been fetched. // Ensure that the pool properties have been fetched.
fetchUsapPoolPolicyPropsIfUnfetched(); fetchUsapPoolPolicyPropsWithMinInterval();
int usapPoolCount = Zygote.getUsapPoolCount(); int usapPoolCount = Zygote.getUsapPoolCount();
int numUsapsToSpawn; int numUsapsToSpawn = mUsapPoolSizeMax - usapPoolCount;
if (isPriorityRefill) { if (usapPoolCount < mUsapPoolSizeMin
// Refill to min || numUsapsToSpawn >= mUsapPoolRefillThreshold) {
numUsapsToSpawn = mUsapPoolSizeMin - usapPoolCount;
Log.i("zygote",
"Priority USAP Pool refill. New USAPs: " + numUsapsToSpawn);
} else {
// Refill up to max
numUsapsToSpawn = mUsapPoolSizeMax - usapPoolCount;
Log.i("zygote",
"Delayed USAP Pool refill. New USAPs: " + numUsapsToSpawn);
}
// Disable some VM functionality and reset some system values // Disable some VM functionality and reset some system values
// before forking. // before forking.
ZygoteHooks.preFork(); ZygoteHooks.preFork();
Zygote.resetNicePriority();
while (--numUsapsToSpawn >= 0) { while (usapPoolCount++ < mUsapPoolSizeMax) {
Runnable caller = Runnable caller = Zygote.forkUsap(mUsapPoolSocket, sessionSocketRawFDs);
Zygote.forkUsap(mUsapPoolSocket, sessionSocketRawFDs, isPriorityRefill);
if (caller != null) { if (caller != null) {
return caller; return caller;
@@ -375,6 +332,10 @@ class ZygoteServer {
// are re-enabled in specializeAppProcess. // are re-enabled in specializeAppProcess.
ZygoteHooks.postForkCommon(); ZygoteHooks.postForkCommon();
Log.i("zygote",
"Filled the USAP pool. New USAPs: " + numUsapsToSpawn);
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return null; return null;
@@ -397,7 +358,7 @@ class ZygoteServer {
mUsapPoolEnabled = newStatus; mUsapPoolEnabled = newStatus;
if (newStatus) { if (newStatus) {
return fillUsapPool(new int[]{ sessionSocket.getFileDescriptor().getInt$() }, false); return fillUsapPool(new int[]{ sessionSocket.getFileDescriptor().getInt$() });
} else { } else {
Zygote.emptyUsapPool(); Zygote.emptyUsapPool();
return null; return null;
@@ -416,8 +377,6 @@ class ZygoteServer {
socketFDs.add(mZygoteSocket.getFileDescriptor()); socketFDs.add(mZygoteSocket.getFileDescriptor());
peers.add(null); peers.add(null);
long usapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
while (true) { while (true) {
fetchUsapPoolPolicyPropsWithMinInterval(); fetchUsapPoolPolicyPropsWithMinInterval();
@@ -471,40 +430,12 @@ class ZygoteServer {
} }
} }
int pollTimeoutMs;
if (usapPoolRefillTriggerTimestamp == INVALID_TIMESTAMP) {
pollTimeoutMs = -1;
} else {
int elapsedTimeMs =
(int) (System.currentTimeMillis() - usapPoolRefillTriggerTimestamp);
if (elapsedTimeMs >= mUsapPoolRefillDelayMs) {
// Normalize the poll timeout value when the time between one poll event and the
// next pushes us over the delay value. This prevents poll receiving a 0
// timeout value, which would result in it returning immediately.
pollTimeoutMs = -1;
} else {
pollTimeoutMs = mUsapPoolRefillDelayMs - elapsedTimeMs;
}
}
int pollReturnValue;
try { try {
pollReturnValue = Os.poll(pollFDs, pollTimeoutMs); Os.poll(pollFDs, -1);
} catch (ErrnoException ex) { } catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex); throw new RuntimeException("poll failed", ex);
} }
UsapPoolRefillAction usapPoolRefillAction = UsapPoolRefillAction.NONE;
if (pollReturnValue == 0) {
// The poll timeout has been exceeded. This only occurs when we have finished the
// USAP pool refill delay period.
usapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
usapPoolRefillAction = UsapPoolRefillAction.DELAYED;
} else {
boolean usapPoolFDRead = false; boolean usapPoolFDRead = false;
while (--pollIndex >= 0) { while (--pollIndex >= 0) {
@@ -528,8 +459,8 @@ class ZygoteServer {
// TODO (chriswailes): Is this extra check necessary? // TODO (chriswailes): Is this extra check necessary?
if (mIsForkChild) { if (mIsForkChild) {
// We're in the child. We should always have a command to run at // We're in the child. We should always have a command to run at this
// this stage if processOneCommand hasn't called "exec". // stage if processOneCommand hasn't called "exec".
if (command == null) { if (command == null) {
throw new IllegalStateException("command == null"); throw new IllegalStateException("command == null");
} }
@@ -543,8 +474,7 @@ class ZygoteServer {
// We don't know whether the remote side of the socket was closed or // We don't know whether the remote side of the socket was closed or
// not until we attempt to read from it from processOneCommand. This // not until we attempt to read from it from processOneCommand. This
// shows up as a regular POLLIN event in our regular processing // shows up as a regular POLLIN event in our regular processing loop.
// loop.
if (connection.isClosedByPeer()) { if (connection.isClosedByPeer()) {
connection.closeSocket(); connection.closeSocket();
peers.remove(pollIndex); peers.remove(pollIndex);
@@ -553,10 +483,10 @@ class ZygoteServer {
} }
} catch (Exception e) { } catch (Exception e) {
if (!mIsForkChild) { if (!mIsForkChild) {
// We're in the server so any exception here is one that has taken // We're in the server so any exception here is one that has taken place
// place pre-fork while processing commands or reading / writing // pre-fork while processing commands or reading / writing from the
// from the control socket. Make a loud noise about any such // control socket. Make a loud noise about any such exceptions so that
// exceptions so that we know exactly what failed and why. // we know exactly what failed and why.
Slog.e(TAG, "Exception executing zygote command: ", e); Slog.e(TAG, "Exception executing zygote command: ", e);
@@ -569,16 +499,15 @@ class ZygoteServer {
socketFDs.remove(pollIndex); socketFDs.remove(pollIndex);
} else { } else {
// We're in the child so any exception caught here has happened post // We're in the child so any exception caught here has happened post
// fork and before we execute ActivityThread.main (or any other // fork and before we execute ActivityThread.main (or any other main()
// main() method). Log the details of the exception and bring down // method). Log the details of the exception and bring down the process.
// the process.
Log.e(TAG, "Caught post-fork exception in child process.", e); Log.e(TAG, "Caught post-fork exception in child process.", e);
throw e; throw e;
} }
} finally { } finally {
// Reset the child flag, in the event that the child process is a child- // Reset the child flag, in the event that the child process is a child-
// zygote. The flag will not be consulted this loop pass after the // zygote. The flag will not be consulted this loop pass after the Runnable
// Runnable is returned. // is returned.
mIsForkChild = false; mIsForkChild = false;
} }
} else { } else {
@@ -586,15 +515,12 @@ class ZygoteServer {
// If this is the event FD the payload will be the number of USAPs removed. // If this is the event FD the payload will be the number of USAPs removed.
// If this is a reporting pipe FD the payload will be the PID of the USAP // If this is a reporting pipe FD the payload will be the PID of the USAP
// that was just specialized. The `continue` statements below ensure that // that was just specialized.
// the messagePayload will always be valid if we complete the try block long messagePayload = -1;
// without an exception.
long messagePayload;
try { try {
byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES]; byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES];
int readBytes = int readBytes = Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length);
Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length);
if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) { if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) {
DataInputStream inputStream = DataInputStream inputStream =
@@ -626,37 +552,18 @@ class ZygoteServer {
} }
} }
// Check to see if the USAP pool needs to be refilled.
if (usapPoolFDRead) { if (usapPoolFDRead) {
int usapPoolCount = Zygote.getUsapPoolCount();
if (usapPoolCount < mUsapPoolSizeMin) {
// Immediate refill
usapPoolRefillAction = UsapPoolRefillAction.IMMEDIATE;
} else if (mUsapPoolSizeMax - usapPoolCount >= mUsapPoolRefillThreshold) {
// Delayed refill
usapPoolRefillTriggerTimestamp = System.currentTimeMillis();
}
}
}
if (usapPoolRefillAction != UsapPoolRefillAction.NONE) {
int[] sessionSocketRawFDs = int[] sessionSocketRawFDs =
socketFDs.subList(1, socketFDs.size()) socketFDs.subList(1, socketFDs.size())
.stream() .stream()
.mapToInt(FileDescriptor::getInt$) .mapToInt(FileDescriptor::getInt$)
.toArray(); .toArray();
final boolean isPriorityRefill = final Runnable command = fillUsapPool(sessionSocketRawFDs);
usapPoolRefillAction == UsapPoolRefillAction.IMMEDIATE;
final Runnable command =
fillUsapPool(sessionSocketRawFDs, isPriorityRefill);
if (command != null) { if (command != null) {
return command; return command;
} else if (isPriorityRefill) {
// Schedule a delayed refill to finish refilling the pool.
usapPoolRefillTriggerTimestamp = System.currentTimeMillis();
} }
} }
} }

View File

@@ -163,15 +163,6 @@ static int gUsapPoolEventFD = -1;
*/ */
static constexpr int USAP_POOL_SIZE_MAX_LIMIT = 100; static constexpr int USAP_POOL_SIZE_MAX_LIMIT = 100;
/** The numeric value for the maximum priority a process may possess. */
static constexpr int PROCESS_PRIORITY_MAX = -20;
/** The numeric value for the minimum priority a process may possess. */
static constexpr int PROCESS_PRIORITY_MIN = 19;
/** The numeric value for the normal priority a process should have. */
static constexpr int PROCESS_PRIORITY_DEFAULT = 0;
/** /**
* A helper class containing accounting information for USAPs. * A helper class containing accounting information for USAPs.
*/ */
@@ -896,8 +887,7 @@ static void ClearUsapTable() {
// Utility routine to fork a process from the zygote. // Utility routine to fork a process from the zygote.
static pid_t ForkCommon(JNIEnv* env, bool is_system_server, static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
const std::vector<int>& fds_to_close, const std::vector<int>& fds_to_close,
const std::vector<int>& fds_to_ignore, const std::vector<int>& fds_to_ignore) {
bool is_priority_fork) {
SetSignalHandlers(); SetSignalHandlers();
// Curry a failure function. // Curry a failure function.
@@ -930,12 +920,6 @@ static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
pid_t pid = fork(); pid_t pid = fork();
if (pid == 0) { if (pid == 0) {
if (is_priority_fork) {
setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
} else {
setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN);
}
// The child process. // The child process.
PreApplicationInit(); PreApplicationInit();
@@ -1133,9 +1117,6 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags, env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
is_system_server, is_child_zygote, managed_instruction_set); is_system_server, is_child_zygote, managed_instruction_set);
// Reset the process priority to the default value.
setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_DEFAULT);
if (env->ExceptionCheck()) { if (env->ExceptionCheck()) {
fail_fn("Error calling post fork hooks."); fail_fn("Error calling post fork hooks.");
} }
@@ -1387,7 +1368,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
fds_to_ignore.push_back(gUsapPoolEventFD); fds_to_ignore.push_back(gUsapPoolEventFD);
} }
pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true); pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore);
if (pid == 0) { if (pid == 0) {
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
@@ -1414,8 +1395,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
pid_t pid = ForkCommon(env, true, pid_t pid = ForkCommon(env, true,
fds_to_close, fds_to_close,
fds_to_ignore, fds_to_ignore);
true);
if (pid == 0) { if (pid == 0) {
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
permitted_capabilities, effective_capabilities, permitted_capabilities, effective_capabilities,
@@ -1457,15 +1437,13 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
* zygote in managed code. * zygote in managed code.
* @param managed_session_socket_fds A list of anonymous session sockets that must be ignored by * @param managed_session_socket_fds A list of anonymous session sockets that must be ignored by
* the FD hygiene code and automatically "closed" in the new USAP. * the FD hygiene code and automatically "closed" in the new USAP.
* @param is_priority_fork Controls the nice level assigned to the newly created process
* @return * @return
*/ */
static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env, static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env,
jclass, jclass,
jint read_pipe_fd, jint read_pipe_fd,
jint write_pipe_fd, jint write_pipe_fd,
jintArray managed_session_socket_fds, jintArray managed_session_socket_fds) {
jboolean is_priority_fork) {
std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()), std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()),
fds_to_ignore(fds_to_close); fds_to_ignore(fds_to_close);
@@ -1487,8 +1465,7 @@ static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env,
fds_to_ignore.push_back(write_pipe_fd); fds_to_ignore.push_back(write_pipe_fd);
fds_to_ignore.insert(fds_to_ignore.end(), session_socket_fds.begin(), session_socket_fds.end()); fds_to_ignore.insert(fds_to_ignore.end(), session_socket_fds.begin(), session_socket_fds.end());
pid_t usap_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore, pid_t usap_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore);
is_priority_fork == JNI_TRUE);
if (usap_pid != 0) { if (usap_pid != 0) {
++gUsapPoolCount; ++gUsapPoolCount;
@@ -1692,10 +1669,6 @@ static jboolean com_android_internal_os_Zygote_nativeDisableExecuteOnly(JNIEnv*
return dl_iterate_phdr(DisableExecuteOnly, nullptr) == 0; return dl_iterate_phdr(DisableExecuteOnly, nullptr) == 0;
} }
static void com_android_internal_os_Zygote_nativeBoostUsapPriority(JNIEnv* env, jclass) {
setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
}
static const JNINativeMethod gMethods[] = { static const JNINativeMethod gMethods[] = {
{ "nativeForkAndSpecialize", { "nativeForkAndSpecialize",
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I",
@@ -1708,7 +1681,7 @@ static const JNINativeMethod gMethods[] = {
(void *) com_android_internal_os_Zygote_nativePreApplicationInit }, (void *) com_android_internal_os_Zygote_nativePreApplicationInit },
{ "nativeInstallSeccompUidGidFilter", "(II)V", { "nativeInstallSeccompUidGidFilter", "(II)V",
(void *) com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter }, (void *) com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter },
{ "nativeForkUsap", "(II[IZ)I", { "nativeForkUsap", "(II[I)I",
(void *) com_android_internal_os_Zygote_nativeForkUsap }, (void *) com_android_internal_os_Zygote_nativeForkUsap },
{ "nativeSpecializeAppProcess", { "nativeSpecializeAppProcess",
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V", "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V",
@@ -1726,9 +1699,7 @@ static const JNINativeMethod gMethods[] = {
{ "nativeEmptyUsapPool", "()V", { "nativeEmptyUsapPool", "()V",
(void *) com_android_internal_os_Zygote_nativeEmptyUsapPool }, (void *) com_android_internal_os_Zygote_nativeEmptyUsapPool },
{ "nativeDisableExecuteOnly", "()Z", { "nativeDisableExecuteOnly", "()Z",
(void *) com_android_internal_os_Zygote_nativeDisableExecuteOnly }, (void *) com_android_internal_os_Zygote_nativeDisableExecuteOnly }
{ "nativeBoostUsapPriority", "()V",
(void* ) com_android_internal_os_Zygote_nativeBoostUsapPriority }
}; };
int register_com_android_internal_os_Zygote(JNIEnv* env) { int register_com_android_internal_os_Zygote(JNIEnv* env) {