aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2009-08-04 20:37:51 -0400
committerMike Lockwood <lockwood@android.com>2009-08-05 17:57:20 -0400
commitee15662140632672a6878787a1ff26f5ebdc1e68 (patch)
treefb2d49a2abe6e380ac38ac86cf3ce2a04fc3fa62
parentc98c2b89706aeadb170472c3af9b381c58346d92 (diff)
downloadsystem_core-ee15662140632672a6878787a1ff26f5ebdc1e68.tar.gz
system_core-ee15662140632672a6878787a1ff26f5ebdc1e68.tar.bz2
system_core-ee15662140632672a6878787a1ff26f5ebdc1e68.zip
adb: add "adb reboot" command.
This will allow rebooting the device via adb on any build, including user builds. An optional argument can be provided (for example, "adb reboot bootloader" or adb reboot recovery") Signed-off-by: Mike Lockwood <lockwood@android.com>
-rw-r--r--adb/adb.c14
-rw-r--r--adb/adb.h2
-rw-r--r--adb/commandline.c17
-rw-r--r--adb/services.c20
4 files changed, 52 insertions, 1 deletions
diff --git a/adb/adb.c b/adb/adb.c
index 956df544..e8d2c8fa 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -30,6 +30,8 @@
#if !ADB_HOST
#include <private/android_filesystem_config.h>
+#include <linux/capability.h>
+#include <linux/prctl.h>
#else
#include "usb_vendors.h"
#endif
@@ -879,6 +881,11 @@ int adb_main(int is_daemon)
/* don't listen on port 5037 if we are running in secure mode */
/* don't run as root if we are running in secure mode */
if (secure) {
+ struct __user_cap_header_struct header;
+ struct __user_cap_data_struct cap;
+
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
/* add extra groups:
** AID_ADB to access the USB driver
** AID_LOG to read system logs (adb logcat)
@@ -896,6 +903,13 @@ int adb_main(int is_daemon)
setgid(AID_SHELL);
setuid(AID_SHELL);
+ /* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */
+ header.version = _LINUX_CAPABILITY_VERSION;
+ header.pid = 0;
+ cap.effective = cap.permitted = (1 << CAP_SYS_BOOT);
+ cap.inheritable = 0;
+ capset(&header, &cap);
+
D("Local port 5037 disabled\n");
} else {
if(install_listener("tcp:5037", "*smartsocket*", NULL)) {
diff --git a/adb/adb.h b/adb/adb.h
index 95610a73..8d57bf26 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -33,7 +33,7 @@
#define ADB_VERSION_MAJOR 1 // Used for help/version information
#define ADB_VERSION_MINOR 0 // Used for help/version information
-#define ADB_SERVER_VERSION 21 // Increment this when we want to force users to start a new adb server
+#define ADB_SERVER_VERSION 22 // Increment this when we want to force users to start a new adb server
typedef struct amessage amessage;
typedef struct apacket apacket;
diff --git a/adb/commandline.c b/adb/commandline.c
index ad1021ca..4ec5c8b7 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -148,6 +148,7 @@ void help()
" adb get-serialno - prints: <serial-number>\n"
" adb status-window - continuously print device status for a specified device\n"
" adb remount - remounts the /system partition on the device read-write\n"
+ " adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
" adb root - restarts adb with root permissions\n"
"\n"
"networking:\n"
@@ -918,6 +919,22 @@ top:
return 1;
}
+ if(!strcmp(argv[0], "reboot")) {
+ int fd;
+ if (argc > 1)
+ snprintf(buf, sizeof(buf), "reboot:%s", argv[1]);
+ else
+ snprintf(buf, sizeof(buf), "reboot:");
+ fd = adb_connect(buf);
+ if(fd >= 0) {
+ read_and_dump(fd);
+ adb_close(fd);
+ return 0;
+ }
+ fprintf(stderr,"error: %s\n", adb_error());
+ return 1;
+ }
+
if(!strcmp(argv[0], "root")) {
int fd = adb_connect("root:");
if(fd >= 0) {
diff --git a/adb/services.c b/adb/services.c
index 78d092b8..517da55f 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -33,6 +33,7 @@
# endif
#else
#include <sys/poll.h>
+#include <sys/reboot.h>
#endif
typedef struct stinfo stinfo;
@@ -133,6 +134,20 @@ void restart_root_service(int fd, void *cookie)
}
}
+void reboot_service(int fd, char *arg)
+{
+ char buf[100];
+ int ret;
+
+ sync();
+ ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, arg);
+ if (ret < 0) {
+ snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno));
+ writex(fd, buf, strlen(buf));
+ }
+ adb_close(fd);
+}
+
#endif
#if 0
@@ -399,6 +414,11 @@ int service_to_fd(const char *name)
ret = create_service_thread(file_sync_service, NULL);
} else if(!strncmp(name, "remount:", 8)) {
ret = create_service_thread(remount_service, NULL);
+ } else if(!strncmp(name, "reboot:", 7)) {
+ char* arg = name + 7;
+ if (*name == 0)
+ arg = NULL;
+ ret = create_service_thread(reboot_service, arg);
} else if(!strncmp(name, "root:", 5)) {
ret = create_service_thread(restart_root_service, NULL);
#endif