init.c revision f24e252903ca0f71c7fbfb135cf17e83e0c2ea90
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <unistd.h>
21#include <fcntl.h>
22#include <ctype.h>
23#include <signal.h>
24#include <sys/wait.h>
25#include <sys/mount.h>
26#include <sys/stat.h>
27#include <sys/poll.h>
28#include <time.h>
29#include <errno.h>
30#include <stdarg.h>
31#include <mtd/mtd-user.h>
32#include <sys/types.h>
33#include <sys/socket.h>
34#include <sys/un.h>
35#include <sys/reboot.h>
36
37#include <cutils/sockets.h>
38#include <termios.h>
39#include <linux/kd.h>
40#include <linux/keychord.h>
41
42#include <sys/system_properties.h>
43
44#include "devices.h"
45#include "init.h"
46#include "property_service.h"
47#include "bootchart.h"
48
49static int property_triggers_enabled = 0;
50
51#if BOOTCHART
52static int   bootchart_count;
53#endif
54
55static char console[32];
56static char serialno[32];
57static char bootmode[32];
58static char baseband[32];
59static char carrier[32];
60static char bootloader[32];
61static char hardware[32];
62static unsigned revision = 0;
63static char qemu[32];
64static struct input_keychord *keychords = 0;
65static int keychords_count = 0;
66static int keychords_length = 0;
67
68static void drain_action_queue(void);
69
70static void notify_service_state(const char *name, const char *state)
71{
72    char pname[PROP_NAME_MAX];
73    int len = strlen(name);
74    if ((len + 10) > PROP_NAME_MAX)
75        return;
76    snprintf(pname, sizeof(pname), "init.svc.%s", name);
77    property_set(pname, state);
78}
79
80static int have_console;
81static char *console_name = "/dev/console";
82static time_t process_needs_restart;
83
84static const char *ENV[32];
85
86/* add_environment - add "key=value" to the current environment */
87int add_environment(const char *key, const char *val)
88{
89    int n;
90
91    for (n = 0; n < 31; n++) {
92        if (!ENV[n]) {
93            size_t len = strlen(key) + strlen(val) + 2;
94            char *entry = malloc(len);
95            snprintf(entry, len, "%s=%s", key, val);
96            ENV[n] = entry;
97            return 0;
98        }
99    }
100
101    return 1;
102}
103
104static void zap_stdio(void)
105{
106    int fd;
107    fd = open("/dev/null", O_RDWR);
108    dup2(fd, 0);
109    dup2(fd, 1);
110    dup2(fd, 2);
111    close(fd);
112}
113
114static void open_console()
115{
116    int fd;
117    if ((fd = open(console_name, O_RDWR)) < 0) {
118        fd = open("/dev/null", O_RDWR);
119    }
120    dup2(fd, 0);
121    dup2(fd, 1);
122    dup2(fd, 2);
123    close(fd);
124}
125
126/*
127 * gettime() - returns the time in seconds of the system's monotonic clock or
128 * zero on error.
129 */
130static time_t gettime(void)
131{
132    struct timespec ts;
133    int ret;
134
135    ret = clock_gettime(CLOCK_MONOTONIC, &ts);
136    if (ret < 0) {
137        ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno));
138        return 0;
139    }
140
141    return ts.tv_sec;
142}
143
144static void publish_socket(const char *name, int fd)
145{
146    char key[64] = ANDROID_SOCKET_ENV_PREFIX;
147    char val[64];
148
149    strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1,
150            name,
151            sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX));
152    snprintf(val, sizeof(val), "%d", fd);
153    add_environment(key, val);
154
155    /* make sure we don't close-on-exec */
156    fcntl(fd, F_SETFD, 0);
157}
158
159void service_start(struct service *svc, const char *dynamic_args)
160{
161    struct stat s;
162    pid_t pid;
163    int needs_console;
164    int n;
165
166        /* starting a service removes it from the disabled
167         * state and immediately takes it out of the restarting
168         * state if it was in there
169         */
170    svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING));
171    svc->time_started = 0;
172
173        /* running processes require no additional work -- if
174         * they're in the process of exiting, we've ensured
175         * that they will immediately restart on exit, unless
176         * they are ONESHOT
177         */
178    if (svc->flags & SVC_RUNNING) {
179        return;
180    }
181
182    needs_console = (svc->flags & SVC_CONSOLE) ? 1 : 0;
183    if (needs_console && (!have_console)) {
184        ERROR("service '%s' requires console\n", svc->name);
185        svc->flags |= SVC_DISABLED;
186        return;
187    }
188
189    if (stat(svc->args[0], &s) != 0) {
190        ERROR("cannot find '%s', disabling '%s'\n", svc->args[0], svc->name);
191        svc->flags |= SVC_DISABLED;
192        return;
193    }
194
195    if ((!(svc->flags & SVC_ONESHOT)) && dynamic_args) {
196        ERROR("service '%s' must be one-shot to use dynamic args, disabling\n", svc->args[0]);
197        svc->flags |= SVC_DISABLED;
198        return;
199    }
200
201    NOTICE("starting '%s'\n", svc->name);
202
203    pid = fork();
204
205    if (pid == 0) {
206        struct socketinfo *si;
207        struct svcenvinfo *ei;
208        char tmp[32];
209        int fd, sz;
210
211        get_property_workspace(&fd, &sz);
212        sprintf(tmp, "%d,%d", dup(fd), sz);
213        add_environment("ANDROID_PROPERTY_WORKSPACE", tmp);
214
215        for (ei = svc->envvars; ei; ei = ei->next)
216            add_environment(ei->name, ei->value);
217
218        for (si = svc->sockets; si; si = si->next) {
219            int s = create_socket(si->name,
220                                  !strcmp(si->type, "dgram") ?
221                                  SOCK_DGRAM : SOCK_STREAM,
222                                  si->perm, si->uid, si->gid);
223            if (s >= 0) {
224                publish_socket(si->name, s);
225            }
226        }
227
228        if (needs_console) {
229            setsid();
230            open_console();
231        } else {
232            zap_stdio();
233        }
234
235#if 0
236        for (n = 0; svc->args[n]; n++) {
237            INFO("args[%d] = '%s'\n", n, svc->args[n]);
238        }
239        for (n = 0; ENV[n]; n++) {
240            INFO("env[%d] = '%s'\n", n, ENV[n]);
241        }
242#endif
243
244        setpgid(0, getpid());
245
246    /* as requested, set our gid, supplemental gids, and uid */
247        if (svc->gid) {
248            setgid(svc->gid);
249        }
250        if (svc->nr_supp_gids) {
251            setgroups(svc->nr_supp_gids, svc->supp_gids);
252        }
253        if (svc->uid) {
254            setuid(svc->uid);
255        }
256
257        if (!dynamic_args)
258            execve(svc->args[0], (char**) svc->args, (char**) ENV);
259        else {
260            char *arg_ptrs[SVC_MAXARGS+1];
261            int arg_idx;
262            char *tmp = strdup(dynamic_args);
263            char *p = tmp;
264
265            /* Copy the static arguments */
266            for (arg_idx = 0; arg_idx < svc->nargs; arg_idx++) {
267                arg_ptrs[arg_idx] = svc->args[arg_idx];
268            }
269
270            int done = 0;
271            while(!done) {
272
273                if (arg_idx == SVC_MAXARGS)
274                    break;
275
276                /* Advance over any leading whitespace */
277                if (*p == ' ') {
278                    for (p; *p != ' '; p++);
279                    p++;
280                }
281                /* Locate next argument */
282                char *q = p;
283                while(1) {
284                    if (*q == ' ') {
285                        *q = '\0';
286                        break;
287                    } else if (*q == '\0') {
288                        done = 1;
289                        break;
290                    }
291                    q++;
292                }
293                arg_ptrs[arg_idx++] = p;
294
295                q++; // Advance q to the next string
296                p = q;
297            }
298            arg_ptrs[arg_idx] = '\0';
299            execve(svc->args[0], (char**) arg_ptrs, (char**) ENV);
300        }
301        _exit(127);
302    }
303
304    if (pid < 0) {
305        ERROR("failed to start '%s'\n", svc->name);
306        svc->pid = 0;
307        return;
308    }
309
310    svc->time_started = gettime();
311    svc->pid = pid;
312    svc->flags |= SVC_RUNNING;
313
314    notify_service_state(svc->name, "running");
315}
316
317void service_stop(struct service *svc)
318{
319        /* we are no longer running, nor should we
320         * attempt to restart
321         */
322    svc->flags &= (~(SVC_RUNNING|SVC_RESTARTING));
323
324        /* if the service has not yet started, prevent
325         * it from auto-starting with its class
326         */
327    svc->flags |= SVC_DISABLED;
328
329    if (svc->pid) {
330        NOTICE("service '%s' is being killed\n", svc->name);
331        kill(-svc->pid, SIGTERM);
332        notify_service_state(svc->name, "stopping");
333    } else {
334        notify_service_state(svc->name, "stopped");
335    }
336}
337
338void property_changed(const char *name, const char *value)
339{
340    if (property_triggers_enabled) {
341        queue_property_triggers(name, value);
342        drain_action_queue();
343    }
344}
345
346#define CRITICAL_CRASH_THRESHOLD    4       /* if we crash >4 times ... */
347#define CRITICAL_CRASH_WINDOW       (4*60)  /* ... in 4 minutes, goto recovery*/
348
349static int wait_for_one_process(int block)
350{
351    pid_t pid;
352    int status;
353    struct service *svc;
354    struct socketinfo *si;
355    time_t now;
356    struct listnode *node;
357    struct command *cmd;
358
359    while ( (pid = waitpid(-1, &status, block ? 0 : WNOHANG)) == -1 && errno == EINTR );
360    if (pid <= 0) return -1;
361    INFO("waitpid returned pid %d, status = %08x\n", pid, status);
362
363    svc = service_find_by_pid(pid);
364    if (!svc) {
365        ERROR("untracked pid %d exited\n", pid);
366        return 0;
367    }
368
369    NOTICE("process '%s', pid %d exited\n", svc->name, pid);
370
371    if (!(svc->flags & SVC_ONESHOT)) {
372        kill(-pid, SIGKILL);
373        NOTICE("process '%s' killing any children in process group\n", svc->name);
374    }
375
376    /* remove any sockets we may have created */
377    for (si = svc->sockets; si; si = si->next) {
378        char tmp[128];
379        snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s", si->name);
380        unlink(tmp);
381    }
382
383    svc->pid = 0;
384    svc->flags &= (~SVC_RUNNING);
385
386        /* oneshot processes go into the disabled state on exit */
387    if (svc->flags & SVC_ONESHOT) {
388        svc->flags |= SVC_DISABLED;
389    }
390
391        /* disabled processes do not get restarted automatically */
392    if (svc->flags & SVC_DISABLED) {
393        notify_service_state(svc->name, "stopped");
394        return 0;
395    }
396
397    now = gettime();
398    if (svc->flags & SVC_CRITICAL) {
399        if (svc->time_crashed + CRITICAL_CRASH_WINDOW >= now) {
400            if (++svc->nr_crashed > CRITICAL_CRASH_THRESHOLD) {
401                ERROR("critical process '%s' exited %d times in %d minutes; "
402                      "rebooting into recovery mode\n", svc->name,
403                      CRITICAL_CRASH_THRESHOLD, CRITICAL_CRASH_WINDOW / 60);
404                sync();
405                __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
406                         LINUX_REBOOT_CMD_RESTART2, "recovery");
407                return 0;
408            }
409        } else {
410            svc->time_crashed = now;
411            svc->nr_crashed = 1;
412        }
413    }
414
415    /* Execute all onrestart commands for this service. */
416    list_for_each(node, &svc->onrestart.commands) {
417        cmd = node_to_item(node, struct command, clist);
418        cmd->func(cmd->nargs, cmd->args);
419    }
420    svc->flags |= SVC_RESTARTING;
421    notify_service_state(svc->name, "restarting");
422    return 0;
423}
424
425static void restart_service_if_needed(struct service *svc)
426{
427    time_t next_start_time = svc->time_started + 5;
428
429    if (next_start_time <= gettime()) {
430        svc->flags &= (~SVC_RESTARTING);
431        service_start(svc, NULL);
432        return;
433    }
434
435    if ((next_start_time < process_needs_restart) ||
436        (process_needs_restart == 0)) {
437        process_needs_restart = next_start_time;
438    }
439}
440
441static void restart_processes()
442{
443    process_needs_restart = 0;
444    service_for_each_flags(SVC_RESTARTING,
445                           restart_service_if_needed);
446}
447
448static int signal_fd = -1;
449
450static void sigchld_handler(int s)
451{
452    write(signal_fd, &s, 1);
453}
454
455static void msg_start(const char *name)
456{
457    struct service *svc;
458    char *tmp = NULL;
459    char *args = NULL;
460
461    if (!strchr(name, ':'))
462        svc = service_find_by_name(name);
463    else {
464        tmp = strdup(name);
465        strcpy(tmp, name);
466        args = strchr(tmp, ':');
467        *args = '\0';
468        args++;
469
470        svc = service_find_by_name(tmp);
471    }
472
473    if (svc) {
474        service_start(svc, args);
475    } else {
476        ERROR("no such service '%s'\n", name);
477    }
478    if (tmp)
479        free(tmp);
480}
481
482static void msg_stop(const char *name)
483{
484    struct service *svc = service_find_by_name(name);
485
486    if (svc) {
487        service_stop(svc);
488    } else {
489        ERROR("no such service '%s'\n", name);
490    }
491}
492
493void handle_control_message(const char *msg, const char *arg)
494{
495    if (!strcmp(msg,"start")) {
496        msg_start(arg);
497    } else if (!strcmp(msg,"stop")) {
498        msg_stop(arg);
499    } else {
500        ERROR("unknown control msg '%s'\n", msg);
501    }
502}
503
504#define MAX_MTD_PARTITIONS 16
505
506static struct {
507    char name[16];
508    int number;
509} mtd_part_map[MAX_MTD_PARTITIONS];
510
511static int mtd_part_count = -1;
512
513static void find_mtd_partitions(void)
514{
515    int fd;
516    char buf[1024];
517    char *pmtdbufp;
518    ssize_t pmtdsize;
519    int r;
520
521    fd = open("/proc/mtd", O_RDONLY);
522    if (fd < 0)
523        return;
524
525    buf[sizeof(buf) - 1] = '\0';
526    pmtdsize = read(fd, buf, sizeof(buf) - 1);
527    pmtdbufp = buf;
528    while (pmtdsize > 0) {
529        int mtdnum, mtdsize, mtderasesize;
530        char mtdname[16];
531        mtdname[0] = '\0';
532        mtdnum = -1;
533        r = sscanf(pmtdbufp, "mtd%d: %x %x %15s",
534                   &mtdnum, &mtdsize, &mtderasesize, mtdname);
535        if ((r == 4) && (mtdname[0] == '"')) {
536            char *x = strchr(mtdname + 1, '"');
537            if (x) {
538                *x = 0;
539            }
540            INFO("mtd partition %d, %s\n", mtdnum, mtdname + 1);
541            if (mtd_part_count < MAX_MTD_PARTITIONS) {
542                strcpy(mtd_part_map[mtd_part_count].name, mtdname + 1);
543                mtd_part_map[mtd_part_count].number = mtdnum;
544                mtd_part_count++;
545            } else {
546                ERROR("too many mtd partitions\n");
547            }
548        }
549        while (pmtdsize > 0 && *pmtdbufp != '\n') {
550            pmtdbufp++;
551            pmtdsize--;
552        }
553        if (pmtdsize > 0) {
554            pmtdbufp++;
555            pmtdsize--;
556        }
557    }
558    close(fd);
559}
560
561int mtd_name_to_number(const char *name)
562{
563    int n;
564    if (mtd_part_count < 0) {
565        mtd_part_count = 0;
566        find_mtd_partitions();
567    }
568    for (n = 0; n < mtd_part_count; n++) {
569        if (!strcmp(name, mtd_part_map[n].name)) {
570            return mtd_part_map[n].number;
571        }
572    }
573    return -1;
574}
575
576static void import_kernel_nv(char *name, int in_qemu)
577{
578    char *value = strchr(name, '=');
579
580    if (value == 0) return;
581    *value++ = 0;
582    if (*name == 0) return;
583
584    if (!in_qemu)
585    {
586        /* on a real device, white-list the kernel options */
587        if (!strcmp(name,"qemu")) {
588            strlcpy(qemu, value, sizeof(qemu));
589        } else if (!strcmp(name,"androidboot.console")) {
590            strlcpy(console, value, sizeof(console));
591        } else if (!strcmp(name,"androidboot.mode")) {
592            strlcpy(bootmode, value, sizeof(bootmode));
593        } else if (!strcmp(name,"androidboot.serialno")) {
594            strlcpy(serialno, value, sizeof(serialno));
595        } else if (!strcmp(name,"androidboot.baseband")) {
596            strlcpy(baseband, value, sizeof(baseband));
597        } else if (!strcmp(name,"androidboot.carrier")) {
598            strlcpy(carrier, value, sizeof(carrier));
599        } else if (!strcmp(name,"androidboot.bootloader")) {
600            strlcpy(bootloader, value, sizeof(bootloader));
601        } else if (!strcmp(name,"androidboot.hardware")) {
602            strlcpy(hardware, value, sizeof(hardware));
603        } else {
604            qemu_cmdline(name, value);
605        }
606    } else {
607        /* in the emulator, export any kernel option with the
608         * ro.kernel. prefix */
609        char  buff[32];
610        int   len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name );
611        if (len < (int)sizeof(buff)) {
612            property_set( buff, value );
613        }
614    }
615}
616
617static void import_kernel_cmdline(int in_qemu)
618{
619    char cmdline[1024];
620    char *ptr;
621    int fd;
622
623    fd = open("/proc/cmdline", O_RDONLY);
624    if (fd >= 0) {
625        int n = read(fd, cmdline, 1023);
626        if (n < 0) n = 0;
627
628        /* get rid of trailing newline, it happens */
629        if (n > 0 && cmdline[n-1] == '\n') n--;
630
631        cmdline[n] = 0;
632        close(fd);
633    } else {
634        cmdline[0] = 0;
635    }
636
637    ptr = cmdline;
638    while (ptr && *ptr) {
639        char *x = strchr(ptr, ' ');
640        if (x != 0) *x++ = 0;
641        import_kernel_nv(ptr, in_qemu);
642        ptr = x;
643    }
644
645        /* don't expose the raw commandline to nonpriv processes */
646    chmod("/proc/cmdline", 0440);
647}
648
649static void get_hardware_name(void)
650{
651    char data[1024];
652    int fd, n;
653    char *x, *hw, *rev;
654
655    /* Hardware string was provided on kernel command line */
656    if (hardware[0])
657        return;
658
659    fd = open("/proc/cpuinfo", O_RDONLY);
660    if (fd < 0) return;
661
662    n = read(fd, data, 1023);
663    close(fd);
664    if (n < 0) return;
665
666    data[n] = 0;
667    hw = strstr(data, "\nHardware");
668    rev = strstr(data, "\nRevision");
669
670    if (hw) {
671        x = strstr(hw, ": ");
672        if (x) {
673            x += 2;
674            n = 0;
675            while (*x && !isspace(*x)) {
676                hardware[n++] = tolower(*x);
677                x++;
678                if (n == 31) break;
679            }
680            hardware[n] = 0;
681        }
682    }
683
684    if (rev) {
685        x = strstr(rev, ": ");
686        if (x) {
687            revision = strtoul(x + 2, 0, 16);
688        }
689    }
690}
691
692static void drain_action_queue(void)
693{
694    struct listnode *node;
695    struct command *cmd;
696    struct action *act;
697    int ret;
698
699    while ((act = action_remove_queue_head())) {
700        INFO("processing action %p (%s)\n", act, act->name);
701        list_for_each(node, &act->commands) {
702            cmd = node_to_item(node, struct command, clist);
703            ret = cmd->func(cmd->nargs, cmd->args);
704            INFO("command '%s' r=%d\n", cmd->args[0], ret);
705        }
706    }
707}
708
709void open_devnull_stdio(void)
710{
711    int fd;
712    static const char *name = "/dev/__null__";
713    if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) {
714        fd = open(name, O_RDWR);
715        unlink(name);
716        if (fd >= 0) {
717            dup2(fd, 0);
718            dup2(fd, 1);
719            dup2(fd, 2);
720            if (fd > 2) {
721                close(fd);
722            }
723            return;
724        }
725    }
726
727    exit(1);
728}
729
730void add_service_keycodes(struct service *svc)
731{
732    struct input_keychord *keychord;
733    int i, size;
734
735    if (svc->keycodes) {
736        /* add a new keychord to the list */
737        size = sizeof(*keychord) + svc->nkeycodes * sizeof(keychord->keycodes[0]);
738        keychords = realloc(keychords, keychords_length + size);
739        if (!keychords) {
740            ERROR("could not allocate keychords\n");
741            keychords_length = 0;
742            keychords_count = 0;
743            return;
744        }
745
746        keychord = (struct input_keychord *)((char *)keychords + keychords_length);
747        keychord->version = KEYCHORD_VERSION;
748        keychord->id = keychords_count + 1;
749        keychord->count = svc->nkeycodes;
750        svc->keychord_id = keychord->id;
751
752        for (i = 0; i < svc->nkeycodes; i++) {
753            keychord->keycodes[i] = svc->keycodes[i];
754        }
755        keychords_count++;
756        keychords_length += size;
757    }
758}
759
760int open_keychord()
761{
762    int fd, ret;
763
764    service_for_each(add_service_keycodes);
765
766    /* nothing to do if no services require keychords */
767    if (!keychords)
768        return -1;
769
770    fd = open("/dev/keychord", O_RDWR);
771    if (fd < 0) {
772        ERROR("could not open /dev/keychord\n");
773        return fd;
774    }
775    fcntl(fd, F_SETFD, FD_CLOEXEC);
776
777    ret = write(fd, keychords, keychords_length);
778    if (ret != keychords_length) {
779        ERROR("could not configure /dev/keychord %d (%d)\n", ret, errno);
780        close(fd);
781        fd = -1;
782    }
783
784    free(keychords);
785    keychords = 0;
786
787    return fd;
788}
789
790void handle_keychord(int fd)
791{
792    struct service *svc;
793    int ret;
794    __u16 id;
795
796    ret = read(fd, &id, sizeof(id));
797    if (ret != sizeof(id)) {
798        ERROR("could not read keychord id\n");
799        return;
800    }
801
802    svc = service_find_by_keychord(id);
803    if (svc) {
804        INFO("starting service %s from keychord\n", svc->name);
805        service_start(svc, NULL);
806    } else {
807        ERROR("service for keychord %d not found\n", id);
808    }
809}
810
811int main(int argc, char **argv)
812{
813    int device_fd = -1;
814    int property_set_fd = -1;
815    int signal_recv_fd = -1;
816    int keychord_fd = -1;
817    int fd_count;
818    int s[2];
819    int fd;
820    struct sigaction act;
821    char tmp[PROP_VALUE_MAX];
822    struct pollfd ufds[4];
823    char *tmpdev;
824    char* debuggable;
825
826    act.sa_handler = sigchld_handler;
827    act.sa_flags = SA_NOCLDSTOP;
828    act.sa_mask = 0;
829    act.sa_restorer = NULL;
830    sigaction(SIGCHLD, &act, 0);
831
832    /* clear the umask */
833    umask(0);
834
835        /* Get the basic filesystem setup we need put
836         * together in the initramdisk on / and then we'll
837         * let the rc file figure out the rest.
838         */
839    mkdir("/dev", 0755);
840    mkdir("/proc", 0755);
841    mkdir("/sys", 0755);
842
843    mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");
844    mkdir("/dev/pts", 0755);
845    mkdir("/dev/socket", 0755);
846    mount("devpts", "/dev/pts", "devpts", 0, NULL);
847    mount("proc", "/proc", "proc", 0, NULL);
848    mount("sysfs", "/sys", "sysfs", 0, NULL);
849
850        /* We must have some place other than / to create the
851         * device nodes for kmsg and null, otherwise we won't
852         * be able to remount / read-only later on.
853         * Now that tmpfs is mounted on /dev, we can actually
854         * talk to the outside world.
855         */
856    open_devnull_stdio();
857    log_init();
858
859    INFO("reading config file\n");
860    parse_config_file("/init.rc");
861
862    /* pull the kernel commandline and ramdisk properties file in */
863    qemu_init();
864    import_kernel_cmdline(0);
865
866    get_hardware_name();
867    snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
868    parse_config_file(tmp);
869
870    action_for_each_trigger("early-init", action_add_queue_tail);
871    drain_action_queue();
872
873    INFO("device init\n");
874    device_fd = device_init();
875
876    property_init();
877
878    // only listen for keychords if ro.debuggable is true
879    debuggable = property_get("ro.debuggable");
880    if (debuggable && !strcmp(debuggable, "1")) {
881        keychord_fd = open_keychord();
882    }
883
884    if (console[0]) {
885        snprintf(tmp, sizeof(tmp), "/dev/%s", console);
886        console_name = strdup(tmp);
887    }
888
889    fd = open(console_name, O_RDWR);
890    if (fd >= 0)
891        have_console = 1;
892    close(fd);
893
894    if( load_565rle_image(INIT_IMAGE_FILE) ) {
895    fd = open("/dev/tty0", O_WRONLY);
896    if (fd >= 0) {
897        const char *msg;
898            msg = "\n"
899        "\n"
900        "\n"
901        "\n"
902        "\n"
903        "\n"
904        "\n"  // console is 40 cols x 30 lines
905        "\n"
906        "\n"
907        "\n"
908        "\n"
909        "\n"
910        "\n"
911        "\n"
912        "             A N D R O I D ";
913        write(fd, msg, strlen(msg));
914        close(fd);
915    }
916    }
917
918    if (qemu[0])
919        import_kernel_cmdline(1);
920
921    if (!strcmp(bootmode,"factory"))
922        property_set("ro.factorytest", "1");
923    else if (!strcmp(bootmode,"factory2"))
924        property_set("ro.factorytest", "2");
925    else
926        property_set("ro.factorytest", "0");
927
928    property_set("ro.serialno", serialno[0] ? serialno : "");
929    property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown");
930    property_set("ro.baseband", baseband[0] ? baseband : "unknown");
931    property_set("ro.carrier", carrier[0] ? carrier : "unknown");
932    property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown");
933
934    property_set("ro.hardware", hardware);
935    snprintf(tmp, PROP_VALUE_MAX, "%d", revision);
936    property_set("ro.revision", tmp);
937
938        /* execute all the boot actions to get us started */
939    action_for_each_trigger("init", action_add_queue_tail);
940    drain_action_queue();
941
942        /* read any property files on system or data and
943         * fire up the property service.  This must happen
944         * after the ro.foo properties are set above so
945         * that /data/local.prop cannot interfere with them.
946         */
947    property_set_fd = start_property_service();
948
949    /* create a signalling mechanism for the sigchld handler */
950    if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) {
951        signal_fd = s[0];
952        signal_recv_fd = s[1];
953        fcntl(s[0], F_SETFD, FD_CLOEXEC);
954        fcntl(s[0], F_SETFL, O_NONBLOCK);
955        fcntl(s[1], F_SETFD, FD_CLOEXEC);
956        fcntl(s[1], F_SETFL, O_NONBLOCK);
957    }
958
959    /* make sure we actually have all the pieces we need */
960    if ((device_fd < 0) ||
961        (property_set_fd < 0) ||
962        (signal_recv_fd < 0)) {
963        ERROR("init startup failure\n");
964        return 1;
965    }
966
967    /* execute all the boot actions to get us started */
968    action_for_each_trigger("early-boot", action_add_queue_tail);
969    action_for_each_trigger("boot", action_add_queue_tail);
970    drain_action_queue();
971
972        /* run all property triggers based on current state of the properties */
973    queue_all_property_triggers();
974    drain_action_queue();
975
976        /* enable property triggers */
977    property_triggers_enabled = 1;
978
979    ufds[0].fd = device_fd;
980    ufds[0].events = POLLIN;
981    ufds[1].fd = property_set_fd;
982    ufds[1].events = POLLIN;
983    ufds[2].fd = signal_recv_fd;
984    ufds[2].events = POLLIN;
985    fd_count = 3;
986
987    if (keychord_fd > 0) {
988        ufds[3].fd = keychord_fd;
989        ufds[3].events = POLLIN;
990        fd_count++;
991    } else {
992        ufds[3].events = 0;
993        ufds[3].revents = 0;
994    }
995
996#if BOOTCHART
997    bootchart_count = bootchart_init();
998    if (bootchart_count < 0) {
999        ERROR("bootcharting init failure\n");
1000    } else if (bootchart_count > 0) {
1001        NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS);
1002    } else {
1003        NOTICE("bootcharting ignored\n");
1004    }
1005#endif
1006
1007    for(;;) {
1008        int nr, i, timeout = -1;
1009
1010        for (i = 0; i < fd_count; i++)
1011            ufds[i].revents = 0;
1012
1013        drain_action_queue();
1014        restart_processes();
1015
1016        if (process_needs_restart) {
1017            timeout = (process_needs_restart - gettime()) * 1000;
1018            if (timeout < 0)
1019                timeout = 0;
1020        }
1021
1022#if BOOTCHART
1023        if (bootchart_count > 0) {
1024            if (timeout < 0 || timeout > BOOTCHART_POLLING_MS)
1025                timeout = BOOTCHART_POLLING_MS;
1026            if (bootchart_step() < 0 || --bootchart_count == 0) {
1027                bootchart_finish();
1028                bootchart_count = 0;
1029            }
1030        }
1031#endif
1032        nr = poll(ufds, fd_count, timeout);
1033        if (nr <= 0)
1034            continue;
1035
1036        if (ufds[2].revents == POLLIN) {
1037            /* we got a SIGCHLD - reap and restart as needed */
1038            read(signal_recv_fd, tmp, sizeof(tmp));
1039            while (!wait_for_one_process(0))
1040                ;
1041            continue;
1042        }
1043
1044        if (ufds[0].revents == POLLIN)
1045            handle_device_fd(device_fd);
1046
1047        if (ufds[1].revents == POLLIN)
1048            handle_property_set_fd(property_set_fd);
1049        if (ufds[3].revents == POLLIN)
1050            handle_keychord(keychord_fd);
1051    }
1052
1053    return 0;
1054}
1055