main_runtime.cpp revision 54b6cfa9a9e5b861a9930af873580d6dc20f773c
1//
2// Copyright 2005 The Android Open Source Project
3//
4// Main entry point for runtime.
5//
6
7#include "ServiceManager.h"
8#include "SignalHandler.h"
9
10#include <utils.h>
11#include <utils/IPCThreadState.h>
12#include <utils/ProcessState.h>
13#include <utils/Log.h>
14#include <cutils/zygote.h>
15
16#include <cutils/properties.h>
17
18#include <private/utils/Static.h>
19
20#include <ui/ISurfaceComposer.h>
21
22#include <android_runtime/AndroidRuntime.h>
23
24#include <stdlib.h>
25#include <unistd.h>
26#include <fcntl.h>
27#include <stdio.h>
28#include <string.h>
29#include <getopt.h>
30#include <signal.h>
31#include <errno.h>
32#include <sys/stat.h>
33#include <linux/capability.h>
34#include <linux/ioctl.h>
35#ifdef HAVE_ANDROID_OS
36# include <linux/android_alarm.h>
37#endif
38
39#undef LOG_TAG
40#define LOG_TAG "runtime"
41
42static const char* ZYGOTE_ARGV[] = {
43    "--setuid=1000",
44    "--setgid=1000",
45    "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
46    /* CAP_SYS_TTY_CONFIG & CAP_SYS_RESOURCE & CAP_NET_BROADCAST &
47     * CAP_NET_ADMIN & CAP_NET_RAW & CAP_NET_BIND_SERVICE  & CAP_KILL &
48     * CAP_SYS_BOOT
49     */
50    "--capabilities=88161312,88161312",
51    "--runtime-init",
52    "--nice-name=system_server",
53    "com.android.server.SystemServer"
54};
55
56using namespace android;
57
58extern "C" status_t system_init();
59
60enum {
61    SYSTEM_PROCESS_TAG = DEFAULT_PROCESS_TAG+1
62};
63
64extern Mutex gEventQMutex;
65extern Condition gEventQCondition;
66
67namespace android {
68
69extern status_t app_init(const char* className);
70extern void set_finish_init_func(void (*func)());
71
72
73/**
74 * This class is used to kill this process (runtime) when the system_server dies.
75 */
76class GrimReaper : public IBinder::DeathRecipient {
77public:
78    GrimReaper() { }
79
80    virtual void binderDied(const wp<IBinder>& who)
81    {
82        LOGI("Grim Reaper killing runtime...");
83        kill(getpid(), SIGKILL);
84    }
85};
86
87extern void QuickTests();
88
89/*
90 * Print usage info.
91 */
92static void usage(const char* argv0)
93{
94    fprintf(stderr,
95        "Usage: runtime [-g gamma] [-l logfile] [-n] [-s]\n"
96        "               [-j app-component] [-v app-verb] [-d app-data]\n"
97        "\n"
98        "-l: File to send log messages to\n"
99        "-n: Don't print to stdout/stderr\n"
100        "-s: Force single-process mode\n"
101        "-j: Custom home app component name\n"
102        "-v: Custom home app intent verb\n"
103        "-d: Custom home app intent data\n"
104    );
105    exit(1);
106}
107
108// Selected application to run.
109static const char* gInitialApplication = NULL;
110static const char* gInitialVerb = NULL;
111static const char* gInitialData = NULL;
112
113static void writeStringToParcel(Parcel& parcel, const char* str)
114{
115    if (str) {
116        parcel.writeString16(String16(str));
117    } else {
118        parcel.writeString16(NULL, 0);
119    }
120}
121
122/*
123 * Starting point for program logic.
124 *
125 * Returns with an exit status code (0 on success, nonzero on error).
126 */
127static int run(sp<ProcessState>& proc)
128{
129    // Temporary hack to call startRunning() on the activity manager.
130    sp<IServiceManager> sm = defaultServiceManager();
131    sp<IBinder> am;
132    while ((am = sm->getService(String16("activity"))) == NULL) {
133        LOGI("Waiting for activity manager...");
134    }
135    Parcel data, reply;
136    // XXX Need to also supply a package name for this to work again.
137    // IActivityManager::getInterfaceDescriptor() is the token for invoking on this interface;
138    // hardcoding it here avoids having to link with the full Activity Manager library
139    data.writeInterfaceToken(String16("android.app.IActivityManager"));
140    writeStringToParcel(data, NULL);
141    writeStringToParcel(data, gInitialApplication);
142    writeStringToParcel(data, gInitialVerb);
143    writeStringToParcel(data, gInitialData);
144LOGI("run() sending FIRST_CALL_TRANSACTION to activity manager");
145    am->transact(IBinder::FIRST_CALL_TRANSACTION, data, &reply);
146
147    if (proc->supportsProcesses()) {
148        // Now we link to the Activity Manager waiting for it to die. If it does kill ourself.
149        // initd will restart this process and bring the system back up.
150        sp<GrimReaper> grim = new GrimReaper();
151        am->linkToDeath(grim, grim.get(), 0);
152
153        // Now join the thread pool. Note this is needed so that the message enqueued in the driver
154        // for the linkToDeath gets processed.
155        IPCThreadState::self()->joinThreadPool();
156    } else {
157        // Keep this thread running forever...
158        while (1) {
159            usleep(100000);
160        }
161    }
162    return 1;
163}
164
165
166};  // namespace android
167
168
169/*
170 * Post-system-process initialization.
171 *
172 * This function continues initialization after the system process
173 * has been initialized.  It needs to be separate because the system
174 * initialization needs to care of starting the Android runtime if it is not
175 * running in its own process, which doesn't return until the runtime is
176 * being shut down.  So it will call back to here from inside of Dalvik,
177 * to allow us to continue booting up.
178 */
179static void finish_system_init(sp<ProcessState>& proc)
180{
181    // If we are running multiprocess, we now need to have the
182    // thread pool started here.  We don't do this in boot_init()
183    // because when running single process we need to start the
184    // thread pool after the Android runtime has been started (so
185    // the pool uses Dalvik threads).
186    if (proc->supportsProcesses()) {
187        proc->startThreadPool();
188    }
189}
190
191
192// This function can be used to enforce security to different
193// root contexts.  For now, we just give every access.
194static bool contextChecker(
195    const String16& name, const sp<IBinder>& caller, void* userData)
196{
197    return true;
198}
199
200/*
201 * Initialization of boot services.
202 *
203 * This is where we perform initialization of all of our low-level
204 * boot services.  Most importantly, here we become the context
205 * manager and use that to publish the service manager that will provide
206 * access to all other services.
207 */
208static void boot_init()
209{
210    LOGI("Entered boot_init()!\n");
211
212    sp<ProcessState> proc(ProcessState::self());
213    LOGD("ProcessState: %p\n", proc.get());
214    proc->becomeContextManager(contextChecker, NULL);
215
216    if (proc->supportsProcesses()) {
217        LOGI("Binder driver opened.  Multiprocess enabled.\n");
218    } else {
219        LOGI("Binder driver not found.  Processes not supported.\n");
220    }
221
222    sp<BServiceManager> sm = new BServiceManager;
223    proc->setContextObject(sm);
224}
225
226/*
227 * Redirect stdin/stdout/stderr to /dev/null.
228 */
229static void redirectStdFds(void)
230{
231    int fd = open("/dev/null", O_RDWR, 0);
232    if (fd < 0) {
233        LOGW("Unable to open /dev/null: %s\n", strerror(errno));
234    } else {
235        dup2(fd, 0);
236        dup2(fd, 1);
237        dup2(fd, 2);
238        close(fd);
239    }
240}
241
242static int hasDir(const char* dir)
243{
244    struct stat s;
245    int res = stat(dir, &s);
246    if (res == 0) {
247        return S_ISDIR(s.st_mode);
248    }
249    return 0;
250}
251
252static void validateTime()
253{
254#if HAVE_ANDROID_OS
255    int fd;
256    int res;
257    time_t min_time = 1167652800; // jan 1 2007, type 'date -ud "1/1 12:00" +%s' to get value for current year
258    struct timespec ts;
259
260    fd = open("/dev/alarm", O_RDWR);
261    if(fd < 0) {
262        LOGW("Unable to open alarm driver: %s\n", strerror(errno));
263        return;
264    }
265    res = ioctl(fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_RTC_WAKEUP), &ts);
266    if(res < 0) {
267        LOGW("Unable to read rtc, %s\n", strerror(errno));
268    }
269    else if(ts.tv_sec >= min_time) {
270        goto done;
271    }
272    LOGW("Invalid time detected, %ld set to %ld\n", ts.tv_sec, min_time);
273    ts.tv_sec = min_time;
274    ts.tv_nsec = 0;
275    res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
276    if(res < 0) {
277        LOGW("Unable to set rtc to %ld: %s\n", ts.tv_sec, strerror(errno));
278    }
279done:
280    close(fd);
281#endif
282}
283
284#ifndef HAVE_ANDROID_OS
285class QuickRuntime : public AndroidRuntime
286{
287public:
288    QuickRuntime() {}
289
290    virtual void onStarted()
291    {
292        printf("QuickRuntime: onStarted\n");
293    }
294};
295#endif
296
297static status_t start_process(const char* name);
298
299static void restart_me(pid_t child, void* userData)
300{
301    start_process((const char*)userData);
302}
303
304static status_t start_process(const char* name)
305{
306    String8 path(name);
307    Vector<const char*> args;
308    String8 leaf(path.getPathLeaf());
309    String8 parentDir(path.getPathDir());
310    args.insertAt(leaf.string(), 0);
311    args.add(parentDir.string());
312    args.add(NULL);
313    pid_t child = fork();
314    if (child < 0) {
315        status_t err = errno;
316        LOGE("*** fork of child %s failed: %s", leaf.string(), strerror(err));
317        return -errno;
318    } else if (child == 0) {
319        LOGI("Executing: %s", path.string());
320        execv(path.string(), const_cast<char**>(args.array()));
321        int err = errno;
322        LOGE("Exec failed: %s\n", strerror(err));
323        _exit(err);
324    } else {
325        SignalHandler::setChildHandler(child, DEFAULT_PROCESS_TAG,
326                restart_me, (void*)name);
327    }
328    return -errno;
329}
330
331/*
332 * Application entry point.
333 *
334 * Parse arguments, set some values, and pass control off to Run().
335 *
336 * This is redefined to "SDL_main" on SDL simulator builds, and
337 * "runtime_main" on wxWidgets builds.
338 */
339extern "C"
340int main(int argc, char* const argv[])
341{
342    bool singleProcess = false;
343    const char* logFile = NULL;
344    int ic;
345    int result = 1;
346    pid_t systemPid;
347
348    sp<ProcessState> proc;
349
350#ifndef HAVE_ANDROID_OS
351    /* Set stdout/stderr to unbuffered for MinGW/MSYS. */
352    //setvbuf(stdout, NULL, _IONBF, 0);
353    //setvbuf(stderr, NULL, _IONBF, 0);
354
355    LOGI("commandline args:\n");
356    for (int i = 0; i < argc; i++)
357        LOGI("  %2d: '%s'\n", i, argv[i]);
358#endif
359
360    while (1) {
361        ic = getopt(argc, argv, "g:j:v:d:l:ns");
362        if (ic < 0)
363            break;
364
365        switch (ic) {
366        case 'g':
367            break;
368        case 'j':
369            gInitialApplication = optarg;
370            break;
371        case 'v':
372            gInitialVerb = optarg;
373            break;
374        case 'd':
375            gInitialData = optarg;
376            break;
377        case 'l':
378            logFile = optarg;
379            break;
380        case 'n':
381            redirectStdFds();
382            break;
383        case 's':
384            singleProcess = true;
385            break;
386        case '?':
387        default:
388            LOGE("runtime: unrecognized flag -%c\n", ic);
389            usage(argv[0]);
390            break;
391        }
392    }
393    if (optind < argc) {
394        LOGE("runtime: extra stuff: %s\n", argv[optind]);
395        usage(argv[0]);
396    }
397
398    if (singleProcess) {
399        ProcessState::setSingleProcess(true);
400    }
401
402    if (logFile != NULL) {
403        android_logToFile(NULL, logFile);
404    }
405
406    /*
407     * Set up ANDROID_* environment variables.
408     *
409     * TODO: the use of $ANDROID_PRODUCT_OUT will go away soon.
410     */
411    static const char* kSystemDir = "/system";
412    static const char* kDataDir = "/data";
413    static const char* kAppSubdir = "/app";
414    const char* out = NULL;
415#ifndef HAVE_ANDROID_OS
416    //out = getenv("ANDROID_PRODUCT_OUT");
417#endif
418    if (out == NULL)
419        out = "";
420
421    char* systemDir = (char*) malloc(strlen(out) + strlen(kSystemDir) +1);
422    char* dataDir = (char*) malloc(strlen(out) + strlen(kDataDir) +1);
423
424    sprintf(systemDir, "%s%s", out, kSystemDir);
425    sprintf(dataDir, "%s%s", out, kDataDir);
426    setenv("ANDROID_ROOT", systemDir, 1);
427    setenv("ANDROID_DATA", dataDir, 1);
428
429    char* assetDir = (char*) malloc(strlen(systemDir) + strlen(kAppSubdir) +1);
430    sprintf(assetDir, "%s%s", systemDir, kAppSubdir);
431
432    LOGI("Startup: sys='%s' asset='%s' data='%s'\n",
433        systemDir, assetDir, dataDir);
434    free(systemDir);
435    free(dataDir);
436
437#ifdef HAVE_ANDROID_OS
438    /* set up a process group for easier killing on the device */
439    setpgid(0, getpid());
440#endif
441
442    // Change to asset dir.  This is only necessary if we've changed to
443    // a different directory, but there's little harm in doing it regardless.
444    //
445    // Expecting assets to live in the current dir is not a great idea,
446    // because some of our code or one of our libraries could change the
447    // directory out from under us.  Preserve the behavior for now.
448    if (chdir(assetDir) != 0) {
449        LOGW("WARNING: could not change dir to '%s': %s\n",
450             assetDir, strerror(errno));
451    }
452    free(assetDir);
453
454#if 0
455    // Hack to keep libc from beating the filesystem to death.  It's
456    // hitting /etc/localtime frequently,
457    //
458    // This statement locks us into Pacific time.  We could do better,
459    // but there's not much point until we're sure that the library
460    // can't be changed to do more along the lines of what we want.
461#ifndef XP_WIN
462    setenv("TZ", "PST+8PDT,M4.1.0/2,M10.5.0/2", true);
463#endif
464#endif
465
466    /* track our progress through the boot sequence */
467    const int LOG_BOOT_PROGRESS_START = 3000;
468    LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
469        ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
470
471    validateTime();
472
473    proc = ProcessState::self();
474
475    boot_init();
476
477    /* If we are in multiprocess mode, have zygote spawn the system
478     * server process and call system_init(). If we are running in
479     * single process mode just call system_init() directly.
480     */
481    if (proc->supportsProcesses()) {
482        // If stdio logging is on, system_server should not inherit our stdio
483        // The dalvikvm instance will copy stdio to the log on its own
484        char propBuf[PROPERTY_VALUE_MAX];
485        bool logStdio = false;
486        property_get("log.redirect-stdio", propBuf, "");
487        logStdio = (strcmp(propBuf, "true") == 0);
488
489        zygote_run_oneshot((int)(!logStdio),
490                sizeof(ZYGOTE_ARGV) / sizeof(ZYGOTE_ARGV[0]),
491                ZYGOTE_ARGV);
492
493        //start_process("/system/bin/mediaserver");
494
495    } else {
496#ifndef HAVE_ANDROID_OS
497        QuickRuntime* runt = new QuickRuntime();
498        runt->start("com/android/server/SystemServer",
499                    false /* spontaneously fork system server from zygote */);
500#endif
501    }
502
503    //printf("+++ post-zygote\n");
504
505    finish_system_init(proc);
506    run(proc);
507
508bail:
509    if (proc != NULL) {
510        proc->setContextObject(NULL);
511    }
512
513    return 0;
514}
515