blob: 4b8b08042f68a9fcab66c9fabfb79854061ab0ab [file] [log] [blame]
Mark Salyzyndfa7a072014-02-11 12:29:31 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Mark Salyzyndfa7a072014-02-11 12:29:31 -080017#include <ctype.h>
18
Elliott Hughes4f713192015-12-04 22:00:26 -080019#include <android-base/stringprintf.h>
Mark Salyzyn932f7ac2015-08-28 08:02:59 -070020#include <cutils/properties.h>
Mark Salyzyndfa7a072014-02-11 12:29:31 -080021
22#include "LogWhiteBlackList.h"
23
24// White and Black list
25
Mark Salyzyn77187782015-05-12 15:21:31 -070026Prune::Prune(uid_t uid, pid_t pid) : mUid(uid), mPid(pid) {
27}
Mark Salyzyndfa7a072014-02-11 12:29:31 -080028
29int Prune::cmp(uid_t uid, pid_t pid) const {
30 if ((mUid == uid_all) || (mUid == uid)) {
31 if (mPid == pid_all) {
32 return 0;
33 }
34 return pid - mPid;
35 }
36 return uid - mUid;
37}
38
Mark Salyzyn73160ac2015-08-20 10:01:44 -070039std::string Prune::format() {
Mark Salyzyndfa7a072014-02-11 12:29:31 -080040 if (mUid != uid_all) {
Chih-Hung Hsieh634118e2014-09-12 16:02:28 -070041 if (mPid != pid_all) {
Mark Salyzyn73160ac2015-08-20 10:01:44 -070042 return android::base::StringPrintf("%u/%u", mUid, mPid);
Chih-Hung Hsieh634118e2014-09-12 16:02:28 -070043 }
Mark Salyzyn73160ac2015-08-20 10:01:44 -070044 return android::base::StringPrintf("%u", mUid);
Mark Salyzyndfa7a072014-02-11 12:29:31 -080045 }
Mark Salyzyn73160ac2015-08-20 10:01:44 -070046 if (mPid != pid_all) {
47 return android::base::StringPrintf("/%u", mPid);
48 }
49 // NB: mPid == pid_all can not happen if mUid == uid_all
50 return std::string("/");
Mark Salyzyndfa7a072014-02-11 12:29:31 -080051}
52
Mark Salyzyn932f7ac2015-08-28 08:02:59 -070053PruneList::PruneList() {
54 init(NULL);
Mark Salyzyndfa7a072014-02-11 12:29:31 -080055}
56
57PruneList::~PruneList() {
58 PruneCollection::iterator it;
59 for (it = mNice.begin(); it != mNice.end();) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -080060 it = mNice.erase(it);
61 }
62 for (it = mNaughty.begin(); it != mNaughty.end();) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -080063 it = mNaughty.erase(it);
64 }
65}
66
Mark Salyzyn501c3732017-03-10 14:31:54 -080067int PruneList::init(const char* str) {
Mark Salyzyn1a01f962014-05-06 13:49:28 -070068 mWorstUidEnabled = true;
Mark Salyzynbec3c3d2015-08-28 08:02:59 -070069 mWorstPidOfSystemEnabled = true;
Mark Salyzyndfa7a072014-02-11 12:29:31 -080070 PruneCollection::iterator it;
71 for (it = mNice.begin(); it != mNice.end();) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -080072 it = mNice.erase(it);
73 }
74 for (it = mNaughty.begin(); it != mNaughty.end();) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -080075 it = mNaughty.erase(it);
76 }
77
Mark Salyzyn932f7ac2015-08-28 08:02:59 -070078 static const char _default[] = "default";
79 // default here means take ro.logd.filter, persist.logd.filter then
80 // internal default in that order.
81 if (str && !strcmp(str, _default)) {
82 str = NULL;
83 }
84 static const char _disable[] = "disable";
85 if (str && !strcmp(str, _disable)) {
86 str = "";
87 }
88
89 std::string filter;
90
91 if (str) {
92 filter = str;
93 } else {
94 char property[PROPERTY_VALUE_MAX];
95 property_get("ro.logd.filter", property, _default);
96 filter = property;
97 property_get("persist.logd.filter", property, filter.c_str());
98 // default here means take ro.logd.filter
99 if (strcmp(property, _default)) {
100 filter = property;
101 }
102 }
103
104 // default here means take internal default.
105 if (filter == _default) {
106 // See README.property for description of filter format
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700107 filter = "~! ~1000/!";
Mark Salyzyn932f7ac2015-08-28 08:02:59 -0700108 }
109 if (filter == _disable) {
110 filter = "";
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800111 }
112
113 mWorstUidEnabled = false;
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700114 mWorstPidOfSystemEnabled = false;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800115
Mark Salyzyn501c3732017-03-10 14:31:54 -0800116 for (str = filter.c_str(); *str; ++str) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800117 if (isspace(*str)) {
118 continue;
119 }
120
Mark Salyzyn501c3732017-03-10 14:31:54 -0800121 PruneCollection* list;
122 if ((*str == '~') || (*str == '!')) { // ~ supported, ! undocumented
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800123 ++str;
124 // special case, translates to worst UID at priority in blacklist
125 if (*str == '!') {
126 mWorstUidEnabled = true;
127 ++str;
128 if (!*str) {
129 break;
130 }
131 if (!isspace(*str)) {
132 return 1;
133 }
134 continue;
135 }
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700136 // special case, translated to worst PID of System at priority
137 static const char worstPid[] = "1000/!";
138 if (!strncmp(str, worstPid, sizeof(worstPid) - 1)) {
139 mWorstPidOfSystemEnabled = true;
140 str += sizeof(worstPid) - 1;
141 if (!*str) {
142 break;
143 }
144 if (!isspace(*str)) {
145 return 1;
146 }
147 continue;
148 }
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800149 if (!*str) {
150 return 1;
151 }
152 list = &mNaughty;
153 } else {
154 list = &mNice;
155 }
156
157 uid_t uid = Prune::uid_all;
158 if (isdigit(*str)) {
159 uid = 0;
160 do {
161 uid = uid * 10 + *str++ - '0';
162 } while (isdigit(*str));
163 }
164
165 pid_t pid = Prune::pid_all;
166 if (*str == '/') {
167 ++str;
168 if (isdigit(*str)) {
169 pid = 0;
170 do {
171 pid = pid * 10 + *str++ - '0';
172 } while (isdigit(*str));
173 }
174 }
175
176 if ((uid == Prune::uid_all) && (pid == Prune::pid_all)) {
177 return 1;
178 }
179
180 if (*str && !isspace(*str)) {
181 return 1;
182 }
183
184 // insert sequentially into list
185 PruneCollection::iterator it = list->begin();
186 while (it != list->end()) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800187 Prune& p = *it;
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700188 int m = uid - p.mUid;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800189 if (m == 0) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700190 if (p.mPid == p.pid_all) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800191 break;
192 }
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700193 if ((pid == p.pid_all) && (p.mPid != p.pid_all)) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800194 it = list->erase(it);
195 continue;
196 }
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700197 m = pid - p.mPid;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800198 }
Mark Salyzyn22e287d2014-03-21 13:12:16 -0700199 if (m <= 0) {
200 if (m < 0) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800201 list->insert(it, Prune(uid, pid));
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800202 }
203 break;
204 }
205 ++it;
206 }
207 if (it == list->end()) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800208 list->push_back(Prune(uid, pid));
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800209 }
210 if (!*str) {
211 break;
212 }
213 }
214
215 return 0;
216}
217
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700218std::string PruneList::format() {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800219 static const char nice_format[] = " %s";
Mark Salyzyn501c3732017-03-10 14:31:54 -0800220 const char* fmt = nice_format + 1;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800221
Mark Salyzynb332f1c2015-08-19 13:53:20 -0700222 std::string string;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800223
224 if (mWorstUidEnabled) {
Mark Salyzynb332f1c2015-08-19 13:53:20 -0700225 string = "~!";
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800226 fmt = nice_format;
Mark Salyzynbec3c3d2015-08-28 08:02:59 -0700227 if (mWorstPidOfSystemEnabled) {
228 string += " ~1000/!";
229 }
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800230 }
231
232 PruneCollection::iterator it;
233
234 for (it = mNice.begin(); it != mNice.end(); ++it) {
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700235 string += android::base::StringPrintf(fmt, (*it).format().c_str());
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800236 fmt = nice_format;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800237 }
238
239 static const char naughty_format[] = " ~%s";
240 fmt = naughty_format + (*fmt != ' ');
241 for (it = mNaughty.begin(); it != mNaughty.end(); ++it) {
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700242 string += android::base::StringPrintf(fmt, (*it).format().c_str());
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800243 fmt = naughty_format;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800244 }
245
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700246 return string;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800247}
248
249// ToDo: Lists are in sorted order, Prune->cmp() returns + or -
250// If there is scaling issues, resort to a better algorithm than linear
251// based on these assumptions.
252
Mark Salyzyn501c3732017-03-10 14:31:54 -0800253bool PruneList::naughty(LogBufferElement* element) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800254 PruneCollection::iterator it;
255 for (it = mNaughty.begin(); it != mNaughty.end(); ++it) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700256 if (!(*it).cmp(element)) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800257 return true;
258 }
259 }
260 return false;
261}
262
Mark Salyzyn501c3732017-03-10 14:31:54 -0800263bool PruneList::nice(LogBufferElement* element) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800264 PruneCollection::iterator it;
265 for (it = mNice.begin(); it != mNice.end(); ++it) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700266 if (!(*it).cmp(element)) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800267 return true;
268 }
269 }
270 return false;
271}