Merge "servicemanager: log on failed lazy start"
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index d09d3e8..18c267d 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -47,6 +47,9 @@
"libutils",
"server_configurable_flags",
],
+ static_libs: [
+ "libasync_safe",
+ ],
export_shared_lib_headers: [
"libbinder",
],
@@ -251,6 +254,7 @@
],
static_libs: [
+ "libasync_safe",
"libdiskusage",
"libotapreoptparameters",
],
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 0cf50a3..204953c 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -36,6 +36,7 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
+#include <async_safe/log.h>
#include <cutils/fs.h>
#include <cutils/properties.h>
#include <cutils/sched_policy.h>
@@ -727,7 +728,8 @@
if (flock(out_fd.get(), LOCK_EX | LOCK_NB) != 0) {
if (errno != EWOULDBLOCK) {
- PLOG(WARNING) << "Error locking profile " << package_name;
+ async_safe_format_log(ANDROID_LOG_WARN, LOG_TAG, "Error locking profile %s: %d",
+ package_name.c_str(), errno);
}
// This implies that the app owning this profile is running
// (and has acquired the lock).
@@ -735,13 +737,15 @@
// The app never acquires the lock for the reference profiles of primary apks.
// Only dex2oat from installd will do that. Since installd is single threaded
// we should not see this case. Nevertheless be prepared for it.
- PLOG(WARNING) << "Failed to flock " << package_name;
+ async_safe_format_log(ANDROID_LOG_WARN, LOG_TAG, "Failed to flock %s: %d",
+ package_name.c_str(), errno);
return false;
}
bool truncated = ftruncate(out_fd.get(), 0) == 0;
if (!truncated) {
- PLOG(WARNING) << "Could not truncate " << package_name;
+ async_safe_format_log(ANDROID_LOG_WARN, LOG_TAG, "Could not truncate %s: %d",
+ package_name.c_str(), errno);
}
// Copy over data.
@@ -755,7 +759,8 @@
write(out_fd.get(), buffer, bytes);
}
if (flock(out_fd.get(), LOCK_UN) != 0) {
- PLOG(WARNING) << "Error unlocking profile " << package_name;
+ async_safe_format_log(ANDROID_LOG_WARN, LOG_TAG, "Error unlocking profile %s: %d",
+ package_name.c_str(), errno);
}
// Use _exit since we don't want to run the global destructors in the child.
// b/62597429
@@ -1513,7 +1518,8 @@
// Validate the path structure.
if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid, uid, storage_flag)) {
- LOG(ERROR) << "Could not validate secondary dex path " << dex_path;
+ async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
+ "Could not validate secondary dex path %s", dex_path.c_str());
_exit(kSecondaryDexDexoptAnalyzerSkippedValidatePath);
}
@@ -1809,7 +1815,8 @@
drop_capabilities(uid);
if (flock(out_oat.fd(), LOCK_EX | LOCK_NB) != 0) {
- PLOG(ERROR) << "flock(" << out_oat.path() << ") failed";
+ async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, "flock(%s) failed",
+ out_oat.path().c_str());
_exit(DexoptReturnCodes::kFlock);
}
@@ -1904,7 +1911,8 @@
const char* volume_uuid_cstr = volume_uuid ? volume_uuid->c_str() : nullptr;
if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid_cstr,
uid, storage_flag)) {
- LOG(ERROR) << "Could not validate secondary dex path " << dex_path;
+ async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
+ "Could not validate secondary dex path %s", dex_path.c_str());
_exit(kReconcileSecondaryDexValidationError);
}
@@ -1917,7 +1925,8 @@
case kSecondaryDexAccessIOError: _exit(kReconcileSecondaryDexAccessIOError);
case kSecondaryDexAccessPermissionError: _exit(kReconcileSecondaryDexValidationError);
default:
- LOG(ERROR) << "Unexpected result from check_secondary_dex_access: " << access_check;
+ async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
+ "Unexpected result from check_secondary_dex_access: %d", access_check);
_exit(kReconcileSecondaryDexValidationError);
}
@@ -1930,7 +1939,7 @@
std::string error_msg;
if (!create_secondary_dex_oat_layout(
dex_path,isas[i], oat_dir, oat_isa_dir, oat_path, &error_msg)) {
- LOG(ERROR) << error_msg;
+ async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, "%s", error_msg.c_str());
_exit(kReconcileSecondaryDexValidationError);
}
@@ -1957,7 +1966,8 @@
result = rmdir_if_empty(oat_dir) && result;
}
if (!result) {
- PLOG(ERROR) << "Failed to clean secondary dex artifacts for location " << dex_path;
+ async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
+ "Could not validate secondary dex path %s", dex_path.c_str());
}
_exit(result ? kReconcileSecondaryDexCleanedUp : kReconcileSecondaryDexAccessIOError);
}
@@ -2030,7 +2040,8 @@
pipe_read.reset();
if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid_cstr, uid, storage_flag)) {
- LOG(ERROR) << "Could not validate secondary dex path " << dex_path;
+ async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
+ "Could not validate secondary dex path %s", dex_path.c_str());
_exit(DexoptReturnCodes::kHashValidatePath);
}
@@ -2041,6 +2052,8 @@
_exit(0);
}
PLOG(ERROR) << "Failed to open secondary dex " << dex_path;
+ async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
+ "Failed to open secondary dex %s: %d", dex_path.c_str(), errno);
_exit(DexoptReturnCodes::kHashOpenPath);
}
@@ -2053,7 +2066,8 @@
if (bytes_read == 0) {
break;
} else if (bytes_read == -1) {
- PLOG(ERROR) << "Failed to read secondary dex " << dex_path;
+ async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
+ "Failed to read secondary dex %s: %d", dex_path.c_str(), errno);
_exit(DexoptReturnCodes::kHashReadDex);
}
diff --git a/cmds/installd/tests/Android.bp b/cmds/installd/tests/Android.bp
index f67ab81..7082017 100644
--- a/cmds/installd/tests/Android.bp
+++ b/cmds/installd/tests/Android.bp
@@ -20,6 +20,7 @@
"libcutils",
],
static_libs: [
+ "libasync_safe",
"libdiskusage",
"libinstalld",
"liblog",
@@ -44,6 +45,7 @@
"server_configurable_flags",
],
static_libs: [
+ "libasync_safe",
"libdiskusage",
"libinstalld",
"liblog",
@@ -84,6 +86,7 @@
"server_configurable_flags",
],
static_libs: [
+ "libasync_safe",
"libdiskusage",
"libinstalld",
"liblog",
@@ -124,6 +127,7 @@
"server_configurable_flags",
],
static_libs: [
+ "libasync_safe",
"libdiskusage",
"libinstalld",
"liblog",
diff --git a/libs/binder/RpcConnection.cpp b/libs/binder/RpcConnection.cpp
index f2302f7..2502d1b 100644
--- a/libs/binder/RpcConnection.cpp
+++ b/libs/binder/RpcConnection.cpp
@@ -19,6 +19,7 @@
#include <binder/RpcConnection.h>
#include <arpa/inet.h>
+#include <inttypes.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
@@ -45,9 +46,55 @@
namespace android {
+using base::borrowed_fd;
using base::unique_fd;
using AddrInfo = std::unique_ptr<addrinfo, decltype(&freeaddrinfo)>;
+namespace {
+bool checkSockaddrSize(const char* name, size_t actual, size_t expected) {
+ if (actual >= expected) return true;
+ ALOGW("getSockaddrPort: family is %s but size is %zu < %zu", name, actual, expected);
+ return false;
+}
+
+// Get the port number of |storage| for certain families. Requires storage->sa_family to be
+// set to a known family; otherwise, return nullopt.
+std::optional<unsigned int> getSockaddrPort(const sockaddr* storage, socklen_t len) {
+ switch (storage->sa_family) {
+ case AF_INET: {
+ if (!checkSockaddrSize("INET", len, sizeof(sockaddr_in))) return std::nullopt;
+ auto inetStorage = reinterpret_cast<const sockaddr_in*>(storage);
+ return ntohs(inetStorage->sin_port);
+ }
+ default: {
+ uint16_t family = storage->sa_family;
+ ALOGW("Don't know how to infer port for family %" PRIu16, family);
+ return std::nullopt;
+ }
+ }
+}
+
+std::optional<unsigned int> getSocketPort(borrowed_fd socketfd,
+ const RpcConnection::SocketAddress& socketAddress) {
+ sockaddr_storage storage{};
+ socklen_t len = sizeof(storage);
+ auto storagePtr = reinterpret_cast<sockaddr*>(&storage);
+ if (0 != getsockname(socketfd.get(), storagePtr, &len)) {
+ int savedErrno = errno;
+ ALOGE("Could not getsockname at %s: %s", socketAddress.toString().c_str(),
+ strerror(savedErrno));
+ return std::nullopt;
+ }
+
+ // getsockname does not fill in family, but getSockaddrPort() needs it.
+ if (storage.ss_family == AF_UNSPEC) {
+ storage.ss_family = socketAddress.addr()->sa_family;
+ }
+ return getSockaddrPort(storagePtr, len);
+}
+
+} // namespace
+
RpcConnection::SocketAddress::~SocketAddress() {}
RpcConnection::RpcConnection() {
@@ -166,14 +213,27 @@
return AddrInfo(aiStart, &freeaddrinfo);
}
-bool RpcConnection::setupInetServer(unsigned int port) {
+bool RpcConnection::setupInetServer(unsigned int port, unsigned int* assignedPort) {
const char* kAddr = "127.0.0.1";
+ if (assignedPort != nullptr) *assignedPort = 0;
auto aiStart = GetAddrInfo(kAddr, port);
if (aiStart == nullptr) return false;
for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
InetSocketAddress socketAddress(ai->ai_addr, ai->ai_addrlen, kAddr, port);
- if (setupSocketServer(socketAddress)) return true;
+ if (!setupSocketServer(socketAddress)) {
+ continue;
+ }
+ auto realPort = getSocketPort(mServer.get(), socketAddress);
+ LOG_ALWAYS_FATAL_IF(!realPort.has_value(), "Unable to get port number after setting up %s",
+ socketAddress.toString().c_str());
+ LOG_ALWAYS_FATAL_IF(port != 0 && *realPort != port,
+ "Requesting inet server on %s but it is set up on %u.",
+ socketAddress.toString().c_str(), *realPort);
+ if (assignedPort != nullptr) {
+ *assignedPort = *realPort;
+ }
+ return true;
}
ALOGE("None of the socket address resolved for %s:%u can be set up as inet server.", kAddr,
port);
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index 6dc4f95..9a0be92 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -30,8 +30,6 @@
namespace android {
-using base::unique_fd;
-
RpcServer::RpcServer() {}
RpcServer::~RpcServer() {}
diff --git a/libs/binder/include/binder/RpcConnection.h b/libs/binder/include/binder/RpcConnection.h
index 2395e78..09aed13 100644
--- a/libs/binder/include/binder/RpcConnection.h
+++ b/libs/binder/include/binder/RpcConnection.h
@@ -74,9 +74,15 @@
#endif // __BIONIC__
/**
- * Creates an RPC server at the current port.
+ * Creates an RPC server at the current port using IPv4.
+ *
+ * TODO(b/182914638): IPv6 support
+ *
+ * Set |port| to 0 to pick an ephemeral port; see discussion of
+ * /proc/sys/net/ipv4/ip_local_port_range in ip(7). In this case, |assignedPort|
+ * will be set to the picked port number, if it is not null.
*/
- [[nodiscard]] bool setupInetServer(unsigned int port);
+ [[nodiscard]] bool setupInetServer(unsigned int port, unsigned int* assignedPort);
/**
* 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 dd68fdb..ce69ea2 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -17,6 +17,7 @@
#include <BnBinderRpcSession.h>
#include <BnBinderRpcTest.h>
#include <aidl/IBinderRpcTest.h>
+#include <android-base/file.h>
#include <android-base/logging.h>
#include <android/binder_auto_utils.h>
#include <android/binder_libbinder.h>
@@ -176,14 +177,27 @@
};
sp<IBinder> MyBinderRpcTest::mHeldBinder;
+class Pipe {
+public:
+ Pipe() { CHECK(android::base::Pipe(&mRead, &mWrite)); }
+ Pipe(Pipe&&) = default;
+ android::base::borrowed_fd readEnd() { return mRead; }
+ android::base::borrowed_fd writeEnd() { return mWrite; }
+
+private:
+ android::base::unique_fd mRead;
+ android::base::unique_fd mWrite;
+};
+
class Process {
public:
- Process(const std::function<void()>& f) {
+ Process(Process&&) = default;
+ Process(const std::function<void(Pipe*)>& f) {
if (0 == (mPid = fork())) {
// racey: assume parent doesn't crash before this is set
prctl(PR_SET_PDEATHSIG, SIGHUP);
- f();
+ f(&mPipe);
}
}
~Process() {
@@ -191,9 +205,11 @@
kill(mPid, SIGKILL);
}
}
+ Pipe* getPipe() { return &mPipe; }
private:
pid_t mPid = 0;
+ Pipe mPipe;
};
static std::string allocateSocketAddress() {
@@ -215,6 +231,7 @@
// whether connection should be invalidated by end of run
bool expectInvalid = false;
+ ProcessConnection(ProcessConnection&&) = default;
~ProcessConnection() {
rootBinder = nullptr;
EXPECT_NE(nullptr, connection);
@@ -238,6 +255,7 @@
// pre-casted root object
sp<IBinderRpcTest> rootIface;
+ BinderRpcTestProcessConnection(BinderRpcTestProcessConnection&&) = default;
~BinderRpcTestProcessConnection() {
if (!proc.expectInvalid) {
int32_t remoteBinders = 0;
@@ -286,11 +304,11 @@
std::string addr = allocateSocketAddress();
unlink(addr.c_str());
- static unsigned int port = 3456;
- port++;
+ static unsigned int vsockPort = 3456;
+ vsockPort++;
auto ret = ProcessConnection{
- .host = Process([&] {
+ .host = Process([&](Pipe* pipe) {
sp<RpcServer> server = RpcServer::make();
server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
@@ -304,12 +322,17 @@
break;
#ifdef __BIONIC__
case SocketType::VSOCK:
- CHECK(connection->setupVsockServer(port));
+ CHECK(connection->setupVsockServer(vsockPort));
break;
#endif // __BIONIC__
- case SocketType::INET:
- CHECK(connection->setupInetServer(port));
+ case SocketType::INET: {
+ unsigned int outPort = 0;
+ CHECK(connection->setupInetServer(0, &outPort));
+ CHECK_NE(0, outPort);
+ CHECK(android::base::WriteFully(pipe->writeEnd(), &outPort,
+ sizeof(outPort)));
break;
+ }
default:
LOG_ALWAYS_FATAL("Unknown socket type");
}
@@ -327,6 +350,13 @@
.connection = RpcConnection::make(),
};
+ unsigned int inetPort = 0;
+ if (socketType == SocketType::INET) {
+ CHECK(android::base::ReadFully(ret.host.getPipe()->readEnd(), &inetPort,
+ sizeof(inetPort)));
+ CHECK_NE(0, inetPort);
+ }
+
// create remainder of connections
for (size_t i = 0; i < numThreads; i++) {
for (size_t tries = 0; tries < 5; tries++) {
@@ -337,11 +367,12 @@
break;
#ifdef __BIONIC__
case SocketType::VSOCK:
- if (ret.connection->addVsockClient(VMADDR_CID_LOCAL, port)) goto success;
+ if (ret.connection->addVsockClient(VMADDR_CID_LOCAL, vsockPort))
+ goto success;
break;
#endif // __BIONIC__
case SocketType::INET:
- if (ret.connection->addInetClient("127.0.0.1", port)) goto success;
+ if (ret.connection->addInetClient("127.0.0.1", inetPort)) goto success;
break;
default:
LOG_ALWAYS_FATAL("Unknown socket type");
diff --git a/opengl/Android.bp b/opengl/Android.bp
index 748f795..16ce15b 100644
--- a/opengl/Android.bp
+++ b/opengl/Android.bp
@@ -68,11 +68,9 @@
name: "gl_headers",
vendor_available: true,
export_include_dirs: ["include"],
-}
-
-llndk_headers {
- name: "gl_llndk_headers",
- export_include_dirs: ["include"],
+ llndk: {
+ llndk_headers: true,
+ },
}
subdirs = [
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 6d59ac0..daaaf88 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -144,7 +144,7 @@
defaults: ["egl_libs_defaults"],
llndk: {
symbol_file: "libEGL.map.txt",
- export_llndk_headers: ["gl_llndk_headers"],
+ export_llndk_headers: ["gl_headers"],
// Don't export EGL/include from the LLNDK variant.
override_export_include_dirs: [],
},
@@ -215,7 +215,7 @@
defaults: ["gles_libs_defaults"],
llndk: {
symbol_file: "libGLESv1_CM.map.txt",
- export_llndk_headers: ["gl_llndk_headers"],
+ export_llndk_headers: ["gl_headers"],
// Don't export EGL/include from the LLNDK variant.
override_export_include_dirs: [],
},
@@ -232,7 +232,7 @@
defaults: ["gles_libs_defaults"],
llndk: {
symbol_file: "libGLESv2.map.txt",
- export_llndk_headers: ["gl_llndk_headers"],
+ export_llndk_headers: ["gl_headers"],
// Don't export EGL/include from the LLNDK variant.
override_export_include_dirs: [],
},
@@ -252,7 +252,7 @@
defaults: ["gles_libs_defaults"],
llndk: {
symbol_file: "libGLESv3.map.txt",
- export_llndk_headers: ["gl_llndk_headers"],
+ export_llndk_headers: ["gl_headers"],
// Don't export EGL/include from the LLNDK variant.
override_export_include_dirs: [],
},
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index d4cb928..440c5b1 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -34,7 +34,7 @@
llndk: {
symbol_file: "libvulkan.map.txt",
export_llndk_headers: [
- "vulkan_headers_llndk",
+ "vulkan_headers",
],
},
clang: true,