Merge changes Ic7620978,I6d5bab58,Id1668c26,Icdb56b6f,Ic0c86a2b am: 794acfc0fe

Change-Id: Iaa075bc86514e0cbef21943dc927b6287ce7652d
diff --git a/logd/Android.bp b/logd/Android.bp
index b337b7c..2663271 100644
--- a/logd/Android.bp
+++ b/logd/Android.bp
@@ -36,7 +36,6 @@
         "CommandListener.cpp",
         "LogListener.cpp",
         "LogReader.cpp",
-        "FlushCommand.cpp",
         "LogBuffer.cpp",
         "LogBufferElement.cpp",
         "LogTimes.cpp",
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp
index 694b5fa..4044dc9 100644
--- a/logd/CommandListener.cpp
+++ b/logd/CommandListener.cpp
@@ -31,6 +31,7 @@
 
 #include <android-base/stringprintf.h>
 #include <cutils/sockets.h>
+#include <log/log_properties.h>
 #include <private/android_filesystem_config.h>
 #include <sysutils/SocketClient.h>
 
@@ -38,37 +39,20 @@
 #include "LogCommand.h"
 #include "LogUtils.h"
 
-CommandListener::CommandListener(LogBuffer* buf, LogReader* /*reader*/,
-                                 LogListener* /*swl*/)
-    : FrameworkListener(getLogSocket()) {
-    // registerCmd(new ShutdownCmd(buf, writer, swl));
-    registerCmd(new ClearCmd(buf));
-    registerCmd(new GetBufSizeCmd(buf));
-    registerCmd(new SetBufSizeCmd(buf));
-    registerCmd(new GetBufSizeUsedCmd(buf));
-    registerCmd(new GetStatisticsCmd(buf));
-    registerCmd(new SetPruneListCmd(buf));
-    registerCmd(new GetPruneListCmd(buf));
-    registerCmd(new GetEventTagCmd(buf));
-    registerCmd(new ReinitCmd());
+CommandListener::CommandListener(LogBuffer* buf, LogTags* tags, PruneList* prune)
+    : FrameworkListener(getLogSocket()), buf_(buf), tags_(tags), prune_(prune) {
+    registerCmd(new ClearCmd(this));
+    registerCmd(new GetBufSizeCmd(this));
+    registerCmd(new SetBufSizeCmd(this));
+    registerCmd(new GetBufSizeUsedCmd(this));
+    registerCmd(new GetStatisticsCmd(this));
+    registerCmd(new SetPruneListCmd(this));
+    registerCmd(new GetPruneListCmd(this));
+    registerCmd(new GetEventTagCmd(this));
+    registerCmd(new ReinitCmd(this));
     registerCmd(new ExitCmd(this));
 }
 
-CommandListener::ShutdownCmd::ShutdownCmd(LogReader* reader, LogListener* swl)
-    : LogCommand("shutdown"), mReader(*reader), mSwl(*swl) {
-}
-
-int CommandListener::ShutdownCmd::runCommand(SocketClient* /*cli*/,
-                                             int /*argc*/, char** /*argv*/) {
-    mSwl.stopListener();
-    mReader.stopListener();
-    exit(0);
-}
-
-CommandListener::ClearCmd::ClearCmd(LogBuffer* buf)
-    : LogCommand("clear"), mBuf(*buf) {
-}
-
 static void setname() {
     static bool name_set;
     if (!name_set) {
@@ -96,14 +80,10 @@
         return 0;
     }
 
-    cli->sendMsg(mBuf.clear((log_id_t)id, uid) ? "busy" : "success");
+    cli->sendMsg(buf()->clear((log_id_t)id, uid) ? "busy" : "success");
     return 0;
 }
 
-CommandListener::GetBufSizeCmd::GetBufSizeCmd(LogBuffer* buf)
-    : LogCommand("getLogSize"), mBuf(*buf) {
-}
-
 int CommandListener::GetBufSizeCmd::runCommand(SocketClient* cli, int argc,
                                                char** argv) {
     setname();
@@ -118,17 +98,13 @@
         return 0;
     }
 
-    unsigned long size = mBuf.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);
     return 0;
 }
 
-CommandListener::SetBufSizeCmd::SetBufSizeCmd(LogBuffer* buf)
-    : LogCommand("setLogSize"), mBuf(*buf) {
-}
-
 int CommandListener::SetBufSizeCmd::runCommand(SocketClient* cli, int argc,
                                                char** argv) {
     setname();
@@ -149,7 +125,7 @@
     }
 
     unsigned long size = atol(argv[2]);
-    if (mBuf.setSize((log_id_t)id, size)) {
+    if (buf()->setSize((log_id_t)id, size)) {
         cli->sendMsg("Range Error");
         return 0;
     }
@@ -158,10 +134,6 @@
     return 0;
 }
 
