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 <ctype.h>
18#include <dirent.h>
19#include <errno.h>
20#include <fcntl.h>
21#include <fstream>
22#include <libgen.h>
23#include <paths.h>
24#include <signal.h>
25#include <stdarg.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <sys/epoll.h>
30#include <sys/mount.h>
31#include <sys/socket.h>
32#include <sys/stat.h>
33#include <sys/types.h>
34#include <sys/un.h>
35#include <sys/wait.h>
36#include <unistd.h>
37
38#include <mtd/mtd-user.h>
39
40#include <selinux/selinux.h>
41#include <selinux/label.h>
42#include <selinux/android.h>
43
44#include <android-base/file.h>
45#include <android-base/stringprintf.h>
46#include <android-base/strings.h>
47#include <cutils/android_reboot.h>
48#include <cutils/fs.h>
49#include <cutils/iosched_policy.h>
50#include <cutils/list.h>
51#include <cutils/sockets.h>
52#include <private/android_filesystem_config.h>
53
54#include <memory>
55
56#include "action.h"
57#include "bootchart.h"
58#include "devices.h"
59#include "import_parser.h"
60#include "init.h"
61#include "init_parser.h"
62#include "keychords.h"
63#include "log.h"
64#include "property_service.h"
65#include "service.h"
66#include "signal_handler.h"
67#include "ueventd.h"
68#include "util.h"
69#include "watchdogd.h"
70
71struct selabel_handle *sehandle;
72struct selabel_handle *sehandle_prop;
73
74static int property_triggers_enabled = 0;
75
76static char qemu[32];
77
78int have_console;
79std::string console_name = "/dev/console";
80static time_t process_needs_restart;
81
82const char *ENV[32];
83
84bool waiting_for_exec = false;
85
86static int epoll_fd = -1;
87
88void register_epoll_handler(int fd, void (*fn)()) {
89    epoll_event ev;
90    ev.events = EPOLLIN;
91    ev.data.ptr = reinterpret_cast<void*>(fn);
92    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
93        ERROR("epoll_ctl failed: %s\n", strerror(errno));
94    }
95}
96
97/* add_environment - add "key=value" to the current environment */
98int add_environment(const char *key, const char *val)
99{
100    size_t n;
101    size_t key_len = strlen(key);
102
103    /* The last environment entry is reserved to terminate the list */
104    for (n = 0; n < (ARRAY_SIZE(ENV) - 1); n++) {
105
106        /* Delete any existing entry for this key */
107        if (ENV[n] != NULL) {
108            size_t entry_key_len = strcspn(ENV[n], "=");
109            if ((entry_key_len == key_len) && (strncmp(ENV[n], key, entry_key_len) == 0)) {
110                free((char*)ENV[n]);
111                ENV[n] = NULL;
112            }
113        }
114
115        /* Add entry if a free slot is available */
116        if (ENV[n] == NULL) {
117            char* entry;
118            asprintf(&entry, "%s=%s", key, val);
119            ENV[n] = entry;
120            return 0;
121        }
122    }
123
124    ERROR("No env. room to store: '%s':'%s'\n", key, val);
125
126    return -1;
127}
128
129void property_changed(const char *name, const char *value)
130{
131    if (property_triggers_enabled)
132        ActionManager::GetInstance().QueuePropertyTrigger(name, value);
133}
134
135static void restart_processes()
136{
137    process_needs_restart = 0;
138    ServiceManager::GetInstance().
139        ForEachServiceWithFlags(SVC_RESTARTING, [] (Service* s) {
140                s->RestartIfNeeded(process_needs_restart);
141            });
142}
143
144void handle_control_message(const std::string& msg, const std::string& name) {
145    Service* svc = ServiceManager::GetInstance().FindServiceByName(name);
146    if (svc == nullptr) {
147        ERROR("no such service '%s'\n", name.c_str());
148        return;
149    }
150
151    if (msg == "start") {
152        svc->Start();
153    } else if (msg == "stop") {
154        svc->Stop();
155    } else if (msg == "restart") {
156        svc->Restart();
157    } else {
158        ERROR("unknown control msg '%s'\n", msg.c_str());
159    }
160}
161
162static int wait_for_coldboot_done_action(const std::vector<std::string>& args) {
163    Timer t;
164
165    NOTICE("Waiting for %s...\n", COLDBOOT_DONE);
166    // Any longer than 1s is an unreasonable length of time to delay booting.
167    // If you're hitting this timeout, check that you didn't make your
168    // sepolicy regular expressions too expensive (http://b/19899875).
169    if (wait_for_file(COLDBOOT_DONE, 1)) {
170        ERROR("Timed out waiting for %s\n", COLDBOOT_DONE);
171    }
172
173    NOTICE("Waiting for %s took %.2fs.\n", COLDBOOT_DONE, t.duration());
174    return 0;
175}
176
177/*
178 * Writes 512 bytes of output from Hardware RNG (/dev/hw_random, backed
179 * by Linux kernel's hw_random framework) into Linux RNG's via /dev/urandom.
180 * Does nothing if Hardware RNG is not present.
181 *
182 * Since we don't yet trust the quality of Hardware RNG, these bytes are not
183 * mixed into the primary pool of Linux RNG and the entropy estimate is left
184 * unmodified.
185 *
186 * If the HW RNG device /dev/hw_random is present, we require that at least
187 * 512 bytes read from it are written into Linux RNG. QA is expected to catch
188 * devices/configurations where these I/O operations are blocking for a long
189 * time. We do not reboot or halt on failures, as this is a best-effort
190 * attempt.
191 */
192static int mix_hwrng_into_linux_rng_action(const std::vector<std::string>& args)
193{
194    int result = -1;
195    int hwrandom_fd = -1;
196    int urandom_fd = -1;
197    char buf[512];
198    ssize_t chunk_size;
199    size_t total_bytes_written = 0;
200
201    hwrandom_fd = TEMP_FAILURE_RETRY(
202            open("/dev/hw_random", O_RDONLY | O_NOFOLLOW | O_CLOEXEC));
203    if (hwrandom_fd == -1) {
204        if (errno == ENOENT) {
205          ERROR("/dev/hw_random not found\n");
206          /* It's not an error to not have a Hardware RNG. */
207          result = 0;
208        } else {
209          ERROR("Failed to open /dev/hw_random: %s\n", strerror(errno));
210        }
211        goto ret;
212    }
213
214    urandom_fd = TEMP_FAILURE_RETRY(
215            open("/dev/urandom", O_WRONLY | O_NOFOLLOW | O_CLOEXEC));
216    if (urandom_fd == -1) {
217        ERROR("Failed to open /dev/urandom: %s\n", strerror(errno));
218        goto ret;
219    }
220
221    while (total_bytes_written < sizeof(buf)) {
222        chunk_size = TEMP_FAILURE_RETRY(
223                read(hwrandom_fd, buf, sizeof(buf) - total_bytes_written));
224        if (chunk_size == -1) {
225            ERROR("Failed to read from /dev/hw_random: %s\n", strerror(errno));
226            goto ret;
227        } else if (chunk_size == 0) {
228            ERROR("Failed to read from /dev/hw_random: EOF\n");
229            goto ret;
230        }
231
232        chunk_size = TEMP_FAILURE_RETRY(write(urandom_fd, buf, chunk_size));
233        if (chunk_size == -1) {
234            ERROR("Failed to write to /dev/urandom: %s\n", strerror(errno));
235            goto ret;
236        }
237        total_bytes_written += chunk_size;
238    }
239
240    INFO("Mixed %zu bytes from /dev/hw_random into /dev/urandom",
241                total_bytes_written);
242    result = 0;
243
244ret:
245    if (hwrandom_fd != -1) {
246        close(hwrandom_fd);
247    }
248    if (urandom_fd != -1) {
249        close(urandom_fd);
250    }
251    return result;
252}
253
254static void security_failure() {
255    ERROR("Security failure; rebooting into recovery mode...\n");
256    android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
257    while (true) { pause(); }  // never reached
258}
259
260#define MMAP_RND_PATH "/proc/sys/vm/mmap_rnd_bits"
261#define MMAP_RND_COMPAT_PATH "/proc/sys/vm/mmap_rnd_compat_bits"
262
263/* __attribute__((unused)) due to lack of mips support: see mips block
264 * in set_mmap_rnd_bits_action */
265static bool __attribute__((unused)) set_mmap_rnd_bits_min(int start, int min, bool compat) {
266    std::string path;
267    if (compat) {
268        path = MMAP_RND_COMPAT_PATH;
269    } else {
270        path = MMAP_RND_PATH;
271    }
272    std::ifstream inf(path, std::fstream::in);
273    if (!inf) {
274        return false;
275    }
276    while (start >= min) {
277        // try to write out new value
278        std::string str_val = std::to_string(start);
279        std::ofstream of(path, std::fstream::out);
280        if (!of) {
281            return false;
282        }
283        of << str_val << std::endl;
284        of.close();
285
286        // check to make sure it was recorded
287        inf.seekg(0);
288        std::string str_rec;
289        inf >> str_rec;
290        if (str_val.compare(str_rec) == 0) {
291            break;
292        }
293        start--;
294    }
295    inf.close();
296    return (start >= min);
297}
298
299/*
300 * Set /proc/sys/vm/mmap_rnd_bits and potentially
301 * /proc/sys/vm/mmap_rnd_compat_bits to the maximum supported values.
302 * Returns -1 if unable to set these to an acceptable value.  Apply
303 * upstream patch-sets https://lkml.org/lkml/2015/12/21/337 and
304 * https://lkml.org/lkml/2016/2/4/831 to enable this.
305 */
306static int set_mmap_rnd_bits_action(const std::vector<std::string>& args)
307{
308    int ret = -1;
309
310    /* values are arch-dependent */
311#if defined(__aarch64__)
312    /* arm64 supports 18 - 33 bits depending on pagesize and VA_SIZE */
313    if (set_mmap_rnd_bits_min(33, 24, false)
314            && set_mmap_rnd_bits_min(16, 16, true)) {
315        ret = 0;
316    }
317#elif defined(__x86_64__)
318    /* x86_64 supports 28 - 32 bits */
319    if (set_mmap_rnd_bits_min(32, 32, false)
320            && set_mmap_rnd_bits_min(16, 16, true)) {
321        ret = 0;
322    }
323#elif defined(__arm__) || defined(__i386__)
324    /* check to see if we're running on 64-bit kernel */
325    bool h64 = !access(MMAP_RND_COMPAT_PATH, F_OK);
326    /* supported 32-bit architecture must have 16 bits set */
327    if (set_mmap_rnd_bits_min(16, 16, h64)) {
328        ret = 0;
329    }
330#elif defined(__mips__) || defined(__mips64__)
331    // TODO: add mips support b/27788820
332    ret = 0;
333#else
334    ERROR("Unknown architecture\n");
335#endif
336
337#ifdef __BRILLO__
338    // TODO: b/27794137
339    ret = 0;
340#endif
341    if (ret == -1) {
342        ERROR("Unable to set adequate mmap entropy value!\n");
343        security_failure();
344    }
345    return ret;
346}
347
348static int keychord_init_action(const std::vector<std::string>& args)
349{
350    keychord_init();
351    return 0;
352}
353
354static int console_init_action(const std::vector<std::string>& args)
355{
356    std::string console = property_get("ro.boot.console");
357    if (!console.empty()) {
358        console_name = "/dev/" + console;
359    }
360
361    int fd = open(console_name.c_str(), O_RDWR | O_CLOEXEC);
362    if (fd >= 0)
363        have_console = 1;
364    close(fd);
365
366    fd = open("/dev/tty0", O_WRONLY | O_CLOEXEC);
367    if (fd >= 0) {
368        const char *msg;
369            msg = "\n"
370        "\n"
371        "\n"
372        "\n"
373        "\n"
374        "\n"
375        "\n"  // console is 40 cols x 30 lines
376        "\n"
377        "\n"
378        "\n"
379        "\n"
380        "\n"
381        "\n"
382        "\n"
383        "             A N D R O I D ";
384        write(fd, msg, strlen(msg));
385        close(fd);
386    }
387
388    return 0;
389}
390
391static void import_kernel_nv(const std::string& key, const std::string& value, bool for_emulator) {
392    if (key.empty()) return;
393
394    if (for_emulator) {
395        // In the emulator, export any kernel option with the "ro.kernel." prefix.
396        property_set(android::base::StringPrintf("ro.kernel.%s", key.c_str()).c_str(), value.c_str());
397        return;
398    }
399
400    if (key == "qemu") {
401        strlcpy(qemu, value.c_str(), sizeof(qemu));
402    } else if (android::base::StartsWith(key, "androidboot.")) {
403        property_set(android::base::StringPrintf("ro.boot.%s", key.c_str() + 12).c_str(),
404                     value.c_str());
405    }
406}
407
408static void export_oem_lock_status() {
409    if (property_get("ro.oem_unlock_supported") != "1") {
410        return;
411    }
412
413    std::string value = property_get("ro.boot.verifiedbootstate");
414
415    if (!value.empty()) {
416        property_set("ro.boot.flash.locked", value == "orange" ? "0" : "1");
417    }
418}
419
420static void export_kernel_boot_props() {
421    struct {
422        const char *src_prop;
423        const char *dst_prop;
424        const char *default_value;
425    } prop_map[] = {
426        { "ro.boot.serialno",   "ro.serialno",   "", },
427        { "ro.boot.mode",       "ro.bootmode",   "unknown", },
428        { "ro.boot.baseband",   "ro.baseband",   "unknown", },
429        { "ro.boot.bootloader", "ro.bootloader", "unknown", },
430        { "ro.boot.hardware",   "ro.hardware",   "unknown", },
431        { "ro.boot.revision",   "ro.revision",   "0", },
432    };
433    for (size_t i = 0; i < ARRAY_SIZE(prop_map); i++) {
434        std::string value = property_get(prop_map[i].src_prop);
435        property_set(prop_map[i].dst_prop, (!value.empty()) ? value.c_str() : prop_map[i].default_value);
436    }
437}
438
439static void process_kernel_dt() {
440    static const char android_dir[] = "/proc/device-tree/firmware/android";
441
442    std::string file_name = android::base::StringPrintf("%s/compatible", android_dir);
443
444    std::string dt_file;
445    android::base::ReadFileToString(file_name, &dt_file);
446    if (!dt_file.compare("android,firmware")) {
447        ERROR("firmware/android is not compatible with 'android,firmware'\n");
448        return;
449    }
450
451    std::unique_ptr<DIR, int(*)(DIR*)>dir(opendir(android_dir), closedir);
452    if (!dir) return;
453
454    struct dirent *dp;
455    while ((dp = readdir(dir.get())) != NULL) {
456        if (dp->d_type != DT_REG || !strcmp(dp->d_name, "compatible") || !strcmp(dp->d_name, "name")) {
457            continue;
458        }
459
460        file_name = android::base::StringPrintf("%s/%s", android_dir, dp->d_name);
461
462        android::base::ReadFileToString(file_name, &dt_file);
463        std::replace(dt_file.begin(), dt_file.end(), ',', '.');
464
465        std::string property_name = android::base::StringPrintf("ro.boot.%s", dp->d_name);
466        property_set(property_name.c_str(), dt_file.c_str());
467    }
468}
469
470static void process_kernel_cmdline() {
471    // Don't expose the raw commandline to unprivileged processes.
472    chmod("/proc/cmdline", 0440);
473
474    // The first pass does the common stuff, and finds if we are in qemu.
475    // The second pass is only necessary for qemu to export all kernel params
476    // as properties.
477    import_kernel_cmdline(false, import_kernel_nv);
478    if (qemu[0]) import_kernel_cmdline(true, import_kernel_nv);
479}
480
481static int queue_property_triggers_action(const std::vector<std::string>& args)
482{
483    ActionManager::GetInstance().QueueAllPropertyTriggers();
484    /* enable property triggers */
485    property_triggers_enabled = 1;
486    return 0;
487}
488
489static void selinux_init_all_handles(void)
490{
491    sehandle = selinux_android_file_context_handle();
492    selinux_android_set_sehandle(sehandle);
493    sehandle_prop = selinux_android_prop_context_handle();
494}
495
496enum selinux_enforcing_status { SELINUX_PERMISSIVE, SELINUX_ENFORCING };
497
498static selinux_enforcing_status selinux_status_from_cmdline() {
499    selinux_enforcing_status status = SELINUX_ENFORCING;
500
501    import_kernel_cmdline(false, [&](const std::string& key, const std::string& value, bool in_qemu) {
502        if (key == "androidboot.selinux" && value == "permissive") {
503            status = SELINUX_PERMISSIVE;
504        }
505    });
506
507    return status;
508}
509
510static bool selinux_is_enforcing(void)
511{
512    if (ALLOW_PERMISSIVE_SELINUX) {
513        return selinux_status_from_cmdline() == SELINUX_ENFORCING;
514    }
515    return true;
516}
517
518int selinux_reload_policy(void)
519{
520    INFO("SELinux: Attempting to reload policy files\n");
521
522    if (selinux_android_reload_policy() == -1) {
523        return -1;
524    }
525
526    if (sehandle)
527        selabel_close(sehandle);
528
529    if (sehandle_prop)
530        selabel_close(sehandle_prop);
531
532    selinux_init_all_handles();
533    return 0;
534}
535
536static int audit_callback(void *data, security_class_t /*cls*/, char *buf, size_t len) {
537
538    property_audit_data *d = reinterpret_cast<property_audit_data*>(data);
539
540    if (!d || !d->name || !d->cr) {
541        ERROR("audit_callback invoked with null data arguments!");
542        return 0;
543    }
544
545    snprintf(buf, len, "property=%s pid=%d uid=%d gid=%d", d->name,
546            d->cr->pid, d->cr->uid, d->cr->gid);
547    return 0;
548}
549
550static void selinux_initialize(bool in_kernel_domain) {
551    Timer t;
552
553    selinux_callback cb;
554    cb.func_log = selinux_klog_callback;
555    selinux_set_callback(SELINUX_CB_LOG, cb);
556    cb.func_audit = audit_callback;
557    selinux_set_callback(SELINUX_CB_AUDIT, cb);
558
559    if (in_kernel_domain) {
560        INFO("Loading SELinux policy...\n");
561        if (selinux_android_load_policy() < 0) {
562            ERROR("failed to load policy: %s\n", strerror(errno));
563            security_failure();
564        }
565
566        bool kernel_enforcing = (security_getenforce() == 1);
567        bool is_enforcing = selinux_is_enforcing();
568        if (kernel_enforcing != is_enforcing) {
569            if (security_setenforce(is_enforcing)) {
570                ERROR("security_setenforce(%s) failed: %s\n",
571                      is_enforcing ? "true" : "false", strerror(errno));
572                security_failure();
573            }
574        }
575
576        if (write_file("/sys/fs/selinux/checkreqprot", "0") == -1) {
577            security_failure();
578        }
579
580        NOTICE("(Initializing SELinux %s took %.2fs.)\n",
581               is_enforcing ? "enforcing" : "non-enforcing", t.duration());
582    } else {
583        selinux_init_all_handles();
584    }
585}
586
587int main(int argc, char** argv) {
588    if (!strcmp(basename(argv[0]), "ueventd")) {
589        return ueventd_main(argc, argv);
590    }
591
592    if (!strcmp(basename(argv[0]), "watchdogd")) {
593        return watchdogd_main(argc, argv);
594    }
595
596    // Clear the umask.
597    umask(0);
598
599    add_environment("PATH", _PATH_DEFPATH);
600
601    bool is_first_stage = (argc == 1) || (strcmp(argv[1], "--second-stage") != 0);
602
603    // Get the basic filesystem setup we need put together in the initramdisk
604    // on / and then we'll let the rc file figure out the rest.
605    if (is_first_stage) {
606        mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
607        mkdir("/dev/pts", 0755);
608        mkdir("/dev/socket", 0755);
609        mount("devpts", "/dev/pts", "devpts", 0, NULL);
610        #define MAKE_STR(x) __STRING(x)
611        mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
612        mount("sysfs", "/sys", "sysfs", 0, NULL);
613    }
614
615    // We must have some place other than / to create the device nodes for
616    // kmsg and null, otherwise we won't be able to remount / read-only
617    // later on. Now that tmpfs is mounted on /dev, we can actually talk
618    // to the outside world.
619    open_devnull_stdio();
620    klog_init();
621    klog_set_level(KLOG_NOTICE_LEVEL);
622
623    NOTICE("init %s started!\n", is_first_stage ? "first stage" : "second stage");
624
625    if (!is_first_stage) {
626        // Indicate that booting is in progress to background fw loaders, etc.
627        close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
628
629        property_init();
630
631        // If arguments are passed both on the command line and in DT,
632        // properties set in DT always have priority over the command-line ones.
633        process_kernel_dt();
634        process_kernel_cmdline();
635
636        // Propagate the kernel variables to internal variables
637        // used by init as well as the current required properties.
638        export_kernel_boot_props();
639    }
640
641    // Set up SELinux, including loading the SELinux policy if we're in the kernel domain.
642    selinux_initialize(is_first_stage);
643
644    // If we're in the kernel domain, re-exec init to transition to the init domain now
645    // that the SELinux policy has been loaded.
646    if (is_first_stage) {
647        if (restorecon("/init") == -1) {
648            ERROR("restorecon failed: %s\n", strerror(errno));
649            security_failure();
650        }
651        char* path = argv[0];
652        char* args[] = { path, const_cast<char*>("--second-stage"), nullptr };
653        if (execv(path, args) == -1) {
654            ERROR("execv(\"%s\") failed: %s\n", path, strerror(errno));
655            security_failure();
656        }
657    }
658
659    // These directories were necessarily created before initial policy load
660    // and therefore need their security context restored to the proper value.
661    // This must happen before /dev is populated by ueventd.
662    NOTICE("Running restorecon...\n");
663    restorecon("/dev");
664    restorecon("/dev/socket");
665    restorecon("/dev/__properties__");
666    restorecon("/property_contexts");
667    restorecon_recursive("/sys");
668
669    epoll_fd = epoll_create1(EPOLL_CLOEXEC);
670    if (epoll_fd == -1) {
671        ERROR("epoll_create1 failed: %s\n", strerror(errno));
672        exit(1);
673    }
674
675    signal_handler_init();
676
677    property_load_boot_defaults();
678    export_oem_lock_status();
679    start_property_service();
680
681    const BuiltinFunctionMap function_map;
682    Action::set_function_map(&function_map);
683
684    Parser& parser = Parser::GetInstance();
685    parser.AddSectionParser("service",std::make_unique<ServiceParser>());
686    parser.AddSectionParser("on", std::make_unique<ActionParser>());
687    parser.AddSectionParser("import", std::make_unique<ImportParser>());
688    parser.ParseConfig("/init.rc");
689
690    ActionManager& am = ActionManager::GetInstance();
691
692    am.QueueEventTrigger("early-init");
693
694    // Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...
695    am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
696    // ... so that we can start queuing up actions that require stuff from /dev.
697    am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
698    am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits");
699    am.QueueBuiltinAction(keychord_init_action, "keychord_init");
700    am.QueueBuiltinAction(console_init_action, "console_init");
701
702    // Trigger all the boot actions to get us started.
703    am.QueueEventTrigger("init");
704
705    // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
706    // wasn't ready immediately after wait_for_coldboot_done
707    am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
708
709    // Don't mount filesystems or start core system services in charger mode.
710    std::string bootmode = property_get("ro.bootmode");
711    if (bootmode == "charger") {
712        am.QueueEventTrigger("charger");
713    } else {
714        am.QueueEventTrigger("late-init");
715    }
716
717    // Run all property triggers based on current state of the properties.
718    am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");
719
720    while (true) {
721        if (!waiting_for_exec) {
722            am.ExecuteOneCommand();
723            restart_processes();
724        }
725
726        int timeout = -1;
727        if (process_needs_restart) {
728            timeout = (process_needs_restart - gettime()) * 1000;
729            if (timeout < 0)
730                timeout = 0;
731        }
732
733        if (am.HasMoreCommands()) {
734            timeout = 0;
735        }
736
737        bootchart_sample(&timeout);
738
739        epoll_event ev;
740        int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));
741        if (nr == -1) {
742            ERROR("epoll_wait failed: %s\n", strerror(errno));
743        } else if (nr == 1) {
744            ((void (*)()) ev.data.ptr)();
745        }
746    }
747
748    return 0;
749}
750