Merge "Make init handle reboots"
This commit is contained in:
commit
072ee01430
20
adb/adb.c
20
adb/adb.c
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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/*" },
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue