diff --git a/logd/FlushCommand.cpp b/logd/FlushCommand.cpp index fd45c4a0a..6a26d00f3 100644 --- a/logd/FlushCommand.cpp +++ b/logd/FlushCommand.cpp @@ -16,7 +16,10 @@ #include +#include + #include "FlushCommand.h" +#include "LogBuffer.h" #include "LogBufferElement.h" #include "LogCommand.h" #include "LogReader.h" diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp index fffc9ba96..230dd1125 100644 --- a/logd/LogAudit.cpp +++ b/logd/LogAudit.cpp @@ -20,10 +20,13 @@ #include #include #include +#include #include #include #include +#include + #include #include #include @@ -31,7 +34,9 @@ #include "libaudit.h" #include "LogAudit.h" +#include "LogBuffer.h" #include "LogKlog.h" +#include "LogReader.h" #ifndef AUDITD_ENFORCE_INTEGRITY #define AUDITD_ENFORCE_INTEGRITY false diff --git a/logd/LogAudit.h b/logd/LogAudit.h index 455ed58c0..3a84541a7 100644 --- a/logd/LogAudit.h +++ b/logd/LogAudit.h @@ -18,7 +18,10 @@ #define _LOGD_LOG_AUDIT_H__ #include -#include "LogReader.h" + +#include "LogBuffer.h" + +class LogReader; class LogAudit : public SocketListener { LogBuffer *logbuf; diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp index fde9ad7e3..eb5194c6f 100644 --- a/logd/LogBufferElement.cpp +++ b/logd/LogBufferElement.cpp @@ -25,9 +25,11 @@ #include #include +#include "LogBuffer.h" #include "LogBufferElement.h" #include "LogCommand.h" #include "LogReader.h" +#include "LogUtils.h" const uint64_t LogBufferElement::FLUSH_ERROR(0); atomic_int_fast64_t LogBufferElement::sequence(1); diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp index 9690489ce..ac2b12895 100644 --- a/logd/LogKlog.cpp +++ b/logd/LogKlog.cpp @@ -20,13 +20,16 @@ #include #include #include +#include #include #include #include #include +#include "LogBuffer.h" #include "LogKlog.h" +#include "LogReader.h" #define KMSG_PRIORITY(PRI) \ '<', \ diff --git a/logd/LogKlog.h b/logd/LogKlog.h index 3c8cc8789..ee73b7187 100644 --- a/logd/LogKlog.h +++ b/logd/LogKlog.h @@ -19,10 +19,12 @@ #include #include -#include "LogReader.h" char *log_strntok_r(char *s, size_t *len, char **saveptr, size_t *sublen); +class LogBuffer; +class LogReader; + class LogKlog : public SocketListener { LogBuffer *logbuf; LogReader *reader; diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp index 846dd7c41..39dd2272a 100644 --- a/logd/LogListener.cpp +++ b/logd/LogListener.cpp @@ -27,6 +27,7 @@ #include #include +#include "LogBuffer.h" #include "LogListener.h" #include "LogUtils.h" diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp index 667a3f249..2c07984ce 100644 --- a/logd/LogReader.cpp +++ b/logd/LogReader.cpp @@ -18,11 +18,15 @@ #include #include #include +#include #include -#include "LogReader.h" #include "FlushCommand.h" +#include "LogBuffer.h" +#include "LogBufferElement.h" +#include "LogReader.h" +#include "LogUtils.h" LogReader::LogReader(LogBuffer *logbuf) : SocketListener(getLogSocket(), true), @@ -176,6 +180,11 @@ bool LogReader::onDataAvailable(SocketClient *cli) { } FlushCommand command(*this, nonBlock, tail, logMask, pid, sequence, timeout); + + // Set acceptable upper limit to wait for slow reader processing b/27242723 + struct timeval t = { LOGD_SNDTIMEO, 0 }; + setsockopt(cli->getSocket(), SOL_SOCKET, SO_SNDTIMEO, (const char *)&t, sizeof(t)); + command.runSocketCommand(cli); return true; } diff --git a/logd/LogReader.h b/logd/LogReader.h index 91559a335..98674b8af 100644 --- a/logd/LogReader.h +++ b/logd/LogReader.h @@ -18,8 +18,10 @@ #define _LOGD_LOG_WRITER_H__ #include -#include "LogBuffer.h" -#include "LogTimes.h" + +#define LOGD_SNDTIMEO 32 + +class LogBuffer; class LogReader : public SocketListener { LogBuffer &mLogbuf; diff --git a/logd/LogTimes.h b/logd/LogTimes.h index 1117088e5..f5969df35 100644 --- a/logd/LogTimes.h +++ b/logd/LogTimes.h @@ -27,6 +27,7 @@ #include class LogReader; +class LogBufferElement; class LogTimeEntry { static pthread_mutex_t timesLock; diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp index de1979071..2014374e7 100644 --- a/logd/tests/logd_test.cpp +++ b/logd/tests/logd_test.cpp @@ -30,6 +30,8 @@ #include #include +#include "../LogReader.h" // pickup LOGD_SNDTIMEO + /* * returns statistics */ @@ -253,6 +255,9 @@ static void dump_log_msg(const char *prefix, fprintf(stderr, "lid=crash "); break; case 5: + fprintf(stderr, "lid=security "); + break; + case 6: fprintf(stderr, "lid=kernel "); break; default: @@ -710,3 +715,56 @@ TEST(logd, timeout) { EXPECT_TRUE(content_timeout); EXPECT_NE(0U, alarm_timeout); } + +// b/27242723 confirmed fixed +TEST(logd, SNDTIMEO) { + static const unsigned sndtimeo = LOGD_SNDTIMEO; // it has to be done! + static const unsigned sleep_time = sndtimeo + 3; + static const unsigned alarm_time = sleep_time + 5; + + int fd; + + ASSERT_TRUE((fd = socket_local_client("logdr", + ANDROID_SOCKET_NAMESPACE_RESERVED, + SOCK_SEQPACKET)) > 0); + + struct sigaction ignore, old_sigaction; + memset(&ignore, 0, sizeof(ignore)); + ignore.sa_handler = caught_signal; + sigemptyset(&ignore.sa_mask); + sigaction(SIGALRM, &ignore, &old_sigaction); + unsigned int old_alarm = alarm(alarm_time); + + static const char ask[] = "stream lids=0,1,2,3,4,5,6"; // all sources + bool reader_requested = write(fd, ask, sizeof(ask)) == sizeof(ask); + EXPECT_TRUE(reader_requested); + + log_msg msg; + bool read_one = recv(fd, msg.buf, sizeof(msg), 0) > 0; + + EXPECT_TRUE(read_one); + if (read_one) { + dump_log_msg("user", &msg, 3, -1); + } + + fprintf (stderr, "Sleep for >%d seconds logd SO_SNDTIMEO ...\n", sndtimeo); + sleep(sleep_time); + + // flush will block if we did not trigger. if it did, last entry returns 0 + int recv_ret; + do { + recv_ret = recv(fd, msg.buf, sizeof(msg), 0); + } while (recv_ret > 0); + int save_errno = (recv_ret < 0) ? errno : 0; + + EXPECT_NE(0U, alarm(old_alarm)); + sigaction(SIGALRM, &old_sigaction, NULL); + + EXPECT_EQ(0, recv_ret); + if (recv_ret > 0) { + dump_log_msg("user", &msg, 3, -1); + } + EXPECT_EQ(0, save_errno); + + close(fd); +}