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