init.c revision 9c5366ba55b1553b2d66f48e3d14fbd274a2944d
14f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/* 24f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 34f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * 44f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 54f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * you may not use this file except in compliance with the License. 64f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * You may obtain a copy of the License at 74f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * 84f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 94f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * 104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * See the License for the specific language governing permissions and 144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * limitations under the License. 154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <stdio.h> 184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <stdlib.h> 194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <string.h> 204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <unistd.h> 214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <fcntl.h> 224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <ctype.h> 234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <signal.h> 244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/wait.h> 254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/mount.h> 264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/stat.h> 274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/poll.h> 284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <errno.h> 294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <stdarg.h> 304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <mtd/mtd-user.h> 314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/types.h> 324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/socket.h> 334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/un.h> 344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <cutils/sockets.h> 364e221f0077373b37ca70e862eface2987557295bSan Mehat#include <cutils/iosched_policy.h> 374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <termios.h> 384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/system_properties.h> 404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "devices.h" 424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "init.h" 434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "property_service.h" 4435237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project#include "bootchart.h" 459c5366ba55b1553b2d66f48e3d14fbd274a2944dColin Cross#include "signal_handler.h" 46a866695ebe3a396a0ec411c0f99e0921c74c0fd2Colin Cross#include "keychords.h" 47ca7648ddfb46347c60014a849b0150a74df4e1d2Colin Cross#include "parser.h" 484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int property_triggers_enabled = 0; 504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if BOOTCHART 524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int bootchart_count; 534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char console[32]; 564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char serialno[32]; 574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char bootmode[32]; 584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char baseband[32]; 594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char carrier[32]; 604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char bootloader[32]; 614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char hardware[32]; 624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic unsigned revision = 0; 634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char qemu[32]; 644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 659c5366ba55b1553b2d66f48e3d14fbd274a2944dColin Crossvoid notify_service_state(const char *name, const char *state) 664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char pname[PROP_NAME_MAX]; 684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int len = strlen(name); 694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if ((len + 10) > PROP_NAME_MAX) 704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(pname, sizeof(pname), "init.svc.%s", name); 724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set(pname, state); 734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int have_console; 764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char *console_name = "/dev/console"; 774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic time_t process_needs_restart; 784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic const char *ENV[32]; 804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/* add_environment - add "key=value" to the current environment */ 824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint add_environment(const char *key, const char *val) 834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int n; 854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (n = 0; n < 31; n++) { 874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!ENV[n]) { 884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project size_t len = strlen(key) + strlen(val) + 2; 894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *entry = malloc(len); 904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(entry, len, "%s=%s", key, val); 914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ENV[n] = entry; 924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 1; 974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void zap_stdio(void) 1004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 1014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 1024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/dev/null", O_RDWR); 1034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 0); 1044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 1); 1054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 2); 1064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 1074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 1084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void open_console() 1104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 1114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 1124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if ((fd = open(console_name, O_RDWR)) < 0) { 1134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/dev/null", O_RDWR); 1144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 0); 1164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 1); 1174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 2); 1184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 1194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 1204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void publish_socket(const char *name, int fd) 1224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 1234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char key[64] = ANDROID_SOCKET_ENV_PREFIX; 1244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char val[64]; 1254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1, 1274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project name, 1284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX)); 1294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(val, sizeof(val), "%d", fd); 1304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project add_environment(key, val); 1314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* make sure we don't close-on-exec */ 1334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fcntl(fd, F_SETFD, 0); 1344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 1354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 136f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehatvoid service_start(struct service *svc, const char *dynamic_args) 1374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 1384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct stat s; 1394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pid_t pid; 1404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int needs_console; 1414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int n; 1424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* starting a service removes it from the disabled 1444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * state and immediately takes it out of the restarting 1454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * state if it was in there 1464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 1474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING)); 1484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->time_started = 0; 1494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* running processes require no additional work -- if 1514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * they're in the process of exiting, we've ensured 1524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * that they will immediately restart on exit, unless 1534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * they are ONESHOT 1544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 1554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->flags & SVC_RUNNING) { 1564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 1574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project needs_console = (svc->flags & SVC_CONSOLE) ? 1 : 0; 1604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (needs_console && (!have_console)) { 1614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("service '%s' requires console\n", svc->name); 1624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_DISABLED; 1634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 1644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (stat(svc->args[0], &s) != 0) { 1674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("cannot find '%s', disabling '%s'\n", svc->args[0], svc->name); 1684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_DISABLED; 1694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 1704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 172f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat if ((!(svc->flags & SVC_ONESHOT)) && dynamic_args) { 173d4cdd13f6f56f3fe8d8511b609e823925fdd83f9San Mehat ERROR("service '%s' must be one-shot to use dynamic args, disabling\n", 174d4cdd13f6f56f3fe8d8511b609e823925fdd83f9San Mehat svc->args[0]); 175f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat svc->flags |= SVC_DISABLED; 176f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat return; 177f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat } 178f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat 1794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NOTICE("starting '%s'\n", svc->name); 1804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pid = fork(); 1824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (pid == 0) { 1844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct socketinfo *si; 1854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct svcenvinfo *ei; 1864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char tmp[32]; 1874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd, sz; 1884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project get_property_workspace(&fd, &sz); 1904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project sprintf(tmp, "%d,%d", dup(fd), sz); 1914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project add_environment("ANDROID_PROPERTY_WORKSPACE", tmp); 1924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (ei = svc->envvars; ei; ei = ei->next) 1944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project add_environment(ei->name, ei->value); 1954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (si = svc->sockets; si; si = si->next) { 1974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int s = create_socket(si->name, 1984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project !strcmp(si->type, "dgram") ? 1994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SOCK_DGRAM : SOCK_STREAM, 2004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project si->perm, si->uid, si->gid); 2014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (s >= 0) { 2024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project publish_socket(si->name, s); 2034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2064e221f0077373b37ca70e862eface2987557295bSan Mehat if (svc->ioprio_class != IoSchedClass_NONE) { 2074e221f0077373b37ca70e862eface2987557295bSan Mehat if (android_set_ioprio(getpid(), svc->ioprio_class, svc->ioprio_pri)) { 2084e221f0077373b37ca70e862eface2987557295bSan Mehat ERROR("Failed to set pid %d ioprio = %d,%d: %s\n", 2094e221f0077373b37ca70e862eface2987557295bSan Mehat getpid(), svc->ioprio_class, svc->ioprio_pri, strerror(errno)); 2104e221f0077373b37ca70e862eface2987557295bSan Mehat } 2114e221f0077373b37ca70e862eface2987557295bSan Mehat } 2124e221f0077373b37ca70e862eface2987557295bSan Mehat 2134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (needs_console) { 2144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setsid(); 2154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project open_console(); 2164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 2174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project zap_stdio(); 2184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if 0 2214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (n = 0; svc->args[n]; n++) { 2224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("args[%d] = '%s'\n", n, svc->args[n]); 2234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (n = 0; ENV[n]; n++) { 2254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("env[%d] = '%s'\n", n, ENV[n]); 2264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 2284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setpgid(0, getpid()); 2304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2315ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project /* as requested, set our gid, supplemental gids, and uid */ 2324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->gid) { 2334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setgid(svc->gid); 2344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->nr_supp_gids) { 2364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setgroups(svc->nr_supp_gids, svc->supp_gids); 2374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->uid) { 2394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setuid(svc->uid); 2404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2428ad15685e6d3d2251ceac4ac7135397cf6140e1aSan Mehat if (!dynamic_args) { 2438ad15685e6d3d2251ceac4ac7135397cf6140e1aSan Mehat if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) { 2448ad15685e6d3d2251ceac4ac7135397cf6140e1aSan Mehat ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno)); 2458ad15685e6d3d2251ceac4ac7135397cf6140e1aSan Mehat } 2468ad15685e6d3d2251ceac4ac7135397cf6140e1aSan Mehat } else { 247f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat char *arg_ptrs[SVC_MAXARGS+1]; 248d4cdd13f6f56f3fe8d8511b609e823925fdd83f9San Mehat int arg_idx = svc->nargs; 249f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat char *tmp = strdup(dynamic_args); 250d4cdd13f6f56f3fe8d8511b609e823925fdd83f9San Mehat char *next = tmp; 251d4cdd13f6f56f3fe8d8511b609e823925fdd83f9San Mehat char *bword; 252f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat 253f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat /* Copy the static arguments */ 254d4cdd13f6f56f3fe8d8511b609e823925fdd83f9San Mehat memcpy(arg_ptrs, svc->args, (svc->nargs * sizeof(char *))); 255f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat 256d4cdd13f6f56f3fe8d8511b609e823925fdd83f9San Mehat while((bword = strsep(&next, " "))) { 257d4cdd13f6f56f3fe8d8511b609e823925fdd83f9San Mehat arg_ptrs[arg_idx++] = bword; 258d4cdd13f6f56f3fe8d8511b609e823925fdd83f9San Mehat if (arg_idx == SVC_MAXARGS) 259f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat break; 260f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat } 261f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat arg_ptrs[arg_idx] = '\0'; 262f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat execve(svc->args[0], (char**) arg_ptrs, (char**) ENV); 263165de92bf1bca1648b4df3047a8f274e0aff4ca9Ivan Djelic } 2644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project _exit(127); 2654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (pid < 0) { 2684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("failed to start '%s'\n", svc->name); 2694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->pid = 0; 2704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 2714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->time_started = gettime(); 2744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->pid = pid; 2754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_RUNNING; 2764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project notify_service_state(svc->name, "running"); 2784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 2794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid service_stop(struct service *svc) 2814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 2824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* we are no longer running, nor should we 2834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * attempt to restart 2844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 2854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags &= (~(SVC_RUNNING|SVC_RESTARTING)); 2864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* if the service has not yet started, prevent 2884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * it from auto-starting with its class 2894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 2904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_DISABLED; 2914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->pid) { 2934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NOTICE("service '%s' is being killed\n", svc->name); 2944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project kill(-svc->pid, SIGTERM); 2954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project notify_service_state(svc->name, "stopping"); 2964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 2974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project notify_service_state(svc->name, "stopped"); 2984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 3004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid property_changed(const char *name, const char *value) 3024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 3034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (property_triggers_enabled) { 3044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project queue_property_triggers(name, value); 3054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 3064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 3084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void restart_service_if_needed(struct service *svc) 3104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 3114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project time_t next_start_time = svc->time_started + 5; 3124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (next_start_time <= gettime()) { 3144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags &= (~SVC_RESTARTING); 315f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat service_start(svc, NULL); 3164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 3174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if ((next_start_time < process_needs_restart) || 3204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project (process_needs_restart == 0)) { 3214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project process_needs_restart = next_start_time; 3224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 3244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void restart_processes() 3264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 3274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project process_needs_restart = 0; 3284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project service_for_each_flags(SVC_RESTARTING, 3294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project restart_service_if_needed); 3304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 3314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void msg_start(const char *name) 3334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 334f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat struct service *svc; 335f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat char *tmp = NULL; 336f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat char *args = NULL; 337f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat 338f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat if (!strchr(name, ':')) 339f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat svc = service_find_by_name(name); 340f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat else { 341f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat tmp = strdup(name); 342f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat args = strchr(tmp, ':'); 343f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat *args = '\0'; 344f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat args++; 345f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat 346f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat svc = service_find_by_name(tmp); 347f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat } 3484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc) { 350f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat service_start(svc, args); 3514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 3524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("no such service '%s'\n", name); 3534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 354f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat if (tmp) 355f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat free(tmp); 3564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 3574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void msg_stop(const char *name) 3594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 3604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct service *svc = service_find_by_name(name); 3614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc) { 3634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project service_stop(svc); 3644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 365770354d7e6cd471daed426fcf04bf7246e7cb18bDima Zavin ERROR("no such service '%s'\n", name); 3664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 3684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid handle_control_message(const char *msg, const char *arg) 3704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 3714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!strcmp(msg,"start")) { 3724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project msg_start(arg); 3734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(msg,"stop")) { 3744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project msg_stop(arg); 3754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 3764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("unknown control msg '%s'\n", msg); 3774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 3794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void import_kernel_nv(char *name, int in_qemu) 3814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 3824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *value = strchr(name, '='); 3834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (value == 0) return; 3854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *value++ = 0; 3864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (*name == 0) return; 3874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!in_qemu) 3894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project { 3904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* on a real device, white-list the kernel options */ 3914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!strcmp(name,"qemu")) { 3924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(qemu, value, sizeof(qemu)); 3934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.console")) { 3944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(console, value, sizeof(console)); 3954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.mode")) { 3964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(bootmode, value, sizeof(bootmode)); 3974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.serialno")) { 3984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(serialno, value, sizeof(serialno)); 3994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.baseband")) { 4004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(baseband, value, sizeof(baseband)); 4014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.carrier")) { 4024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(carrier, value, sizeof(carrier)); 4034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.bootloader")) { 4044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(bootloader, value, sizeof(bootloader)); 4054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.hardware")) { 4064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(hardware, value, sizeof(hardware)); 4074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 4084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project qemu_cmdline(name, value); 4094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 4114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* in the emulator, export any kernel option with the 4124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * ro.kernel. prefix */ 4134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char buff[32]; 4144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name ); 4154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (len < (int)sizeof(buff)) { 4164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set( buff, value ); 4174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 4204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void import_kernel_cmdline(int in_qemu) 4224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 4234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char cmdline[1024]; 4244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *ptr; 4254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 4264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/proc/cmdline", O_RDONLY); 4284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd >= 0) { 4294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int n = read(fd, cmdline, 1023); 4304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (n < 0) n = 0; 4314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* get rid of trailing newline, it happens */ 4334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (n > 0 && cmdline[n-1] == '\n') n--; 4344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project cmdline[n] = 0; 4364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 4374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 4384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project cmdline[0] = 0; 4394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ptr = cmdline; 4424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while (ptr && *ptr) { 4434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *x = strchr(ptr, ' '); 4444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (x != 0) *x++ = 0; 4454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project import_kernel_nv(ptr, in_qemu); 4464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ptr = x; 4474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* don't expose the raw commandline to nonpriv processes */ 4504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project chmod("/proc/cmdline", 0440); 4514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 4524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void get_hardware_name(void) 4544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 4554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char data[1024]; 4564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd, n; 4574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *x, *hw, *rev; 4584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* Hardware string was provided on kernel command line */ 4604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (hardware[0]) 4614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 4624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/proc/cpuinfo", O_RDONLY); 4644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd < 0) return; 4654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project n = read(fd, data, 1023); 4674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 4684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (n < 0) return; 4694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project data[n] = 0; 4714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project hw = strstr(data, "\nHardware"); 4724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project rev = strstr(data, "\nRevision"); 4734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (hw) { 4754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project x = strstr(hw, ": "); 4764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (x) { 4774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project x += 2; 4784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project n = 0; 4794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while (*x && !isspace(*x)) { 4804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project hardware[n++] = tolower(*x); 4814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project x++; 4824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (n == 31) break; 4834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project hardware[n] = 0; 4854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (rev) { 4894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project x = strstr(rev, ": "); 4904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (x) { 4914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project revision = strtoul(x + 2, 0, 16); 4924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 4954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 49611e1c42df69b15c938aa1b7570e4370e6ab15a86Jay Freeman (saurik)void drain_action_queue(void) 4974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 4984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct listnode *node; 4994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct command *cmd; 5004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct action *act; 5014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int ret; 5024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while ((act = action_remove_queue_head())) { 5044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("processing action %p (%s)\n", act, act->name); 5054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project list_for_each(node, &act->commands) { 5064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project cmd = node_to_item(node, struct command, clist); 5074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ret = cmd->func(cmd->nargs, cmd->args); 5084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("command '%s' r=%d\n", cmd->args[0], ret); 5094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 5124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid open_devnull_stdio(void) 5144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 5154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 5164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static const char *name = "/dev/__null__"; 5174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) { 5184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open(name, O_RDWR); 5194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project unlink(name); 5204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd >= 0) { 5214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 0); 5224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 1); 5234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 2); 5244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd > 2) { 5254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 5264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 5284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project exit(1); 5324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 5334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint main(int argc, char **argv) 5354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 5365ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project int fd_count; 5374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int s[2]; 5384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 5394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct sigaction act; 5404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char tmp[PROP_VALUE_MAX]; 5414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct pollfd ufds[4]; 5424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *tmpdev; 5435ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project char* debuggable; 5444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* clear the umask */ 5464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project umask(0); 5474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* Get the basic filesystem setup we need put 5494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * together in the initramdisk on / and then we'll 5504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * let the rc file figure out the rest. 5514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 5524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/dev", 0755); 5534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/proc", 0755); 5544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/sys", 0755); 5554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755"); 5574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/dev/pts", 0755); 5584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/dev/socket", 0755); 5594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mount("devpts", "/dev/pts", "devpts", 0, NULL); 5604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mount("proc", "/proc", "proc", 0, NULL); 5614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mount("sysfs", "/sys", "sysfs", 0, NULL); 5624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* We must have some place other than / to create the 5644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * device nodes for kmsg and null, otherwise we won't 5654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * be able to remount / read-only later on. 5664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Now that tmpfs is mounted on /dev, we can actually 5674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * talk to the outside world. 5684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 5694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project open_devnull_stdio(); 5704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project log_init(); 5714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("reading config file\n"); 5734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project parse_config_file("/init.rc"); 5744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* pull the kernel commandline and ramdisk properties file in */ 5764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project qemu_init(); 5774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project import_kernel_cmdline(0); 5784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project get_hardware_name(); 5804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware); 5814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project parse_config_file(tmp); 5824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project action_for_each_trigger("early-init", action_add_queue_tail); 5844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 5854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("device init\n"); 5870dd7ca6e87abb689700c5e3a816a949b03b1154bColin Cross device_init(); 5884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_init(); 5905ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 5915ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project // only listen for keychords if ro.debuggable is true 592a866695ebe3a396a0ec411c0f99e0921c74c0fd2Colin Cross keychord_init(); 5934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (console[0]) { 5954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(tmp, sizeof(tmp), "/dev/%s", console); 5964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project console_name = strdup(tmp); 5974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open(console_name, O_RDWR); 6004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd >= 0) 6014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project have_console = 1; 6024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 6034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if( load_565rle_image(INIT_IMAGE_FILE) ) { 6055ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project fd = open("/dev/tty0", O_WRONLY); 6065ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project if (fd >= 0) { 6075ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project const char *msg; 6084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project msg = "\n" 6095ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 6105ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 6115ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 6125ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 6135ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 6145ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" // console is 40 cols x 30 lines 6155ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 6165ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 6175ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 6185ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 6195ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 6205ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 6215ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 6225ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project " A N D R O I D "; 6235ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project write(fd, msg, strlen(msg)); 6245ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project close(fd); 6255ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } 6264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (qemu[0]) 6294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project import_kernel_cmdline(1); 6304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!strcmp(bootmode,"factory")) 6324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.factorytest", "1"); 6334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project else if (!strcmp(bootmode,"factory2")) 6344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.factorytest", "2"); 6354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project else 6364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.factorytest", "0"); 6374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.serialno", serialno[0] ? serialno : ""); 6394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown"); 6404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.baseband", baseband[0] ? baseband : "unknown"); 6414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.carrier", carrier[0] ? carrier : "unknown"); 6424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown"); 6434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.hardware", hardware); 6454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(tmp, PROP_VALUE_MAX, "%d", revision); 6464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.revision", tmp); 6474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* execute all the boot actions to get us started */ 6494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project action_for_each_trigger("init", action_add_queue_tail); 65031712beaf7de127a1249b909cdefffbc25fff076Colin Cross action_for_each_trigger("early-fs", action_add_queue_tail); 65131712beaf7de127a1249b909cdefffbc25fff076Colin Cross action_for_each_trigger("fs", action_add_queue_tail); 65231712beaf7de127a1249b909cdefffbc25fff076Colin Cross action_for_each_trigger("post-fs", action_add_queue_tail); 6534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 6544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* read any property files on system or data and 6564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * fire up the property service. This must happen 6574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * after the ro.foo properties are set above so 6584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * that /data/local.prop cannot interfere with them. 6594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 660d11beb2b1516144327c3f730f75e6b4bc65f1374Colin Cross start_property_service(); 6614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6629c5366ba55b1553b2d66f48e3d14fbd274a2944dColin Cross signal_init(); 6634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* make sure we actually have all the pieces we need */ 6650dd7ca6e87abb689700c5e3a816a949b03b1154bColin Cross if ((get_device_fd() < 0) || 666d11beb2b1516144327c3f730f75e6b4bc65f1374Colin Cross (get_property_set_fd() < 0) || 6679c5366ba55b1553b2d66f48e3d14fbd274a2944dColin Cross (get_signal_fd() < 0)) { 6684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("init startup failure\n"); 6694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 1; 6704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* execute all the boot actions to get us started */ 6734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project action_for_each_trigger("early-boot", action_add_queue_tail); 6744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project action_for_each_trigger("boot", action_add_queue_tail); 6754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 6764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* run all property triggers based on current state of the properties */ 6784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project queue_all_property_triggers(); 6794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 6804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* enable property triggers */ 6824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_triggers_enabled = 1; 6834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6840dd7ca6e87abb689700c5e3a816a949b03b1154bColin Cross ufds[0].fd = get_device_fd(); 6854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[0].events = POLLIN; 686d11beb2b1516144327c3f730f75e6b4bc65f1374Colin Cross ufds[1].fd = get_property_set_fd(); 6874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[1].events = POLLIN; 6889c5366ba55b1553b2d66f48e3d14fbd274a2944dColin Cross ufds[2].fd = get_signal_fd(); 6894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[2].events = POLLIN; 6905ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project fd_count = 3; 6915ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 692a866695ebe3a396a0ec411c0f99e0921c74c0fd2Colin Cross if (get_keychord_fd() > 0) { 693a866695ebe3a396a0ec411c0f99e0921c74c0fd2Colin Cross ufds[3].fd = get_keychord_fd(); 6945ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ufds[3].events = POLLIN; 6955ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project fd_count++; 6965ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } else { 6975ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ufds[3].events = 0; 6985ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ufds[3].revents = 0; 6995ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } 7004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if BOOTCHART 70235237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project bootchart_count = bootchart_init(); 70335237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project if (bootchart_count < 0) { 7044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("bootcharting init failure\n"); 70535237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project } else if (bootchart_count > 0) { 70635237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS); 70735237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project } else { 70835237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project NOTICE("bootcharting ignored\n"); 7094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 7104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 7114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for(;;) { 7135ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project int nr, i, timeout = -1; 7144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7155ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project for (i = 0; i < fd_count; i++) 7165ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ufds[i].revents = 0; 7174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 7194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project restart_processes(); 7204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (process_needs_restart) { 7224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project timeout = (process_needs_restart - gettime()) * 1000; 7234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (timeout < 0) 7244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project timeout = 0; 7254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 7264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if BOOTCHART 7284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (bootchart_count > 0) { 7294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (timeout < 0 || timeout > BOOTCHART_POLLING_MS) 7304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project timeout = BOOTCHART_POLLING_MS; 7314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (bootchart_step() < 0 || --bootchart_count == 0) { 7324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project bootchart_finish(); 7334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project bootchart_count = 0; 7344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 7354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 7364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 7375ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project nr = poll(ufds, fd_count, timeout); 7384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (nr <= 0) 7394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project continue; 7404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (ufds[2].revents == POLLIN) { 7429c5366ba55b1553b2d66f48e3d14fbd274a2944dColin Cross handle_signal(); 7434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project continue; 7444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 7454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (ufds[0].revents == POLLIN) 7470dd7ca6e87abb689700c5e3a816a949b03b1154bColin Cross handle_device_fd(); 7484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (ufds[1].revents == POLLIN) 750d11beb2b1516144327c3f730f75e6b4bc65f1374Colin Cross handle_property_set_fd(); 7515ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project if (ufds[3].revents == POLLIN) 752a866695ebe3a396a0ec411c0f99e0921c74c0fd2Colin Cross handle_keychord(); 7534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 7544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 7564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 757