From cf07494ac2a101c3afbe23a7d85121553f586cf7 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Tue, 5 May 2015 19:25:23 -0700 Subject: [PATCH] Split adb_main.cpp into client and daemon. The name "client" is somewhat misleading as it also contains the host side adb server, but it's a part of the client binary. Change-Id: I128b7bab213e330eb21b5010cd1fec5f7a62c8af --- adb/Android.mk | 4 +- adb/adb.cpp | 9 +- adb/adb.h | 1 - adb/client/main.cpp | 180 +++++++++++++++++ adb/{adb_main.cpp => daemon/main.cpp} | 269 ++++++-------------------- adb/usb_linux.cpp | 4 - adb/usb_linux_client.cpp | 4 - adb/usb_osx.cpp | 23 ++- adb/usb_windows.cpp | 6 - 9 files changed, 261 insertions(+), 239 deletions(-) create mode 100644 adb/client/main.cpp rename adb/{adb_main.cpp => daemon/main.cpp} (52%) diff --git a/adb/Android.mk b/adb/Android.mk index 1aed2cb27..4ffb589e3 100644 --- a/adb/Android.mk +++ b/adb/Android.mk @@ -175,7 +175,7 @@ endif LOCAL_CLANG := $(adb_host_clang) LOCAL_SRC_FILES := \ - adb_main.cpp \ + client/main.cpp \ console.cpp \ commandline.cpp \ adb_client.cpp \ @@ -227,7 +227,7 @@ include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_SRC_FILES := \ - adb_main.cpp \ + daemon/main.cpp \ services.cpp \ file_sync_service.cpp \ framebuffer_service.cpp \ diff --git a/adb/adb.cpp b/adb/adb.cpp index 9abcc73f5..c4e3434c0 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp @@ -796,13 +796,12 @@ int handle_forward_request(const char* service, TransportType type, const char* return 0; } -int handle_host_request(const char* service, TransportType type, const char* serial, int reply_fd, asocket *s) -{ - if(!strcmp(service, "kill")) { - fprintf(stderr,"adb server killed by remote request\n"); +int handle_host_request(const char* service, TransportType type, + const char* serial, int reply_fd, asocket* s) { + if (strcmp(service, "kill") == 0) { + fprintf(stderr, "adb server killed by remote request\n"); fflush(stdout); SendOkay(reply_fd); - usb_cleanup(); exit(0); } diff --git a/adb/adb.h b/adb/adb.h index daabf8c41..7942a8639 100644 --- a/adb/adb.h +++ b/adb/adb.h @@ -324,7 +324,6 @@ int local_connect_arbitrary_ports(int console_port, int adb_port); /* usb host/client interface */ void usb_init(); -void usb_cleanup(); int usb_write(usb_handle *h, const void *data, int len); int usb_read(usb_handle *h, void *data, int len); int usb_close(usb_handle *h); diff --git a/adb/client/main.cpp b/adb/client/main.cpp new file mode 100644 index 000000000..61fd6c5d2 --- /dev/null +++ b/adb/client/main.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define TRACE_TAG TRACE_ADB + +#include "sysdeps.h" + +#include +#include +#include + +// We only build the affinity WAR code for Linux. +#if defined(__linux__) +#include +#endif + +#include "base/file.h" +#include "base/logging.h" +#include "base/stringprintf.h" + +#include "adb.h" +#include "adb_auth.h" +#include "adb_listeners.h" +#include "transport.h" + +#if defined(WORKAROUND_BUG6558362) && defined(__linux__) +static const bool kWorkaroundBug6558362 = true; +#else +static const bool kWorkaroundBug6558362 = false; +#endif + +// We only build the affinity WAR code for Linux. +#if defined(__linux__) +static void adb_set_affinity(void) { + const char affinity_env[] = "ADB_CPU_AFFINITY_BUG6558362"; + const char* cpunum_str = getenv(affinity_env); + if (cpunum_str == nullptr || *cpunum_str == '\0') { + return; + } + + char* strtol_res; + int cpu_num = strtol(cpunum_str, &strtol_res, 0); + if (*strtol_res != '\0') { + fatal("bad number (%s) in env var %s. Expecting 0..n.\n", cpunum_str, + affinity_env); + } + + cpu_set_t cpu_set; + sched_getaffinity(0, sizeof(cpu_set), &cpu_set); + D("orig cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]); + + CPU_ZERO(&cpu_set); + CPU_SET(cpu_num, &cpu_set); + sched_setaffinity(0, sizeof(cpu_set), &cpu_set); + + sched_getaffinity(0, sizeof(cpu_set), &cpu_set); + D("new cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]); +} +#endif + +#if defined(_WIN32) +static const char kNullFileName[] = "NUL"; + +static BOOL WINAPI ctrlc_handler(DWORD type) { + exit(STATUS_CONTROL_C_EXIT); + return TRUE; +} + +static std::string GetLogFilePath() { + const char log_name[] = "adb.log"; + char temp_path[MAX_PATH - sizeof(log_name) + 1]; + + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx + DWORD nchars = GetTempPath(sizeof(temp_path), temp_path); + CHECK_LE(nchars, sizeof(temp_path)); + if (nchars == 0) { + // TODO(danalbert): Log the error message from FormatError(). + // Windows unfortunately has two errnos, errno and GetLastError(), so + // I'm not sure what to do about PLOG here. Probably better to just + // ignore it and add a simplified version of FormatError() for use in + // log messages. + LOG(ERROR) << "Error creating log file"; + } + + return std::string(temp_path) + log_name; +} +#else +static const char kNullFileName[] = "/dev/null"; + +static std::string GetLogFilePath() { + return std::string("/tmp/adb.log"); +} +#endif + +static void close_stdin() { + int fd = unix_open(kNullFileName, O_RDONLY); + CHECK_NE(fd, -1); + dup2(fd, STDIN_FILENO); + adb_close(fd); +} + +static void setup_daemon_logging(void) { + int fd = unix_open(GetLogFilePath().c_str(), O_WRONLY | O_CREAT | O_APPEND, + 0640); + if (fd == -1) { + fd = unix_open(kNullFileName, O_WRONLY); + } + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + adb_close(fd); + fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid()); +} + +int adb_main(int is_daemon, int server_port) { + HOST = 1; + +#if defined(_WIN32) + SetConsoleCtrlHandler(ctrlc_handler, TRUE); +#else + signal(SIGPIPE, SIG_IGN); +#endif + + init_transport_registration(); + +#if defined(__linux__) + if (kWorkaroundBug6558362 && is_daemon) { + adb_set_affinity(); + } +#endif + + usb_init(); + local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); + adb_auth_init(); + + std::string local_name = android::base::StringPrintf("tcp:%d", server_port); + if (install_listener(local_name, "*smartsocket*", nullptr, 0)) { + LOG(FATAL) << "Could not install *smartsocket* listener"; + } + + if (is_daemon) { + // Inform our parent that we are up and running. + // TODO(danalbert): Can't use SendOkay because we're sending "OK\n", not + // "OKAY". + // TODO(danalbert): Why do we use stdout for Windows? +#if defined(_WIN32) + int reply_fd = STDOUT_FILENO; +#else + int reply_fd = STDERR_FILENO; +#endif + android::base::WriteStringToFd("OK\n", reply_fd); + close_stdin(); + setup_daemon_logging(); + } + + D("Event loop starting\n"); + fdevent_loop(); + + return 0; +} + +int main(int argc, char** argv) { + // adb client/server + adb_sysdeps_init(); + adb_trace_init(); + D("Handling commandline()\n"); + return adb_commandline(argc - 1, const_cast(argv + 1)); +} diff --git a/adb/adb_main.cpp b/adb/daemon/main.cpp similarity index 52% rename from adb/adb_main.cpp rename to adb/daemon/main.cpp index 3f88d1303..d8eb03d2a 100644 --- a/adb/adb_main.cpp +++ b/adb/daemon/main.cpp @@ -22,66 +22,22 @@ #include #include #include +#include +#include + +#include "base/logging.h" +#include "base/stringprintf.h" +#include "cutils/properties.h" +#include "private/android_filesystem_config.h" +#include "selinux/selinux.h" #include "adb.h" #include "adb_auth.h" #include "adb_listeners.h" #include "transport.h" - -#include - -#if !ADB_HOST -#include -#include - -#include "cutils/properties.h" -#include "private/android_filesystem_config.h" -#include "selinux/selinux.h" - #include "qemu_tracing.h" -#endif -static void adb_cleanup(void) -{ - usb_cleanup(); -} - -#if defined(_WIN32) -static BOOL WINAPI ctrlc_handler(DWORD type) -{ - exit(STATUS_CONTROL_C_EXIT); - return TRUE; -} -#endif - -#if ADB_HOST -#ifdef WORKAROUND_BUG6558362 -#include -#define AFFINITY_ENVVAR "ADB_CPU_AFFINITY_BUG6558362" -void adb_set_affinity(void) -{ - cpu_set_t cpu_set; - const char* cpunum_str = getenv(AFFINITY_ENVVAR); - char* strtol_res; - int cpu_num; - - if (!cpunum_str || !*cpunum_str) - return; - cpu_num = strtol(cpunum_str, &strtol_res, 0); - if (*strtol_res != '\0') - fatal("bad number (%s) in env var %s. Expecting 0..n.\n", cpunum_str, AFFINITY_ENVVAR); - - sched_getaffinity(0, sizeof(cpu_set), &cpu_set); - D("orig cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]); - CPU_ZERO(&cpu_set); - CPU_SET(cpu_num, &cpu_set); - sched_setaffinity(0, sizeof(cpu_set), &cpu_set); - sched_getaffinity(0, sizeof(cpu_set), &cpu_set); - D("new cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]); -} -#endif -#else /* ADB_HOST */ -static const char *root_seclabel = NULL; +static const char* root_seclabel = nullptr; static void drop_capabilities_bounding_set_if_needed() { #ifdef ALLOW_ADBD_ROOT @@ -91,19 +47,19 @@ static void drop_capabilities_bounding_set_if_needed() { return; } #endif - int i; - for (i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) { + for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) { if (i == CAP_SETUID || i == CAP_SETGID) { // CAP_SETUID CAP_SETGID needed by /system/bin/run-as continue; } + int err = prctl(PR_CAPBSET_DROP, i, 0, 0, 0); // Some kernels don't have file capabilities compiled in, and // prctl(PR_CAPBSET_DROP) returns EINVAL. Don't automatically // die when we see such misconfigured kernels. if ((err < 0) && (errno != EINVAL)) { - exit(1); + PLOG(FATAL) << "Could not drop capabilities"; } } } @@ -155,120 +111,49 @@ static bool should_drop_privileges() { return drop; #else return true; // "adb root" not allowed, always drop privileges. -#endif /* ALLOW_ADBD_ROOT */ -} -#endif /* ADB_HOST */ - -void start_logging(void) -{ -#if defined(_WIN32) - char temp[ MAX_PATH ]; - FILE* fnul; - FILE* flog; - - GetTempPath( sizeof(temp) - 8, temp ); - strcat( temp, "adb.log" ); - - /* Win32 specific redirections */ - fnul = fopen( "NUL", "rt" ); - if (fnul != NULL) - stdin[0] = fnul[0]; - - flog = fopen( temp, "at" ); - if (flog == NULL) - flog = fnul; - - setvbuf( flog, NULL, _IONBF, 0 ); - - stdout[0] = flog[0]; - stderr[0] = flog[0]; - fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); -#else - int fd; - - fd = unix_open("/dev/null", O_RDONLY); - dup2(fd, 0); - adb_close(fd); - - fd = unix_open("/tmp/adb.log", O_WRONLY | O_CREAT | O_APPEND, 0640); - if(fd < 0) { - fd = unix_open("/dev/null", O_WRONLY); - } - dup2(fd, 1); - dup2(fd, 2); - adb_close(fd); - fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); -#endif +#endif // ALLOW_ADBD_ROOT } -int adb_main(int is_daemon, int server_port) -{ -#if !ADB_HOST - int port; - char value[PROPERTY_VALUE_MAX]; +int adbd_main(int server_port) { + umask(0); - umask(000); -#endif - - atexit(adb_cleanup); -#if defined(_WIN32) - SetConsoleCtrlHandler( ctrlc_handler, TRUE ); -#else - // No SIGCHLD. Let the service subproc handle its children. signal(SIGPIPE, SIG_IGN); -#endif init_transport_registration(); -#if ADB_HOST - HOST = 1; - -#ifdef WORKAROUND_BUG6558362 - if(is_daemon) adb_set_affinity(); -#endif - usb_init(); - local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); - adb_auth_init(); - - std::string local_name = android::base::StringPrintf("tcp:%d", server_port); - if (install_listener(local_name, "*smartsocket*", NULL, 0)) { - exit(1); - } -#else // We need to call this even if auth isn't enabled because the file // descriptor will always be open. adbd_cloexec_auth_socket(); - property_get("ro.adb.secure", value, "0"); - auth_enabled = !strcmp(value, "1"); - if (auth_enabled) + auth_enabled = property_get_bool("ro.adb.secure", 0) != 0; + if (auth_enabled) { adbd_auth_init(); + } // Our external storage path may be different than apps, since // we aren't able to bind mount after dropping root. const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE"); - if (NULL != adb_external_storage) { + if (adb_external_storage != nullptr) { setenv("EXTERNAL_STORAGE", adb_external_storage, 1); } else { D("Warning: ADB_EXTERNAL_STORAGE is not set. Leaving EXTERNAL_STORAGE" " unchanged.\n"); } - /* add extra groups: - ** AID_ADB to access the USB driver - ** AID_LOG to read system logs (adb logcat) - ** AID_INPUT to diagnose input issues (getevent) - ** AID_INET to diagnose network issues (ping) - ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump) - ** AID_SDCARD_R to allow reading from the SD card - ** AID_SDCARD_RW to allow writing to the SD card - ** AID_NET_BW_STATS to read out qtaguid statistics - */ - gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_NET_BT, - AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW, - AID_NET_BW_STATS }; - if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { - exit(1); + // Add extra groups: + // AID_ADB to access the USB driver + // AID_LOG to read system logs (adb logcat) + // AID_INPUT to diagnose input issues (getevent) + // AID_INET to diagnose network issues (ping) + // AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump) + // AID_SDCARD_R to allow reading from the SD card + // AID_SDCARD_RW to allow writing to the SD card + // AID_NET_BW_STATS to read out qtaguid statistics + gid_t groups[] = {AID_ADB, AID_LOG, AID_INPUT, + AID_INET, AID_NET_BT, AID_NET_BT_ADMIN, + AID_SDCARD_R, AID_SDCARD_RW, AID_NET_BW_STATS}; + if (setgroups(sizeof(groups) / sizeof(groups[0]), groups) != 0) { + PLOG(FATAL) << "Could not set supplental groups"; } /* don't listen on a port (default 5037) if running in secure mode */ @@ -278,96 +163,73 @@ int adb_main(int is_daemon, int server_port) /* then switch user and group to "shell" */ if (setgid(AID_SHELL) != 0) { - exit(1); + PLOG(FATAL) << "Could not setgid"; } if (setuid(AID_SHELL) != 0) { - exit(1); + PLOG(FATAL) << "Could not setuid"; } D("Local port disabled\n"); } else { - if ((root_seclabel != NULL) && (is_selinux_enabled() > 0)) { - // b/12587913: fix setcon to allow const pointers - if (setcon((char *)root_seclabel) < 0) { - exit(1); + if ((root_seclabel != nullptr) && (is_selinux_enabled() > 0)) { + if (setcon(root_seclabel) < 0) { + LOG(FATAL) << "Could not set selinux context"; } } - std::string local_name = android::base::StringPrintf("tcp:%d", server_port); - if (install_listener(local_name, "*smartsocket*", NULL, 0)) { - exit(1); + std::string local_name = + android::base::StringPrintf("tcp:%d", server_port); + if (install_listener(local_name, "*smartsocket*", nullptr, 0)) { + LOG(FATAL) << "Could not install *smartsocket* listener"; } } - int usb = 0; + bool is_usb = false; if (access(USB_ADB_PATH, F_OK) == 0 || access(USB_FFS_ADB_EP0, F_OK) == 0) { - // listen on USB + // Listen on USB. usb_init(); - usb = 1; + is_usb = true; } - // If one of these properties is set, also listen on that port - // If one of the properties isn't set and we couldn't listen on usb, - // listen on the default port. - property_get("service.adb.tcp.port", value, ""); - if (!value[0]) { - property_get("persist.adb.tcp.port", value, ""); + // If one of these properties is set, also listen on that port. + // If one of the properties isn't set and we couldn't listen on usb, listen + // on the default port. + char prop_port[PROPERTY_VALUE_MAX]; + property_get("service.adb.tcp.port", prop_port, ""); + if (prop_port[0] == '\0') { + property_get("persist.adb.tcp.port", prop_port, ""); } - if (sscanf(value, "%d", &port) == 1 && port > 0) { + + int port; + if (sscanf(prop_port, "%d", &port) == 1 && port > 0) { printf("using port=%d\n", port); - // listen on TCP port specified by service.adb.tcp.port property + // Listen on TCP port specified by service.adb.tcp.port property. local_init(port); - } else if (!usb) { - // listen on default port + } else if (!is_usb) { + // Listen on default port. local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); } - D("adb_main(): pre init_jdwp()\n"); + D("adbd_main(): pre init_jdwp()\n"); init_jdwp(); - D("adb_main(): post init_jdwp()\n"); -#endif + D("adbd_main(): post init_jdwp()\n"); - if (is_daemon) - { - // inform our parent that we are up and running. -#if defined(_WIN32) - DWORD count; - WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL ); -#else - fprintf(stderr, "OK\n"); -#endif - start_logging(); - } D("Event loop starting\n"); - fdevent_loop(); - usb_cleanup(); - return 0; } -#if !ADB_HOST -void close_stdin() { +static void close_stdin() { int fd = unix_open("/dev/null", O_RDONLY); if (fd == -1) { perror("failed to open /dev/null, stdin will remain open"); return; } - dup2(fd, 0); + dup2(fd, STDIN_FILENO); adb_close(fd); } -#endif -// TODO(danalbert): Split this file up into adb_main.cpp and adbd_main.cpp. -int main(int argc, char **argv) { -#if ADB_HOST - // adb client/server - adb_sysdeps_init(); - adb_trace_init(); - D("Handling commandline()\n"); - return adb_commandline(argc - 1, const_cast(argv + 1)); -#else - // adbd +int main(int argc, char** argv) { while (true) { static struct option opts[] = { {"root_seclabel", required_argument, nullptr, 's'}, @@ -377,8 +239,6 @@ int main(int argc, char **argv) { int option_index = 0; int c = getopt_long(argc, argv, "", opts, &option_index); - if (c == -1) - break; switch (c) { case 's': root_seclabel = optarg; @@ -405,6 +265,5 @@ int main(int argc, char **argv) { adb_qemu_trace_init(); D("Handling main()\n"); - return adb_main(0, DEFAULT_ADB_PORT); -#endif + return adbd_main(DEFAULT_ADB_PORT); } diff --git a/adb/usb_linux.cpp b/adb/usb_linux.cpp index 132883079..1e5d5c88d 100644 --- a/adb/usb_linux.cpp +++ b/adb/usb_linux.cpp @@ -310,10 +310,6 @@ static void find_usb_device(const char *base, closedir(busdir); } -void usb_cleanup() -{ -} - static int usb_bulk_write(usb_handle *h, const void *data, int len) { struct usbdevfs_urb *urb = &h->urb_out; diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp index 1d6ed94c8..63bb1c71b 100644 --- a/adb/usb_linux_client.cpp +++ b/adb/usb_linux_client.cpp @@ -495,10 +495,6 @@ void usb_init() usb_adb_init(); } -void usb_cleanup() -{ -} - int usb_write(usb_handle *h, const void *data, int len) { return h->write(h, data, len); diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp index 0d0b3ad63..af6513093 100644 --- a/adb/usb_osx.cpp +++ b/adb/usb_osx.cpp @@ -401,11 +401,18 @@ void* RunLoopThread(void* unused) return NULL; } +static void usb_cleanup() { + DBG("usb_cleanup\n"); + close_usb_devices(); + if (currentRunLoop) + CFRunLoopStop(currentRunLoop); +} -static int initialized = 0; void usb_init() { - if (!initialized) - { + static bool initialized = false; + if (!initialized) { + atexit(usb_cleanup); + adb_mutex_init(&start_lock, NULL); adb_cond_init(&start_cond, NULL); @@ -421,18 +428,10 @@ void usb_init() { adb_mutex_destroy(&start_lock); adb_cond_destroy(&start_cond); - initialized = 1; + initialized = true; } } -void usb_cleanup() -{ - DBG("usb_cleanup\n"); - close_usb_devices(); - if (currentRunLoop) - CFRunLoopStop(currentRunLoop); -} - int usb_write(usb_handle *handle, const void *buf, int len) { IOReturn result; diff --git a/adb/usb_windows.cpp b/adb/usb_windows.cpp index 1d6ec8cd8..25deb1bea 100644 --- a/adb/usb_windows.cpp +++ b/adb/usb_windows.cpp @@ -93,9 +93,6 @@ void* device_poll_thread(void* unused); /// Initializes this module void usb_init(); -/// Cleans up this module -void usb_cleanup(); - /// Opens usb interface (device) by interface (device) name. usb_handle* do_usb_open(const wchar_t* interface_name); @@ -186,9 +183,6 @@ void usb_init() { } } -void usb_cleanup() { -} - usb_handle* do_usb_open(const wchar_t* interface_name) { // Allocate our handle usb_handle* ret = (usb_handle*)malloc(sizeof(usb_handle));