Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5b3838d authored by Tom Cherry's avatar Tom Cherry
Browse files

logd: make LogBuffer an interface

We may use different implementations of LogBuffer in the future, so we
make it interface and create a concrete ChattyLogBuffer class that
implements it.

Test: logging unit tests
Change-Id: I5731d6404640664c9acc26b7c677dff3110c6a11
parent 68630a0d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -33,12 +33,12 @@ cc_library_static {

    srcs: [
        "LogCommand.cpp",
        "ChattyLogBuffer.cpp",
        "CommandListener.cpp",
        "LogListener.cpp",
        "LogReader.cpp",
        "LogReaderList.cpp",
        "LogReaderThread.cpp",
        "LogBuffer.cpp",
        "LogBufferElement.cpp",
        "LogStatistics.cpp",
        "LogWhiteBlackList.cpp",
+73 −104
Original line number Diff line number Diff line
@@ -13,9 +13,11 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// for manual checking of stale entries during LogBuffer::erase()
// for manual checking of stale entries during ChattyLogBuffer::erase()
//#define DEBUG_CHECK_FOR_STALE_ENTRIES

#include "ChattyLogBuffer.h"

#include <ctype.h>
#include <endian.h>
#include <errno.h>
@@ -32,7 +34,6 @@
#include <cutils/properties.h>
#include <private/android_logger.h>

#include "LogBuffer.h"
#include "LogKlog.h"
#include "LogReader.h"
#include "LogUtils.h"
@@ -44,10 +45,10 @@
// Default
#define log_buffer_size(id) mMaxSize[id]

void LogBuffer::init() {
void ChattyLogBuffer::Init() {
    log_id_for_each(i) {
        if (setSize(i, __android_logger_get_buffer_size(i))) {
            setSize(i, LOG_BUFFER_MIN_SIZE);
        if (SetSize(i, __android_logger_get_buffer_size(i))) {
            SetSize(i, LOG_BUFFER_MIN_SIZE);
        }
    }
    // Release any sleeping reader threads to dump their current content.
@@ -57,7 +58,7 @@ void LogBuffer::init() {
    }
}

LogBuffer::LogBuffer(LogReaderList* reader_list, LogTags* tags, PruneList* prune,
ChattyLogBuffer::ChattyLogBuffer(LogReaderList* reader_list, LogTags* tags, PruneList* prune,
                                 LogStatistics* stats)
    : reader_list_(reader_list), tags_(tags), prune_(prune), stats_(stats) {
    pthread_rwlock_init(&mLogElementsLock, nullptr);
@@ -67,17 +68,17 @@ LogBuffer::LogBuffer(LogReaderList* reader_list, LogTags* tags, PruneList* prune
        droppedElements[i] = nullptr;
    }

    init();
    Init();
}

LogBuffer::~LogBuffer() {
ChattyLogBuffer::~ChattyLogBuffer() {
    log_id_for_each(i) {
        delete lastLoggedElements[i];
        delete droppedElements[i];
    }
}

LogBufferElementCollection::iterator LogBuffer::GetOldest(log_id_t log_id) {
LogBufferElementCollection::iterator ChattyLogBuffer::GetOldest(log_id_t log_id) {
    auto it = mLogElements.begin();
    if (oldest_[log_id]) {
        it = *oldest_[log_id];
@@ -93,8 +94,7 @@ LogBufferElementCollection::iterator LogBuffer::GetOldest(log_id_t log_id) {

enum match_type { DIFFERENT, SAME, SAME_LIBLOG };

static enum match_type identical(LogBufferElement* elem,
                                 LogBufferElement* last) {
static enum match_type identical(LogBufferElement* elem, LogBufferElement* last) {
    // is it mostly identical?
    //  if (!elem) return DIFFERENT;
    ssize_t lenl = elem->getMsgLen();
@@ -108,8 +108,7 @@ static enum match_type identical(LogBufferElement* elem,
    if (elem->getTid() != last->getTid()) return DIFFERENT;

    // last is more than a minute old, stop squashing identical messages
    if (elem->getRealTime().nsec() >
        (last->getRealTime().nsec() + 60 * NS_PER_SEC))
    if (elem->getRealTime().nsec() > (last->getRealTime().nsec() + 60 * NS_PER_SEC))
        return DIFFERENT;

    // Identical message
@@ -118,21 +117,17 @@ static enum match_type identical(LogBufferElement* elem,
    if (lenl == lenr) {
        if (!fastcmp<memcmp>(msgl, msgr, lenl)) return SAME;
        // liblog tagged messages (content gets summed)
        if ((elem->getLogId() == LOG_ID_EVENTS) &&
            (lenl == sizeof(android_log_event_int_t)) &&
            !fastcmp<memcmp>(msgl, msgr, sizeof(android_log_event_int_t) -
                                             sizeof(int32_t)) &&
            (elem->getTag() == LIBLOG_LOG_TAG)) {
        if (elem->getLogId() == LOG_ID_EVENTS && lenl == sizeof(android_log_event_int_t) &&
            !fastcmp<memcmp>(msgl, msgr, sizeof(android_log_event_int_t) - sizeof(int32_t)) &&
            elem->getTag() == LIBLOG_LOG_TAG) {
            return SAME_LIBLOG;
        }
    }

    // audit message (except sequence number) identical?
    if (last->isBinary() &&
        (lenl > static_cast<ssize_t>(sizeof(android_log_event_string_t))) &&
        (lenr > static_cast<ssize_t>(sizeof(android_log_event_string_t)))) {
        if (fastcmp<memcmp>(msgl, msgr, sizeof(android_log_event_string_t) -
                                            sizeof(int32_t))) {
    if (last->isBinary() && lenl > static_cast<ssize_t>(sizeof(android_log_event_string_t)) &&
        lenr > static_cast<ssize_t>(sizeof(android_log_event_string_t))) {
        if (fastcmp<memcmp>(msgl, msgr, sizeof(android_log_event_string_t) - sizeof(int32_t))) {
            return DIFFERENT;
        }
        msgl += sizeof(android_log_event_string_t);
@@ -148,15 +143,14 @@ static enum match_type identical(LogBufferElement* elem,
    if (!avcr) return DIFFERENT;
    lenr -= avcr - msgr;
    if (lenl != lenr) return DIFFERENT;
    if (fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc),
                        lenl - strlen(avc))) {
    if (fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc), lenl - strlen(avc))) {
        return DIFFERENT;
    }
    return SAME;
}

int LogBuffer::log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
                   pid_t tid, const char* msg, uint16_t len) {
int ChattyLogBuffer::Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
                         const char* msg, uint16_t len) {
    if (log_id >= LOG_ID_MAX) {
        return -EINVAL;
    }
@@ -278,8 +272,7 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
            if (dropped) {
                // Sum up liblog tag messages?
                if ((count == 0) /* at Pass 1 */ && (match == SAME_LIBLOG)) {
                    android_log_event_int_t* event =
                        reinterpret_cast<android_log_event_int_t*>(
                    android_log_event_int_t* event = reinterpret_cast<android_log_event_int_t*>(
                            const_cast<char*>(currentLast->getMsg()));
                    //
                    // To unit test, differentiate with something like:
@@ -345,24 +338,24 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
    return len;
}

// assumes LogBuffer::wrlock() held, owns elem, look after garbage collection
void LogBuffer::log(LogBufferElement* elem) {
// assumes ChattyLogBuffer::wrlock() held, owns elem, look after garbage collection
void ChattyLogBuffer::log(LogBufferElement* elem) {
    mLogElements.push_back(elem);
    stats_->Add(elem);
    maybePrune(elem->getLogId());
    reader_list_->NotifyNewLog(1 << elem->getLogId());
}

// LogBuffer::wrlock() must be held when this function is called.
void LogBuffer::maybePrune(log_id_t id) {
// ChattyLogBuffer::wrlock() must be held when this function is called.
void ChattyLogBuffer::maybePrune(log_id_t id) {
    unsigned long prune_rows;
    if (stats_->ShouldPrune(id, log_buffer_size(id), &prune_rows)) {
        prune(id, prune_rows);
    }
}

LogBufferElementCollection::iterator LogBuffer::erase(
    LogBufferElementCollection::iterator it, bool coalesce) {
LogBufferElementCollection::iterator ChattyLogBuffer::erase(LogBufferElementCollection::iterator it,
                                                            bool coalesce) {
    LogBufferElement* element = *it;
    log_id_t id = element->getLogId();

@@ -370,8 +363,7 @@ LogBufferElementCollection::iterator LogBuffer::erase(
    // after the element is erased from the main logging list.

    {  // start of scope for found iterator
        int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY))
                      ? element->getTag()
        int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element->getTag()
                                                                 : element->getUid();
        LogBufferIteratorMap::iterator found = mLastWorst[id].find(key);
        if ((found != mLastWorst[id].end()) && (it == found->second)) {
@@ -383,10 +375,8 @@ LogBufferElementCollection::iterator LogBuffer::erase(
        // element->getUid() may not be AID_SYSTEM for next-best-watermark.
        // will not assume id != LOG_ID_EVENTS or LOG_ID_SECURITY for KISS and
        // long term code stability, find() check should be fast for those ids.
        LogBufferPidIteratorMap::iterator found =
            mLastWorstPidOfSystem[id].find(element->getPid());
        if ((found != mLastWorstPidOfSystem[id].end()) &&
            (it == found->second)) {
        LogBufferPidIteratorMap::iterator found = mLastWorstPidOfSystem[id].find(element->getPid());
        if (found != mLastWorstPidOfSystem[id].end() && it == found->second) {
            mLastWorstPidOfSystem[id].erase(found);
        }
    }
@@ -396,9 +386,8 @@ LogBufferElementCollection::iterator LogBuffer::erase(
    log_id_for_each(i) { doSetLast |= setLast[i] = oldest_[i] && it == *oldest_[i]; }
#ifdef DEBUG_CHECK_FOR_STALE_ENTRIES
    LogBufferElementCollection::iterator bad = it;
    int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY))
                  ? element->getTag()
                  : element->getUid();
    int key =
            (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element->getTag() : element->getUid();
#endif
    it = mLogElements.erase(it);
    if (doSetLast) {
@@ -417,14 +406,12 @@ LogBufferElementCollection::iterator LogBuffer::erase(
    log_id_for_each(i) {
        for (auto b : mLastWorst[i]) {
            if (bad == b.second) {
                android::prdebug("stale mLastWorst[%d] key=%d mykey=%d\n", i,
                                 b.first, key);
                android::prdebug("stale mLastWorst[%d] key=%d mykey=%d\n", i, b.first, key);
            }
        }
        for (auto b : mLastWorstPidOfSystem[i]) {
            if (bad == b.second) {
                android::prdebug("stale mLastWorstPidOfSystem[%d] pid=%d\n", i,
                                 b.first);
                android::prdebug("stale mLastWorstPidOfSystem[%d] pid=%d\n", i, b.first);
            }
        }
    }
@@ -453,15 +440,10 @@ class LogBufferElementKey {
    } __packed;

  public:
    LogBufferElementKey(uid_t uid, pid_t pid, pid_t tid)
        : uid(uid), pid(pid), tid(tid) {
    }
    explicit LogBufferElementKey(uint64_t key) : value(key) {
    }
    LogBufferElementKey(uid_t uid, pid_t pid, pid_t tid) : uid(uid), pid(pid), tid(tid) {}
    explicit LogBufferElementKey(uint64_t key) : value(key) {}

    uint64_t getKey() {
        return value;
    }
    uint64_t getKey() { return value; }
};

class LogBufferElementLast {
@@ -470,8 +452,7 @@ class LogBufferElementLast {

  public:
    bool coalesce(LogBufferElement* element, uint16_t dropped) {
        LogBufferElementKey key(element->getUid(), element->getPid(),
                                element->getTid());
        LogBufferElementKey key(element->getUid(), element->getPid(), element->getTid());
        LogBufferElementMap::iterator it = map.find(key.getKey());
        if (it != map.end()) {
            LogBufferElement* found = it->second;
@@ -487,14 +468,11 @@ class LogBufferElementLast {
    }

    void add(LogBufferElement* element) {
        LogBufferElementKey key(element->getUid(), element->getPid(),
                                element->getTid());
        LogBufferElementKey key(element->getUid(), element->getPid(), element->getTid());
        map[key.getKey()] = element;
    }

    inline void clear() {
        map.clear();
    }
    void clear() { map.clear(); }

    void clear(LogBufferElement* element) {
        uint64_t current = element->getRealTime().nsec() - (EXPIRE_RATELIMIT * NS_PER_SEC);
@@ -512,11 +490,11 @@ class LogBufferElementLast {

// If the selected reader is blocking our pruning progress, decide on
// what kind of mitigation is necessary to unblock the situation.
void LogBuffer::kickMe(LogReaderThread* me, log_id_t id, unsigned long pruneRows) {
void ChattyLogBuffer::kickMe(LogReaderThread* me, log_id_t id, unsigned long pruneRows) {
    if (stats_->Sizes(id) > (2 * log_buffer_size(id))) {  // +100%
        // A misbehaving or slow reader has its connection
        // dropped if we hit too much memory pressure.
        android::prdebug("Kicking blocked reader, pid %d, from LogBuffer::kickMe()\n",
        android::prdebug("Kicking blocked reader, pid %d, from ChattyLogBuffer::kickMe()\n",
                         me->client()->getPid());
        me->release_Locked();
    } else if (me->deadline().time_since_epoch().count() != 0) {
@@ -525,7 +503,7 @@ void LogBuffer::kickMe(LogReaderThread* me, log_id_t id, unsigned long pruneRows
    } else {
        // tell slow reader to skip entries to catch up
        android::prdebug(
                "Skipping %lu entries from slow reader, pid %d, from LogBuffer::kickMe()\n",
                "Skipping %lu entries from slow reader, pid %d, from ChattyLogBuffer::kickMe()\n",
                pruneRows, me->client()->getPid());
        me->triggerSkip_Locked(id, pruneRows);
    }
@@ -576,9 +554,9 @@ void LogBuffer::kickMe(LogReaderThread* me, log_id_t id, unsigned long pruneRows
// The third thread is optional, and only gets hit if there was a whitelist
// and more needs to be pruned against the backstop of the region lock.
//
// LogBuffer::wrlock() must be held when this function is called.
// ChattyLogBuffer::wrlock() must be held when this function is called.
//
bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
bool ChattyLogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
    LogReaderThread* oldest = nullptr;
    bool busy = false;
    bool clearAll = pruneRows == ULONG_MAX;
@@ -606,8 +584,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
        while (it != mLogElements.end()) {
            LogBufferElement* element = *it;

            if ((element->getLogId() != id) ||
                (element->getUid() != caller_uid)) {
            if (element->getLogId() != id || element->getUid() != caller_uid) {
                ++it;
                continue;
            }
@@ -666,10 +643,8 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
        bool gc = pruneRows <= 1;
        if (!gc && (worst != -1)) {
            {  // begin scope for worst found iterator
                LogBufferIteratorMap::iterator found =
                    mLastWorst[id].find(worst);
                if ((found != mLastWorst[id].end()) &&
                    (found->second != mLogElements.end())) {
                LogBufferIteratorMap::iterator found = mLastWorst[id].find(worst);
                if (found != mLastWorst[id].end() && found->second != mLogElements.end()) {
                    leading = false;
                    it = found->second;
                }
@@ -677,10 +652,9 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
            if (worstPid) {  // begin scope for pid worst found iterator
                // FYI: worstPid only set if !LOG_ID_EVENTS and
                //      !LOG_ID_SECURITY, not going to make that assumption ...
                LogBufferPidIteratorMap::iterator found =
                    mLastWorstPidOfSystem[id].find(worstPid);
                if ((found != mLastWorstPidOfSystem[id].end()) &&
                    (found->second != mLogElements.end())) {
                LogBufferPidIteratorMap::iterator found = mLastWorstPidOfSystem[id].find(worstPid);
                if (found != mLastWorstPidOfSystem[id].end() &&
                    found->second != mLogElements.end()) {
                    leading = false;
                    it = found->second;
                }
@@ -722,8 +696,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
                continue;
            }

            int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY))
                          ? element->getTag()
            int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element->getTag()
                                                                     : element->getUid();

            if (hasBlacklist && prune_->naughty(element)) {
@@ -755,10 +728,9 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {

            if (dropped) {
                last.add(element);
                if (worstPid &&
                    ((!gc && (element->getPid() == worstPid)) ||
                     (mLastWorstPidOfSystem[id].find(element->getPid()) ==
                      mLastWorstPidOfSystem[id].end()))) {
                if (worstPid && ((!gc && element->getPid() == worstPid) ||
                                 mLastWorstPidOfSystem[id].find(element->getPid()) ==
                                         mLastWorstPidOfSystem[id].end())) {
                    // element->getUid() may not be AID_SYSTEM, next best
                    // watermark if current one empty. id is not LOG_ID_EVENTS
                    // or LOG_ID_SECURITY because of worstPid check.
@@ -772,8 +744,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
                continue;
            }

            if ((key != worst) ||
                (worstPid && (element->getPid() != worstPid))) {
            if (key != worst || (worstPid && element->getPid() != worstPid)) {
                leading = false;
                last.clear(element);
                ++it;
@@ -801,16 +772,14 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
                    it = erase(it, true);
                } else {
                    last.add(element);
                    if (worstPid &&
                        (!gc || (mLastWorstPidOfSystem[id].find(worstPid) ==
                                 mLastWorstPidOfSystem[id].end()))) {
                    if (worstPid && (!gc || mLastWorstPidOfSystem[id].find(worstPid) ==
                                                    mLastWorstPidOfSystem[id].end())) {
                        // element->getUid() may not be AID_SYSTEM, next best
                        // watermark if current one empty. id is not
                        // LOG_ID_EVENTS or LOG_ID_SECURITY because of worstPid.
                        mLastWorstPidOfSystem[id][worstPid] = it;
                    }
                    if ((!gc && !worstPid) ||
                        (mLastWorst[id].find(worst) == mLastWorst[id].end())) {
                    if ((!gc && !worstPid) || mLastWorst[id].find(worst) == mLastWorst[id].end()) {
                        mLastWorst[id][worst] = it;
                    }
                    ++it;
@@ -882,7 +851,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
}

// clear all rows of type "id" from the buffer.
bool LogBuffer::clear(log_id_t id, uid_t uid) {
bool ChattyLogBuffer::Clear(log_id_t id, uid_t uid) {
    bool busy = true;
    // If it takes more than 4 tries (seconds) to clear, then kill reader(s)
    for (int retry = 4;;) {
@@ -903,7 +872,7 @@ bool LogBuffer::clear(log_id_t id, uid_t uid) {
                for (const auto& reader_thread : reader_list_->reader_threads()) {
                    if (reader_thread->IsWatching(id)) {
                        android::prdebug(
                                "Kicking blocked reader, pid %d, from LogBuffer::clear()\n",
                                "Kicking blocked reader, pid %d, from ChattyLogBuffer::clear()\n",
                                reader_thread->client()->getPid());
                        reader_thread->release_Locked();
                    }
@@ -922,7 +891,7 @@ bool LogBuffer::clear(log_id_t id, uid_t uid) {
}

// set the total space allocated to "id"
int LogBuffer::setSize(log_id_t id, unsigned long size) {
int ChattyLogBuffer::SetSize(log_id_t id, unsigned long size) {
    // Reasonable limits ...
    if (!__android_logger_valid_buffer_size(size)) {
        return -1;
@@ -934,14 +903,14 @@ int LogBuffer::setSize(log_id_t id, unsigned long size) {
}

// get the total space allocated to "id"
unsigned long LogBuffer::getSize(log_id_t id) {
unsigned long ChattyLogBuffer::GetSize(log_id_t id) {
    rdlock();
    size_t retval = log_buffer_size(id);
    unlock();
    return retval;
}

uint64_t LogBuffer::flushTo(
uint64_t ChattyLogBuffer::FlushTo(
        SocketClient* reader, uint64_t start, pid_t* lastTid, bool privileged, bool security,
        const std::function<FlushToResult(const LogBufferElement* element)>& filter) {
    LogBufferElementCollection::iterator it;

logd/ChattyLogBuffer.h

0 → 100644
+97 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012-2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <sys/types.h>

#include <list>
#include <optional>
#include <string>

#include <android/log.h>
#include <private/android_filesystem_config.h>
#include <sysutils/SocketClient.h>

#include "LogBuffer.h"
#include "LogBufferElement.h"
#include "LogStatistics.h"
#include "LogTags.h"
#include "LogWhiteBlackList.h"

typedef std::list<LogBufferElement*> LogBufferElementCollection;

class LogReaderList;
class LogReaderThread;

class ChattyLogBuffer : public LogBuffer {
    LogBufferElementCollection mLogElements;
    pthread_rwlock_t mLogElementsLock;

    // watermark of any worst/chatty uid processing
    typedef std::unordered_map<uid_t, LogBufferElementCollection::iterator> LogBufferIteratorMap;
    LogBufferIteratorMap mLastWorst[LOG_ID_MAX];
    // watermark of any worst/chatty pid of system processing
    typedef std::unordered_map<pid_t, LogBufferElementCollection::iterator> LogBufferPidIteratorMap;
    LogBufferPidIteratorMap mLastWorstPidOfSystem[LOG_ID_MAX];

    unsigned long mMaxSize[LOG_ID_MAX];

    LogBufferElement* lastLoggedElements[LOG_ID_MAX];
    LogBufferElement* droppedElements[LOG_ID_MAX];
    void log(LogBufferElement* elem);

  public:
    ChattyLogBuffer(LogReaderList* reader_list, LogTags* tags, PruneList* prune,
                    LogStatistics* stats);
    ~ChattyLogBuffer();
    void Init() override;

    int Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char* msg,
            uint16_t len) override;
    uint64_t FlushTo(
            SocketClient* writer, uint64_t start, pid_t* lastTid, bool privileged, bool security,
            const std::function<FlushToResult(const LogBufferElement* element)>& filter) override;

    bool Clear(log_id_t id, uid_t uid = AID_ROOT) override;
    unsigned long GetSize(log_id_t id) override;
    int SetSize(log_id_t id, unsigned long size) override;

  private:
    void wrlock() { pthread_rwlock_wrlock(&mLogElementsLock); }
    void rdlock() { pthread_rwlock_rdlock(&mLogElementsLock); }
    void unlock() { pthread_rwlock_unlock(&mLogElementsLock); }

    void maybePrune(log_id_t id);
    void kickMe(LogReaderThread* me, log_id_t id, unsigned long pruneRows);

    bool prune(log_id_t id, unsigned long pruneRows, uid_t uid = AID_ROOT);
    LogBufferElementCollection::iterator erase(LogBufferElementCollection::iterator it,
                                               bool coalesce = false);

    // Returns an iterator to the oldest element for a given log type, or mLogElements.end() if
    // there are no logs for the given log type. Requires mLogElementsLock to be held.
    LogBufferElementCollection::iterator GetOldest(log_id_t log_id);

    LogReaderList* reader_list_;
    LogTags* tags_;
    PruneList* prune_;
    LogStatistics* stats_;

    // Keeps track of the iterator to the oldest log message of a given log type, as an
    // optimization when pruning logs.  Use GetOldest() to retrieve.
    std::optional<LogBufferElementCollection::iterator> oldest_[LOG_ID_MAX];
};
+4 −4
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ int CommandListener::ClearCmd::runCommand(SocketClient* cli, int argc,
        return 0;
    }

    cli->sendMsg(buf()->clear((log_id_t)id, uid) ? "busy" : "success");
    cli->sendMsg(buf()->Clear((log_id_t)id, uid) ? "busy" : "success");
    return 0;
}

@@ -99,7 +99,7 @@ int CommandListener::GetBufSizeCmd::runCommand(SocketClient* cli, int argc,
        return 0;
    }

    unsigned long size = buf()->getSize((log_id_t)id);
    unsigned long size = buf()->GetSize((log_id_t)id);
    char buf[512];
    snprintf(buf, sizeof(buf), "%lu", size);
    cli->sendMsg(buf);
@@ -126,7 +126,7 @@ int CommandListener::SetBufSizeCmd::runCommand(SocketClient* cli, int argc,
    }

    unsigned long size = atol(argv[2]);
    if (buf()->setSize((log_id_t)id, size)) {
    if (buf()->SetSize((log_id_t)id, size)) {
        cli->sendMsg("Range Error");
        return 0;
    }
@@ -299,7 +299,7 @@ int CommandListener::ReinitCmd::runCommand(SocketClient* cli, int /*argc*/,
    setname();

    android::prdebug("logd reinit");
    buf()->init();
    buf()->Init();
    prune()->init(nullptr);

    // This only works on userdebug and eng devices to re-read the
+4 −6
Original line number Diff line number Diff line
@@ -274,8 +274,7 @@ int LogAudit::logPrint(const char* fmt, ...) {
        memcpy(event->data + str_len - denial_metadata.length(),
               denial_metadata.c_str(), denial_metadata.length());

        rc = logbuf->log(
            LOG_ID_EVENTS, now, uid, pid, tid, reinterpret_cast<char*>(event),
        rc = logbuf->Log(LOG_ID_EVENTS, now, uid, pid, tid, reinterpret_cast<char*>(event),
                         (message_len <= UINT16_MAX) ? (uint16_t)message_len : UINT16_MAX);
        if (rc >= 0) {
            notify |= 1 << LOG_ID_EVENTS;
@@ -328,8 +327,7 @@ int LogAudit::logPrint(const char* fmt, ...) {
        strncpy(newstr + 1 + str_len + prefix_len + suffix_len,
                denial_metadata.c_str(), denial_metadata.length());

        rc = logbuf->log(
            LOG_ID_MAIN, now, uid, pid, tid, newstr,
        rc = logbuf->Log(LOG_ID_MAIN, now, uid, pid, tid, newstr,
                         (message_len <= UINT16_MAX) ? (uint16_t)message_len : UINT16_MAX);

        if (rc >= 0) {
Loading