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