Home | History | Annotate | Download | only in init
      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 <errno.h>
     29 #include <stdarg.h>
     30 #include <mtd/mtd-user.h>
     31 #include <sys/types.h>
     32 #include <sys/socket.h>
     33 #include <sys/un.h>
     34 #include <libgen.h>
     35 
     36 #include <cutils/list.h>
     37 #include <cutils/sockets.h>
     38 #include <cutils/iosched_policy.h>
     39 #include <private/android_filesystem_config.h>
     40 #include <termios.h>
     41 
     42 #include <sys/system_properties.h>
     43 
     44 #include "devices.h"
     45 #include "init.h"
     46 #include "log.h"
     47 #include "property_service.h"
     48 #include "bootchart.h"
     49 #include "signal_handler.h"
     50 #include "keychords.h"
     51 #include "init_parser.h"
     52 #include "util.h"
     53 #include "ueventd.h"
     54 
     55 static int property_triggers_enabled = 0;
     56 
     57 #if BOOTCHART
     58 static int   bootchart_count;
     59 #endif
     60 
     61 static char console[32];
     62 static char serialno[32];
     63 static char bootmode[32];
     64 static char baseband[32];
     65 static char carrier[32];
     66 static char bootloader[32];
     67 static char hardware[32];
     68 static char modelno[32];
     69 static unsigned revision = 0;
     70 static char qemu[32];
     71 
     72 static struct action *cur_action = NULL;
     73 static struct command *cur_command = NULL;
     74 static struct listnode *command_queue = NULL;
     75 
     76 void notify_service_state(const char *name, const char *state)
     77 {
     78     char pname[PROP_NAME_MAX];
     79     int len = strlen(name);
     80     if ((len + 10) > PROP_NAME_MAX)
     81         return;
     82     snprintf(pname, sizeof(pname), "init.svc.%s", name);
     83     property_set(pname, state);
     84 }
     85 
     86 static int have_console;
     87 static char *console_name = "/dev/console";
     88 static time_t process_needs_restart;
     89 
     90 static const char *ENV[32];
     91 
     92 /* add_environment - add "key=value" to the current environment */
     93 int add_environment(const char *key, const char *val)
     94 {
     95     int n;
     96 
     97     for (n = 0; n < 31; n++) {
     98         if (!ENV[n]) {
     99             size_t len = strlen(key) + strlen(val) + 2;
    100             char *entry = malloc(len);
    101             snprintf(entry, len, "%s=%s", key, val);
    102             ENV[n] = entry;
    103             return 0;
    104         }
    105     }
    106 
    107     return 1;
    108 }
    109 
    110 static void zap_stdio(void)
    111 {
    112     int fd;
    113     fd = open("/dev/null", O_RDWR);
    114     dup2(fd, 0);
    115     dup2(fd, 1);
    116     dup2(fd, 2);
    117     close(fd);
    118 }
    119 
    120 static void open_console()
    121 {
    122     int fd;
    123     if ((fd = open(console_name, O_RDWR)) < 0) {
    124         fd = open("/dev/null", O_RDWR);
    125     }
    126     dup2(fd, 0);
    127     dup2(fd, 1);
    128     dup2(fd, 2);
    129     close(fd);
    130 }
    131 
    132 static void publish_socket(const char *name, int fd)
    133 {
    134     char key[64] = ANDROID_SOCKET_ENV_PREFIX;
    135     char val[64];
    136 
    137     strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1,
    138             name,
    139             sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX));
    140     snprintf(val, sizeof(val), "%d", fd);
    141     add_environment(key, val);
    142 
    143     /* make sure we don't close-on-exec */
    144     fcntl(fd, F_SETFD, 0);
    145 }
    146 
    147 void service_start(struct service *svc, const char *dynamic_args)
    148 {
    149     struct stat s;
    150     pid_t pid;
    151     int needs_console;
    152     int n;
    153 
    154         /* starting a service removes it from the disabled or reset
    155          * state and immediately takes it out of the restarting
    156          * state if it was in there
    157          */
    158     svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET));
    159     svc->time_started = 0;
    160 
    161         /* running processes require no additional work -- if
    162          * they're in the process of exiting, we've ensured
    163          * that they will immediately restart on exit, unless
    164          * they are ONESHOT
    165          */
    166     if (svc->flags & SVC_RUNNING) {
    167         return;
    168     }
    169 
    170     needs_console = (svc->flags & SVC_CONSOLE) ? 1 : 0;
    171     if (needs_console && (!have_console)) {
    172         ERROR("service '%s' requires console\n", svc->name);
    173         svc->flags |= SVC_DISABLED;
    174         return;
    175     }
    176 
    177     if (stat(svc->args[0], &s) != 0) {
    178         ERROR("cannot find '%s', disabling '%s'\n", svc->args[0], svc->name);
    179         svc->flags |= SVC_DISABLED;
    180         return;
    181     }
    182 
    183     if ((!(svc->flags & SVC_ONESHOT)) && dynamic_args) {
    184         ERROR("service '%s' must be one-shot to use dynamic args, disabling\n",
    185                svc->args[0]);
    186         svc->flags |= SVC_DISABLED;
    187         return;
    188     }
    189 
    190     NOTICE("starting '%s'\n", svc->name);
    191 
    192     pid = fork();
    193 
    194     if (pid == 0) {
    195         struct socketinfo *si;
    196         struct svcenvinfo *ei;
    197         char tmp[32];
    198         int fd, sz;
    199 
    200         if (properties_inited()) {
    201             get_property_workspace(&fd, &sz);
    202             sprintf(tmp, "%d,%d", dup(fd), sz);
    203             add_environment("ANDROID_PROPERTY_WORKSPACE", tmp);
    204         }
    205 
    206         for (ei = svc->envvars; ei; ei = ei->next)
    207             add_environment(ei->name, ei->value);
    208 
    209         for (si = svc->sockets; si; si = si->next) {
    210             int socket_type = (
    211                     !strcmp(si->type, "stream") ? SOCK_STREAM :
    212                         (!strcmp(si->type, "dgram") ? SOCK_DGRAM : SOCK_SEQPACKET));
    213             int s = create_socket(si->name, socket_type,
    214                                   si->perm, si->uid, si->gid);
    215             if (s >= 0) {
    216                 publish_socket(si->name, s);
    217             }
    218         }
    219 
    220         if (svc->ioprio_class != IoSchedClass_NONE) {
    221             if (android_set_ioprio(getpid(), svc->ioprio_class, svc->ioprio_pri)) {
    222                 ERROR("Failed to set pid %d ioprio = %d,%d: %s\n",
    223                       getpid(), svc->ioprio_class, svc->ioprio_pri, strerror(errno));
    224             }
    225         }
    226 
    227         if (needs_console) {
    228             setsid();
    229             open_console();
    230         } else {
    231             zap_stdio();
    232         }
    233 
    234 #if 0
    235         for (n = 0; svc->args[n]; n++) {
    236             INFO("args[%d] = '%s'\n", n, svc->args[n]);
    237         }
    238         for (n = 0; ENV[n]; n++) {
    239             INFO("env[%d] = '%s'\n", n, ENV[n]);
    240         }
    241 #endif
    242 
    243         setpgid(0, getpid());
    244 
    245     /* as requested, set our gid, supplemental gids, and uid */
    246         if (svc->gid) {
    247             if (setgid(svc->gid) != 0) {
    248                 ERROR("setgid failed: %s\n", strerror(errno));
    249                 _exit(127);
    250             }
    251         }
    252         if (svc->nr_supp_gids) {
    253             if (setgroups(svc->nr_supp_gids, svc->supp_gids) != 0) {
    254                 ERROR("setgroups failed: %s\n", strerror(errno));
    255                 _exit(127);
    256             }
    257         }
    258         if (svc->uid) {
    259             if (setuid(svc->uid) != 0) {
    260                 ERROR("setuid failed: %s\n", strerror(errno));
    261                 _exit(127);
    262             }
    263         }
    264 
    265         if (!dynamic_args) {
    266             if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) {
    267                 ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno));
    268             }
    269         } else {
    270             char *arg_ptrs[INIT_PARSER_MAXARGS+1];
    271             int arg_idx = svc->nargs;
    272             char *tmp = strdup(dynamic_args);
    273             char *next = tmp;
    274             char *bword;
    275 
    276             /* Copy the static arguments */
    277             memcpy(arg_ptrs, svc->args, (svc->nargs * sizeof(char *)));
    278 
    279             while((bword = strsep(&next, " "))) {
    280                 arg_ptrs[arg_idx++] = bword;
    281                 if (arg_idx == INIT_PARSER_MAXARGS)
    282                     break;
    283             }
    284             arg_ptrs[arg_idx] = '\0';
    285             execve(svc->args[0], (char**) arg_ptrs, (char**) ENV);
    286         }
    287         _exit(127);
    288     }
    289 
    290     if (pid < 0) {
    291         ERROR("failed to start '%s'\n", svc->name);
    292         svc->pid = 0;
    293         return;
    294     }
    295 
    296     svc->time_started = gettime();
    297     svc->pid = pid;
    298     svc->flags |= SVC_RUNNING;
    299 
    300     if (properties_inited())
    301         notify_service_state(svc->name, "running");
    302 }
    303 
    304 /* The how field should be either SVC_DISABLED or SVC_RESET */
    305 static void service_stop_or_reset(struct service *svc, int how)
    306 {
    307         /* we are no longer running, nor should we
    308          * attempt to restart
    309          */
    310     svc->flags &= (~(SVC_RUNNING|SVC_RESTARTING));
    311 
    312     if ((how != SVC_DISABLED) && (how != SVC_RESET)) {
    313         /* Hrm, an illegal flag.  Default to SVC_DISABLED */
    314         how = SVC_DISABLED;
    315     }
    316         /* if the service has not yet started, prevent
    317          * it from auto-starting with its class
    318          */
    319     if (how == SVC_RESET) {
    320         svc->flags |= (svc->flags & SVC_RC_DISABLED) ? SVC_DISABLED : SVC_RESET;
    321     } else {
    322         svc->flags |= how;
    323     }
    324 
    325     if (svc->pid) {
    326         NOTICE("service '%s' is being killed\n", svc->name);
    327         kill(-svc->pid, SIGKILL);
    328         notify_service_state(svc->name, "stopping");
    329     } else {
    330         notify_service_state(svc->name, "stopped");
    331     }
    332 }
    333 
    334 void service_reset(struct service *svc)
    335 {
    336     service_stop_or_reset(svc, SVC_RESET);
    337 }
    338 
    339 void service_stop(struct service *svc)
    340 {
    341     service_stop_or_reset(svc, SVC_DISABLED);
    342 }
    343 
    344 void property_changed(const char *name, const char *value)
    345 {
    346     if (property_triggers_enabled)
    347         queue_property_triggers(name, value);
    348 }
    349 
    350 static void restart_service_if_needed(struct service *svc)
    351 {
    352     time_t next_start_time = svc->time_started + 5;
    353 
    354     if (next_start_time <= gettime()) {
    355         svc->flags &= (~SVC_RESTARTING);
    356         service_start(svc, NULL);
    357         return;
    358     }
    359 
    360     if ((next_start_time < process_needs_restart) ||
    361         (process_needs_restart == 0)) {
    362         process_needs_restart = next_start_time;
    363     }
    364 }
    365 
    366 static void restart_processes()
    367 {
    368     process_needs_restart = 0;
    369     service_for_each_flags(SVC_RESTARTING,
    370                            restart_service_if_needed);
    371 }
    372 
    373 static void msg_start(const char *name)
    374 {
    375     struct service *svc;
    376     char *tmp = NULL;
    377     char *args = NULL;
    378 
    379     if (!strchr(name, ':'))
    380         svc = service_find_by_name(name);
    381     else {
    382         tmp = strdup(name);
    383         args = strchr(tmp, ':');
    384         *args = '\0';
    385         args++;
    386 
    387         svc = service_find_by_name(tmp);
    388     }
    389 
    390     if (svc) {
    391         service_start(svc, args);
    392     } else {
    393         ERROR("no such service '%s'\n", name);
    394     }
    395     if (tmp)
    396         free(tmp);
    397 }
    398 
    399 static void msg_stop(const char *name)
    400 {
    401     struct service *svc = service_find_by_name(name);
    402 
    403     if (svc) {
    404         service_stop(svc);
    405     } else {
    406         ERROR("no such service '%s'\n", name);
    407     }
    408 }
    409 
    410 void handle_control_message(const char *msg, const char *arg)
    411 {
    412     if (!strcmp(msg,"start")) {
    413         msg_start(arg);
    414     } else if (!strcmp(msg,"stop")) {
    415         msg_stop(arg);
    416     } else if (!strcmp(msg,"restart")) {
    417         msg_stop(arg);
    418         msg_start(arg);
    419     } else {
    420         ERROR("unknown control msg '%s'\n", msg);
    421     }
    422 }
    423 
    424 static void import_kernel_nv(char *name, int in_qemu)
    425 {
    426     char *value = strchr(name, '=');
    427 
    428     if (value == 0) return;
    429     *value++ = 0;
    430     if (*name == 0) return;
    431 
    432     if (!in_qemu)
    433     {
    434         /* on a real device, white-list the kernel options */
    435         if (!strcmp(name,"qemu")) {
    436             strlcpy(qemu, value, sizeof(qemu));
    437         } else if (!strcmp(name,"androidboot.console")) {
    438             strlcpy(console, value, sizeof(console));
    439         } else if (!strcmp(name,"androidboot.mode")) {
    440             strlcpy(bootmode, value, sizeof(bootmode));
    441         } else if (!strcmp(name,"androidboot.serialno")) {
    442             strlcpy(serialno, value, sizeof(serialno));
    443         } else if (!strcmp(name,"androidboot.baseband")) {
    444             strlcpy(baseband, value, sizeof(baseband));
    445         } else if (!strcmp(name,"androidboot.carrier")) {
    446             strlcpy(carrier, value, sizeof(carrier));
    447         } else if (!strcmp(name,"androidboot.bootloader")) {
    448             strlcpy(bootloader, value, sizeof(bootloader));
    449         } else if (!strcmp(name,"androidboot.hardware")) {
    450             strlcpy(hardware, value, sizeof(hardware));
    451         } else if (!strcmp(name,"androidboot.modelno")) {
    452             strlcpy(modelno, value, sizeof(modelno));
    453         }
    454     } else {
    455         /* in the emulator, export any kernel option with the
    456          * ro.kernel. prefix */
    457         char  buff[32];
    458         int   len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name );
    459         if (len < (int)sizeof(buff)) {
    460             property_set( buff, value );
    461         }
    462     }
    463 }
    464 
    465 static struct command *get_first_command(struct action *act)
    466 {
    467     struct listnode *node;
    468     node = list_head(&act->commands);
    469     if (!node || list_empty(&act->commands))
    470         return NULL;
    471 
    472     return node_to_item(node, struct command, clist);
    473 }
    474 
    475 static struct command *get_next_command(struct action *act, struct command *cmd)
    476 {
    477     struct listnode *node;
    478     node = cmd->clist.next;
    479     if (!node)
    480         return NULL;
    481     if (node == &act->commands)
    482         return NULL;
    483 
    484     return node_to_item(node, struct command, clist);
    485 }
    486 
    487 static int is_last_command(struct action *act, struct command *cmd)
    488 {
    489     return (list_tail(&act->commands) == &cmd->clist);
    490 }
    491 
    492 void execute_one_command(void)
    493 {
    494     int ret;
    495 
    496     if (!cur_action || !cur_command || is_last_command(cur_action, cur_command)) {
    497         cur_action = action_remove_queue_head();
    498         cur_command = NULL;
    499         if (!cur_action)
    500             return;
    501         INFO("processing action %p (%s)\n", cur_action, cur_action->name);
    502         cur_command = get_first_command(cur_action);
    503     } else {
    504         cur_command = get_next_command(cur_action, cur_command);
    505     }
    506 
    507     if (!cur_command)
    508         return;
    509 
    510     ret = cur_command->func(cur_command->nargs, cur_command->args);
    511     INFO("command '%s' r=%d\n", cur_command->args[0], ret);
    512 }
    513 
    514 static int wait_for_coldboot_done_action(int nargs, char **args)
    515 {
    516     int ret;
    517     INFO("wait for %s\n", coldboot_done);
    518     ret = wait_for_file(coldboot_done, COMMAND_RETRY_TIMEOUT);
    519     if (ret)
    520         ERROR("Timed out waiting for %s\n", coldboot_done);
    521     return ret;
    522 }
    523 
    524 static int property_init_action(int nargs, char **args)
    525 {
    526     bool load_defaults = true;
    527 
    528     INFO("property init\n");
    529     if (!strcmp(bootmode, "charger"))
    530         load_defaults = false;
    531     property_init(load_defaults);
    532     return 0;
    533 }
    534 
    535 static int keychord_init_action(int nargs, char **args)
    536 {
    537     keychord_init();
    538     return 0;
    539 }
    540 
    541 static int console_init_action(int nargs, char **args)
    542 {
    543     int fd;
    544     char tmp[PROP_VALUE_MAX];
    545 
    546     if (console[0]) {
    547         snprintf(tmp, sizeof(tmp), "/dev/%s", console);
    548         console_name = strdup(tmp);
    549     }
    550 
    551     fd = open(console_name, O_RDWR);
    552     if (fd >= 0)
    553         have_console = 1;
    554     close(fd);
    555 
    556     if( load_565rle_image(INIT_IMAGE_FILE) ) {
    557         fd = open("/dev/tty0", O_WRONLY);
    558         if (fd >= 0) {
    559             const char *msg;
    560                 msg = "\n"
    561             "\n"
    562             "\n"
    563             "\n"
    564             "\n"
    565             "\n"
    566             "\n"  // console is 40 cols x 30 lines
    567             "\n"
    568             "\n"
    569             "\n"
    570             "\n"
    571             "\n"
    572             "\n"
    573             "\n"
    574             "             A N D R O I D ";
    575             write(fd, msg, strlen(msg));
    576             close(fd);
    577         }
    578     }
    579     return 0;
    580 }
    581 
    582 static int set_init_properties_action(int nargs, char **args)
    583 {
    584     char tmp[PROP_VALUE_MAX];
    585 
    586     if (qemu[0])
    587         import_kernel_cmdline(1, import_kernel_nv);
    588 
    589     if (!strcmp(bootmode,"factory"))
    590         property_set("ro.factorytest", "1");
    591     else if (!strcmp(bootmode,"factory2"))
    592         property_set("ro.factorytest", "2");
    593     else
    594         property_set("ro.factorytest", "0");
    595 
    596     property_set("ro.serialno", serialno[0] ? serialno : "");
    597     property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown");
    598     property_set("ro.baseband", baseband[0] ? baseband : "unknown");
    599     property_set("ro.carrier", carrier[0] ? carrier : "unknown");
    600     property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown");
    601 
    602     if (modelno[0])
    603         property_set("ro.boot.modelno", modelno);
    604 
    605     property_set("ro.hardware", hardware);
    606     snprintf(tmp, PROP_VALUE_MAX, "%d", revision);
    607     property_set("ro.revision", tmp);
    608     return 0;
    609 }
    610 
    611 static int property_service_init_action(int nargs, char **args)
    612 {
    613     /* read any property files on system or data and
    614      * fire up the property service.  This must happen
    615      * after the ro.foo properties are set above so
    616      * that /data/local.prop cannot interfere with them.
    617      */
    618     start_property_service();
    619     return 0;
    620 }
    621 
    622 static int signal_init_action(int nargs, char **args)
    623 {
    624     signal_init();
    625     return 0;
    626 }
    627 
    628 static int check_startup_action(int nargs, char **args)
    629 {
    630     /* make sure we actually have all the pieces we need */
    631     if ((get_property_set_fd() < 0) ||
    632         (get_signal_fd() < 0)) {
    633         ERROR("init startup failure\n");
    634         exit(1);
    635     }
    636 
    637         /* signal that we hit this point */
    638     unlink("/dev/.booting");
    639 
    640     return 0;
    641 }
    642 
    643 static int queue_property_triggers_action(int nargs, char **args)
    644 {
    645     queue_all_property_triggers();
    646     /* enable property triggers */
    647     property_triggers_enabled = 1;
    648     return 0;
    649 }
    650 
    651 #if BOOTCHART
    652 static int bootchart_init_action(int nargs, char **args)
    653 {
    654     bootchart_count = bootchart_init();
    655     if (bootchart_count < 0) {
    656         ERROR("bootcharting init failure\n");
    657     } else if (bootchart_count > 0) {
    658         NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS);
    659     } else {
    660         NOTICE("bootcharting ignored\n");
    661     }
    662 
    663     return 0;
    664 }
    665 #endif
    666 
    667 int main(int argc, char **argv)
    668 {
    669     int fd_count = 0;
    670     struct pollfd ufds[4];
    671     char *tmpdev;
    672     char* debuggable;
    673     char tmp[32];
    674     int property_set_fd_init = 0;
    675     int signal_fd_init = 0;
    676     int keychord_fd_init = 0;
    677 
    678     if (!strcmp(basename(argv[0]), "ueventd"))
    679         return ueventd_main(argc, argv);
    680 
    681     /* clear the umask */
    682     umask(0);
    683 
    684         /* Get the basic filesystem setup we need put
    685          * together in the initramdisk on / and then we'll
    686          * let the rc file figure out the rest.
    687          */
    688     mkdir("/dev", 0755);
    689     mkdir("/proc", 0755);
    690     mkdir("/sys", 0755);
    691 
    692     mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
    693     mkdir("/dev/pts", 0755);
    694     mkdir("/dev/socket", 0755);
    695     mount("devpts", "/dev/pts", "devpts", 0, NULL);
    696     mount("proc", "/proc", "proc", 0, NULL);
    697     mount("sysfs", "/sys", "sysfs", 0, NULL);
    698 
    699         /* indicate that booting is in progress to background fw loaders, etc */
    700     close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000));
    701 
    702         /* We must have some place other than / to create the
    703          * device nodes for kmsg and null, otherwise we won't
    704          * be able to remount / read-only later on.
    705          * Now that tmpfs is mounted on /dev, we can actually
    706          * talk to the outside world.
    707          */
    708     open_devnull_stdio();
    709     klog_init();
    710 
    711     INFO("reading config file\n");
    712     init_parse_config_file("/init.rc");
    713 
    714     /* pull the kernel commandline and ramdisk properties file in */
    715     import_kernel_cmdline(0, import_kernel_nv);
    716     /* don't expose the raw commandline to nonpriv processes */
    717     chmod("/proc/cmdline", 0440);
    718     get_hardware_name(hardware, &revision);
    719     snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
    720     init_parse_config_file(tmp);
    721 
    722     action_for_each_trigger("early-init", action_add_queue_tail);
    723 
    724     queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");
    725     queue_builtin_action(property_init_action, "property_init");
    726     queue_builtin_action(keychord_init_action, "keychord_init");
    727     queue_builtin_action(console_init_action, "console_init");
    728     queue_builtin_action(set_init_properties_action, "set_init_properties");
    729 
    730     /* execute all the boot actions to get us started */
    731     action_for_each_trigger("init", action_add_queue_tail);
    732 
    733     /* skip mounting filesystems in charger mode */
    734     if (strcmp(bootmode, "charger") != 0) {
    735         action_for_each_trigger("early-fs", action_add_queue_tail);
    736         action_for_each_trigger("fs", action_add_queue_tail);
    737         action_for_each_trigger("post-fs", action_add_queue_tail);
    738         action_for_each_trigger("post-fs-data", action_add_queue_tail);
    739     }
    740 
    741     queue_builtin_action(property_service_init_action, "property_service_init");
    742     queue_builtin_action(signal_init_action, "signal_init");
    743     queue_builtin_action(check_startup_action, "check_startup");
    744 
    745     if (!strcmp(bootmode, "charger")) {
    746         action_for_each_trigger("charger", action_add_queue_tail);
    747     } else {
    748         action_for_each_trigger("early-boot", action_add_queue_tail);
    749         action_for_each_trigger("boot", action_add_queue_tail);
    750     }
    751 
    752         /* run all property triggers based on current state of the properties */
    753     queue_builtin_action(queue_property_triggers_action, "queue_propety_triggers");
    754 
    755 
    756 #if BOOTCHART
    757     queue_builtin_action(bootchart_init_action, "bootchart_init");
    758 #endif
    759 
    760     for(;;) {
    761         int nr, i, timeout = -1;
    762 
    763         execute_one_command();
    764         restart_processes();
    765 
    766         if (!property_set_fd_init && get_property_set_fd() > 0) {
    767             ufds[fd_count].fd = get_property_set_fd();
    768             ufds[fd_count].events = POLLIN;
    769             ufds[fd_count].revents = 0;
    770             fd_count++;
    771             property_set_fd_init = 1;
    772         }
    773         if (!signal_fd_init && get_signal_fd() > 0) {
    774             ufds[fd_count].fd = get_signal_fd();
    775             ufds[fd_count].events = POLLIN;
    776             ufds[fd_count].revents = 0;
    777             fd_count++;
    778             signal_fd_init = 1;
    779         }
    780         if (!keychord_fd_init && get_keychord_fd() > 0) {
    781             ufds[fd_count].fd = get_keychord_fd();
    782             ufds[fd_count].events = POLLIN;
    783             ufds[fd_count].revents = 0;
    784             fd_count++;
    785             keychord_fd_init = 1;
    786         }
    787 
    788         if (process_needs_restart) {
    789             timeout = (process_needs_restart - gettime()) * 1000;
    790             if (timeout < 0)
    791                 timeout = 0;
    792         }
    793 
    794         if (!action_queue_empty() || cur_action)
    795             timeout = 0;
    796 
    797 #if BOOTCHART
    798         if (bootchart_count > 0) {
    799             if (timeout < 0 || timeout > BOOTCHART_POLLING_MS)
    800                 timeout = BOOTCHART_POLLING_MS;
    801             if (bootchart_step() < 0 || --bootchart_count == 0) {
    802                 bootchart_finish();
    803                 bootchart_count = 0;
    804             }
    805         }
    806 #endif
    807 
    808         nr = poll(ufds, fd_count, timeout);
    809         if (nr <= 0)
    810             continue;
    811 
    812         for (i = 0; i < fd_count; i++) {
    813             if (ufds[i].revents == POLLIN) {
    814                 if (ufds[i].fd == get_property_set_fd())
    815                     handle_property_set_fd();
    816                 else if (ufds[i].fd == get_keychord_fd())
    817                     handle_keychord();
    818                 else if (ufds[i].fd == get_signal_fd())
    819                     handle_signal();
    820             }
    821         }
    822     }
    823 
    824     return 0;
    825 }
    826