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 &lt;command&gt;" 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