Merge "Make init handle reboots"

This commit is contained in:
Nick Kralevich 2013-04-24 15:43:09 +00:00 committed by Android (Google) Code Review
commit 072ee01430
11 changed files with 80 additions and 49 deletions

View File

@ -1199,9 +1199,8 @@ static void drop_capabilities_bounding_set_if_needed() {
#endif
int i;
for (i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
if (i == CAP_SETUID || i == CAP_SETGID || i == CAP_SYS_BOOT) {
if (i == CAP_SETUID || i == CAP_SETGID) {
// CAP_SETUID CAP_SETGID needed by /system/bin/run-as
// CAP_SYS_BOOT needed by /system/bin/reboot
continue;
}
int err = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
@ -1302,13 +1301,6 @@ int adb_main(int is_daemon, int server_port)
/* don't listen on a port (default 5037) if running in secure mode */
/* don't run as root if we are running in secure mode */
if (should_drop_privileges()) {
struct __user_cap_header_struct header;
struct __user_cap_data_struct cap[2];
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
exit(1);
}
drop_capabilities_bounding_set_if_needed();
/* add extra groups:
@ -1338,16 +1330,6 @@ int adb_main(int is_daemon, int server_port)
exit(1);
}
memset(&header, 0, sizeof(header));
memset(cap, 0, sizeof(cap));
/* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */
header.version = _LINUX_CAPABILITY_VERSION_3;
header.pid = 0;
cap[CAP_TO_INDEX(CAP_SYS_BOOT)].effective |= CAP_TO_MASK(CAP_SYS_BOOT);
cap[CAP_TO_INDEX(CAP_SYS_BOOT)].permitted |= CAP_TO_MASK(CAP_SYS_BOOT);
capset(&header, cap);
D("Local port disabled\n");
} else {
char local_name[30];

View File

@ -165,6 +165,7 @@ void restart_usb_service(int fd, void *cookie)
void reboot_service(int fd, void *arg)
{
char buf[100];
char property_val[PROPERTY_VALUE_MAX];
int pid, ret;
sync();
@ -182,11 +183,19 @@ void reboot_service(int fd, void *arg)
waitpid(pid, &ret, 0);
}
ret = android_reboot(ANDROID_RB_RESTART2, 0, (char *) arg);
ret = snprintf(property_val, sizeof(property_val), "reboot,%s", (char *) arg);
if (ret >= (int) sizeof(property_val)) {
snprintf(buf, sizeof(buf), "reboot string too long. length=%d\n", ret);
writex(fd, buf, strlen(buf));
goto cleanup;
}
ret = property_set(ANDROID_RB_PROPERTY, property_val);
if (ret < 0) {
snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno));
snprintf(buf, sizeof(buf), "reboot failed: %d\n", ret);
writex(fd, buf, strlen(buf));
}
cleanup:
free(arg);
adb_close(fd);
}

View File

@ -24,9 +24,8 @@ __BEGIN_DECLS
#define ANDROID_RB_POWEROFF 0xDEAD0002
#define ANDROID_RB_RESTART2 0xDEAD0003
/* Flags */
#define ANDROID_RB_FLAG_NO_SYNC 0x1
#define ANDROID_RB_FLAG_NO_REMOUNT_RO 0x2
/* Properties */
#define ANDROID_RB_PROPERTY "sys.powerctl"
int android_reboot(int cmd, int flags, char *arg);

View File

