Loading logd/FlushCommand.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ #include "LogUtils.h" FlushCommand::FlushCommand(LogReader& reader, bool nonBlock, unsigned long tail, unsigned int logMask, pid_t pid, uint64_t start, unsigned int logMask, pid_t pid, log_time start, uint64_t timeout) : mReader(reader), mNonBlock(nonBlock), Loading @@ -35,7 +35,7 @@ FlushCommand::FlushCommand(LogReader& reader, bool nonBlock, unsigned long tail, mLogMask(logMask), mPid(pid), mStart(start), mTimeout((start > 1) ? timeout : 0) { mTimeout((start != log_time::EPOCH) ? timeout : 0) { } // runSocketCommand is called once for every open client on the Loading logd/FlushCommand.h +3 −3 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ #ifndef _FLUSH_COMMAND_H #define _FLUSH_COMMAND_H #include <android/log.h> #include <private/android_logger.h> #include <sysutils/SocketClientCommand.h> class LogBufferElement; Loading @@ -31,13 +31,13 @@ class FlushCommand : public SocketClientCommand { unsigned long mTail; unsigned int mLogMask; pid_t mPid; uint64_t mStart; log_time mStart; uint64_t mTimeout; public: explicit FlushCommand(LogReader& mReader, bool nonBlock = false, unsigned long tail = -1, unsigned int logMask = -1, pid_t pid = 0, uint64_t start = 1, pid_t pid = 0, log_time start = log_time::EPOCH, uint64_t timeout = 0); virtual void runSocketCommand(SocketClient* client); Loading logd/LogBuffer.cpp +35 −27 Original line number Diff line number Diff line Loading @@ -181,7 +181,7 @@ static enum match_type identical(LogBufferElement* elem, lenr -= avcr - msgr; if (lenl != lenr) return DIFFERENT; // TODO: After b/35468874 is addressed, revisit "lenl > strlen(avc)" // condition, it might become superflous. // condition, it might become superfluous. if (lenl > strlen(avc) && fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc), lenl - strlen(avc))) { Loading Loading @@ -374,18 +374,12 @@ void LogBuffer::log(LogBufferElement* elem) { // NB: if end is region locked, place element at end of list LogBufferElementCollection::iterator it = mLogElements.end(); LogBufferElementCollection::iterator last = it; while (last != mLogElements.begin()) { --it; if ((*it)->getRealTime() <= elem->getRealTime()) { break; } last = it; } if (last == mLogElements.end()) { if (__predict_true(it != mLogElements.begin())) --it; if (__predict_false(it == mLogElements.begin()) || __predict_true((*it)->getRealTime() <= elem->getRealTime())) { mLogElements.push_back(elem); } else { uint64_t end = 1; log_time end = log_time::EPOCH; bool end_set = false; bool end_always = false; Loading @@ -399,6 +393,7 @@ void LogBuffer::log(LogBufferElement* elem) { end_always = true; break; } // it passing mEnd is blocked by the following checks. if (!end_set || (end <= entry->mEnd)) { end = entry->mEnd; end_set = true; Loading @@ -407,12 +402,20 @@ void LogBuffer::log(LogBufferElement* elem) { times++; } if (end_always || (end_set && (end >= (*last)->getSequence()))) { if (end_always || (end_set && (end > (*it)->getRealTime()))) { mLogElements.push_back(elem); } else { // should be short as timestamps are localized near end() do { last = it; if (__predict_false(it == mLogElements.begin())) { break; } --it; } while (((*it)->getRealTime() > elem->getRealTime()) && (!end_set || (end <= (*it)->getRealTime()))); mLogElements.insert(last, elem); } LogTimeEntry::unlock(); } Loading Loading @@ -587,12 +590,12 @@ class LogBufferElementLast { } void clear(LogBufferElement* element) { uint64_t current = element->getRealTime().nsec() - (EXPIRE_RATELIMIT * NS_PER_SEC); log_time current = element->getRealTime() - log_time(EXPIRE_RATELIMIT, 0); for (LogBufferElementMap::iterator it = map.begin(); it != map.end();) { LogBufferElement* mapElement = it->second; if ((mapElement->getDropped() >= EXPIRE_THRESHOLD) && (current > mapElement->getRealTime().nsec())) { (current > mapElement->getRealTime())) { it = map.erase(it); } else { ++it; Loading Loading @@ -688,7 +691,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { mLastSet[id] = true; } if (oldest && (oldest->mStart <= element->getSequence())) { if (oldest && (oldest->mStart <= element->getRealTime().nsec())) { busy = true; if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) { oldest->triggerReader_Locked(); Loading Loading @@ -780,7 +783,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { while (it != mLogElements.end()) { LogBufferElement* element = *it; if (oldest && (oldest->mStart <= element->getSequence())) { if (oldest && (oldest->mStart <= element->getRealTime().nsec())) { busy = true; if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) { oldest->triggerReader_Locked(); Loading Loading @@ -934,7 +937,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { mLastSet[id] = true; } if (oldest && (oldest->mStart <= element->getSequence())) { if (oldest && (oldest->mStart <= element->getRealTime().nsec())) { busy = true; if (whitelist) { break; Loading Loading @@ -978,7 +981,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { mLastSet[id] = true; } if (oldest && (oldest->mStart <= element->getSequence())) { if (oldest && (oldest->mStart <= element->getRealTime().nsec())) { busy = true; if (stats.sizes(id) > (2 * log_buffer_size(id))) { // kick a misbehaving log reader client off the island Loading Loading @@ -1071,32 +1074,37 @@ unsigned long LogBuffer::getSize(log_id_t id) { return retval; } uint64_t LogBuffer::flushTo( SocketClient* reader, const uint64_t start, bool privileged, bool security, log_time LogBuffer::flushTo( SocketClient* reader, const log_time& start, bool privileged, bool security, int (*filter)(const LogBufferElement* element, void* arg), void* arg) { LogBufferElementCollection::iterator it; uint64_t max = start; uid_t uid = reader->getUid(); pthread_mutex_lock(&mLogElementsLock); if (start <= 1) { if (start == log_time::EPOCH) { // client wants to start from the beginning it = mLogElements.begin(); } else { LogBufferElementCollection::iterator last = mLogElements.begin(); // 30 second limit to continue search for out-of-order entries. log_time min = start - log_time(30, 0); // Client wants to start from some specified time. Chances are // we are better off starting from the end of the time sorted list. for (it = mLogElements.end(); it != mLogElements.begin(); /* do nothing */) { --it; LogBufferElement* element = *it; if (element->getSequence() <= start) { it++; if (element->getRealTime() > start) { last = it; } else if (element->getRealTime() < min) { break; } } it = last; } log_time max = start; // Help detect if the valid message before is from the same source so // we can differentiate chatty filter types. pid_t lastTid[LOG_ID_MAX] = { 0 }; Loading @@ -1112,7 +1120,7 @@ uint64_t LogBuffer::flushTo( continue; } if (element->getSequence() <= start) { if (element->getRealTime() <= start) { continue; } Loading logd/LogBuffer.h +1 −1 Original line number Diff line number Diff line Loading @@ -115,7 +115,7 @@ class LogBuffer { int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char* msg, unsigned short len); uint64_t flushTo(SocketClient* writer, const uint64_t start, log_time flushTo(SocketClient* writer, const log_time& start, bool privileged, bool security, int (*filter)(const LogBufferElement* element, void* arg) = NULL, Loading logd/LogBufferElement.cpp +4 −6 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ #include "LogReader.h" #include "LogUtils.h" const uint64_t LogBufferElement::FLUSH_ERROR(0); const log_time LogBufferElement::FLUSH_ERROR((uint32_t)-1, (uint32_t)-1); atomic_int_fast64_t LogBufferElement::sequence(1); LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime, Loading @@ -39,7 +39,6 @@ LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime, : mUid(uid), mPid(pid), mTid(tid), mSequence(sequence.fetch_add(1, memory_order_relaxed)), mRealTime(realtime), mMsgLen(len), mLogId(log_id) { Loading @@ -55,7 +54,6 @@ LogBufferElement::LogBufferElement(const LogBufferElement& elem) mUid(elem.mUid), mPid(elem.mPid), mTid(elem.mTid), mSequence(elem.mSequence), mRealTime(elem.mRealTime), mMsgLen(elem.mMsgLen), mLogId(elem.mLogId) { Loading Loading @@ -206,7 +204,7 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogBuffer* parent return retval; } uint64_t LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, log_time LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, bool privileged, bool lastSame) { struct logger_entry_v4 entry; Loading @@ -229,7 +227,7 @@ uint64_t LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, if (!mMsg) { entry.len = populateDroppedMessage(buffer, parent, lastSame); if (!entry.len) return mSequence; if (!entry.len) return mRealTime; iovec[1].iov_base = buffer; } else { entry.len = mMsgLen; Loading @@ -237,7 +235,7 @@ uint64_t LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, } iovec[1].iov_len = entry.len; uint64_t retval = reader->sendDatav(iovec, 2) ? FLUSH_ERROR : mSequence; log_time retval = reader->sendDatav(iovec, 2) ? FLUSH_ERROR : mRealTime; if (buffer) free(buffer); Loading Loading
logd/FlushCommand.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ #include "LogUtils.h" FlushCommand::FlushCommand(LogReader& reader, bool nonBlock, unsigned long tail, unsigned int logMask, pid_t pid, uint64_t start, unsigned int logMask, pid_t pid, log_time start, uint64_t timeout) : mReader(reader), mNonBlock(nonBlock), Loading @@ -35,7 +35,7 @@ FlushCommand::FlushCommand(LogReader& reader, bool nonBlock, unsigned long tail, mLogMask(logMask), mPid(pid), mStart(start), mTimeout((start > 1) ? timeout : 0) { mTimeout((start != log_time::EPOCH) ? timeout : 0) { } // runSocketCommand is called once for every open client on the Loading
logd/FlushCommand.h +3 −3 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ #ifndef _FLUSH_COMMAND_H #define _FLUSH_COMMAND_H #include <android/log.h> #include <private/android_logger.h> #include <sysutils/SocketClientCommand.h> class LogBufferElement; Loading @@ -31,13 +31,13 @@ class FlushCommand : public SocketClientCommand { unsigned long mTail; unsigned int mLogMask; pid_t mPid; uint64_t mStart; log_time mStart; uint64_t mTimeout; public: explicit FlushCommand(LogReader& mReader, bool nonBlock = false, unsigned long tail = -1, unsigned int logMask = -1, pid_t pid = 0, uint64_t start = 1, pid_t pid = 0, log_time start = log_time::EPOCH, uint64_t timeout = 0); virtual void runSocketCommand(SocketClient* client); Loading
logd/LogBuffer.cpp +35 −27 Original line number Diff line number Diff line Loading @@ -181,7 +181,7 @@ static enum match_type identical(LogBufferElement* elem, lenr -= avcr - msgr; if (lenl != lenr) return DIFFERENT; // TODO: After b/35468874 is addressed, revisit "lenl > strlen(avc)" // condition, it might become superflous. // condition, it might become superfluous. if (lenl > strlen(avc) && fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc), lenl - strlen(avc))) { Loading Loading @@ -374,18 +374,12 @@ void LogBuffer::log(LogBufferElement* elem) { // NB: if end is region locked, place element at end of list LogBufferElementCollection::iterator it = mLogElements.end(); LogBufferElementCollection::iterator last = it; while (last != mLogElements.begin()) { --it; if ((*it)->getRealTime() <= elem->getRealTime()) { break; } last = it; } if (last == mLogElements.end()) { if (__predict_true(it != mLogElements.begin())) --it; if (__predict_false(it == mLogElements.begin()) || __predict_true((*it)->getRealTime() <= elem->getRealTime())) { mLogElements.push_back(elem); } else { uint64_t end = 1; log_time end = log_time::EPOCH; bool end_set = false; bool end_always = false; Loading @@ -399,6 +393,7 @@ void LogBuffer::log(LogBufferElement* elem) { end_always = true; break; } // it passing mEnd is blocked by the following checks. if (!end_set || (end <= entry->mEnd)) { end = entry->mEnd; end_set = true; Loading @@ -407,12 +402,20 @@ void LogBuffer::log(LogBufferElement* elem) { times++; } if (end_always || (end_set && (end >= (*last)->getSequence()))) { if (end_always || (end_set && (end > (*it)->getRealTime()))) { mLogElements.push_back(elem); } else { // should be short as timestamps are localized near end() do { last = it; if (__predict_false(it == mLogElements.begin())) { break; } --it; } while (((*it)->getRealTime() > elem->getRealTime()) && (!end_set || (end <= (*it)->getRealTime()))); mLogElements.insert(last, elem); } LogTimeEntry::unlock(); } Loading Loading @@ -587,12 +590,12 @@ class LogBufferElementLast { } void clear(LogBufferElement* element) { uint64_t current = element->getRealTime().nsec() - (EXPIRE_RATELIMIT * NS_PER_SEC); log_time current = element->getRealTime() - log_time(EXPIRE_RATELIMIT, 0); for (LogBufferElementMap::iterator it = map.begin(); it != map.end();) { LogBufferElement* mapElement = it->second; if ((mapElement->getDropped() >= EXPIRE_THRESHOLD) && (current > mapElement->getRealTime().nsec())) { (current > mapElement->getRealTime())) { it = map.erase(it); } else { ++it; Loading Loading @@ -688,7 +691,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { mLastSet[id] = true; } if (oldest && (oldest->mStart <= element->getSequence())) { if (oldest && (oldest->mStart <= element->getRealTime().nsec())) { busy = true; if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) { oldest->triggerReader_Locked(); Loading Loading @@ -780,7 +783,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { while (it != mLogElements.end()) { LogBufferElement* element = *it; if (oldest && (oldest->mStart <= element->getSequence())) { if (oldest && (oldest->mStart <= element->getRealTime().nsec())) { busy = true; if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) { oldest->triggerReader_Locked(); Loading Loading @@ -934,7 +937,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { mLastSet[id] = true; } if (oldest && (oldest->mStart <= element->getSequence())) { if (oldest && (oldest->mStart <= element->getRealTime().nsec())) { busy = true; if (whitelist) { break; Loading Loading @@ -978,7 +981,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { mLastSet[id] = true; } if (oldest && (oldest->mStart <= element->getSequence())) { if (oldest && (oldest->mStart <= element->getRealTime().nsec())) { busy = true; if (stats.sizes(id) > (2 * log_buffer_size(id))) { // kick a misbehaving log reader client off the island Loading Loading @@ -1071,32 +1074,37 @@ unsigned long LogBuffer::getSize(log_id_t id) { return retval; } uint64_t LogBuffer::flushTo( SocketClient* reader, const uint64_t start, bool privileged, bool security, log_time LogBuffer::flushTo( SocketClient* reader, const log_time& start, bool privileged, bool security, int (*filter)(const LogBufferElement* element, void* arg), void* arg) { LogBufferElementCollection::iterator it; uint64_t max = start; uid_t uid = reader->getUid(); pthread_mutex_lock(&mLogElementsLock); if (start <= 1) { if (start == log_time::EPOCH) { // client wants to start from the beginning it = mLogElements.begin(); } else { LogBufferElementCollection::iterator last = mLogElements.begin(); // 30 second limit to continue search for out-of-order entries. log_time min = start - log_time(30, 0); // Client wants to start from some specified time. Chances are // we are better off starting from the end of the time sorted list. for (it = mLogElements.end(); it != mLogElements.begin(); /* do nothing */) { --it; LogBufferElement* element = *it; if (element->getSequence() <= start) { it++; if (element->getRealTime() > start) { last = it; } else if (element->getRealTime() < min) { break; } } it = last; } log_time max = start; // Help detect if the valid message before is from the same source so // we can differentiate chatty filter types. pid_t lastTid[LOG_ID_MAX] = { 0 }; Loading @@ -1112,7 +1120,7 @@ uint64_t LogBuffer::flushTo( continue; } if (element->getSequence() <= start) { if (element->getRealTime() <= start) { continue; } Loading
logd/LogBuffer.h +1 −1 Original line number Diff line number Diff line Loading @@ -115,7 +115,7 @@ class LogBuffer { int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char* msg, unsigned short len); uint64_t flushTo(SocketClient* writer, const uint64_t start, log_time flushTo(SocketClient* writer, const log_time& start, bool privileged, bool security, int (*filter)(const LogBufferElement* element, void* arg) = NULL, Loading
logd/LogBufferElement.cpp +4 −6 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ #include "LogReader.h" #include "LogUtils.h" const uint64_t LogBufferElement::FLUSH_ERROR(0); const log_time LogBufferElement::FLUSH_ERROR((uint32_t)-1, (uint32_t)-1); atomic_int_fast64_t LogBufferElement::sequence(1); LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime, Loading @@ -39,7 +39,6 @@ LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime, : mUid(uid), mPid(pid), mTid(tid), mSequence(sequence.fetch_add(1, memory_order_relaxed)), mRealTime(realtime), mMsgLen(len), mLogId(log_id) { Loading @@ -55,7 +54,6 @@ LogBufferElement::LogBufferElement(const LogBufferElement& elem) mUid(elem.mUid), mPid(elem.mPid), mTid(elem.mTid), mSequence(elem.mSequence), mRealTime(elem.mRealTime), mMsgLen(elem.mMsgLen), mLogId(elem.mLogId) { Loading Loading @@ -206,7 +204,7 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogBuffer* parent return retval; } uint64_t LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, log_time LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, bool privileged, bool lastSame) { struct logger_entry_v4 entry; Loading @@ -229,7 +227,7 @@ uint64_t LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, if (!mMsg) { entry.len = populateDroppedMessage(buffer, parent, lastSame); if (!entry.len) return mSequence; if (!entry.len) return mRealTime; iovec[1].iov_base = buffer; } else { entry.len = mMsgLen; Loading @@ -237,7 +235,7 @@ uint64_t LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, } iovec[1].iov_len = entry.len; uint64_t retval = reader->sendDatav(iovec, 2) ? FLUSH_ERROR : mSequence; log_time retval = reader->sendDatav(iovec, 2) ? FLUSH_ERROR : mRealTime; if (buffer) free(buffer); Loading