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