@ -230,7 +230,6 @@ static const struct fs_path_config android_files[] = {
/* the following files have enhanced capabilities and ARE included in user builds. */
{ 00750, AID_ROOT, AID_SHELL, (1 << CAP_SETUID) | (1 << CAP_SETGID), "system/bin/run-as" },
{ 00750, AID_ROOT, AID_SHELL, 1 << CAP_SYS_BOOT, "system/bin/reboot" },
{ 00755, AID_ROOT, AID_SHELL, 0, "system/bin/*" },
{ 00755, AID_ROOT, AID_ROOT, 0, "system/lib/valgrind/*" },

View File

@ -32,6 +32,7 @@
#include <sys/wait.h>
#include <linux/loop.h>
#include <cutils/partition_utils.h>
#include <cutils/android_reboot.h>
#include <sys/system_properties.h>
#include <fs_mgr.h>
@ -599,6 +600,43 @@ int do_restart(int nargs, char **args)
return 0;
}
int do_powerctl(int nargs, char **args)
{
char command[PROP_VALUE_MAX];
int res;
int len = 0;
int cmd = 0;
char *reboot_target;
res = expand_props(command, args[1], sizeof(command));
if (res) {
ERROR("powerctl: cannot expand '%s'\n", args[1]);
return -EINVAL;
}
if (strncmp(command, "shutdown", 8) == 0) {
cmd = ANDROID_RB_POWEROFF;
len = 8;
} else if (strncmp(command, "reboot", 6) == 0) {
cmd = ANDROID_RB_RESTART2;
len = 6;
} else {
ERROR("powerctl: unrecognized command '%s'\n", command);
return -EINVAL;
}
if (command[len] == ',') {
reboot_target = &command[len + 1];
} else if (command[len] == '\0') {
reboot_target = "";
} else {
ERROR("powerctl: unrecognized reboot target '%s'\n", &command[len]);
return -EINVAL;
}
return android_reboot(cmd, 0, reboot_target);
}
int do_trigger(int nargs, char **args)
{
action_for_each_trigger(args[1], action_add_queue_tail);

View File

@ -130,6 +130,8 @@ int lookup_keyword(const char *s)
if (!strcmp(s, "neshot")) return K_oneshot;
if (!strcmp(s, "nrestart")) return K_onrestart;
break;
case 'p':
if (!strcmp(s, "owerctl")) return K_powerctl;
case 'r':
if (!strcmp(s, "estart")) return K_restart;
if (!strcmp(s, "estorecon")) return K_restorecon;

View File

@ -14,6 +14,7 @@ int do_insmod(int nargs, char **args);
int do_mkdir(int nargs, char **args);
int do_mount_all(int nargs, char **args);
int do_mount(int nargs, char **args);
int do_powerctl(int nargs, char **args);
int do_restart(int nargs, char **args);
int do_restorecon(int nargs, char **args);
int do_rm(int nargs, char **args);
@ -66,6 +67,7 @@ enum {
KEYWORD(on, SECTION, 0, 0)
KEYWORD(oneshot, OPTION, 0, 0)
KEYWORD(onrestart, OPTION, 0, 0)
KEYWORD(powerctl, COMMAND, 1, do_powerctl)
KEYWORD(restart, COMMAND, 1, do_restart)
KEYWORD(restorecon, COMMAND, 1, do_restorecon)
KEYWORD(rm, COMMAND, 1, do_rm)

1
init/property_service.c Executable file → Normal file
View File

@ -77,6 +77,7 @@ struct {
{ "runtime.", AID_SYSTEM, 0 },
{ "hw.", AID_SYSTEM, 0 },
{ "sys.", AID_SYSTEM, 0 },
{ "sys.powerctl", AID_SHELL, 0 },
{ "service.", AID_SYSTEM, 0 },
{ "wlan.", AID_SYSTEM, 0 },
{ "bluetooth.", AID_BLUETOOTH, 0 },

View File

@ -105,11 +105,8 @@ int android_reboot(int cmd, int flags, char *arg)
{
int ret;
if (!(flags & ANDROID_RB_FLAG_NO_SYNC))
sync();
if (!(flags & ANDROID_RB_FLAG_NO_REMOUNT_RO))
remount_ro();
sync();
remount_ro();
switch (cmd) {
case ANDROID_RB_RESTART:

View File

@ -17,35 +17,34 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <cutils/properties.h>
#include <cutils/android_reboot.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int ret;
int nosync = 0;
int poweroff = 0;
int flags = 0;
size_t prop_len;
char property_val[PROPERTY_VALUE_MAX];
const char *cmd = "reboot";
char *optarg = "";
opterr = 0;
do {
int c;
c = getopt(argc, argv, "np");
c = getopt(argc, argv, "p");
if (c == EOF) {
break;
}
switch (c) {
case 'n':
nosync = 1;
break;
case 'p':
poweroff = 1;
cmd = "shutdown";
break;
case '?':
fprintf(stderr, "usage: %s [-n] [-p] [rebootcommand]\n", argv[0]);
fprintf(stderr, "usage: %s [-p] [rebootcommand]\n", argv[0]);
exit(EXIT_FAILURE);
}
} while (1);
@ -55,20 +54,20 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
if(nosync)
/* also set NO_REMOUNT_RO as remount ro includes an implicit sync */
flags = ANDROID_RB_FLAG_NO_SYNC | ANDROID_RB_FLAG_NO_REMOUNT_RO;
if (argc > optind)
optarg = argv[optind];
if(poweroff)
ret = android_reboot(ANDROID_RB_POWEROFF, flags, 0);
else if(argc > optind)
ret = android_reboot(ANDROID_RB_RESTART2, flags, argv[optind]);
else
ret = android_reboot(ANDROID_RB_RESTART, flags, 0);
prop_len = snprintf(property_val, sizeof(property_val), "%s,%s", cmd, optarg);
if (prop_len >= sizeof(property_val)) {
fprintf(stderr, "reboot command too long: %s\n", optarg);
exit(EXIT_FAILURE);
}
ret = property_set(ANDROID_RB_PROPERTY, property_val);
if(ret < 0) {
perror("reboot");
exit(EXIT_FAILURE);
}
fprintf(stderr, "reboot returned\n");
fprintf(stderr, "Done\n");
return 0;
}

View File

@ -398,6 +398,9 @@ on property:vold.decrypt=trigger_shutdown_framework
class_reset late_start
class_reset main
on property:sys.powerctl=*
powerctl ${sys.powerctl}
## Daemon processes to be run by init.
##
service ueventd /sbin/ueventd