diff options
author | Mark Salyzyn <salyzyn@google.com> | 2014-02-06 18:11:13 -0800 |
---|---|---|
committer | Mark Salyzyn <salyzyn@google.com> | 2014-03-13 14:48:02 -0700 |
commit | 64d6fe936253b336049c285369a56cf139bd002f (patch) | |
tree | c273b80eca5fb74af38367d475f31c5cf44dac9a /logd/LogBuffer.cpp | |
parent | 34facab86b0fe7ec613de92b46b637f864fb0682 (diff) | |
download | system_core-64d6fe936253b336049c285369a56cf139bd002f.zip system_core-64d6fe936253b336049c285369a56cf139bd002f.tar.gz system_core-64d6fe936253b336049c285369a56cf139bd002f.tar.bz2 |
logd: prune by worst offending UID
(cherry picked from commit 3c4919e4748d32d7f3e147ab57f4fafee28c7447)
Change-Id: I39965007569123ff5eebe01b5bfa555bbcb2dfe7
Diffstat (limited to 'logd/LogBuffer.cpp')
-rw-r--r-- | logd/LogBuffer.cpp | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp index e16aa69..cf172d1 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp @@ -131,7 +131,60 @@ void LogBuffer::prune(log_id_t id, unsigned long pruneRows) { t++; } - LogBufferElementCollection::iterator it = mLogElements.begin(); + LogBufferElementCollection::iterator it; + + // prune by worst offender by uid + while (pruneRows > 0) { + // recalculate the worst offender on every batched pass + uid_t worst = (uid_t) -1; + size_t worst_sizes = 0; + size_t second_worst_sizes = 0; + + LidStatistics &l = stats.id(id); + UidStatisticsCollection::iterator iu; + for (iu = l.begin(); iu != l.end(); ++iu) { + UidStatistics *u = (*iu); + size_t sizes = u->sizes(); + if (worst_sizes < sizes) { + second_worst_sizes = worst_sizes; + worst_sizes = sizes; + worst = u->getUid(); + } + if ((second_worst_sizes < sizes) && (sizes < worst_sizes)) { + second_worst_sizes = sizes; + } + } + + bool kick = false; + for(it = mLogElements.begin(); it != mLogElements.end();) { + LogBufferElement *e = *it; + + if (oldest && (oldest->mStart <= e->getMonotonicTime())) { + break; + } + + if ((e->getLogId() == id) && (e->getUid() == worst)) { + it = mLogElements.erase(it); + unsigned short len = e->getMsgLen(); + stats.subtract(len, id, worst, e->getPid()); + delete e; + kick = true; + pruneRows--; + if ((pruneRows == 0) || (worst_sizes < second_worst_sizes)) { + break; + } + worst_sizes -= len; + } else { + ++it; + } + } + + if (!kick) { + break; // the following loop will ask bad clients to skip/drop + } + } + + it = mLogElements.begin(); while((pruneRows > 0) && (it != mLogElements.end())) { LogBufferElement *e = *it; if (e->getLogId() == id) { |