From 03468c8c509975f2f410b402b2bc211b42aa0ed9 Mon Sep 17 00:00:00 2001 From: Yabin Cui Date: Tue, 5 Apr 2016 13:50:44 -0700 Subject: [PATCH 1/3] adb: add reconnect command. Add reconnect command for debugging. `reconnect` kicks a transport from the host side, `reconnect device` kicks a transport from the device side. They can be used to produce transport errors. Bug: 25935458 Change-Id: I47daa338796b561941e7aba44a51a6dd117d1e98 (cherry picked from commit 1f4ec19e499ba981e4117f647d191603c2713e79) --- adb/adb.cpp | 7 +++++++ adb/adb_client.cpp | 11 +++++++---- adb/commandline.cpp | 11 +++++++++++ adb/services.cpp | 9 +++++++++ adb/transport.cpp | 6 +++++- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/adb/adb.cpp b/adb/adb.cpp index cb54d04e0..e0c05039d 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp @@ -1134,6 +1134,13 @@ int handle_host_request(const char* service, TransportType type, /* we don't even need to send a reply */ return 0; } + + if (!strcmp(service, "reconnect")) { + if (s->transport != nullptr) { + kick_transport(s->transport); + } + return SendOkay(reply_fd, "done"); + } #endif // ADB_HOST int ret = handle_forward_request(service, type, serial, reply_fd); diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp index db9b71087..7412587e7 100644 --- a/adb/adb_client.cpp +++ b/adb/adb_client.cpp @@ -149,7 +149,8 @@ int _adb_connect(const std::string& service, std::string* error) { } } - if (memcmp(&service[0],"host",4) != 0 && switch_socket_transport(fd, error)) { + if ((memcmp(&service[0],"host",4) != 0 || service == "host:reconnect") && + switch_socket_transport(fd, error)) { return -1; } @@ -159,9 +160,11 @@ int _adb_connect(const std::string& service, std::string* error) { return -1; } - if (!adb_status(fd, error)) { - adb_close(fd); - return -1; + if (service != "reconnect") { + if (!adb_status(fd, error)) { + adb_close(fd); + return -1; + } } D("_adb_connect: return fd %d", fd); diff --git a/adb/commandline.cpp b/adb/commandline.cpp index 8e76168cb..e635c3c3e 100644 --- a/adb/commandline.cpp +++ b/adb/commandline.cpp @@ -239,6 +239,9 @@ static void help() { " - If it is \"system\", \"vendor\", \"oem\" or \"data\", only the corresponding partition\n" " is updated.\n" "\n" + "internal debugging:\n" + " adb reconnect Kick current connection from host side and make it reconnect.\n" + " adb reconnect device Kick current connection from device side and make it reconnect.\n" "environment variables:\n" " ADB_TRACE - Print debug information. A comma separated list of the following values\n" " 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n" @@ -1857,6 +1860,14 @@ int adb_commandline(int argc, const char **argv) { } } return 0; + } else if (!strcmp(argv[0], "reconnect")) { + if (argc == 1) { + return adb_query_command("host:reconnect"); + } else if (argc == 2 && !strcmp(argv[1], "device")) { + std::string err; + adb_connect("reconnect", &err); + return 0; + } } usage(); diff --git a/adb/services.cpp b/adb/services.cpp index 2eef1c265..aacf2749a 100644 --- a/adb/services.cpp +++ b/adb/services.cpp @@ -184,6 +184,13 @@ void reboot_service(int fd, void* arg) adb_close(fd); } +static void reconnect_service(int fd, void* arg) { + WriteFdExactly(fd, "done"); + adb_close(fd); + atransport* t = static_cast(arg); + kick_transport(t); +} + int reverse_service(const char* command) { int s[2]; if (adb_socketpair(s)) { @@ -345,6 +352,8 @@ int service_to_fd(const char* name, const atransport* transport) { ret = create_service_thread(set_verity_enabled_state_service, (void*)0); } else if(!strncmp(name, "enable-verity:", 15)) { ret = create_service_thread(set_verity_enabled_state_service, (void*)1); + } else if (!strcmp(name, "reconnect")) { + ret = create_service_thread(reconnect_service, const_cast(transport)); #endif } if (ret >= 0) { diff --git a/adb/transport.cpp b/adb/transport.cpp index 8ca1e494a..d0c096178 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp @@ -304,7 +304,11 @@ static void kick_transport_locked(atransport* t) { void kick_transport(atransport* t) { adb_mutex_lock(&transport_lock); - kick_transport_locked(t); + // As kick_transport() can be called from threads without guarantee that t is valid, + // check if the transport is in transport_list first. + if (std::find(transport_list.begin(), transport_list.end(), t) != transport_list.end()) { + kick_transport_locked(t); + } adb_mutex_unlock(&transport_lock); } From 988e9bc1f80230c99f7b171b6669cdec77c62396 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Fri, 15 Apr 2016 11:35:00 -0700 Subject: [PATCH 2/3] adb: bump the server version to 36. The recent `adb root` changes are incompatible with older versions of the server. Bump the version number to force the server to restart. Bug: http://b/28194507 Change-Id: I970806e3b68c1f8e3273a4b1f0ecc4aca5086be9 (cherry picked from commit 057095d2076dfe571fb2a3c6904f77282aaeacaa) --- adb/adb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adb/adb.h b/adb/adb.h index 59644d43e..ea208004d 100644 --- a/adb/adb.h +++ b/adb/adb.h @@ -50,7 +50,7 @@ constexpr size_t MAX_PAYLOAD = MAX_PAYLOAD_V2; std::string adb_version(); // Increment this when we want to force users to start a new adb server. -#define ADB_SERVER_VERSION 35 +#define ADB_SERVER_VERSION 36 class atransport; struct usb_handle; From d1e2300a719d1effeea85cda9ac5a8f795c38390 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Mon, 18 Apr 2016 11:09:28 -0700 Subject: [PATCH 3/3] adb: increase the FD table size on Win32. 128 maximum FDs is a pretty low limit, which can easily be exhausted by port forwarding. Bump the maximum up to 2048, and add a test that checks whether we can actually use a few hundred sockets. Bug: https://code.google.com/p/android/issues/detail?id=12141 Bug: http://b/28246942 Change-Id: Ia4a2ff776e8e58ec13378756f19d80392679ece9 (cherry picked from commit b31e17107cfe5fe34e952657b846b1f93f568e88) --- adb/sysdeps_test.cpp | 29 +++++++++++++++++++++++++++++ adb/sysdeps_win32.cpp | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/adb/sysdeps_test.cpp b/adb/sysdeps_test.cpp index 78efea8ad..f0c334ef2 100644 --- a/adb/sysdeps_test.cpp +++ b/adb/sysdeps_test.cpp @@ -215,3 +215,32 @@ TEST_F(sysdeps_poll, disconnect) { // Linux returns POLLIN | POLLHUP, Windows returns just POLLHUP. EXPECT_EQ(POLLHUP, pfd.revents & POLLHUP); } + +TEST_F(sysdeps_poll, fd_count) { + // https://code.google.com/p/android/issues/detail?id=12141 + static constexpr int num_sockets = 512; + std::vector sockets; + std::vector pfds; + sockets.resize(num_sockets * 2); + for (int32_t i = 0; i < num_sockets; ++i) { + ASSERT_EQ(0, adb_socketpair(&sockets[i * 2])) << strerror(errno); + ASSERT_TRUE(WriteFdExactly(sockets[i * 2], &i, sizeof(i))); + adb_pollfd pfd; + pfd.events = POLLIN; + pfd.fd = sockets[i * 2 + 1]; + pfds.push_back(pfd); + } + + ASSERT_EQ(num_sockets, adb_poll(pfds.data(), pfds.size(), 0)); + for (int i = 0; i < num_sockets; ++i) { + ASSERT_NE(0, pfds[i].revents & POLLIN); + + int32_t buf[2] = { -1, -1 }; + ASSERT_EQ(adb_read(pfds[i].fd, buf, sizeof(buf)), static_cast(sizeof(int32_t))); + ASSERT_EQ(i, buf[0]); + } + + for (int fd : sockets) { + adb_close(fd); + } +} diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp index 7eae186c4..44ed81c94 100644 --- a/adb/sysdeps_win32.cpp +++ b/adb/sysdeps_win32.cpp @@ -191,7 +191,7 @@ typedef struct FHRec_ #define fh_socket u.socket #define WIN32_FH_BASE 2048 -#define WIN32_MAX_FHS 128 +#define WIN32_MAX_FHS 2048 static adb_mutex_t _win32_lock; static FHRec _win32_fhs[ WIN32_MAX_FHS ];