-CommandListener::GetBufSizeUsedCmd::GetBufSizeUsedCmd(LogBuffer* buf)
-    : LogCommand("getLogSizeUsed"), mBuf(*buf) {
-}
-
 int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient* cli, int argc,
                                                    char** argv) {
     setname();
@@ -176,17 +148,13 @@
         return 0;
     }
 
-    unsigned long size = mBuf.getSizeUsed((log_id_t)id);
+    unsigned long size = buf()->getSizeUsed((log_id_t)id);
     char buf[512];
     snprintf(buf, sizeof(buf), "%lu", size);
     cli->sendMsg(buf);
     return 0;
 }
 
-CommandListener::GetStatisticsCmd::GetStatisticsCmd(LogBuffer* buf)
-    : LogCommand("getStatistics"), mBuf(*buf) {
-}
-
 // This returns a string with a length prefix with the format <length>\n<data>\n\f.  The length
 // prefix includes the length of the prefix itself.
 static std::string PackageString(const std::string& str) {
@@ -241,25 +209,17 @@
         }
     }
 
-    cli->sendMsg(PackageString(mBuf.formatStatistics(uid, pid, logMask)).c_str());
+    cli->sendMsg(PackageString(buf()->formatStatistics(uid, pid, logMask)).c_str());
     return 0;
 }
 
-CommandListener::GetPruneListCmd::GetPruneListCmd(LogBuffer* buf)
-    : LogCommand("getPruneList"), mBuf(*buf) {
-}
-
 int CommandListener::GetPruneListCmd::runCommand(SocketClient* cli,
                                                  int /*argc*/, char** /*argv*/) {
     setname();
-    cli->sendMsg(PackageString(mBuf.formatPrune()).c_str());
+    cli->sendMsg(PackageString(prune()->format()).c_str());
     return 0;
 }
 
-CommandListener::SetPruneListCmd::SetPruneListCmd(LogBuffer* buf)
-    : LogCommand("setPruneList"), mBuf(*buf) {
-}
-
 int CommandListener::SetPruneListCmd::runCommand(SocketClient* cli, int argc,
                                                  char** argv) {
     setname();
@@ -276,7 +236,7 @@
         str += argv[i];
     }
 
-    int ret = mBuf.initPrune(str.c_str());
+    int ret = prune()->init(str.c_str());
 
     if (ret) {
         cli->sendMsg("Invalid");
@@ -288,10 +248,6 @@
     return 0;
 }
 
-CommandListener::GetEventTagCmd::GetEventTagCmd(LogBuffer* buf)
-    : LogCommand("getEventTag"), mBuf(*buf) {
-}
-
 int CommandListener::GetEventTagCmd::runCommand(SocketClient* cli, int argc,
                                                 char** argv) {
     setname();
@@ -328,39 +284,45 @@
             cli->sendMsg("can not mix id= with either format= or name=");
             return 0;
         }
-        cli->sendMsg(PackageString(mBuf.formatEntry(atoi(id), uid)).c_str());
+        cli->sendMsg(PackageString(tags()->formatEntry(atoi(id), uid)).c_str());
         return 0;
     }
 
-    cli->sendMsg(PackageString(mBuf.formatGetEventTag(uid, name, format)).c_str());
+    cli->sendMsg(PackageString(tags()->formatGetEventTag(uid, name, format)).c_str());
 
     return 0;
 }
 
-CommandListener::ReinitCmd::ReinitCmd() : LogCommand("reinit") {
-}
-
 int CommandListener::ReinitCmd::runCommand(SocketClient* cli, int /*argc*/,
                                            char** /*argv*/) {
     setname();
 
-    reinit_signal_handler(SIGHUP);
+    android::prdebug("logd reinit");
+    buf()->init();
+    prune()->init(nullptr);
+
+    // This only works on userdebug and eng devices to re-read the
+    // /data/misc/logd/event-log-tags file right after /data is mounted.
+    // The operation is near to boot and should only happen once.  There
+    // are races associated with its use since it can trigger a Rebuild
+    // of the file, but that is a can-not-happen since the file was not
+    // read yet.  More dangerous if called later, but if all is well it
+    // should just skip over everything and not write any new entries.
+    if (__android_log_is_debuggable()) {
+        tags()->ReadFileEventLogTags(tags()->debug_event_log_tags);
+    }
 
     cli->sendMsg("success");
 
     return 0;
 }
 
-CommandListener::ExitCmd::ExitCmd(CommandListener* parent)
-    : LogCommand("EXIT"), mParent(*parent) {
-}
-
 int CommandListener::ExitCmd::runCommand(SocketClient* cli, int /*argc*/,
                                          char** /*argv*/) {
     setname();
 
     cli->sendMsg("success");
-    release(cli);
+    parent_->release(cli);
 
     return 0;
 }
