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