Merge changes I9b5b2876,I3b93e0a9 am: 94a9ae334e am: fc87fc210a
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1697653
Change-Id: Ie4e84581e417b39b6a0b81b4e1d0864e731bce46
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index e9186f0..a6850ff 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -49,8 +49,6 @@
return setupSocketServer(UnixSocketAddress(path));
}
-#ifdef __BIONIC__
-
bool RpcServer::setupVsockServer(unsigned int port) {
// realizing value w/ this type at compile time to avoid ubsan abort
constexpr unsigned int kAnyCid = VMADDR_CID_ANY;
@@ -58,8 +56,6 @@
return setupSocketServer(VsockSocketAddress(kAnyCid, port));
}
-#endif // __BIONIC__
-
bool RpcServer::setupInetServer(unsigned int port, unsigned int* assignedPort) {
const char* kAddr = "127.0.0.1";
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index d9b5c73..0471705 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -61,14 +61,10 @@
return setupSocketClient(UnixSocketAddress(path));
}
-#ifdef __BIONIC__
-
bool RpcSession::setupVsockClient(unsigned int cid, unsigned int port) {
return setupSocketClient(VsockSocketAddress(cid, port));
}
-#endif // __BIONIC__
-
bool RpcSession::setupInetClient(const char* addr, unsigned int port) {
auto aiStart = InetSocketAddress::getAddrInfo(addr, port);
if (aiStart == nullptr) return false;
@@ -219,42 +215,52 @@
// we've already setup one client
for (size_t i = 0; i + 1 < numThreadsAvailable; i++) {
- // TODO(b/185167543): avoid race w/ accept4 not being called on server
- for (size_t tries = 0; tries < 5; tries++) {
- if (setupOneSocketClient(addr, mId.value())) break;
- usleep(10000);
- }
+ // TODO(b/185167543): shutdown existing connections?
+ if (!setupOneSocketClient(addr, mId.value())) return false;
}
return true;
}
bool RpcSession::setupOneSocketClient(const RpcSocketAddress& addr, int32_t id) {
- unique_fd serverFd(
- TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
- if (serverFd == -1) {
- int savedErrno = errno;
- ALOGE("Could not create socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
- return false;
+ for (size_t tries = 0; tries < 5; tries++) {
+ if (tries > 0) usleep(10000);
+
+ unique_fd serverFd(
+ TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
+ if (serverFd == -1) {
+ int savedErrno = errno;
+ ALOGE("Could not create socket at %s: %s", addr.toString().c_str(),
+ strerror(savedErrno));
+ return false;
+ }
+
+ if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), addr.addr(), addr.addrSize()))) {
+ if (errno == ECONNRESET) {
+ ALOGW("Connection reset on %s", addr.toString().c_str());
+ continue;
+ }
+ int savedErrno = errno;
+ ALOGE("Could not connect socket at %s: %s", addr.toString().c_str(),
+ strerror(savedErrno));
+ return false;
+ }
+
+ if (sizeof(id) != TEMP_FAILURE_RETRY(write(serverFd.get(), &id, sizeof(id)))) {
+ int savedErrno = errno;
+ ALOGE("Could not write id to socket at %s: %s", addr.toString().c_str(),
+ strerror(savedErrno));
+ return false;
+ }
+
+ LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get());
+
+ addClient(std::move(serverFd));
+ return true;
}
- if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), addr.addr(), addr.addrSize()))) {
- int savedErrno = errno;
- ALOGE("Could not connect socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
- return false;
- }
-
- if (sizeof(id) != TEMP_FAILURE_RETRY(write(serverFd.get(), &id, sizeof(id)))) {
- int savedErrno = errno;
- ALOGE("Could not write id to socket at %s: %s", addr.toString().c_str(),
- strerror(savedErrno));
- return false;
- }
-
- LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get());
-
- addClient(std::move(serverFd));
- return true;
+ ALOGE("Ran out of retries to connect to %s", addr.toString().c_str());
+ return false;
}
void RpcSession::addClient(unique_fd fd) {
diff --git a/libs/binder/RpcSocketAddress.h b/libs/binder/RpcSocketAddress.h
index c6a06cf..c7ba5d9 100644
--- a/libs/binder/RpcSocketAddress.h
+++ b/libs/binder/RpcSocketAddress.h
@@ -24,9 +24,7 @@
#include <sys/types.h>
#include <sys/un.h>
-#ifdef __BIONIC__
-#include <linux/vm_sockets.h>
-#endif
+#include "vm_sockets.h"
namespace android {
@@ -59,8 +57,6 @@
sockaddr_un mAddr;
};
-#ifdef __BIONIC__
-
class VsockSocketAddress : public RpcSocketAddress {
public:
VsockSocketAddress(unsigned int cid, unsigned int port)
@@ -80,8 +76,6 @@
sockaddr_vm mAddr;
};
-#endif // __BIONIC__
-
class InetSocketAddress : public RpcSocketAddress {
public:
InetSocketAddress(const sockaddr* sockAddr, size_t size, const char* addr, unsigned int port)
diff --git a/libs/binder/include/binder/RpcServer.h b/libs/binder/include/binder/RpcServer.h
index 8c9ba00..3534d51 100644
--- a/libs/binder/include/binder/RpcServer.h
+++ b/libs/binder/include/binder/RpcServer.h
@@ -57,12 +57,10 @@
*/
[[nodiscard]] bool setupUnixDomainServer(const char* path);
-#ifdef __BIONIC__
/**
* Creates an RPC server at the current port.
*/
[[nodiscard]] bool setupVsockServer(unsigned int port);
-#endif // __BIONIC__
/**
* Creates an RPC server at the current port using IPv4.
diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h
index f647c95..0b77787 100644
--- a/libs/binder/include/binder/RpcSession.h
+++ b/libs/binder/include/binder/RpcSession.h
@@ -52,12 +52,10 @@
*/
[[nodiscard]] bool setupUnixDomainClient(const char* path);
-#ifdef __BIONIC__
/**
* Connects to an RPC server at the CVD & port.
*/
[[nodiscard]] bool setupVsockClient(unsigned int cvd, unsigned int port);
-#endif // __BIONIC__
/**
* Connects to an RPC server at the given address and port.
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 8d10727..b3ce744 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -34,14 +34,11 @@
#include <iostream>
#include <thread>
-#ifdef __BIONIC__
-#include <linux/vm_sockets.h>
-#endif //__BIONIC__
-
#include <sys/prctl.h>
#include <unistd.h>
-#include "../RpcState.h" // for debugging
+#include "../RpcState.h" // for debugging
+#include "../vm_sockets.h" // for VMADDR_*
namespace android {
@@ -291,19 +288,15 @@
enum class SocketType {
UNIX,
-#ifdef __BIONIC__
VSOCK,
-#endif // __BIONIC__
INET,
};
static inline std::string PrintSocketType(const testing::TestParamInfo<SocketType>& info) {
switch (info.param) {
case SocketType::UNIX:
return "unix_domain_socket";
-#ifdef __BIONIC__
case SocketType::VSOCK:
return "vm_socket";
-#endif // __BIONIC__
case SocketType::INET:
return "inet_socket";
default:
@@ -334,59 +327,53 @@
server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
server->setMaxThreads(numThreads);
+ unsigned int outPort = 0;
+
switch (socketType) {
case SocketType::UNIX:
CHECK(server->setupUnixDomainServer(addr.c_str())) << addr;
break;
-#ifdef __BIONIC__
case SocketType::VSOCK:
CHECK(server->setupVsockServer(vsockPort));
break;
-#endif // __BIONIC__
case SocketType::INET: {
- unsigned int outPort = 0;
CHECK(server->setupInetServer(0, &outPort));
CHECK_NE(0, outPort);
- CHECK(android::base::WriteFully(pipe->writeEnd(), &outPort,
- sizeof(outPort)));
break;
}
default:
LOG_ALWAYS_FATAL("Unknown socket type");
}
+ CHECK(android::base::WriteFully(pipe->writeEnd(), &outPort, sizeof(outPort)));
+
configure(server);
server->join();
}),
};
- unsigned int inetPort = 0;
+ // always read socket, so that we have waited for the server to start
+ unsigned int outPort = 0;
+ CHECK(android::base::ReadFully(ret.host.getPipe()->readEnd(), &outPort, sizeof(outPort)));
if (socketType == SocketType::INET) {
- CHECK(android::base::ReadFully(ret.host.getPipe()->readEnd(), &inetPort,
- sizeof(inetPort)));
- CHECK_NE(0, inetPort);
+ CHECK_NE(0, outPort);
}
for (size_t i = 0; i < numSessions; i++) {
sp<RpcSession> session = RpcSession::make();
- for (size_t tries = 0; tries < 10; tries++) {
- usleep(10000);
- switch (socketType) {
- case SocketType::UNIX:
- if (session->setupUnixDomainClient(addr.c_str())) goto success;
- break;
-#ifdef __BIONIC__
- case SocketType::VSOCK:
- if (session->setupVsockClient(VMADDR_CID_LOCAL, vsockPort)) goto success;
- break;
-#endif // __BIONIC__
- case SocketType::INET:
- if (session->setupInetClient("127.0.0.1", inetPort)) goto success;
- break;
- default:
- LOG_ALWAYS_FATAL("Unknown socket type");
- }
+ switch (socketType) {
+ case SocketType::UNIX:
+ if (session->setupUnixDomainClient(addr.c_str())) goto success;
+ break;
+ case SocketType::VSOCK:
+ if (session->setupVsockClient(VMADDR_CID_LOCAL, vsockPort)) goto success;
+ break;
+ case SocketType::INET:
+ if (session->setupInetClient("127.0.0.1", outPort)) goto success;
+ break;
+ default:
+ LOG_ALWAYS_FATAL("Unknown socket type");
}
LOG_ALWAYS_FATAL("Could not connect");
success:
@@ -934,9 +921,10 @@
INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc,
::testing::ValuesIn({
SocketType::UNIX,
+// TODO(b/185269356): working on host
#ifdef __BIONIC__
SocketType::VSOCK,
-#endif // __BIONIC__
+#endif
SocketType::INET,
}),
PrintSocketType);
diff --git a/libs/binder/vm_sockets.h b/libs/binder/vm_sockets.h
new file mode 100644
index 0000000..7d9732b
--- /dev/null
+++ b/libs/binder/vm_sockets.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** Copied and modified from bionic/libc/kernel/uapi/linux/vm_sockets.h
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#pragma once
+
+#ifdef __BIONIC__
+#include <linux/vm_sockets.h>
+#else
+
+#ifndef _UAPI_VM_SOCKETS_H
+#define _UAPI_VM_SOCKETS_H
+#define SO_VM_SOCKETS_BUFFER_SIZE 0
+#define SO_VM_SOCKETS_BUFFER_MIN_SIZE 1
+#define SO_VM_SOCKETS_BUFFER_MAX_SIZE 2
+#define SO_VM_SOCKETS_PEER_HOST_VM_ID 3
+#define SO_VM_SOCKETS_TRUSTED 5
+#define SO_VM_SOCKETS_CONNECT_TIMEOUT 6
+#define SO_VM_SOCKETS_NONBLOCK_TXRX 7
+#define VMADDR_CID_ANY (-1U)
+#define VMADDR_PORT_ANY (-1U)
+#define VMADDR_CID_HYPERVISOR 0
+#define VMADDR_CID_LOCAL 1
+#define VMADDR_CID_HOST 2
+#define VM_SOCKETS_INVALID_VERSION (-1U)
+#define VM_SOCKETS_VERSION_EPOCH(_v) (((_v)&0xFF000000) >> 24)
+#define VM_SOCKETS_VERSION_MAJOR(_v) (((_v)&0x00FF0000) >> 16)
+#define VM_SOCKETS_VERSION_MINOR(_v) (((_v)&0x0000FFFF))
+struct sockaddr_vm {
+ sa_family_t svm_family;
+ // NOLINTNEXTLINE(google-runtime-int)
+ unsigned short svm_reserved1;
+ unsigned int svm_port;
+ unsigned int svm_cid;
+ // NOLINTNEXTLINE(google-runtime-int)
+ unsigned char svm_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) - sizeof(unsigned short) -
+ sizeof(unsigned int) - sizeof(unsigned int)];
+};
+#define IOCTL_VM_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9)
+#ifndef AF_VSOCK
+#define AF_VSOCK 40
+#endif
+#endif
+
+#endif