From 0d847fb4cb6e219f210689051dc4bd6c0dc120a0 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Tue, 4 Aug 2020 17:41:47 -0700 Subject: [PATCH] liblog: add a timeout for logd command socket operations Add a 2s timeout for logd command socket operations: android_logger_clear android_logger_get_log_readable_size android_logger_get_log_size android_logger_set_log_size android_logger_get_statistics android_logger_get_prune_list android_logger_set_prune_list That correspond to: logcat -c logcat -g logcat -G logcat -S logcat -p logcat -P These operations should return immediately in typical circumstances, but if logd is stuck, they would otherwise block indefinitely. This allows the commands to gracefully timeout instead. Test: kill -s STOP `pidof logd`; logcat -g (and other options) times out appropriately Test: logcat -g (and other options) work successfully otherwise Change-Id: I6c4671a9b3daa4a454c0a14ae7d0b7d3b08be77a --- liblog/logd_reader.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/liblog/logd_reader.cpp b/liblog/logd_reader.cpp index 82ed6b2b5..7123f602a 100644 --- a/liblog/logd_reader.cpp +++ b/liblog/logd_reader.cpp @@ -41,7 +41,7 @@ // Connects to /dev/socket/ and returns the associated fd or returns -1 on error. // O_CLOEXEC is always set. -static int socket_local_client(const std::string& name, int type) { +static int socket_local_client(const std::string& name, int type, bool timeout) { sockaddr_un addr = {.sun_family = AF_LOCAL}; std::string path = "/dev/socket/" + name; @@ -55,6 +55,18 @@ static int socket_local_client(const std::string& name, int type) { return -1; } + if (timeout) { + // Sending and receiving messages should be instantaneous, but we don't want to wait forever if + // logd is hung, so we set a gracious 2s timeout. + struct timeval t = {2, 0}; + if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &t, sizeof(t)) == -1) { + return -1; + } + if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t)) == -1) { + return -1; + } + } + if (connect(fd, reinterpret_cast(&addr), sizeof(addr)) == -1) { close(fd); return -1; @@ -69,7 +81,7 @@ ssize_t SendLogdControlMessage(char* buf, size_t buf_size) { size_t len; char* cp; int errno_save = 0; - int sock = socket_local_client("logd", SOCK_STREAM); + int sock = socket_local_client("logd", SOCK_STREAM, true); if (sock < 0) { return sock; } @@ -268,7 +280,7 @@ static int logdOpen(struct logger_list* logger_list) { return sock; } - sock = socket_local_client("logdr", SOCK_SEQPACKET); + sock = socket_local_client("logdr", SOCK_SEQPACKET, false); if (sock <= 0) { if ((sock == -1) && errno) { return -errno;