diff --git a/logd/CommandListener.h b/logd/CommandListener.h
index ed99419..c90c247 100644
--- a/logd/CommandListener.h
+++ b/logd/CommandListener.h
@@ -14,85 +14,53 @@
  * limitations under the License.
  */
 
-#ifndef _COMMANDLISTENER_H__
-#define _COMMANDLISTENER_H__
+#pragma once
 
 #include <sysutils/FrameworkListener.h>
+
 #include "LogBuffer.h"
 #include "LogCommand.h"
 #include "LogListener.h"
 #include "LogReader.h"
-
-// See main.cpp for implementation
-void reinit_signal_handler(int /*signal*/);
+#include "LogTags.h"
+#include "LogWhiteBlackList.h"
 
 class CommandListener : public FrameworkListener {
-   public:
-    CommandListener(LogBuffer* buf, LogReader* reader, LogListener* swl);
-    virtual ~CommandListener() {
-    }
+  public:
+    CommandListener(LogBuffer* buf, LogTags* tags, PruneList* prune);
+    virtual ~CommandListener() {}
 
-   private:
+  private:
     static int getLogSocket();
 
-    class ShutdownCmd : public LogCommand {
-        LogReader& mReader;
-        LogListener& mSwl;
+    LogBuffer* buf_;
+    LogTags* tags_;
+    PruneList* prune_;
 
-       public:
-        ShutdownCmd(LogReader* reader, LogListener* swl);
-        virtual ~ShutdownCmd() {
-        }
-        int runCommand(SocketClient* c, int argc, char** argv);
-    };
-
-#define LogBufferCmd(name)                                      \
+#define LogCmd(name, command_string)                            \
     class name##Cmd : public LogCommand {                       \
-        LogBuffer& mBuf;                                        \
+      public:                                                   \
+        explicit name##Cmd(CommandListener* parent)             \
+            : LogCommand(#command_string), parent_(parent) {}   \
+        virtual ~name##Cmd() {}                                 \
+        int runCommand(SocketClient* c, int argc, char** argv); \
                                                                 \
-       public:                                                  \
-        explicit name##Cmd(LogBuffer* buf);                     \
-        virtual ~name##Cmd() {                                  \
-        }                                                       \
-        int runCommand(SocketClient* c, int argc, char** argv); \
+      private:                                                  \
+        LogBuffer* buf() const { return parent_->buf_; }        \
+        LogTags* tags() const { return parent_->tags_; }        \
+        PruneList* prune() const { return parent_->prune_; }    \
+        CommandListener* parent_;                               \
     }
 
-    LogBufferCmd(Clear);
-    LogBufferCmd(GetBufSize);
-    LogBufferCmd(SetBufSize);
-    LogBufferCmd(GetBufSizeUsed);
-    LogBufferCmd(GetStatistics);
-    LogBufferCmd(GetPruneList);
-    LogBufferCmd(SetPruneList);
-    LogBufferCmd(GetEventTag);
-
-#define LogCmd(name)                                            \
-    class name##Cmd : public LogCommand {                       \
-       public:                                                  \
-        name##Cmd();                                            \
-        virtual ~name##Cmd() {                                  \
-        }                                                       \
-        int runCommand(SocketClient* c, int argc, char** argv); \
-    }
-
-    LogCmd(Reinit);
-
-#define LogParentCmd(name)                                      \
-    class name##Cmd : public LogCommand {                       \
-        CommandListener& mParent;                               \
-                                                                \
-       public:                                                  \
-        name##Cmd();                                            \
-        explicit name##Cmd(CommandListener* parent);            \
-        virtual ~name##Cmd() {                                  \
-        }                                                       \
-        int runCommand(SocketClient* c, int argc, char** argv); \
-        void release(SocketClient* c) {                         \
-            mParent.release(c);                                 \
-        }                                                       \
-    }
-
-    LogParentCmd(Exit);
+    LogCmd(Clear, clear);
+    LogCmd(GetBufSize, getLogSize);
+    LogCmd(SetBufSize, setLogSize);
+    LogCmd(GetBufSizeUsed, getLogSizeUsed);
+    LogCmd(GetStatistics, getStatistics);
+    LogCmd(GetPruneList, getPruneList);
+    LogCmd(SetPruneList, setPruneList);
+    LogCmd(GetEventTag, getEventTag);
+    LogCmd(Reinit, reinit);
+    LogCmd(Exit, EXIT);
+#undef LogCmd
 };
