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

Commit 794acfc0 authored by Tom Cherry's avatar Tom Cherry Committed by Gerrit Code Review
Browse files

Merge changes Ic7620978,I6d5bab58,Id1668c26,Icdb56b6f,Ic0c86a2b

* changes:
  logd: remove FlushCommand
  logd: rename mOldest -> oldest_
  logd: separate PruneList from LogBuffer
  logd: don't use SIGHUP to reinitialize
  logd: decouple LogTags from LogBuffer
parents f2554ab2 79d54f78
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ cc_library_static {
        "CommandListener.cpp",
        "LogListener.cpp",
        "LogReader.cpp",
        "FlushCommand.cpp",
        "LogBuffer.cpp",
        "LogBufferElement.cpp",
        "LogTimes.cpp",
+36 −74
Original line number Diff line number Diff line
@@ -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 @@ int CommandListener::ClearCmd::runCommand(SocketClient* cli, int argc,
        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 @@ int CommandListener::GetBufSizeCmd::runCommand(SocketClient* cli, int argc,
        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 @@ int CommandListener::SetBufSizeCmd::runCommand(SocketClient* cli, int argc,
    }

    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 @@ int CommandListener::SetBufSizeCmd::runCommand(SocketClient* cli, int argc,
    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 @@ int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient* cli, int argc,
        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 @@ int CommandListener::GetStatisticsCmd::runCommand(SocketClient* cli, int argc,
        }
    }

    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 @@ int CommandListener::SetPruneListCmd::runCommand(SocketClient* cli, int argc,
        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 @@ int CommandListener::SetPruneListCmd::runCommand(SocketClient* cli, int argc,
    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 @@ int CommandListener::GetEventTagCmd::runCommand(SocketClient* cli, int argc,
            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;
}
+32 −64
Original line number Diff line number Diff line
@@ -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() {
    }
    CommandListener(LogBuffer* buf, LogTags* tags, PruneList* prune);
    virtual ~CommandListener() {}

  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(LogBuffer* buf);                     \
        virtual ~name##Cmd() {                                  \
        }                                                       \
        explicit name##Cmd(CommandListener* parent)             \
            : LogCommand(#command_string), parent_(parent) {}   \
        virtual ~name##Cmd() {}                                 \
        int runCommand(SocketClient* c, int argc, char** argv); \
    }

    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);                                 \
        }                                                       \
      private:                                                  \
        LogBuffer* buf() const { return parent_->buf_; }        \
        LogTags* tags() const { return parent_->tags_; }        \
        PruneList* prune() const { return parent_->prune_; }    \
        CommandListener* parent_;                               \
    }

    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

logd/FlushCommand.cpp

deleted100644 → 0
+0 −75
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.
 */

#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);
}

logd/FlushCommand.h

deleted100644 → 0
+0 −43
Original line number Diff line number Diff line
/*
 * 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
Loading