1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License. 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage dalvik.system; 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 191662d76b21f3f77ed666f82977f02793569c1302Elliott Hughesimport java.io.File; 20bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Provides access to the Dalvik "zygote" feature, which allows a VM instance to 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be partially initialized and then fork()'d from the partially initialized 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * state. 2504aaaf18dac85eee31b3451226daf586a455feb7Jesse Wilson * 268f273343b7758c09822c74b4f8a0dcf7df3a78b5Jesse Wilson * @hide 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class Zygote { 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Bit values for "debugFlags" argument. The definitions are duplicated 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in the native code. 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** enable debugging over JDWP */ 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int DEBUG_ENABLE_DEBUGGER = 1; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** enable JNI checks */ 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int DEBUG_ENABLE_CHECKJNI = 1 << 1; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** enable Java programming language "assert" statements */ 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int DEBUG_ENABLE_ASSERT = 1 << 2; 3983fb59fbf3e96661cc20d18fcbb9b8c3e96eb7e8Ben Cheng /** disable the JIT compiler */ 4083fb59fbf3e96661cc20d18fcbb9b8c3e96eb7e8Ben Cheng public static final int DEBUG_ENABLE_SAFEMODE = 1 << 3; 417632f95bb9d2e0ba7f71a02ca4c33422a233283bElliott Hughes /** Enable logging of third-party JNI activity. */ 427632f95bb9d2e0ba7f71a02ca4c33422a233283bElliott Hughes public static final int DEBUG_ENABLE_JNI_LOGGING = 1 << 4; 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 441d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey /** No external storage should be mounted. */ 451d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey public static final int MOUNT_EXTERNAL_NONE = 0; 461d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey /** Single-user external storage should be mounted. */ 471d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey public static final int MOUNT_EXTERNAL_SINGLEUSER = 1; 481d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey /** Multi-user external storage should be mounted. */ 491d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey public static final int MOUNT_EXTERNAL_MULTIUSER = 2; 50ee016ac51e9ca82eb9bc92795e61af02f67ae8c8Jeff Sharkey /** All multi-user external storage should be mounted. */ 51ee016ac51e9ca82eb9bc92795e61af02f67ae8c8Jeff Sharkey public static final int MOUNT_EXTERNAL_MULTIUSER_ALL = 3; 521d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey 53b8043536d296263c983051b2d5106df69d8f5658Ben Cheng /** 54b8043536d296263c983051b2d5106df69d8f5658Ben Cheng * When set by the system server, all subsequent apps will be launched in 55b8043536d296263c983051b2d5106df69d8f5658Ben Cheng * VM safe mode. 56b8043536d296263c983051b2d5106df69d8f5658Ben Cheng */ 57b8043536d296263c983051b2d5106df69d8f5658Ben Cheng public static boolean systemInSafeMode = false; 58b8043536d296263c983051b2d5106df69d8f5658Ben Cheng 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Zygote() {} 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 61bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro private static void preFork() { 6264c6c367497c7fcf88e7527022234043e4460758Jesse Wilson Daemons.stop(); 631662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes waitUntilAllThreadsStopped(); 641662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes } 651662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes 661662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes /** 671662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes * We must not fork until we're single-threaded again. Wait until /proc shows we're 681662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes * down to just one thread. 691662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes */ 701662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes private static void waitUntilAllThreadsStopped() { 711662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes File tasks = new File("/proc/self/task"); 721662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes while (tasks.list().length > 1) { 731662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes try { 741662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes // Experimentally, booting and playing about with a stingray, I never saw us 751662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes // go round this loop more than once with a 10ms sleep. 761662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes Thread.sleep(10); 771662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes } catch (InterruptedException ignored) { 781662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes } 791662d76b21f3f77ed666f82977f02793569c1302Elliott Hughes } 80bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro } 81bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro 82bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro private static void postFork() { 8364c6c367497c7fcf88e7527022234043e4460758Jesse Wilson Daemons.start(); 84bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro } 85bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Forks a new Zygote instance, but does not leave the zygote mode. 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The current VM must have been started with the -Xzygote flag. The 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * new child is expected to eventually call forkAndSpecialize() 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return 0 if this is the child, pid of the child 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this is the parent, or -1 on error 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 94bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro public static int fork() { 95bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro preFork(); 96bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro int pid = nativeFork(); 97bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro postFork(); 98bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro return pid; 99bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro } 100bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro 101bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro native public static int nativeFork(); 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Forks a new VM instance. The current VM must have been started 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with the -Xzygote flag. <b>NOTE: new instance keeps all 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * root capabilities. The new process is expected to call capset()</b>. 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param uid the UNIX uid that the new process should setuid() to after 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * fork()ing and and before spawning any threads. 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param gid the UNIX gid that the new process should setgid() to after 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * fork()ing and and before spawning any threads. 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param gids null-ok; a list of UNIX gids that the new process should 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * setgroups() to after fork and before spawning any threads. 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param debugFlags bit flags that enable debugging features. 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param rlimits null-ok an array of rlimit tuples, with the second 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * dimension having a length of 3 and representing 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (resource, rlim_cur, rlim_max). These are set via the posix 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * setrlimit(2) call. 119f0429097a74dc0341bb7e6e4825152fc36b657f0Stephen Smalley * @param seInfo null-ok a string specifying SEAndroid information for 120f0429097a74dc0341bb7e6e4825152fc36b657f0Stephen Smalley * the new process. 121f0429097a74dc0341bb7e6e4825152fc36b657f0Stephen Smalley * @param niceName null-ok a string specifying the process name. 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return 0 if this is the child, pid of the child 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this is the parent, or -1 on error. 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1261d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags, 1271d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey int[][] rlimits, int mountExternal, String seInfo, String niceName) { 128bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro preFork(); 1291d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey int pid = nativeForkAndSpecialize( 1301d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName); 131bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro postFork(); 132bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro return pid; 133bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro } 134bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro 1351d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey native public static int nativeForkAndSpecialize(int uid, int gid, int[] gids, int debugFlags, 1361d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey int[][] rlimits, int mountExternal, String seInfo, String niceName); 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Special method to start the system server process. In addition to the 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * common actions performed in forkAndSpecialize, the pid of the child 141f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * process is recorded such that the death of the child process will cause 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * zygote to exit. 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param uid the UNIX uid that the new process should setuid() to after 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * fork()ing and and before spawning any threads. 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param gid the UNIX gid that the new process should setgid() to after 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * fork()ing and and before spawning any threads. 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param gids null-ok; a list of UNIX gids that the new process should 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * setgroups() to after fork and before spawning any threads. 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param debugFlags bit flags that enable debugging features. 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param rlimits null-ok an array of rlimit tuples, with the second 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * dimension having a length of 3 and representing 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (resource, rlim_cur, rlim_max). These are set via the posix 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * setrlimit(2) call. 15509b06cc1a333f64e9a508bfcc3f0bc6373f96d87Andy McFadden * @param permittedCapabilities argument for setcap() 15609b06cc1a333f64e9a508bfcc3f0bc6373f96d87Andy McFadden * @param effectiveCapabilities argument for setcap() 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return 0 if this is the child, pid of the child 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this is the parent, or -1 on error. 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1611d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags, 1621d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) { 163bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro preFork(); 1641d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey int pid = nativeForkSystemServer( 1651d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities); 166bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro postFork(); 167bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro return pid; 168bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro } 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1701d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey native public static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags, 1711d7a4a8f05b12e365e898a4c7639e285118643b8Jeff Sharkey int[][] rlimits, long permittedCapabilities, long effectiveCapabilities); 1727047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown 1737047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown /** 1747047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown * Executes "/system/bin/sh -c <command>" using the exec() system call. 1757047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown * This method never returns. 1767047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown * 1777047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown * @param command The shell command to execute. 1787047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown */ 1797047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown public static void execShell(String command) { 1807047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown nativeExecShell(command); 1817047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown } 1827047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown 1837047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown /** 1847047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown * Appends quotes shell arguments to the specified string builder. 1857047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown * The arguments are quoted using single-quotes, escaped if necessary, 1867047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown * prefixed with a space, and appended to the command. 1877047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown * 1887047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown * @param command A string builder for the shell command being constructed. 1897047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown * @param args An array of argument strings to be quoted and appended to the command. 1907047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown * @see #execShell(String) 1917047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown */ 1927047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown public static void appendQuotedShellArgs(StringBuilder command, String[] args) { 1937047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown for (String arg : args) { 1947047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown command.append(" '").append(arg.replace("'", "'\\''")).append("'"); 1957047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown } 1967047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown } 1977047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown 1987047a3d4bf12a8eb33156a0abeb900b0ef95263bJeff Brown native private static void nativeExecShell(String command); 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 200