init.c revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
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)
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    NOTICE("starting '%s'\n", svc->name);
196
197    pid = fork();
198
199    if (pid == 0) {
200        struct socketinfo *si;
201        struct svcenvinfo *ei;
202        char tmp[32];
203        int fd, sz;
204
205        get_property_workspace(&fd, &sz);
206        sprintf(tmp, "%d,%d", dup(fd), sz);
207        add_environment("ANDROID_PROPERTY_WORKSPACE", tmp);
208
209        for (ei = svc->envvars; ei; ei = ei->next)
210            add_environment(ei->name, ei->value);
211
212        for (si = svc->sockets; si; si = si->next) {
213            int s = create_socket(si->name,
214                                  !strcmp(si->type, "dgram") ?
215                                  SOCK_DGRAM : SOCK_STREAM,
216                                  si->perm, si->uid, si->gid);
217            if (s >= 0) {
218                publish_socket(si->name, s);
219            }
220        }
221
222        if (needs_console) {
223            setsid();
224            open_console();
225        } else {
226            zap_stdio();
227        }
228
229#if 0
230        for (n = 0; svc->args[n]; n++) {
231            INFO("args[%d] = '%s'\n", n, svc->args[n]);
232        }
233        for (n = 0; ENV[n]; n++) {
234            INFO("env[%d] = '%s'\n", n, ENV[n]);
235        }
236#endif
237
238        setpgid(0, getpid());
239
240    /* as requested, set our gid, supplemental gids, and uid */
241        if (svc->gid) {
242            setgid(svc->gid);
243        }
244        if (svc->nr_supp_gids) {
245            setgroups(svc->nr_supp_gids, svc->supp_gids);
246        }
247        if (svc->uid) {
248            setuid(svc->uid);
249        }
250
251        execve(svc->args[0], (char**) svc->args, (char**) ENV);
252        _exit(127);
253    }
254
255    if (pid < 0) {
256        ERROR("failed to start '%s'\n", svc->name);
257        svc->pid = 0;
258        return;
259    }
260
261    svc->time_started = gettime();
262    svc->pid = pid;
263    svc->flags |= SVC_RUNNING;
264
265    notify_service_state(svc->name, "running");
266}
267
268void service_stop(struct service *svc)
269{
270        /* we are no longer running, nor should we
271         * attempt to restart
272         */
273    svc->flags &= (~(SVC_RUNNING|SVC_RESTARTING));
274
275        /* if the service has not yet started, prevent
276         * it from auto-starting with its class
277         */
278    svc->flags |= SVC_DISABLED;
279
280    if (svc->pid) {
281        NOTICE("service '%s' is being killed\n", svc->name);
282        kill(-svc->pid, SIGTERM);
283        notify_service_state(svc->name, "stopping");
284    } else {
285        notify_service_state(svc->name, "stopped");
286    }
287}
288
289void property_changed(const char *name, const char *value)
290{
291    if (property_triggers_enabled) {
292        queue_property_triggers(name, value);
293        drain_action_queue();
294    }
295}
296
297#define CRITICAL_CRASH_THRESHOLD    4       /* if we crash >4 times ... */
298#define CRITICAL_CRASH_WINDOW       (4*60)  /* ... in 4 minutes, goto recovery*/
299
300static int wait_for_one_process(int block)
301{
302    pid_t pid;
303    int status;
304    struct service *svc;
305    struct socketinfo *si;
306    time_t now;
307    struct listnode *node;
308    struct command *cmd;
309
310    while ( (pid = waitpid(-1, &status, block ? 0 : WNOHANG)) == -1 && errno == EINTR );
311    if (pid <= 0) return -1;
312    INFO("waitpid returned pid %d, status = %08x\n", pid, status);
313
314    svc = service_find_by_pid(pid);
315    if (!svc) {
316        ERROR("untracked pid %d exited\n", pid);
317        return 0;
318    }
319
320    NOTICE("process '%s', pid %d exited\n", svc->name, pid);
321
322    if (!(svc->flags & SVC_ONESHOT)) {
323        kill(-pid, SIGKILL);
324        NOTICE("process '%s' killing any children in process group\n", svc->name);
325    }
326
327    /* remove any sockets we may have created */
328    for (si = svc->sockets; si; si = si->next) {
329        char tmp[128];
330        snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s", si->name);
331        unlink(tmp);
332    }
333
334    svc->pid = 0;
335    svc->flags &= (~SVC_RUNNING);
336
337        /* oneshot processes go into the disabled state on exit */
338    if (svc->flags & SVC_ONESHOT) {
339        svc->flags |= SVC_DISABLED;
340    }
341
342        /* disabled processes do not get restarted automatically */
343    if (svc->flags & SVC_DISABLED) {
344        notify_service_state(svc->name, "stopped");
345        return 0;
346    }
347
348    now = gettime();
349    if (svc->flags & SVC_CRITICAL) {
350        if (svc->time_crashed + CRITICAL_CRASH_WINDOW >= now) {
351            if (++svc->nr_crashed > CRITICAL_CRASH_THRESHOLD) {
352                ERROR("critical process '%s' exited %d times in %d minutes; "
353                      "rebooting into recovery mode\n", svc->name,
354                      CRITICAL_CRASH_THRESHOLD, CRITICAL_CRASH_WINDOW / 60);
355                sync();
356                __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
357                         LINUX_REBOOT_CMD_RESTART2, "recovery");
358                return 0;
359            }
360        } else {
361            svc->time_crashed = now;
362            svc->nr_crashed = 1;
363        }
364    }
365
366    /* Execute all onrestart commands for this service. */
367    list_for_each(node, &svc->onrestart.commands) {
368        cmd = node_to_item(node, struct command, clist);
369        cmd->func(cmd->nargs, cmd->args);
370    }
371    svc->flags |= SVC_RESTARTING;
372    notify_service_state(svc->name, "restarting");
373    return 0;
374}
375
376static void restart_service_if_needed(struct service *svc)
377{
378    time_t next_start_time = svc->time_started + 5;
379
380    if (next_start_time <= gettime()) {
381        svc->flags &= (~SVC_RESTARTING);
382        service_start(svc);
383        return;
384    }
385
386    if ((next_start_time < process_needs_restart) ||
387        (process_needs_restart == 0)) {
388        process_needs_restart = next_start_time;
389    }
390}
391
392static void restart_processes()
393{
394    process_needs_restart = 0;
395    service_for_each_flags(SVC_RESTARTING,
396                           restart_service_if_needed);
397}
398
399static int signal_fd = -1;
400
401static void sigchld_handler(int s)
402{
403    write(signal_fd, &s, 1);
404}
405
406static void msg_start(const char *name)
407{
408    struct service *svc = service_find_by_name(name);
409
410    if (svc) {
411        service_start(svc);
412    } else {
413        ERROR("no such service '%s'\n", name);
414    }
415}
416
417static void msg_stop(const char *name)
418{
419    struct service *svc = service_find_by_name(name);
420
421    if (svc) {
422        service_stop(svc);
423    } else {
424        ERROR("no such service '%s'\n");
425    }
426}
427
428void handle_control_message(const char *msg, const char *arg)
429{
430    if (!strcmp(msg,"start")) {
431        msg_start(arg);
432    } else if (!strcmp(msg,"stop")) {
433        msg_stop(arg);
434    } else {
435        ERROR("unknown control msg '%s'\n", msg);
436    }
437}
438
439#define MAX_MTD_PARTITIONS 16
440
441static struct {
442    char name[16];
443    int number;
444} mtd_part_map[MAX_MTD_PARTITIONS];
445
446static int mtd_part_count = -1;
447
448static void find_mtd_partitions(void)
449{
450    int fd;
451    char buf[1024];
452    char *pmtdbufp;
453    ssize_t pmtdsize;
454    int r;
455
456    fd = open("/proc/mtd", O_RDONLY);
457    if (fd < 0)
458        return;
459
460    buf[sizeof(buf) - 1] = '\0';
461    pmtdsize = read(fd, buf, sizeof(buf) - 1);
462    pmtdbufp = buf;
463    while (pmtdsize > 0) {
464        int mtdnum, mtdsize, mtderasesize;
465        char mtdname[16];
466        mtdname[0] = '\0';
467        mtdnum = -1;
468        r = sscanf(pmtdbufp, "mtd%d: %x %x %15s",
469                   &mtdnum, &mtdsize, &mtderasesize, mtdname);
470        if ((r == 4) && (mtdname[0] == '"')) {
471            char *x = strchr(mtdname + 1, '"');
472            if (x) {
473                *x = 0;
474            }
475            INFO("mtd partition %d, %s\n", mtdnum, mtdname + 1);
476            if (mtd_part_count < MAX_MTD_PARTITIONS) {
477                strcpy(mtd_part_map[mtd_part_count].name, mtdname + 1);
478                mtd_part_map[mtd_part_count].number = mtdnum;
479                mtd_part_count++;
480            } else {
481                ERROR("too many mtd partitions\n");
482            }
483        }
484        while (pmtdsize > 0 && *pmtdbufp != '\n') {
485            pmtdbufp++;
486            pmtdsize--;
487        }
488        if (pmtdsize > 0) {
489            pmtdbufp++;
490            pmtdsize--;
491        }
492    }
493    close(fd);
494}
495
496int mtd_name_to_number(const char *name)
497{
498    int n;
499    if (mtd_part_count < 0) {
500        mtd_part_count = 0;
501        find_mtd_partitions();
502    }
503    for (n = 0; n < mtd_part_count; n++) {
504        if (!strcmp(name, mtd_part_map[n].name)) {
505            return mtd_part_map[n].number;
506        }
507    }
508    return -1;
509}
510
511static void import_kernel_nv(char *name, int in_qemu)
512{
513    char *value = strchr(name, '=');
514
515    if (value == 0) return;
516    *value++ = 0;
517    if (*name == 0) return;
518
519    if (!in_qemu)
520    {
521        /* on a real device, white-list the kernel options */
522        if (!strcmp(name,"qemu")) {
523            strlcpy(qemu, value, sizeof(qemu));
524        } else if (!strcmp(name,"androidboot.console")) {
525            strlcpy(console, value, sizeof(console));
526        } else if (!strcmp(name,"androidboot.mode")) {
527            strlcpy(bootmode, value, sizeof(bootmode));
528        } else if (!strcmp(name,"androidboot.serialno")) {
529            strlcpy(serialno, value, sizeof(serialno));
530        } else if (!strcmp(name,"androidboot.baseband")) {
531            strlcpy(baseband, value, sizeof(baseband));
532        } else if (!strcmp(name,"androidboot.carrier")) {
533            strlcpy(carrier, value, sizeof(carrier));
534        } else if (!strcmp(name,"androidboot.bootloader")) {
535            strlcpy(bootloader, value, sizeof(bootloader));
536        } else if (!strcmp(name,"androidboot.hardware")) {
537            strlcpy(hardware, value, sizeof(hardware));
538        } else {
539            qemu_cmdline(name, value);
540        }
541    } else {
542        /* in the emulator, export any kernel option with the
543         * ro.kernel. prefix */
544        char  buff[32];
545        int   len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name );
546        if (len < (int)sizeof(buff)) {
547            property_set( buff, value );
548        }
549    }
550}
551
552static void import_kernel_cmdline(int in_qemu)
553{
554    char cmdline[1024];
555    char *ptr;
556    int fd;
557
558    fd = open("/proc/cmdline", O_RDONLY);
559    if (fd >= 0) {
560        int n = read(fd, cmdline, 1023);
561        if (n < 0) n = 0;
562
563        /* get rid of trailing newline, it happens */
564        if (n > 0 && cmdline[n-1] == '\n') n--;
565
566        cmdline[n] = 0;
567        close(fd);
568    } else {
569        cmdline[0] = 0;
570    }
571
572    ptr = cmdline;
573    while (ptr && *ptr) {
574        char *x = strchr(ptr, ' ');
575        if (x != 0) *x++ = 0;
576        import_kernel_nv(ptr, in_qemu);
577        ptr = x;
578    }
579
580        /* don't expose the raw commandline to nonpriv processes */
581    chmod("/proc/cmdline", 0440);
582}
583
584static void get_hardware_name(void)
585{
586    char data[1024];
587    int fd, n;
588    char *x, *hw, *rev;
589
590    /* Hardware string was provided on kernel command line */
591    if (hardware[0])
592        return;
593
594    fd = open("/proc/cpuinfo", O_RDONLY);
595    if (fd < 0) return;
596
597    n = read(fd, data, 1023);
598    close(fd);
599    if (n < 0) return;
600
601    data[n] = 0;
602    hw = strstr(data, "\nHardware");
603    rev = strstr(data, "\nRevision");
604
605    if (hw) {
606        x = strstr(hw, ": ");
607        if (x) {
608            x += 2;
609            n = 0;
610            while (*x && !isspace(*x)) {
611                hardware[n++] = tolower(*x);
612                x++;
613                if (n == 31) break;
614            }
615            hardware[n] = 0;
616        }
617    }
618
619    if (rev) {
620        x = strstr(rev, ": ");
621        if (x) {
622            revision = strtoul(x + 2, 0, 16);
623        }
624    }
625}
626
627static void drain_action_queue(void)
628{
629    struct listnode *node;
630    struct command *cmd;
631    struct action *act;
632    int ret;
633
634    while ((act = action_remove_queue_head())) {
635        INFO("processing action %p (%s)\n", act, act->name);
636        list_for_each(node, &act->commands) {
637            cmd = node_to_item(node, struct command, clist);
638            ret = cmd->func(cmd->nargs, cmd->args);
639            INFO("command '%s' r=%d\n", cmd->args[0], ret);
640        }
641    }
642}
643
644void open_devnull_stdio(void)
645{
646    int fd;
647    static const char *name = "/dev/__null__";
648    if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) {
649        fd = open(name, O_RDWR);
650        unlink(name);
651        if (fd >= 0) {
652            dup2(fd, 0);
653            dup2(fd, 1);
654            dup2(fd, 2);
655            if (fd > 2) {
656                close(fd);
657            }
658            return;
659        }
660    }
661
662    exit(1);
663}
664
665void add_service_keycodes(struct service *svc)
666{
667    struct input_keychord *keychord;
668    int i, size;
669
670    if (svc->keycodes) {
671        /* add a new keychord to the list */
672        size = sizeof(*keychord) + svc->nkeycodes * sizeof(keychord->keycodes[0]);
673        keychords = realloc(keychords, keychords_length + size);
674        if (!keychords) {
675            ERROR("could not allocate keychords\n");
676            keychords_length = 0;
677            keychords_count = 0;
678            return;
679        }
680
681        keychord = (struct input_keychord *)((char *)keychords + keychords_length);
682        keychord->version = KEYCHORD_VERSION;
683        keychord->id = keychords_count + 1;
684        keychord->count = svc->nkeycodes;
685        svc->keychord_id = keychord->id;
686
687        for (i = 0; i < svc->nkeycodes; i++) {
688            keychord->keycodes[i] = svc->keycodes[i];
689        }
690        keychords_count++;
691        keychords_length += size;
692    }
693}
694
695int open_keychord()
696{
697    int fd, ret;
698
699    service_for_each(add_service_keycodes);
700
701    /* nothing to do if no services require keychords */
702    if (!keychords)
703        return -1;
704
705    fd = open("/dev/keychord", O_RDWR);
706    if (fd < 0) {
707        ERROR("could not open /dev/keychord\n");
708        return fd;
709    }
710    fcntl(fd, F_SETFD, FD_CLOEXEC);
711
712    ret = write(fd, keychords, keychords_length);
713    if (ret != keychords_length) {
714        ERROR("could not configure /dev/keychord %d (%d)\n", ret, errno);
715        close(fd);
716        fd = -1;
717    }
718
719    free(keychords);
720    keychords = 0;
721
722    return fd;
723}
724
725void handle_keychord(int fd)
726{
727    struct service *svc;
728    int ret;
729    __u16 id;
730
731    ret = read(fd, &id, sizeof(id));
732    if (ret != sizeof(id)) {
733        ERROR("could not read keychord id\n");
734        return;
735    }
736
737    svc = service_find_by_keychord(id);
738    if (svc) {
739        INFO("starting service %s from keychord\n", svc->name);
740        service_start(svc);
741    } else {
742        ERROR("service for keychord %d not found\n", id);
743    }
744}
745
746int main(int argc, char **argv)
747{
748    int device_fd = -1;
749    int property_set_fd = -1;
750    int signal_recv_fd = -1;
751    int keychord_fd = -1;
752    int fd_count;
753    int s[2];
754    int fd;
755    struct sigaction act;
756    char tmp[PROP_VALUE_MAX];
757    struct pollfd ufds[4];
758    char *tmpdev;
759    char* debuggable;
760
761    act.sa_handler = sigchld_handler;
762    act.sa_flags = SA_NOCLDSTOP;
763    act.sa_mask = 0;
764    act.sa_restorer = NULL;
765    sigaction(SIGCHLD, &act, 0);
766
767    /* clear the umask */
768    umask(0);
769
770        /* Get the basic filesystem setup we need put
771         * together in the initramdisk on / and then we'll
772         * let the rc file figure out the rest.
773         */
774    mkdir("/dev", 0755);
775    mkdir("/proc", 0755);
776    mkdir("/sys", 0755);
777
778    mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");
779    mkdir("/dev/pts", 0755);
780    mkdir("/dev/socket", 0755);
781    mount("devpts", "/dev/pts", "devpts", 0, NULL);
782    mount("proc", "/proc", "proc", 0, NULL);
783    mount("sysfs", "/sys", "sysfs", 0, NULL);
784
785        /* We must have some place other than / to create the
786         * device nodes for kmsg and null, otherwise we won't
787         * be able to remount / read-only later on.
788         * Now that tmpfs is mounted on /dev, we can actually
789         * talk to the outside world.
790         */
791    open_devnull_stdio();
792    log_init();
793
794    INFO("reading config file\n");
795    parse_config_file("/init.rc");
796
797    /* pull the kernel commandline and ramdisk properties file in */
798    qemu_init();
799    import_kernel_cmdline(0);
800
801    get_hardware_name();
802    snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
803    parse_config_file(tmp);
804
805    action_for_each_trigger("early-init", action_add_queue_tail);
806    drain_action_queue();
807
808    INFO("device init\n");
809    device_fd = device_init();
810
811    property_init();
812
813    // only listen for keychords if ro.debuggable is true
814    debuggable = property_get("ro.debuggable");
815    if (debuggable && !strcmp(debuggable, "1")) {
816        keychord_fd = open_keychord();
817    }
818
819    if (console[0]) {
820        snprintf(tmp, sizeof(tmp), "/dev/%s", console);
821        console_name = strdup(tmp);
822    }
823
824    fd = open(console_name, O_RDWR);
825    if (fd >= 0)
826        have_console = 1;
827    close(fd);
828
829    if( load_565rle_image(INIT_IMAGE_FILE) ) {
830    fd = open("/dev/tty0", O_WRONLY);
831    if (fd >= 0) {
832        const char *msg;
833            msg = "\n"
834        "\n"
835        "\n"
836        "\n"
837        "\n"
838        "\n"
839        "\n"  // console is 40 cols x 30 lines
840        "\n"
841        "\n"
842        "\n"
843        "\n"
844        "\n"
845        "\n"
846        "\n"
847        "             A N D R O I D ";
848        write(fd, msg, strlen(msg));
849        close(fd);
850    }
851    }
852
853    if (qemu[0])
854        import_kernel_cmdline(1);
855
856    if (!strcmp(bootmode,"factory"))
857        property_set("ro.factorytest", "1");
858    else if (!strcmp(bootmode,"factory2"))
859        property_set("ro.factorytest", "2");
860    else
861        property_set("ro.factorytest", "0");
862
863    property_set("ro.serialno", serialno[0] ? serialno : "");
864    property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown");
865    property_set("ro.baseband", baseband[0] ? baseband : "unknown");
866    property_set("ro.carrier", carrier[0] ? carrier : "unknown");
867    property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown");
868
869    property_set("ro.hardware", hardware);
870    snprintf(tmp, PROP_VALUE_MAX, "%d", revision);
871    property_set("ro.revision", tmp);
872
873        /* execute all the boot actions to get us started */
874    action_for_each_trigger("init", action_add_queue_tail);
875    drain_action_queue();
876
877        /* read any property files on system or data and
878         * fire up the property service.  This must happen
879         * after the ro.foo properties are set above so
880         * that /data/local.prop cannot interfere with them.
881         */
882    property_set_fd = start_property_service();
883
884    /* create a signalling mechanism for the sigchld handler */
885    if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) {
886        signal_fd = s[0];
887        signal_recv_fd = s[1];
888        fcntl(s[0], F_SETFD, FD_CLOEXEC);
889        fcntl(s[0], F_SETFL, O_NONBLOCK);
890        fcntl(s[1], F_SETFD, FD_CLOEXEC);
891        fcntl(s[1], F_SETFL, O_NONBLOCK);
892    }
893
894    /* make sure we actually have all the pieces we need */
895    if ((device_fd < 0) ||
896        (property_set_fd < 0) ||
897        (signal_recv_fd < 0)) {
898        ERROR("init startup failure\n");
899        return 1;
900    }
901
902    /* execute all the boot actions to get us started */
903    action_for_each_trigger("early-boot", action_add_queue_tail);
904    action_for_each_trigger("boot", action_add_queue_tail);
905    drain_action_queue();
906
907        /* run all property triggers based on current state of the properties */
908    queue_all_property_triggers();
909    drain_action_queue();
910
911        /* enable property triggers */
912    property_triggers_enabled = 1;
913
914    ufds[0].fd = device_fd;
915    ufds[0].events = POLLIN;
916    ufds[1].fd = property_set_fd;
917    ufds[1].events = POLLIN;
918    ufds[2].fd = signal_recv_fd;
919    ufds[2].events = POLLIN;
920    fd_count = 3;
921
922    if (keychord_fd > 0) {
923        ufds[3].fd = keychord_fd;
924        ufds[3].events = POLLIN;
925        fd_count++;
926    } else {
927        ufds[3].events = 0;
928        ufds[3].revents = 0;
929    }
930
931#if BOOTCHART
932    bootchart_count = bootchart_init();
933    if (bootchart_count < 0) {
934        ERROR("bootcharting init failure\n");
935    } else if (bootchart_count > 0) {
936        NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS);
937    } else {
938        NOTICE("bootcharting ignored\n");
939    }
940#endif
941
942    for(;;) {
943        int nr, i, timeout = -1;
944
945        for (i = 0; i < fd_count; i++)
946            ufds[i].revents = 0;
947
948        drain_action_queue();
949        restart_processes();
950
951        if (process_needs_restart) {
952            timeout = (process_needs_restart - gettime()) * 1000;
953            if (timeout < 0)
954                timeout = 0;
955        }
956
957#if BOOTCHART
958        if (bootchart_count > 0) {
959            if (timeout < 0 || timeout > BOOTCHART_POLLING_MS)
960                timeout = BOOTCHART_POLLING_MS;
961            if (bootchart_step() < 0 || --bootchart_count == 0) {
962                bootchart_finish();
963                bootchart_count = 0;
964            }
965        }
966#endif
967        nr = poll(ufds, fd_count, timeout);
968        if (nr <= 0)
969            continue;
970
971        if (ufds[2].revents == POLLIN) {
972            /* we got a SIGCHLD - reap and restart as needed */
973            read(signal_recv_fd, tmp, sizeof(tmp));
974            while (!wait_for_one_process(0))
975                ;
976            continue;
977        }
978
979        if (ufds[0].revents == POLLIN)
980            handle_device_fd(device_fd);
981
982        if (ufds[1].revents == POLLIN)
983            handle_property_set_fd(property_set_fd);
984        if (ufds[3].revents == POLLIN)
985            handle_keychord(keychord_fd);
986    }
987
988    return 0;
989}
990