-
-#endif
diff --git a/logd/FlushCommand.cpp b/logd/FlushCommand.cpp
deleted file mode 100644
index 0845504..0000000
--- a/logd/FlushCommand.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.
- */
-
-#include <stdlib.h>
-
-#include <private/android_filesystem_config.h>
-
-#include "FlushCommand.h"
-#include "LogBuffer.h"
-#include "LogBufferElement.h"
-#include "LogCommand.h"
-#include "LogReader.h"
-#include "LogTimes.h"
-#include "LogUtils.h"
-
-// runSocketCommand is called once for every open client on the
-// log reader socket. Here we manage and associated the reader
-// client tracking and log region locks LastLogTimes list of
-// LogTimeEntrys, and spawn a transitory per-client thread to
-// work at filing data to the  socket.
-//
-// global LogTimeEntry::wrlock() is used to protect access,
-// reference counts are used to ensure that individual
-// LogTimeEntry lifetime is managed when not protected.
-void FlushCommand::runSocketCommand(SocketClient* client) {
-    LogTimeEntry* entry = nullptr;
-    LastLogTimes& times = mReader.logbuf().mTimes;
-
-    LogTimeEntry::wrlock();
-    LastLogTimes::iterator it = times.begin();
-    while (it != times.end()) {
-        entry = it->get();
-        if (entry->mClient == client) {
-            if (!entry->isWatchingMultiple(mLogMask)) {
-                LogTimeEntry::unlock();
-                return;
-            }
-            if (entry->mTimeout.tv_sec || entry->mTimeout.tv_nsec) {
-                LogTimeEntry::unlock();
-                return;
-            }
-            entry->triggerReader_Locked();
-            LogTimeEntry::unlock();
-            return;
-        }
-        it++;
-    }
-
-    LogTimeEntry::unlock();
-}
-
-bool FlushCommand::hasReadLogs(SocketClient* client) {
-    return clientHasLogCredentials(client);
-}
-
-static bool clientHasSecurityCredentials(SocketClient* client) {
-    return (client->getUid() == AID_SYSTEM) || (client->getGid() == AID_SYSTEM);
-}
-
-bool FlushCommand::hasSecurityLogs(SocketClient* client) {
-    return clientHasSecurityCredentials(client);
-}
diff --git a/logd/FlushCommand.h b/logd/FlushCommand.h
deleted file mode 100644
index a69d439..0000000
--- a/logd/FlushCommand.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012-2013 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.
- */
-#ifndef _FLUSH_COMMAND_H
-#define _FLUSH_COMMAND_H
-
-#include <android/log.h>
-#include <sysutils/SocketClientCommand.h>
-
-class LogBufferElement;
-
-#include "LogTimes.h"
-
-class LogReader;
-
-class FlushCommand : public SocketClientCommand {
-    LogReader& mReader;
-    log_mask_t mLogMask;
-
-   public:
-    explicit FlushCommand(LogReader& reader, log_mask_t logMask)
-        : mReader(reader), mLogMask(logMask) {
-    }
-
-    virtual void runSocketCommand(SocketClient* client);
-
-    static bool hasReadLogs(SocketClient* client);
-    static bool hasSecurityLogs(SocketClient* client);
-};
-
-#endif
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 36273de..a3e4e09 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -92,11 +92,7 @@
         unlock();
     }
 
-    // We may have been triggered by a SIGHUP. Release any sleeping reader
-    // threads to dump their current content.
-    //
-    // NB: this is _not_ performed in the context of a SIGHUP, it is
-    // performed during startup, and in context of reinit administrative thread
+    // Release any sleeping reader threads to dump their current content.
     LogTimeEntry::wrlock();
 
     LastLogTimes::iterator times = mTimes.begin();
@@ -109,8 +105,11 @@
     LogTimeEntry::unlock();
 }
 
