summaryrefslogtreecommitdiffstats
path: root/logd/LogBuffer.cpp
diff options
context:
space:
mode:
authorMark Salyzyn <salyzyn@google.com>2014-02-06 18:11:13 -0800
committerMark Salyzyn <salyzyn@google.com>2014-03-13 14:48:02 -0700
commit64d6fe936253b336049c285369a56cf139bd002f (patch)
treec273b80eca5fb74af38367d475f31c5cf44dac9a /logd/LogBuffer.cpp
parent34facab86b0fe7ec613de92b46b637f864fb0682 (diff)
downloadsystem_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.cpp55
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) {