-LogBuffer::LogBuffer(LastLogTimes* times)
-    : monotonic(android_log_clockid() == CLOCK_MONOTONIC), mTimes(*times) {
+LogBuffer::LogBuffer(LastLogTimes* times, LogTags* tags, PruneList* prune)
+    : monotonic(android_log_clockid() == CLOCK_MONOTONIC),
+      mTimes(*times),
+      tags_(tags),
+      prune_(prune) {
     pthread_rwlock_init(&mLogElementsLock, nullptr);
 
     log_id_for_each(i) {
@@ -130,14 +129,14 @@
 
 LogBufferElementCollection::iterator LogBuffer::GetOldest(log_id_t log_id) {
     auto it = mLogElements.begin();
-    if (mOldest[log_id]) {
-        it = *mOldest[log_id];
+    if (oldest_[log_id]) {
+        it = *oldest_[log_id];
     }
     while (it != mLogElements.end() && (*it)->getLogId() != log_id) {
         it++;
     }
     if (it != mLogElements.end()) {
-        mOldest[log_id] = it;
+        oldest_[log_id] = it;
     }
     return it;
 }
@@ -232,7 +231,7 @@
     const char* tag = nullptr;
     size_t tag_len = 0;
     if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) {
-        tag = tagToName(elem->getTag());
+        tag = tags_->tagToName(elem->getTag());
         if (tag) {
             tag_len = strlen(tag);
         }
@@ -461,7 +460,7 @@
 
     bool setLast[LOG_ID_MAX];
     bool doSetLast = false;
-    log_id_for_each(i) { doSetLast |= setLast[i] = mOldest[i] && it == *mOldest[i]; }
+    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))
@@ -473,9 +472,9 @@
         log_id_for_each(i) {
             if (setLast[i]) {
                 if (__predict_false(it == mLogElements.end())) {
-                    mOldest[i] = std::nullopt;
+                    oldest_[i] = std::nullopt;
                 } else {
-                    mOldest[i] = it;  // Store the next iterator even if it does not correspond to
+                    oldest_[i] = it;  // Store the next iterator even if it does not correspond to
                                       // the same log_id, as a starting point for GetOldest().
                 }
             }
@@ -698,7 +697,7 @@
     }
 
     // prune by worst offenders; by blacklist, UID, and by PID of system UID
-    bool hasBlacklist = (id != LOG_ID_SECURITY) && mPrune.naughty();
+    bool hasBlacklist = (id != LOG_ID_SECURITY) && prune_->naughty();
     while (!clearAll && (pruneRows > 0)) {
         // recalculate the worst offender on every batched pass
         int worst = -1;  // not valid for getUid() or getKey()
@@ -706,7 +705,7 @@
         size_t second_worst_sizes = 0;
         pid_t worstPid = 0;  // POSIX guarantees PID != 0
 
-        if (worstUidEnabledForLogid(id) && mPrune.worstUidEnabled()) {
+        if (worstUidEnabledForLogid(id) && prune_->worstUidEnabled()) {
             // Calculate threshold as 12.5% of available storage
             size_t threshold = log_buffer_size(id) / 8;
 
@@ -720,7 +719,7 @@
                     .findWorst(worst, worst_sizes, second_worst_sizes,
                                threshold);
 
-                if ((worst == AID_SYSTEM) && mPrune.worstPidOfSystemEnabled()) {
+                if ((worst == AID_SYSTEM) && prune_->worstPidOfSystemEnabled()) {
                     stats.sortPids(worst, (pid_t)0, 2, id)
                         .findWorst(worstPid, worst_sizes, second_worst_sizes);
                 }
@@ -802,7 +801,7 @@
                           ? element->getTag()
                           : element->getUid();
 
-            if (hasBlacklist && mPrune.naughty(element)) {
+            if (hasBlacklist && prune_->naughty(element)) {
                 last.clear(element);
                 it = erase(it);
                 if (dropped) {
@@ -899,13 +898,13 @@
         }
         last.clear();
 
-        if (!kick || !mPrune.worstUidEnabled()) {
+        if (!kick || !prune_->worstUidEnabled()) {
             break;  // the following loop will ask bad clients to skip/drop
         }
     }
 
     bool whitelist = false;
-    bool hasWhitelist = (id != LOG_ID_SECURITY) && mPrune.nice() && !clearAll;
+    bool hasWhitelist = (id != LOG_ID_SECURITY) && prune_->nice() && !clearAll;
     it = GetOldest(id);
     while ((pruneRows > 0) && (it != mLogElements.end())) {
         LogBufferElement* element = *it;
@@ -921,7 +920,7 @@
             break;
         }
 
-        if (hasWhitelist && !element->getDropped() && mPrune.nice(element)) {
+        if (hasWhitelist && !element->getDropped() && prune_->nice(element)) {
             // WhiteListed
             whitelist = true;
             it++;
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index 458fbbb..9a36712 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef _LOGD_LOG_BUFFER_H__
-#define _LOGD_LOG_BUFFER_H__
+#pragma once
 
 #include <sys/types.h>
 
@@ -81,10 +80,6 @@
 
     LogStatistics stats;
 
-    PruneList mPrune;
-    // 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> mOldest[LOG_ID_MAX];
     // watermark of any worst/chatty uid processing
     typedef std::unordered_map<uid_t, LogBufferElementCollection::iterator>
         LogBufferIteratorMap;
@@ -98,8 +93,6 @@
 
     bool monotonic;
 
-    LogTags tags;
-
     LogBufferElement* lastLoggedElements[LOG_ID_MAX];
     LogBufferElement* droppedElements[LOG_ID_MAX];
     void log(LogBufferElement* elem);
@@ -107,7 +100,7 @@
    public:
     LastLogTimes& mTimes;
 
-    explicit LogBuffer(LastLogTimes* times);
+    LogBuffer(LastLogTimes* times, LogTags* tags, PruneList* prune);
     ~LogBuffer();
     void init();
     bool isMonotonic() {
@@ -136,24 +129,6 @@
         stats.enableStatistics();
     }
 
-    int initPrune(const char* cp) {
-        return mPrune.init(cp);
-    }
-    std::string formatPrune() {
-        return mPrune.format();
-    }
-
-    std::string formatGetEventTag(uid_t uid, const char* name,
-                                  const char* format) {
-        return tags.formatGetEventTag(uid, name, format);
-    }
-    std::string formatEntry(uint32_t tag, uid_t uid) {
-        return tags.formatEntry(tag, uid);
-    }
-    const char* tagToName(uint32_t tag) {
-        return tags.tagToName(tag);
-    }
-
     // helper must be protected directly or implicitly by wrlock()/unlock()
     const char* pidToName(pid_t pid) {
         return stats.pidToName(pid);
@@ -186,6 +161,11 @@
     // 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);
-};
 
-#endif  // _LOGD_LOG_BUFFER_H__
+    LogTags* tags_;
+    PruneList* prune_;
+
+    // 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];
+};
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp
index f79d39c..c6dea69 100644
--- a/logd/LogReader.cpp
+++ b/logd/LogReader.cpp
@@ -24,21 +24,35 @@
 #include <cutils/sockets.h>
 #include <private/android_logger.h>
 
-#include "FlushCommand.h"
 #include "LogBuffer.h"
 #include "LogBufferElement.h"
 #include "LogReader.h"
 #include "LogUtils.h"
 
+static bool CanReadSecurityLogs(SocketClient* client) {
+    return client->getUid() == AID_SYSTEM || client->getGid() == AID_SYSTEM;
+}
+
 LogReader::LogReader(LogBuffer* logbuf)
     : SocketListener(getLogSocket(), true), mLogbuf(*logbuf) {
 }
 
 // When we are notified a new log entry is available, inform
 // listening sockets who are watching this entry's log id.
-void LogReader::notifyNewLog(log_mask_t logMask) {
-    FlushCommand command(*this, logMask);
-    runOnEachSocket(&command);
+void LogReader::notifyNewLog(log_mask_t log_mask) {
+    LastLogTimes& times = mLogbuf.mTimes;
+
+    LogTimeEntry::wrlock();
+    for (const auto& entry : times) {
+        if (!entry->isWatchingMultiple(log_mask)) {
+            continue;
+        }
+        if (entry->mTimeout.tv_sec || entry->mTimeout.tv_nsec) {
+            continue;
+        }
+        entry->triggerReader_Locked();
+    }
+    LogTimeEntry::unlock();
 }
 
 // Note returning false will release the SocketClient instance.
@@ -129,6 +143,9 @@
         nonBlock = true;
     }
 
+    bool privileged = clientHasLogCredentials(cli);
+    bool can_read_security = CanReadSecurityLogs(cli);
+
     uint64_t sequence = 1;
     // Convert realtime to sequence number
     if (start != log_time::EPOCH) {
@@ -178,8 +195,7 @@
         } logFindStart(logMask, pid, start, sequence,
                        logbuf().isMonotonic() && android::isMonotonic(start));
 
-        logbuf().flushTo(cli, sequence, nullptr, FlushCommand::hasReadLogs(cli),
-                         FlushCommand::hasSecurityLogs(cli),
+        logbuf().flushTo(cli, sequence, nullptr, privileged, can_read_security,
                          logFindStart.callback, &logFindStart);
 
         if (!logFindStart.found()) {
@@ -203,7 +219,7 @@
 
     LogTimeEntry::wrlock();
     auto entry = std::make_unique<LogTimeEntry>(*this, cli, nonBlock, tail, logMask, pid, start,
-                                                sequence, timeout);
+                                                sequence, timeout, privileged, can_read_security);
     if (!entry->startReader_Locked()) {
         LogTimeEntry::unlock();
         return false;
diff --git a/logd/LogTags.cpp b/logd/LogTags.cpp
index e45cc8a..3e52b38 100644
--- a/logd/LogTags.cpp
+++ b/logd/LogTags.cpp
@@ -391,23 +391,6 @@
     return me->tagToName(tag);
 }
 
-// Prototype in LogUtils.h allowing external access to our database.
-//
-// This only works on userdebug and eng devices to re-read the
-// /data/misc/logd/event-log-tags file right after /data is mounted.
-// The operation is near to boot and should only happen once.  There
-// are races associated with its use since it can trigger a Rebuild
-// of the file, but that is a can-not-happen since the file was not
-// read yet.  More dangerous if called later, but if all is well it
-// should just skip over everything and not write any new entries.
-void android::ReReadEventLogTags() {
-    LogTags* me = logtags;
-
-    if (me && __android_log_is_debuggable()) {
-        me->ReadFileEventLogTags(me->debug_event_log_tags);
-    }
-}
-
 // converts an event tag into a format
 const char* LogTags::tagToFormat(uint32_t tag) const {
     tag2format_const_iterator iform;
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp
index ed8d2f5..ad150bd 100644
--- a/logd/LogTimes.cpp
+++ b/logd/LogTimes.cpp
@@ -18,7 +18,6 @@
 #include <string.h>
 #include <sys/prctl.h>
 
-#include "FlushCommand.h"
 #include "LogBuffer.h"
 #include "LogReader.h"
 #include "LogTimes.h"
@@ -27,7 +26,8 @@
 
 LogTimeEntry::LogTimeEntry(LogReader& reader, SocketClient* client, bool nonBlock,
                            unsigned long tail, log_mask_t logMask, pid_t pid, log_time start_time,
-                           uint64_t start, uint64_t timeout)
+                           uint64_t start, uint64_t timeout, bool privileged,
+                           bool can_read_security_logs)
     : leadingDropped(false),
       mReader(reader),
       mLogMask(logMask),
@@ -38,7 +38,9 @@
       mClient(client),
       mStartTime(start_time),
       mStart(start),
-      mNonBlock(nonBlock) {
+      mNonBlock(nonBlock),
+      privileged_(privileged),
+      can_read_security_logs_(can_read_security_logs) {
     mTimeout.tv_sec = timeout / NS_PER_SEC;
     mTimeout.tv_nsec = timeout % NS_PER_SEC;
     memset(mLastTid, 0, sizeof(mLastTid));
@@ -72,9 +74,6 @@
 
     LogBuffer& logbuf = me->mReader.logbuf();
 
-    bool privileged = FlushCommand::hasReadLogs(client);
-    bool security = FlushCommand::hasSecurityLogs(client);
-
     me->leadingDropped = true;
 
     wrlock();
@@ -96,12 +95,12 @@
         unlock();
 
         if (me->mTail) {
-            logbuf.flushTo(client, start, nullptr, privileged, security,
+            logbuf.flushTo(client, start, nullptr, me->privileged_, me->can_read_security_logs_,
                            FilterFirstPass, me);
             me->leadingDropped = true;
         }
-        start = logbuf.flushTo(client, start, me->mLastTid, privileged,
-                               security, FilterSecondPass, me);
+        start = logbuf.flushTo(client, start, me->mLastTid, me->privileged_,
+                               me->can_read_security_logs_, FilterSecondPass, me);
 
         // We only ignore entries before the original start time for the first flushTo(), if we
         // get entries after this first flush before the original start time, then the client
diff --git a/logd/LogTimes.h b/logd/LogTimes.h
index a99c73b..56c930a 100644
--- a/logd/LogTimes.h
+++ b/logd/LogTimes.h
@@ -52,7 +52,7 @@
   public:
     LogTimeEntry(LogReader& reader, SocketClient* client, bool nonBlock, unsigned long tail,
                  log_mask_t logMask, pid_t pid, log_time start_time, uint64_t sequence,
-                 uint64_t timeout);
+                 uint64_t timeout, bool privileged, bool can_read_security_logs);
 
     SocketClient* mClient;
     log_time mStartTime;
@@ -98,6 +98,10 @@
     // flushTo filter callbacks
     static int FilterFirstPass(const LogBufferElement* element, void* me);
     static int FilterSecondPass(const LogBufferElement* element, void* me);
+
+  private:
+    bool privileged_;
+    bool can_read_security_logs_;
 };
 
 typedef std::list<std::unique_ptr<LogTimeEntry>> LastLogTimes;
diff --git a/logd/LogUtils.h b/logd/LogUtils.h
index fa9f398..f9cd42d 100644
--- a/logd/LogUtils.h
+++ b/logd/LogUtils.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef _LOGD_LOG_UTILS_H__
-#define _LOGD_LOG_UTILS_H__
+#pragma once
 
 #include <sys/cdefs.h>
 #include <sys/types.h>
@@ -41,7 +40,6 @@
 
 // Furnished in LogTags.cpp. Thread safe.
 const char* tagToName(uint32_t tag);
-void ReReadEventLogTags();
 
 // Furnished by LogKlog.cpp
 char* log_strntok_r(char* s, ssize_t& len, char*& saveptr, ssize_t& sublen);
@@ -72,5 +70,3 @@
     return (id == LOG_ID_MAIN) || (id == LOG_ID_SYSTEM) ||
            (id == LOG_ID_RADIO) || (id == LOG_ID_EVENTS);
 }
-
-#endif  // _LOGD_LOG_UTILS_H__
diff --git a/logd/fuzz/log_buffer_log_fuzzer.cpp b/logd/fuzz/log_buffer_log_fuzzer.cpp
index 4d1589b..14c5163 100644
--- a/logd/fuzz/log_buffer_log_fuzzer.cpp
+++ b/logd/fuzz/log_buffer_log_fuzzer.cpp
@@ -94,12 +94,14 @@
     }
 
     LastLogTimes times;
-    LogBuffer log_buffer(&times);
+    LogTags tags;
+    PruneList prune_list;
+    LogBuffer log_buffer(&times, &tags, &prune_list);
     size_t data_left = size;
     const uint8_t** pdata = &data;
 
     log_buffer.enableStatistics();
-    log_buffer.initPrune(nullptr);
+    prune_list.init(nullptr);
     // We want to get pruning code to get called.
     log_id_for_each(i) { log_buffer.setSize(i, 10000); }
 
diff --git a/logd/main.cpp b/logd/main.cpp
index 23bbf86..cc45eb3 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -52,6 +52,7 @@
 #include "LogBuffer.h"
 #include "LogKlog.h"
 #include "LogListener.h"
+#include "LogTags.h"
 #include "LogUtils.h"
 
 #define KMSG_PRIORITY(PRI)                                 \
@@ -150,50 +151,6 @@
     }
 }
 
-static sem_t reinit;
-static bool reinit_running = false;
-static LogBuffer* logBuf = nullptr;
-
-static void* reinit_thread_start(void* /*obj*/) {
-    prctl(PR_SET_NAME, "logd.daemon");
-
-    while (reinit_running && !sem_wait(&reinit) && reinit_running) {
-        if (fdDmesg >= 0) {
-            static const char reinit_message[] = { KMSG_PRIORITY(LOG_INFO),
-                                                   'l',
-                                                   'o',
-                                                   'g',
-                                                   'd',
-                                                   '.',
-                                                   'd',
-                                                   'a',
-                                                   'e',
-                                                   'm',
-                                                   'o',
-                                                   'n',
-                                                   ':',
-                                                   ' ',
-                                                   'r',
-                                                   'e',
-                                                   'i',
-                                                   'n',
-                                                   'i',
-                                                   't',
-                                                   '\n' };
-            write(fdDmesg, reinit_message, sizeof(reinit_message));
-        }
-
-        // Anything that reads persist.<property>
-        if (logBuf) {
-            logBuf->init();
-            logBuf->initPrune(nullptr);
-        }
-        android::ReReadEventLogTags();
-    }
-
-    return nullptr;
-}
-
 char* android::uidToName(uid_t u) {
     struct Userdata {
         uid_t uid;
@@ -220,12 +177,6 @@
     return userdata.name;
 }
 
-// Serves as a global method to trigger reinitialization
-// and as a function that can be provided to signal().
-void reinit_signal_handler(int /*signal*/) {
-    sem_post(&reinit);
-}
-
 static void readDmesg(LogAudit* al, LogKlog* kl) {
     if (!al && !kl) {
         return;
@@ -336,24 +287,10 @@
         return EXIT_FAILURE;
     }
 
-    // Reinit Thread
-    sem_init(&reinit, 0, 0);
-    pthread_attr_t attr;
-    if (!pthread_attr_init(&attr)) {
-        struct sched_param param;
-
-        memset(&param, 0, sizeof(param));
-        pthread_attr_setschedparam(&attr, &param);
-        pthread_attr_setschedpolicy(&attr, SCHED_BATCH);
-        if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) {
-            pthread_t thread;
-            reinit_running = true;
-            if (pthread_create(&thread, &attr, reinit_thread_start, nullptr)) {
-                reinit_running = false;
-            }
-        }
-        pthread_attr_destroy(&attr);
-    }
+    // A cache of event log tags
+    LogTags log_tags;
+    // Pruning configuration.
+    PruneList prune_list;
 
     // Serves the purpose of managing the last logs times read on a
     // socket connection, and as a reader lock on a range of log
@@ -364,9 +301,7 @@
     // LogBuffer is the object which is responsible for holding all
     // log entries.
 
-    logBuf = new LogBuffer(times);
-
-    signal(SIGHUP, reinit_signal_handler);
+    LogBuffer* logBuf = new LogBuffer(times, &log_tags, &prune_list);
 
     if (__android_logger_property_get_bool(
             "logd.statistics", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST |
@@ -396,7 +331,7 @@
     // Command listener listens on /dev/socket/logd for incoming logd
     // administrative commands.
 
-    CommandListener* cl = new CommandListener(logBuf, reader, swl);
+    CommandListener* cl = new CommandListener(logBuf, &log_tags, &prune_list);
     if (cl->startListener()) {
         return EXIT_FAILURE;
     }