diff options
author | Mark Salyzyn | 2017-03-10 16:31:54 -0600 |
---|---|---|
committer | Mark Salyzyn | 2017-03-13 12:31:09 -0500 |
commit | 501c373916e292764400dbae735f44b33378400f (patch) | |
tree | 56946d23a00461d2a462658f36689faa1d9d71a3 | |
parent | 488525b47ba23b2548f3bf6aa2f4ce6267b2d9b5 (diff) | |
download | platform-system-core-501c373916e292764400dbae735f44b33378400f.tar.gz platform-system-core-501c373916e292764400dbae735f44b33378400f.tar.xz platform-system-core-501c373916e292764400dbae735f44b33378400f.zip |
logd: specify clang format
Switch _all_ file's coding style to match to ease all future changes.
SideEffects: None
Test: compile
Bug: 35373582
Change-Id: I470cb17f64fa48f14aafc02f574e296bffe3a3f3
32 files changed, 1745 insertions, 1626 deletions
diff --git a/logd/.clang-format b/logd/.clang-format new file mode 100644 index 000000000..393c3094b --- /dev/null +++ b/logd/.clang-format | |||
@@ -0,0 +1,11 @@ | |||
1 | BasedOnStyle: Google | ||
2 | AllowShortFunctionsOnASingleLine: false | ||
3 | |||
4 | CommentPragmas: NOLINT:.* | ||
5 | DerivePointerAlignment: false | ||
6 | IndentWidth: 4 | ||
7 | PointerAlignment: Left | ||
8 | TabWidth: 4 | ||
9 | PenaltyExcessCharacter: 32 | ||
10 | |||
11 | Cpp11BracedListStyle: false | ||
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp index 6ad735152..06c0ab5fe 100644 --- a/logd/CommandListener.cpp +++ b/logd/CommandListener.cpp | |||
@@ -20,8 +20,8 @@ | |||
20 | #include <errno.h> | 20 | #include <errno.h> |
21 | #include <fcntl.h> | 21 | #include <fcntl.h> |
22 | #include <netinet/in.h> | 22 | #include <netinet/in.h> |
23 | #include <string.h> | ||
24 | #include <stdlib.h> | 23 | #include <stdlib.h> |
24 | #include <string.h> | ||
25 | #include <sys/prctl.h> | 25 | #include <sys/prctl.h> |
26 | #include <sys/socket.h> | 26 | #include <sys/socket.h> |
27 | #include <sys/types.h> | 27 | #include <sys/types.h> |
@@ -37,9 +37,9 @@ | |||
37 | #include "LogCommand.h" | 37 | #include "LogCommand.h" |
38 | #include "LogUtils.h" | 38 | #include "LogUtils.h" |
39 | 39 | ||
40 | CommandListener::CommandListener(LogBuffer *buf, LogReader * /*reader*/, | 40 | CommandListener::CommandListener(LogBuffer* buf, LogReader* /*reader*/, |
41 | LogListener * /*swl*/) : | 41 | LogListener* /*swl*/) |
42 | FrameworkListener(getLogSocket()) { | 42 | : FrameworkListener(getLogSocket()) { |
43 | // registerCmd(new ShutdownCmd(buf, writer, swl)); | 43 | // registerCmd(new ShutdownCmd(buf, writer, swl)); |
44 | registerCmd(new ClearCmd(buf)); | 44 | registerCmd(new ClearCmd(buf)); |
45 | registerCmd(new GetBufSizeCmd(buf)); | 45 | registerCmd(new GetBufSizeCmd(buf)); |
@@ -53,24 +53,19 @@ CommandListener::CommandListener(LogBuffer *buf, LogReader * /*reader*/, | |||
53 | registerCmd(new ExitCmd(this)); | 53 | registerCmd(new ExitCmd(this)); |
54 | } | 54 | } |
55 | 55 | ||
56 | CommandListener::ShutdownCmd::ShutdownCmd(LogReader *reader, | 56 | CommandListener::ShutdownCmd::ShutdownCmd(LogReader* reader, LogListener* swl) |
57 | LogListener *swl) : | 57 | : LogCommand("shutdown"), mReader(*reader), mSwl(*swl) { |
58 | LogCommand("shutdown"), | ||
59 | mReader(*reader), | ||
60 | mSwl(*swl) { | ||
61 | } | 58 | } |
62 | 59 | ||
63 | int CommandListener::ShutdownCmd::runCommand(SocketClient * /*cli*/, | 60 | int CommandListener::ShutdownCmd::runCommand(SocketClient* /*cli*/, |
64 | int /*argc*/, | 61 | int /*argc*/, char** /*argv*/) { |
65 | char ** /*argv*/) { | ||
66 | mSwl.stopListener(); | 62 | mSwl.stopListener(); |
67 | mReader.stopListener(); | 63 | mReader.stopListener(); |
68 | exit(0); | 64 | exit(0); |
69 | } | 65 | } |
70 | 66 | ||
71 | CommandListener::ClearCmd::ClearCmd(LogBuffer *buf) : | 67 | CommandListener::ClearCmd::ClearCmd(LogBuffer* buf) |
72 | LogCommand("clear"), | 68 | : LogCommand("clear"), mBuf(*buf) { |
73 | mBuf(*buf) { | ||
74 | } | 69 | } |
75 | 70 | ||
76 | static void setname() { | 71 | static void setname() { |
@@ -81,8 +76,8 @@ static void setname() { | |||
81 | } | 76 | } |
82 | } | 77 | } |
83 | 78 | ||
84 | int CommandListener::ClearCmd::runCommand(SocketClient *cli, | 79 | int CommandListener::ClearCmd::runCommand(SocketClient* cli, int argc, |
85 | int argc, char **argv) { | 80 | char** argv) { |
86 | setname(); | 81 | setname(); |
87 | uid_t uid = cli->getUid(); | 82 | uid_t uid = cli->getUid(); |
88 | if (clientHasLogCredentials(cli)) { | 83 | if (clientHasLogCredentials(cli)) { |
@@ -100,17 +95,16 @@ int CommandListener::ClearCmd::runCommand(SocketClient *cli, | |||
100 | return 0; | 95 | return 0; |
101 | } | 96 | } |
102 | 97 | ||
103 | cli->sendMsg(mBuf.clear((log_id_t) id, uid) ? "busy" : "success"); | 98 | cli->sendMsg(mBuf.clear((log_id_t)id, uid) ? "busy" : "success"); |
104 | return 0; | 99 | return 0; |
105 | } | 100 | } |
106 | 101 | ||
107 | CommandListener::GetBufSizeCmd::GetBufSizeCmd(LogBuffer *buf) : | 102 | CommandListener::GetBufSizeCmd::GetBufSizeCmd(LogBuffer* buf) |
108 | LogCommand("getLogSize"), | 103 | : LogCommand("getLogSize"), mBuf(*buf) { |
109 | mBuf(*buf) { | ||
110 | } | 104 | } |
111 | 105 | ||
112 | int CommandListener::GetBufSizeCmd::runCommand(SocketClient *cli, | 106 | int CommandListener::GetBufSizeCmd::runCommand(SocketClient* cli, int argc, |
113 | int argc, char **argv) { | 107 | char** argv) { |
114 | setname(); | 108 | setname(); |
115 | if (argc < 2) { | 109 | if (argc < 2) { |
116 | cli->sendMsg("Missing Argument"); | 110 | cli->sendMsg("Missing Argument"); |
@@ -123,20 +117,19 @@ int CommandListener::GetBufSizeCmd::runCommand(SocketClient *cli, | |||
123 | return 0; | 117 | return 0; |
124 | } | 118 | } |
125 | 119 | ||
126 | unsigned long size = mBuf.getSize((log_id_t) id); | 120 | unsigned long size = mBuf.getSize((log_id_t)id); |
127 | char buf[512]; | 121 | char buf[512]; |
128 | snprintf(buf, sizeof(buf), "%lu", size); | 122 | snprintf(buf, sizeof(buf), "%lu", size); |
129 | cli->sendMsg(buf); | 123 | cli->sendMsg(buf); |
130 | return 0; | 124 | return 0; |
131 | } | 125 | } |
132 | 126 | ||
133 | CommandListener::SetBufSizeCmd::SetBufSizeCmd(LogBuffer *buf) : | 127 | CommandListener::SetBufSizeCmd::SetBufSizeCmd(LogBuffer* buf) |
134 | LogCommand("setLogSize"), | 128 | : LogCommand("setLogSize"), mBuf(*buf) { |
135 | mBuf(*buf) { | ||
136 | } | 129 | } |
137 | 130 | ||
138 | int CommandListener::SetBufSizeCmd::runCommand(SocketClient *cli, | 131 | int CommandListener::SetBufSizeCmd::runCommand(SocketClient* cli, int argc, |
139 | int argc, char **argv) { | 132 | char** argv) { |
140 | setname(); | 133 | setname(); |
141 | if (!clientHasLogCredentials(cli)) { | 134 | if (!clientHasLogCredentials(cli)) { |
142 | cli->sendMsg("Permission Denied"); | 135 | cli->sendMsg("Permission Denied"); |
@@ -155,7 +148,7 @@ int CommandListener::SetBufSizeCmd::runCommand(SocketClient *cli, | |||
155 | } | 148 | } |
156 | 149 | ||
157 | unsigned long size = atol(argv[2]); | 150 | unsigned long size = atol(argv[2]); |
158 | if (mBuf.setSize((log_id_t) id, size)) { | 151 | if (mBuf.setSize((log_id_t)id, size)) { |
159 | cli->sendMsg("Range Error"); | 152 | cli->sendMsg("Range Error"); |
160 | return 0; | 153 | return 0; |
161 | } | 154 | } |
@@ -164,13 +157,12 @@ int CommandListener::SetBufSizeCmd::runCommand(SocketClient *cli, | |||
164 | return 0; | 157 | return 0; |
165 | } | 158 | } |
166 | 159 | ||
167 | CommandListener::GetBufSizeUsedCmd::GetBufSizeUsedCmd(LogBuffer *buf) : | 160 | CommandListener::GetBufSizeUsedCmd::GetBufSizeUsedCmd(LogBuffer* buf) |
168 | LogCommand("getLogSizeUsed"), | 161 | : LogCommand("getLogSizeUsed"), mBuf(*buf) { |
169 | mBuf(*buf) { | ||
170 | } | 162 | } |
171 | 163 | ||
172 | int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient *cli, | 164 | int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient* cli, int argc, |
173 | int argc, char **argv) { | 165 | char** argv) { |
174 | setname(); | 166 | setname(); |
175 | if (argc < 2) { | 167 | if (argc < 2) { |
176 | cli->sendMsg("Missing Argument"); | 168 | cli->sendMsg("Missing Argument"); |
@@ -183,29 +175,29 @@ int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient *cli, | |||
183 | return 0; | 175 | return 0; |
184 | } | 176 | } |
185 | 177 | ||
186 | unsigned long size = mBuf.getSizeUsed((log_id_t) id); | 178 | unsigned long size = mBuf.getSizeUsed((log_id_t)id); |
187 | char buf[512]; | 179 | char buf[512]; |
188 | snprintf(buf, sizeof(buf), "%lu", size); | 180 | snprintf(buf, sizeof(buf), "%lu", size); |
189 | cli->sendMsg(buf); | 181 | cli->sendMsg(buf); |
190 | return 0; | 182 | return 0; |
191 | } | 183 | } |
192 | 184 | ||
193 | CommandListener::GetStatisticsCmd::GetStatisticsCmd(LogBuffer *buf) : | 185 | CommandListener::GetStatisticsCmd::GetStatisticsCmd(LogBuffer* buf) |
194 | LogCommand("getStatistics"), | 186 | : LogCommand("getStatistics"), mBuf(*buf) { |
195 | mBuf(*buf) { | ||
196 | } | 187 | } |
197 | 188 | ||
198 | static std::string package_string(const std::string &str) { | 189 | static std::string package_string(const std::string& str) { |
199 | // Calculate total buffer size prefix, count is the string length w/o nul | 190 | // Calculate total buffer size prefix, count is the string length w/o nul |
200 | char fmt[32]; | 191 | char fmt[32]; |
201 | for(size_t l = str.length(), y = 0, x = 6; y != x; y = x, x = strlen(fmt) - 2) { | 192 | for (size_t l = str.length(), y = 0, x = 6; y != x; |
193 | y = x, x = strlen(fmt) - 2) { | ||
202 | snprintf(fmt, sizeof(fmt), "%zu\n%%s\n\f", l + x); | 194 | snprintf(fmt, sizeof(fmt), "%zu\n%%s\n\f", l + x); |
203 | } | 195 | } |
204 | return android::base::StringPrintf(fmt, str.c_str()); | 196 | return android::base::StringPrintf(fmt, str.c_str()); |
205 | } | 197 | } |
206 | 198 | ||
207 | int CommandListener::GetStatisticsCmd::runCommand(SocketClient *cli, | 199 | int CommandListener::GetStatisticsCmd::runCommand(SocketClient* cli, int argc, |
208 | int argc, char **argv) { | 200 | char** argv) { |
209 | setname(); | 201 | setname(); |
210 | uid_t uid = cli->getUid(); | 202 | uid_t uid = cli->getUid(); |
211 | if (clientHasLogCredentials(cli)) { | 203 | if (clientHasLogCredentials(cli)) { |
@@ -236,30 +228,28 @@ int CommandListener::GetStatisticsCmd::runCommand(SocketClient *cli, | |||
236 | } | 228 | } |
237 | } | 229 | } |
238 | 230 | ||
239 | cli->sendMsg(package_string(mBuf.formatStatistics(uid, pid, | 231 | cli->sendMsg( |
240 | logMask)).c_str()); | 232 | package_string(mBuf.formatStatistics(uid, pid, logMask)).c_str()); |
241 | return 0; | 233 | return 0; |
242 | } | 234 | } |
243 | 235 | ||
244 | CommandListener::GetPruneListCmd::GetPruneListCmd(LogBuffer *buf) : | 236 | CommandListener::GetPruneListCmd::GetPruneListCmd(LogBuffer* buf) |
245 | LogCommand("getPruneList"), | 237 | : LogCommand("getPruneList"), mBuf(*buf) { |
246 | mBuf(*buf) { | ||
247 | } | 238 | } |
248 | 239 | ||
249 | int CommandListener::GetPruneListCmd::runCommand(SocketClient *cli, | 240 | int CommandListener::GetPruneListCmd::runCommand(SocketClient* cli, |
250 | int /*argc*/, char ** /*argv*/) { | 241 | int /*argc*/, char** /*argv*/) { |
251 | setname(); | 242 | setname(); |
252 | cli->sendMsg(package_string(mBuf.formatPrune()).c_str()); | 243 | cli->sendMsg(package_string(mBuf.formatPrune()).c_str()); |
253 | return 0; | 244 | return 0; |
254 | } | 245 | } |
255 | 246 | ||
256 | CommandListener::SetPruneListCmd::SetPruneListCmd(LogBuffer *buf) : | 247 | CommandListener::SetPruneListCmd::SetPruneListCmd(LogBuffer* buf) |
257 | LogCommand("setPruneList"), | 248 | : LogCommand("setPruneList"), mBuf(*buf) { |
258 | mBuf(*buf) { | ||
259 | } | 249 | } |
260 | 250 | ||
261 | int CommandListener::SetPruneListCmd::runCommand(SocketClient *cli, | 251 | int CommandListener::SetPruneListCmd::runCommand(SocketClient* cli, int argc, |
262 | int argc, char **argv) { | 252 | char** argv) { |
263 | setname(); | 253 | setname(); |
264 | if (!clientHasLogCredentials(cli)) { | 254 | if (!clientHasLogCredentials(cli)) { |
265 | cli->sendMsg("Permission Denied"); | 255 | cli->sendMsg("Permission Denied"); |
@@ -286,22 +276,21 @@ int CommandListener::SetPruneListCmd::runCommand(SocketClient *cli, | |||
286 | return 0; | 276 | return 0; |
287 | } | 277 | } |
288 | 278 | ||
289 | CommandListener::GetEventTagCmd::GetEventTagCmd(LogBuffer *buf) : | 279 | CommandListener::GetEventTagCmd::GetEventTagCmd(LogBuffer* buf) |
290 | LogCommand("getEventTag"), | 280 | : LogCommand("getEventTag"), mBuf(*buf) { |
291 | mBuf(*buf) { | ||
292 | } | 281 | } |
293 | 282 | ||
294 | int CommandListener::GetEventTagCmd::runCommand(SocketClient *cli, | 283 | int CommandListener::GetEventTagCmd::runCommand(SocketClient* cli, int argc, |
295 | int argc, char ** argv) { | 284 | char** argv) { |
296 | setname(); | 285 | setname(); |
297 | uid_t uid = cli->getUid(); | 286 | uid_t uid = cli->getUid(); |
298 | if (clientHasLogCredentials(cli)) { | 287 | if (clientHasLogCredentials(cli)) { |
299 | uid = AID_ROOT; | 288 | uid = AID_ROOT; |
300 | } | 289 | } |
301 | 290 | ||
302 | const char *name = NULL; | 291 | const char* name = NULL; |
303 | const char *format = NULL; | 292 | const char* format = NULL; |
304 | const char *id = NULL; | 293 | const char* id = NULL; |
305 | for (int i = 1; i < argc; ++i) { | 294 | for (int i = 1; i < argc; ++i) { |
306 | static const char _name[] = "name="; | 295 | static const char _name[] = "name="; |
307 | if (!strncmp(argv[i], _name, strlen(_name))) { | 296 | if (!strncmp(argv[i], _name, strlen(_name))) { |
@@ -331,8 +320,8 @@ int CommandListener::GetEventTagCmd::runCommand(SocketClient *cli, | |||
331 | return 0; | 320 | return 0; |
332 | } | 321 | } |
333 | 322 | ||
334 | cli->sendMsg(package_string(mBuf.formatGetEventTag(uid, | 323 | cli->sendMsg( |
335 | name, format)).c_str()); | 324 | package_string(mBuf.formatGetEventTag(uid, name, format)).c_str()); |
336 | 325 | ||
337 | return 0; | 326 | return 0; |
338 | } | 327 | } |
@@ -340,8 +329,8 @@ int CommandListener::GetEventTagCmd::runCommand(SocketClient *cli, | |||
340 | CommandListener::ReinitCmd::ReinitCmd() : LogCommand("reinit") { | 329 | CommandListener::ReinitCmd::ReinitCmd() : LogCommand("reinit") { |
341 | } | 330 | } |
342 | 331 | ||
343 | int CommandListener::ReinitCmd::runCommand(SocketClient *cli, | 332 | int CommandListener::ReinitCmd::runCommand(SocketClient* cli, int /*argc*/, |
344 | int /*argc*/, char ** /*argv*/) { | 333 | char** /*argv*/) { |
345 | setname(); | 334 | setname(); |
346 | 335 | ||
347 | reinit_signal_handler(SIGHUP); | 336 | reinit_signal_handler(SIGHUP); |
@@ -351,13 +340,12 @@ int CommandListener::ReinitCmd::runCommand(SocketClient *cli, | |||
351 | return 0; | 340 | return 0; |
352 | } | 341 | } |
353 | 342 | ||
354 | CommandListener::ExitCmd::ExitCmd(CommandListener *parent) : | 343 | CommandListener::ExitCmd::ExitCmd(CommandListener* parent) |
355 | LogCommand("EXIT"), | 344 | : LogCommand("EXIT"), mParent(*parent) { |
356 | mParent(*parent) { | ||
357 | } | 345 | } |
358 | 346 | ||
359 | int CommandListener::ExitCmd::runCommand(SocketClient * cli, | 347 | int CommandListener::ExitCmd::runCommand(SocketClient* cli, int /*argc*/, |
360 | int /*argc*/, char ** /*argv*/) { | 348 | char** /*argv*/) { |
361 | setname(); | 349 | setname(); |
362 | 350 | ||
363 | cli->sendMsg("success"); | 351 | cli->sendMsg("success"); |
@@ -371,9 +359,8 @@ int CommandListener::getLogSocket() { | |||
371 | int sock = android_get_control_socket(socketName); | 359 | int sock = android_get_control_socket(socketName); |
372 | 360 | ||
373 | if (sock < 0) { | 361 | if (sock < 0) { |
374 | sock = socket_local_server(socketName, | 362 | sock = socket_local_server( |
375 | ANDROID_SOCKET_NAMESPACE_RESERVED, | 363 | socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); |
376 | SOCK_STREAM); | ||
377 | } | 364 | } |
378 | 365 | ||
379 | return sock; | 366 | return sock; |
diff --git a/logd/CommandListener.h b/logd/CommandListener.h index 39de03b5a..ed9941938 100644 --- a/logd/CommandListener.h +++ b/logd/CommandListener.h | |||
@@ -18,40 +18,43 @@ | |||
18 | #define _COMMANDLISTENER_H__ | 18 | #define _COMMANDLISTENER_H__ |
19 | 19 | ||
20 | #include <sysutils/FrameworkListener.h> | 20 | #include <sysutils/FrameworkListener.h> |
21 | #include "LogCommand.h" | ||
22 | #include "LogBuffer.h" | 21 | #include "LogBuffer.h" |
23 | #include "LogReader.h" | 22 | #include "LogCommand.h" |
24 | #include "LogListener.h" | 23 | #include "LogListener.h" |
24 | #include "LogReader.h" | ||
25 | 25 | ||
26 | // See main.cpp for implementation | 26 | // See main.cpp for implementation |
27 | void reinit_signal_handler(int /*signal*/); | 27 | void reinit_signal_handler(int /*signal*/); |
28 | 28 | ||
29 | class CommandListener : public FrameworkListener { | 29 | class CommandListener : public FrameworkListener { |
30 | public: | ||
31 | CommandListener(LogBuffer* buf, LogReader* reader, LogListener* swl); | ||
32 | virtual ~CommandListener() { | ||
33 | } | ||
30 | 34 | ||
31 | public: | 35 | private: |
32 | CommandListener(LogBuffer *buf, LogReader *reader, LogListener *swl); | ||
33 | virtual ~CommandListener() {} | ||
34 | |||
35 | private: | ||
36 | static int getLogSocket(); | 36 | static int getLogSocket(); |
37 | 37 | ||
38 | class ShutdownCmd : public LogCommand { | 38 | class ShutdownCmd : public LogCommand { |
39 | LogReader &mReader; | 39 | LogReader& mReader; |
40 | LogListener &mSwl; | 40 | LogListener& mSwl; |
41 | 41 | ||
42 | public: | 42 | public: |
43 | ShutdownCmd(LogReader *reader, LogListener *swl); | 43 | ShutdownCmd(LogReader* reader, LogListener* swl); |
44 | virtual ~ShutdownCmd() {} | 44 | virtual ~ShutdownCmd() { |
45 | int runCommand(SocketClient *c, int argc, char ** argv); | 45 | } |
46 | int runCommand(SocketClient* c, int argc, char** argv); | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | #define LogBufferCmd(name) \ | 49 | #define LogBufferCmd(name) \ |
49 | class name##Cmd : public LogCommand { \ | 50 | class name##Cmd : public LogCommand { \ |
50 | LogBuffer &mBuf; \ | 51 | LogBuffer& mBuf; \ |
51 | public: \ | 52 | \ |
52 | explicit name##Cmd(LogBuffer *buf); \ | 53 | public: \ |
53 | virtual ~name##Cmd() {} \ | 54 | explicit name##Cmd(LogBuffer* buf); \ |
54 | int runCommand(SocketClient *c, int argc, char ** argv); \ | 55 | virtual ~name##Cmd() { \ |
56 | } \ | ||
57 | int runCommand(SocketClient* c, int argc, char** argv); \ | ||
55 | } | 58 | } |
56 | 59 | ||
57 | LogBufferCmd(Clear); | 60 | LogBufferCmd(Clear); |
@@ -63,29 +66,33 @@ private: | |||
63 | LogBufferCmd(SetPruneList); | 66 | LogBufferCmd(SetPruneList); |
64 | LogBufferCmd(GetEventTag); | 67 | LogBufferCmd(GetEventTag); |
65 | 68 | ||
66 | #define LogCmd(name) \ | 69 | #define LogCmd(name) \ |
67 | class name##Cmd : public LogCommand { \ | 70 | class name##Cmd : public LogCommand { \ |
68 | public: \ | 71 | public: \ |
69 | name##Cmd(); \ | 72 | name##Cmd(); \ |
70 | virtual ~name##Cmd() {} \ | 73 | virtual ~name##Cmd() { \ |
71 | int runCommand(SocketClient *c, int argc, char ** argv); \ | 74 | } \ |
75 | int runCommand(SocketClient* c, int argc, char** argv); \ | ||
72 | } | 76 | } |
73 | 77 | ||
74 | LogCmd(Reinit); | 78 | LogCmd(Reinit); |
75 | 79 | ||
76 | #define LogParentCmd(name) \ | 80 | #define LogParentCmd(name) \ |
77 | class name##Cmd : public LogCommand { \ | 81 | class name##Cmd : public LogCommand { \ |
78 | CommandListener &mParent; \ | 82 | CommandListener& mParent; \ |
79 | public: \ | 83 | \ |
80 | name##Cmd(); \ | 84 | public: \ |
81 | explicit name##Cmd(CommandListener *parent); \ | 85 | name##Cmd(); \ |
82 | virtual ~name##Cmd() {} \ | 86 | explicit name##Cmd(CommandListener* parent); \ |
83 | int runCommand(SocketClient *c, int argc, char ** argv); \ | 87 | virtual ~name##Cmd() { \ |
84 | void release(SocketClient *c) { mParent.release(c); } \ | 88 | } \ |
89 | int runCommand(SocketClient* c, int argc, char** argv); \ | ||
90 | void release(SocketClient* c) { \ | ||
91 | mParent.release(c); \ | ||
92 | } \ | ||
85 | } | 93 | } |
86 | 94 | ||
87 | LogParentCmd(Exit); | 95 | LogParentCmd(Exit); |
88 | |||
89 | }; | 96 | }; |
90 | 97 | ||
91 | #endif | 98 | #endif |
diff --git a/logd/FlushCommand.cpp b/logd/FlushCommand.cpp index 6a26d00f3..5a5c0d981 100644 --- a/logd/FlushCommand.cpp +++ b/logd/FlushCommand.cpp | |||
@@ -26,20 +26,16 @@ | |||
26 | #include "LogTimes.h" | 26 | #include "LogTimes.h" |
27 | #include "LogUtils.h" | 27 | #include "LogUtils.h" |
28 | 28 | ||
29 | FlushCommand::FlushCommand(LogReader &reader, | 29 | FlushCommand::FlushCommand(LogReader& reader, bool nonBlock, unsigned long tail, |
30 | bool nonBlock, | 30 | unsigned int logMask, pid_t pid, uint64_t start, |
31 | unsigned long tail, | 31 | uint64_t timeout) |
32 | unsigned int logMask, | 32 | : mReader(reader), |
33 | pid_t pid, | 33 | mNonBlock(nonBlock), |
34 | uint64_t start, | 34 | mTail(tail), |
35 | uint64_t timeout) : | 35 | mLogMask(logMask), |
36 | mReader(reader), | 36 | mPid(pid), |
37 | mNonBlock(nonBlock), | 37 | mStart(start), |
38 | mTail(tail), | 38 | mTimeout((start > 1) ? timeout : 0) { |
39 | mLogMask(logMask), | ||
40 | mPid(pid), | ||
41 | mStart(start), | ||
42 | mTimeout((start > 1) ? timeout : 0) { | ||
43 | } | 39 | } |
44 | 40 | ||
45 | // runSocketCommand is called once for every open client on the | 41 | // runSocketCommand is called once for every open client on the |
@@ -51,13 +47,13 @@ FlushCommand::FlushCommand(LogReader &reader, | |||
51 | // global LogTimeEntry::lock() is used to protect access, | 47 | // global LogTimeEntry::lock() is used to protect access, |
52 | // reference counts are used to ensure that individual | 48 | // reference counts are used to ensure that individual |
53 | // LogTimeEntry lifetime is managed when not protected. | 49 | // LogTimeEntry lifetime is managed when not protected. |
54 | void FlushCommand::runSocketCommand(SocketClient *client) { | 50 | void FlushCommand::runSocketCommand(SocketClient* client) { |
55 | LogTimeEntry *entry = NULL; | 51 | LogTimeEntry* entry = NULL; |
56 | LastLogTimes × = mReader.logbuf().mTimes; | 52 | LastLogTimes& times = mReader.logbuf().mTimes; |
57 | 53 | ||
58 | LogTimeEntry::lock(); | 54 | LogTimeEntry::lock(); |
59 | LastLogTimes::iterator it = times.begin(); | 55 | LastLogTimes::iterator it = times.begin(); |
60 | while(it != times.end()) { | 56 | while (it != times.end()) { |
61 | entry = (*it); | 57 | entry = (*it); |
62 | if (entry->mClient == client) { | 58 | if (entry->mClient == client) { |
63 | if (entry->mTimeout.tv_sec || entry->mTimeout.tv_nsec) { | 59 | if (entry->mTimeout.tv_sec || entry->mTimeout.tv_nsec) { |
@@ -77,7 +73,7 @@ void FlushCommand::runSocketCommand(SocketClient *client) { | |||
77 | 73 | ||
78 | if (it == times.end()) { | 74 | if (it == times.end()) { |
79 | // Create LogTimeEntry in notifyNewLog() ? | 75 | // Create LogTimeEntry in notifyNewLog() ? |
80 | if (mTail == (unsigned long) -1) { | 76 | if (mTail == (unsigned long)-1) { |
81 | LogTimeEntry::unlock(); | 77 | LogTimeEntry::unlock(); |
82 | return; | 78 | return; |
83 | } | 79 | } |
@@ -93,14 +89,14 @@ void FlushCommand::runSocketCommand(SocketClient *client) { | |||
93 | LogTimeEntry::unlock(); | 89 | LogTimeEntry::unlock(); |
94 | } | 90 | } |
95 | 91 | ||
96 | bool FlushCommand::hasReadLogs(SocketClient *client) { | 92 | bool FlushCommand::hasReadLogs(SocketClient* client) { |
97 | return clientHasLogCredentials(client); | 93 | return clientHasLogCredentials(client); |
98 | } | 94 | } |
99 | 95 | ||
100 | static bool clientHasSecurityCredentials(SocketClient *client) { | 96 | static bool clientHasSecurityCredentials(SocketClient* client) { |
101 | return (client->getUid() == AID_SYSTEM) || (client->getGid() == AID_SYSTEM); | 97 | return (client->getUid() == AID_SYSTEM) || (client->getGid() == AID_SYSTEM); |
102 | } | 98 | } |
103 | 99 | ||
104 | bool FlushCommand::hasSecurityLogs(SocketClient *client) { | 100 | bool FlushCommand::hasSecurityLogs(SocketClient* client) { |
105 | return clientHasSecurityCredentials(client); | 101 | return clientHasSecurityCredentials(client); |
106 | } | 102 | } |
diff --git a/logd/FlushCommand.h b/logd/FlushCommand.h index 1e7818a97..45cb9c509 100644 --- a/logd/FlushCommand.h +++ b/logd/FlushCommand.h | |||
@@ -26,7 +26,7 @@ class LogBufferElement; | |||
26 | class LogReader; | 26 | class LogReader; |
27 | 27 | ||
28 | class FlushCommand : public SocketClientCommand { | 28 | class FlushCommand : public SocketClientCommand { |
29 | LogReader &mReader; | 29 | LogReader& mReader; |
30 | bool mNonBlock; | 30 | bool mNonBlock; |
31 | unsigned long mTail; | 31 | unsigned long mTail; |
32 | unsigned int mLogMask; | 32 | unsigned int mLogMask; |
@@ -34,18 +34,15 @@ class FlushCommand : public SocketClientCommand { | |||
34 | uint64_t mStart; | 34 | uint64_t mStart; |
35 | uint64_t mTimeout; | 35 | uint64_t mTimeout; |
36 | 36 | ||
37 | public: | 37 | public: |
38 | explicit FlushCommand(LogReader &mReader, | 38 | explicit FlushCommand(LogReader& mReader, bool nonBlock = false, |
39 | bool nonBlock = false, | 39 | unsigned long tail = -1, unsigned int logMask = -1, |
40 | unsigned long tail = -1, | 40 | pid_t pid = 0, uint64_t start = 1, |
41 | unsigned int logMask = -1, | 41 | uint64_t timeout = 0); |
42 | pid_t pid = 0, | 42 | virtual void runSocketCommand(SocketClient* client); |
43 | uint64_t start = 1, | 43 | |
44 | uint64_t timeout = 0); | 44 | static bool hasReadLogs(SocketClient* client); |
45 | virtual void runSocketCommand(SocketClient *client); | 45 | static bool hasSecurityLogs(SocketClient* client); |
46 | |||
47 | static bool hasReadLogs(SocketClient *client); | ||
48 | static bool hasSecurityLogs(SocketClient *client); | ||
49 | }; | 46 | }; |
50 | 47 | ||
51 | #endif | 48 | #endif |
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp index 92d957fb1..2d9024ac5 100644 --- a/logd/LogAudit.cpp +++ b/logd/LogAudit.cpp | |||
@@ -29,38 +29,52 @@ | |||
29 | #include <private/android_filesystem_config.h> | 29 | #include <private/android_filesystem_config.h> |
30 | #include <private/android_logger.h> | 30 | #include <private/android_logger.h> |
31 | 31 | ||
32 | #include "libaudit.h" | ||
33 | #include "LogAudit.h" | 32 | #include "LogAudit.h" |
34 | #include "LogBuffer.h" | 33 | #include "LogBuffer.h" |
35 | #include "LogKlog.h" | 34 | #include "LogKlog.h" |
36 | #include "LogReader.h" | 35 | #include "LogReader.h" |
37 | #include "LogUtils.h" | 36 | #include "LogUtils.h" |
37 | #include "libaudit.h" | ||
38 | 38 | ||
39 | #define KMSG_PRIORITY(PRI) \ | 39 | #define KMSG_PRIORITY(PRI) \ |
40 | '<', \ | 40 | '<', '0' + LOG_MAKEPRI(LOG_AUTH, LOG_PRI(PRI)) / 10, \ |
41 | '0' + LOG_MAKEPRI(LOG_AUTH, LOG_PRI(PRI)) / 10, \ | 41 | '0' + LOG_MAKEPRI(LOG_AUTH, LOG_PRI(PRI)) % 10, '>' |
42 | '0' + LOG_MAKEPRI(LOG_AUTH, LOG_PRI(PRI)) % 10, \ | 42 | |
43 | '>' | 43 | LogAudit::LogAudit(LogBuffer* buf, LogReader* reader, int fdDmesg) |
44 | 44 | : SocketListener(mSock = getLogSocket(), false), | |
45 | LogAudit::LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg) : | 45 | logbuf(buf), |
46 | SocketListener(mSock = getLogSocket(), false), | 46 | reader(reader), |
47 | logbuf(buf), | 47 | fdDmesg(fdDmesg), |
48 | reader(reader), | 48 | main(__android_logger_property_get_bool("ro.logd.auditd.main", |
49 | fdDmesg(fdDmesg), | 49 | BOOL_DEFAULT_TRUE)), |
50 | main(__android_logger_property_get_bool("ro.logd.auditd.main", | 50 | events(__android_logger_property_get_bool("ro.logd.auditd.events", |
51 | BOOL_DEFAULT_TRUE)), | 51 | BOOL_DEFAULT_TRUE)), |
52 | events(__android_logger_property_get_bool("ro.logd.auditd.events", | 52 | initialized(false), |
53 | BOOL_DEFAULT_TRUE)), | 53 | tooFast(false) { |
54 | initialized(false), | ||
55 | tooFast(false) { | ||
56 | static const char auditd_message[] = { KMSG_PRIORITY(LOG_INFO), | 54 | static const char auditd_message[] = { KMSG_PRIORITY(LOG_INFO), |
57 | 'l', 'o', 'g', 'd', '.', 'a', 'u', 'd', 'i', 't', 'd', ':', | 55 | 'l', |
58 | ' ', 's', 't', 'a', 'r', 't', '\n' }; | 56 | 'o', |
57 | 'g', | ||
58 | 'd', | ||
59 | '.', | ||
60 | 'a', | ||
61 | 'u', | ||
62 | 'd', | ||
63 | 'i', | ||
64 | 't', | ||
65 | 'd', | ||
66 | ':', | ||
67 | ' ', | ||
68 | 's', | ||
69 | 't', | ||
70 | 'a', | ||
71 | 'r', | ||
72 | 't', | ||
73 | '\n' }; | ||
59 | write(fdDmesg, auditd_message, sizeof(auditd_message)); | 74 | write(fdDmesg, auditd_message, sizeof(auditd_message)); |
60 | } | 75 | } |
61 | 76 | ||
62 | void LogAudit::checkRateLimit() { | 77 | void LogAudit::checkRateLimit() { |
63 | |||
64 | // trim list for AUDIT_RATE_LIMIT_BURST_DURATION of history | 78 | // trim list for AUDIT_RATE_LIMIT_BURST_DURATION of history |
65 | log_time oldest(AUDIT_RATE_LIMIT_BURST_DURATION, 0); | 79 | log_time oldest(AUDIT_RATE_LIMIT_BURST_DURATION, 0); |
66 | bucket.emplace(android_log_clockid()); | 80 | bucket.emplace(android_log_clockid()); |
@@ -69,8 +83,9 @@ void LogAudit::checkRateLimit() { | |||
69 | 83 | ||
70 | static const size_t upperThreshold = | 84 | static const size_t upperThreshold = |
71 | ((AUDIT_RATE_LIMIT_BURST_DURATION * | 85 | ((AUDIT_RATE_LIMIT_BURST_DURATION * |
72 | (AUDIT_RATE_LIMIT_DEFAULT + AUDIT_RATE_LIMIT_MAX)) + 1) / | 86 | (AUDIT_RATE_LIMIT_DEFAULT + AUDIT_RATE_LIMIT_MAX)) + |
73 | 2; | 87 | 1) / |
88 | 2; | ||
74 | if (bucket.size() >= upperThreshold) { | 89 | if (bucket.size() >= upperThreshold) { |
75 | // Hit peak, slow down source | 90 | // Hit peak, slow down source |
76 | if (!tooFast) { | 91 | if (!tooFast) { |
@@ -89,8 +104,8 @@ void LogAudit::checkRateLimit() { | |||
89 | 104 | ||
90 | if (!tooFast) return; | 105 | if (!tooFast) return; |
91 | 106 | ||
92 | static const size_t lowerThreshold = AUDIT_RATE_LIMIT_BURST_DURATION * | 107 | static const size_t lowerThreshold = |
93 | AUDIT_RATE_LIMIT_MAX; | 108 | AUDIT_RATE_LIMIT_BURST_DURATION * AUDIT_RATE_LIMIT_MAX; |
94 | 109 | ||
95 | if (bucket.size() >= lowerThreshold) return; | 110 | if (bucket.size() >= lowerThreshold) return; |
96 | 111 | ||
@@ -99,7 +114,7 @@ void LogAudit::checkRateLimit() { | |||
99 | audit_rate_limit(mSock, AUDIT_RATE_LIMIT_DEFAULT); | 114 | audit_rate_limit(mSock, AUDIT_RATE_LIMIT_DEFAULT); |
100 | } | 115 | } |
101 | 116 | ||
102 | bool LogAudit::onDataAvailable(SocketClient *cli) { | 117 | bool LogAudit::onDataAvailable(SocketClient* cli) { |
103 | if (!initialized) { | 118 | if (!initialized) { |
104 | prctl(PR_SET_NAME, "logd.auditd"); | 119 | prctl(PR_SET_NAME, "logd.auditd"); |
105 | initialized = true; | 120 | initialized = true; |
@@ -123,14 +138,14 @@ bool LogAudit::onDataAvailable(SocketClient *cli) { | |||
123 | return true; | 138 | return true; |
124 | } | 139 | } |
125 | 140 | ||
126 | int LogAudit::logPrint(const char *fmt, ...) { | 141 | int LogAudit::logPrint(const char* fmt, ...) { |
127 | if (fmt == NULL) { | 142 | if (fmt == NULL) { |
128 | return -EINVAL; | 143 | return -EINVAL; |
129 | } | 144 | } |
130 | 145 | ||
131 | va_list args; | 146 | va_list args; |
132 | 147 | ||
133 | char *str = NULL; | 148 | char* str = NULL; |
134 | va_start(args, fmt); | 149 | va_start(args, fmt); |
135 | int rc = vasprintf(&str, fmt, args); | 150 | int rc = vasprintf(&str, fmt, args); |
136 | va_end(args); | 151 | va_end(args); |
@@ -139,7 +154,7 @@ int LogAudit::logPrint(const char *fmt, ...) { | |||
139 | return rc; | 154 | return rc; |
140 | } | 155 | } |
141 | 156 | ||
142 | char *cp; | 157 | char* cp; |
143 | // Work around kernels missing | 158 | // Work around kernels missing |
144 | // https://github.com/torvalds/linux/commit/b8f89caafeb55fba75b74bea25adc4e4cd91be67 | 159 | // https://github.com/torvalds/linux/commit/b8f89caafeb55fba75b74bea25adc4e4cd91be67 |
145 | // Such kernels improperly add newlines inside audit messages. | 160 | // Such kernels improperly add newlines inside audit messages. |
@@ -160,19 +175,19 @@ int LogAudit::logPrint(const char *fmt, ...) { | |||
160 | 175 | ||
161 | // Dedupe messages, checking for identical messages starting with avc: | 176 | // Dedupe messages, checking for identical messages starting with avc: |
162 | static unsigned count; | 177 | static unsigned count; |
163 | static char *last_str; | 178 | static char* last_str; |
164 | static bool last_info; | 179 | static bool last_info; |
165 | 180 | ||
166 | if (last_str != NULL) { | 181 | if (last_str != NULL) { |
167 | static const char avc[] = "): avc: "; | 182 | static const char avc[] = "): avc: "; |
168 | char *avcl = strstr(last_str, avc); | 183 | char* avcl = strstr(last_str, avc); |
169 | bool skip = false; | 184 | bool skip = false; |
170 | 185 | ||
171 | if (avcl) { | 186 | if (avcl) { |
172 | char *avcr = strstr(str, avc); | 187 | char* avcr = strstr(str, avc); |
173 | 188 | ||
174 | skip = avcr && !fastcmp<strcmp>(avcl + strlen(avc), | 189 | skip = avcr && |
175 | avcr + strlen(avc)); | 190 | !fastcmp<strcmp>(avcl + strlen(avc), avcr + strlen(avc)); |
176 | if (skip) { | 191 | if (skip) { |
177 | ++count; | 192 | ++count; |
178 | free(last_str); | 193 | free(last_str); |
@@ -183,19 +198,17 @@ int LogAudit::logPrint(const char *fmt, ...) { | |||
183 | if (!skip) { | 198 | if (!skip) { |
184 | static const char resume[] = " duplicate messages suppressed\n"; | 199 | static const char resume[] = " duplicate messages suppressed\n"; |
185 | 200 | ||
186 | iov[0].iov_base = last_info ? | 201 | iov[0].iov_base = last_info ? const_cast<char*>(log_info) |
187 | const_cast<char *>(log_info) : | 202 | : const_cast<char*>(log_warning); |
188 | const_cast<char *>(log_warning); | 203 | iov[0].iov_len = |
189 | iov[0].iov_len = last_info ? | 204 | last_info ? sizeof(log_info) : sizeof(log_warning); |
190 | sizeof(log_info) : | ||
191 | sizeof(log_warning); | ||
192 | iov[1].iov_base = last_str; | 205 | iov[1].iov_base = last_str; |
193 | iov[1].iov_len = strlen(last_str); | 206 | iov[1].iov_len = strlen(last_str); |
194 | if (count > 1) { | 207 | if (count > 1) { |
195 | iov[2].iov_base = const_cast<char *>(resume); | 208 | iov[2].iov_base = const_cast<char*>(resume); |
196 | iov[2].iov_len = strlen(resume); | 209 | iov[2].iov_len = strlen(resume); |
197 | } else { | 210 | } else { |
198 | iov[2].iov_base = const_cast<char *>(newline); | 211 | iov[2].iov_base = const_cast<char*>(newline); |
199 | iov[2].iov_len = strlen(newline); | 212 | iov[2].iov_len = strlen(newline); |
200 | } | 213 | } |
201 | 214 | ||
@@ -210,15 +223,12 @@ int LogAudit::logPrint(const char *fmt, ...) { | |||
210 | last_info = info; | 223 | last_info = info; |
211 | } | 224 | } |
212 | if (count == 0) { | 225 | if (count == 0) { |
213 | iov[0].iov_base = info ? | 226 | iov[0].iov_base = info ? const_cast<char*>(log_info) |
214 | const_cast<char *>(log_info) : | 227 | : const_cast<char*>(log_warning); |
215 | const_cast<char *>(log_warning); | 228 | iov[0].iov_len = info ? sizeof(log_info) : sizeof(log_warning); |
216 | iov[0].iov_len = info ? | ||
217 | sizeof(log_info) : | ||
218 | sizeof(log_warning); | ||
219 | iov[1].iov_base = str; | 229 | iov[1].iov_base = str; |
220 | iov[1].iov_len = strlen(str); | 230 | iov[1].iov_len = strlen(str); |
221 | iov[2].iov_base = const_cast<char *>(newline); | 231 | iov[2].iov_base = const_cast<char*>(newline); |
222 | iov[2].iov_len = strlen(newline); | 232 | iov[2].iov_len = strlen(newline); |
223 | 233 | ||
224 | writev(fdDmesg, iov, arraysize(iov)); | 234 | writev(fdDmesg, iov, arraysize(iov)); |
@@ -236,10 +246,10 @@ int LogAudit::logPrint(const char *fmt, ...) { | |||
236 | log_time now; | 246 | log_time now; |
237 | 247 | ||
238 | static const char audit_str[] = " audit("; | 248 | static const char audit_str[] = " audit("; |
239 | char *timeptr = strstr(str, audit_str); | 249 | char* timeptr = strstr(str, audit_str); |
240 | if (timeptr | 250 | if (timeptr && |
241 | && ((cp = now.strptime(timeptr + sizeof(audit_str) - 1, "%s.%q"))) | 251 | ((cp = now.strptime(timeptr + sizeof(audit_str) - 1, "%s.%q"))) && |
242 | && (*cp == ':')) { | 252 | (*cp == ':')) { |
243 | memcpy(timeptr + sizeof(audit_str) - 1, "0.0", 3); | 253 | memcpy(timeptr + sizeof(audit_str) - 1, "0.0", 3); |
244 | memmove(timeptr + sizeof(audit_str) - 1 + 3, cp, strlen(cp) + 1); | 254 | memmove(timeptr + sizeof(audit_str) - 1 + 3, cp, strlen(cp) + 1); |
245 | if (!isMonotonic()) { | 255 | if (!isMonotonic()) { |
@@ -258,7 +268,7 @@ int LogAudit::logPrint(const char *fmt, ...) { | |||
258 | } | 268 | } |
259 | 269 | ||
260 | static const char pid_str[] = " pid="; | 270 | static const char pid_str[] = " pid="; |
261 | char *pidptr = strstr(str, pid_str); | 271 | char* pidptr = strstr(str, pid_str); |
262 | if (pidptr && isdigit(pidptr[sizeof(pid_str) - 1])) { | 272 | if (pidptr && isdigit(pidptr[sizeof(pid_str) - 1])) { |
263 | cp = pidptr + sizeof(pid_str) - 1; | 273 | cp = pidptr + sizeof(pid_str) - 1; |
264 | pid = 0; | 274 | pid = 0; |
@@ -280,19 +290,19 @@ int LogAudit::logPrint(const char *fmt, ...) { | |||
280 | 290 | ||
281 | bool notify = false; | 291 | bool notify = false; |
282 | 292 | ||
283 | if (events) { // begin scope for event buffer | 293 | if (events) { // begin scope for event buffer |
284 | uint32_t buffer[(n + sizeof(uint32_t) - 1) / sizeof(uint32_t)]; | 294 | uint32_t buffer[(n + sizeof(uint32_t) - 1) / sizeof(uint32_t)]; |
285 | 295 | ||
286 | android_log_event_string_t *event | 296 | android_log_event_string_t* event = |
287 | = reinterpret_cast<android_log_event_string_t *>(buffer); | 297 | reinterpret_cast<android_log_event_string_t*>(buffer); |
288 | event->header.tag = htole32(AUDITD_LOG_TAG); | 298 | event->header.tag = htole32(AUDITD_LOG_TAG); |
289 | event->type = EVENT_TYPE_STRING; | 299 | event->type = EVENT_TYPE_STRING; |
290 | event->length = htole32(l); | 300 | event->length = htole32(l); |
291 | memcpy(event->data, str, l); | 301 | memcpy(event->data, str, l); |
292 | 302 | ||
293 | rc = logbuf->log(LOG_ID_EVENTS, now, uid, pid, tid, | 303 | rc = logbuf->log(LOG_ID_EVENTS, now, uid, pid, tid, |
294 | reinterpret_cast<char *>(event), | 304 | reinterpret_cast<char*>(event), |
295 | (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX); | 305 | (n <= USHRT_MAX) ? (unsigned short)n : USHRT_MAX); |
296 | if (rc >= 0) { | 306 | if (rc >= 0) { |
297 | notify = true; | 307 | notify = true; |
298 | } | 308 | } |
@@ -302,9 +312,9 @@ int LogAudit::logPrint(const char *fmt, ...) { | |||
302 | // log to main | 312 | // log to main |
303 | 313 | ||
304 | static const char comm_str[] = " comm=\""; | 314 | static const char comm_str[] = " comm=\""; |
305 | const char *comm = strstr(str, comm_str); | 315 | const char* comm = strstr(str, comm_str); |
306 | const char *estr = str + strlen(str); | 316 | const char* estr = str + strlen(str); |
307 | const char *commfree = NULL; | 317 | const char* commfree = NULL; |
308 | if (comm) { | 318 | if (comm) { |
309 | estr = comm; | 319 | estr = comm; |
310 | comm += sizeof(comm_str) - 1; | 320 | comm += sizeof(comm_str) - 1; |
@@ -320,7 +330,7 @@ int LogAudit::logPrint(const char *fmt, ...) { | |||
320 | } | 330 | } |
321 | } | 331 | } |
322 | 332 | ||
323 | const char *ecomm = strchr(comm, '"'); | 333 | const char* ecomm = strchr(comm, '"'); |
324 | if (ecomm) { | 334 | if (ecomm) { |
325 | ++ecomm; | 335 | ++ecomm; |
326 | l = ecomm - comm; | 336 | l = ecomm - comm; |
@@ -335,7 +345,7 @@ int LogAudit::logPrint(const char *fmt, ...) { | |||
335 | size_t e = strnlen(ecomm, LOGGER_ENTRY_MAX_PAYLOAD - b); | 345 | size_t e = strnlen(ecomm, LOGGER_ENTRY_MAX_PAYLOAD - b); |
336 | n = b + e + l + 2; | 346 | n = b + e + l + 2; |
337 | 347 | ||
338 | if (main) { // begin scope for main buffer | 348 | if (main) { // begin scope for main buffer |
339 | char newstr[n]; | 349 | char newstr[n]; |
340 | 350 | ||
341 | *newstr = info ? ANDROID_LOG_INFO : ANDROID_LOG_WARN; | 351 | *newstr = info ? ANDROID_LOG_INFO : ANDROID_LOG_WARN; |
@@ -344,7 +354,7 @@ int LogAudit::logPrint(const char *fmt, ...) { | |||
344 | strncpy(newstr + 1 + l + b, ecomm, e); | 354 | strncpy(newstr + 1 + l + b, ecomm, e); |
345 | 355 | ||
346 | rc = logbuf->log(LOG_ID_MAIN, now, uid, pid, tid, newstr, | 356 | rc = logbuf->log(LOG_ID_MAIN, now, uid, pid, tid, newstr, |
347 | (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX); | 357 | (n <= USHRT_MAX) ? (unsigned short)n : USHRT_MAX); |
348 | 358 | ||
349 | if (rc >= 0) { | 359 | if (rc >= 0) { |
350 | notify = true; | 360 | notify = true; |
@@ -352,7 +362,7 @@ int LogAudit::logPrint(const char *fmt, ...) { | |||
352 | // end scope for main buffer | 362 | // end scope for main buffer |
353 | } | 363 | } |
354 | 364 | ||
355 | free(const_cast<char *>(commfree)); | 365 | free(const_cast<char*>(commfree)); |
356 | free(str); | 366 | free(str); |
357 | 367 | ||
358 | if (notify) { | 368 | if (notify) { |
@@ -365,8 +375,8 @@ int LogAudit::logPrint(const char *fmt, ...) { | |||
365 | return rc; | 375 | return rc; |
366 | } | 376 | } |
367 | 377 | ||
368 | int LogAudit::log(char *buf, size_t len) { | 378 | int LogAudit::log(char* buf, size_t len) { |
369 | char *audit = strstr(buf, " audit("); | 379 | char* audit = strstr(buf, " audit("); |
370 | if (!audit || (audit >= &buf[len])) { | 380 | if (!audit || (audit >= &buf[len])) { |
371 | return 0; | 381 | return 0; |
372 | } | 382 | } |
@@ -374,7 +384,7 @@ int LogAudit::log(char *buf, size_t len) { | |||
374 | *audit = '\0'; | 384 | *audit = '\0'; |
375 | 385 | ||
376 | int rc; | 386 | int rc; |
377 | char *type = strstr(buf, "type="); | 387 | char* type = strstr(buf, "type="); |
378 | if (type && (type < &buf[len])) { | 388 | if (type && (type < &buf[len])) { |
379 | rc = logPrint("%s %s", type, audit + 1); | 389 | rc = logPrint("%s %s", type, audit + 1); |
380 | } else { | 390 | } else { |
diff --git a/logd/LogAudit.h b/logd/LogAudit.h index 045d6314f..594781910 100644 --- a/logd/LogAudit.h +++ b/logd/LogAudit.h | |||
@@ -26,9 +26,9 @@ | |||
26 | class LogReader; | 26 | class LogReader; |
27 | 27 | ||
28 | class LogAudit : public SocketListener { | 28 | class LogAudit : public SocketListener { |
29 | LogBuffer *logbuf; | 29 | LogBuffer* logbuf; |
30 | LogReader *reader; | 30 | LogReader* reader; |
31 | int fdDmesg; // fdDmesg >= 0 is functionally bool dmesg | 31 | int fdDmesg; // fdDmesg >= 0 is functionally bool dmesg |
32 | bool main; | 32 | bool main; |
33 | bool events; | 33 | bool events; |
34 | bool initialized; | 34 | bool initialized; |
@@ -38,18 +38,20 @@ class LogAudit : public SocketListener { | |||
38 | std::queue<log_time> bucket; | 38 | std::queue<log_time> bucket; |
39 | void checkRateLimit(); | 39 | void checkRateLimit(); |
40 | 40 | ||
41 | public: | 41 | public: |
42 | LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg); | 42 | LogAudit(LogBuffer* buf, LogReader* reader, int fdDmesg); |
43 | int log(char *buf, size_t len); | 43 | int log(char* buf, size_t len); |
44 | bool isMonotonic() { return logbuf->isMonotonic(); } | 44 | bool isMonotonic() { |
45 | return logbuf->isMonotonic(); | ||
46 | } | ||
45 | 47 | ||
46 | protected: | 48 | protected: |
47 | virtual bool onDataAvailable(SocketClient *cli); | 49 | virtual bool onDataAvailable(SocketClient* cli); |
48 | 50 | ||
49 | private: | 51 | private: |
50 | static int getLogSocket(); | 52 | static int getLogSocket(); |
51 | int logPrint(const char *fmt, ...) | 53 | int logPrint(const char* fmt, ...) |
52 | __attribute__ ((__format__ (__printf__, 2, 3))); | 54 | __attribute__((__format__(__printf__, 2, 3))); |
53 | }; | 55 | }; |
54 | 56 | ||
55 | #endif | 57 | #endif |
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp index 7613c1e98..9c634f680 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp | |||
@@ -72,8 +72,8 @@ void LogBuffer::init() { | |||
72 | // | 72 | // |
73 | pthread_mutex_lock(&mLogElementsLock); | 73 | pthread_mutex_lock(&mLogElementsLock); |
74 | LogBufferElementCollection::iterator it = mLogElements.begin(); | 74 | LogBufferElementCollection::iterator it = mLogElements.begin(); |
75 | while((it != mLogElements.end())) { | 75 | while ((it != mLogElements.end())) { |
76 | LogBufferElement *e = *it; | 76 | LogBufferElement* e = *it; |
77 | if (monotonic) { | 77 | if (monotonic) { |
78 | if (!android::isMonotonic(e->mRealTime)) { | 78 | if (!android::isMonotonic(e->mRealTime)) { |
79 | LogKlog::convertRealToMonotonic(e->mRealTime); | 79 | LogKlog::convertRealToMonotonic(e->mRealTime); |
@@ -96,8 +96,8 @@ void LogBuffer::init() { | |||
96 | LogTimeEntry::lock(); | 96 | LogTimeEntry::lock(); |
97 | 97 | ||
98 | LastLogTimes::iterator times = mTimes.begin(); | 98 | LastLogTimes::iterator times = mTimes.begin(); |
99 | while(times != mTimes.end()) { | 99 | while (times != mTimes.end()) { |
100 | LogTimeEntry *entry = (*times); | 100 | LogTimeEntry* entry = (*times); |
101 | if (entry->owned_Locked()) { | 101 | if (entry->owned_Locked()) { |
102 | entry->triggerReader_Locked(); | 102 | entry->triggerReader_Locked(); |
103 | } | 103 | } |
@@ -107,9 +107,8 @@ void LogBuffer::init() { | |||
107 | LogTimeEntry::unlock(); | 107 | LogTimeEntry::unlock(); |
108 | } | 108 | } |
109 | 109 | ||
110 | LogBuffer::LogBuffer(LastLogTimes *times): | 110 | LogBuffer::LogBuffer(LastLogTimes* times) |
111 | monotonic(android_log_clockid() == CLOCK_MONOTONIC), | 111 | : monotonic(android_log_clockid() == CLOCK_MONOTONIC), mTimes(*times) { |
112 | mTimes(*times) { | ||
113 | pthread_mutex_init(&mLogElementsLock, NULL); | 112 | pthread_mutex_init(&mLogElementsLock, NULL); |
114 | 113 | ||
115 | log_id_for_each(i) { | 114 | log_id_for_each(i) { |
@@ -127,28 +126,26 @@ LogBuffer::~LogBuffer() { | |||
127 | } | 126 | } |
128 | } | 127 | } |
129 | 128 | ||
130 | enum match_type { | 129 | enum match_type { DIFFERENT, SAME, SAME_LIBLOG }; |
131 | DIFFERENT, | ||
132 | SAME, | ||
133 | SAME_LIBLOG | ||
134 | }; | ||
135 | 130 | ||
136 | static enum match_type identical(LogBufferElement* elem, LogBufferElement* last) { | 131 | static enum match_type identical(LogBufferElement* elem, |
132 | LogBufferElement* last) { | ||
137 | // is it mostly identical? | 133 | // is it mostly identical? |
138 | // if (!elem) return DIFFERENT; | 134 | // if (!elem) return DIFFERENT; |
139 | unsigned short lenl = elem->getMsgLen(); | 135 | unsigned short lenl = elem->getMsgLen(); |
140 | if (!lenl) return DIFFERENT; | 136 | if (!lenl) return DIFFERENT; |
141 | // if (!last) return DIFFERENT; | 137 | // if (!last) return DIFFERENT; |
142 | unsigned short lenr = last->getMsgLen(); | 138 | unsigned short lenr = last->getMsgLen(); |
143 | if (!lenr) return DIFFERENT; | 139 | if (!lenr) return DIFFERENT; |
144 | // if (elem->getLogId() != last->getLogId()) return DIFFERENT; | 140 | // if (elem->getLogId() != last->getLogId()) return DIFFERENT; |
145 | if (elem->getUid() != last->getUid()) return DIFFERENT; | 141 | if (elem->getUid() != last->getUid()) return DIFFERENT; |
146 | if (elem->getPid() != last->getPid()) return DIFFERENT; | 142 | if (elem->getPid() != last->getPid()) return DIFFERENT; |
147 | if (elem->getTid() != last->getTid()) return DIFFERENT; | 143 | if (elem->getTid() != last->getTid()) return DIFFERENT; |
148 | 144 | ||
149 | // last is more than a minute old, stop squashing identical messages | 145 | // last is more than a minute old, stop squashing identical messages |
150 | if (elem->getRealTime().nsec() > | 146 | if (elem->getRealTime().nsec() > |
151 | (last->getRealTime().nsec() + 60 * NS_PER_SEC)) return DIFFERENT; | 147 | (last->getRealTime().nsec() + 60 * NS_PER_SEC)) |
148 | return DIFFERENT; | ||
152 | 149 | ||
153 | // Identical message | 150 | // Identical message |
154 | const char* msgl = elem->getMsg(); | 151 | const char* msgl = elem->getMsg(); |
@@ -158,47 +155,47 @@ static enum match_type identical(LogBufferElement* elem, LogBufferElement* last) | |||
158 | // liblog tagged messages (content gets summed) | 155 | // liblog tagged messages (content gets summed) |
159 | if ((elem->getLogId() == LOG_ID_EVENTS) && | 156 | if ((elem->getLogId() == LOG_ID_EVENTS) && |
160 | (lenl == sizeof(android_log_event_int_t)) && | 157 | (lenl == sizeof(android_log_event_int_t)) && |
161 | !fastcmp<memcmp>(msgl, msgr, | 158 | !fastcmp<memcmp>(msgl, msgr, sizeof(android_log_event_int_t) - |
162 | sizeof(android_log_event_int_t) - sizeof(int32_t)) && | 159 | sizeof(int32_t)) && |
163 | (elem->getTag() == LIBLOG_LOG_TAG)) return SAME_LIBLOG; | 160 | (elem->getTag() == LIBLOG_LOG_TAG)) |
161 | return SAME_LIBLOG; | ||
164 | } | 162 | } |
165 | 163 | ||
166 | // audit message (except sequence number) identical? | 164 | // audit message (except sequence number) identical? |
167 | static const char avc[] = "): avc: "; | 165 | static const char avc[] = "): avc: "; |
168 | 166 | ||
169 | if (last->isBinary()) { | 167 | if (last->isBinary()) { |
170 | if (fastcmp<memcmp>(msgl, msgr, | 168 | if (fastcmp<memcmp>(msgl, msgr, sizeof(android_log_event_string_t) - |
171 | sizeof(android_log_event_string_t) - | 169 | sizeof(int32_t))) |
172 | sizeof(int32_t))) return DIFFERENT; | 170 | return DIFFERENT; |
173 | msgl += sizeof(android_log_event_string_t); | 171 | msgl += sizeof(android_log_event_string_t); |
174 | lenl -= sizeof(android_log_event_string_t); | 172 | lenl -= sizeof(android_log_event_string_t); |
175 | msgr += sizeof(android_log_event_string_t); | 173 | msgr += sizeof(android_log_event_string_t); |
176 | lenr -= sizeof(android_log_event_string_t); | 174 | lenr -= sizeof(android_log_event_string_t); |
177 | } | 175 | } |
178 | const char *avcl = android::strnstr(msgl, lenl, avc); | 176 | const char* avcl = android::strnstr(msgl, lenl, avc); |
179 | if (!avcl) return DIFFERENT; | 177 | if (!avcl) return DIFFERENT; |
180 | lenl -= avcl - msgl; | 178 | lenl -= avcl - msgl; |
181 | const char *avcr = android::strnstr(msgr, lenr, avc); | 179 | const char* avcr = android::strnstr(msgr, lenr, avc); |
182 | if (!avcr) return DIFFERENT; | 180 | if (!avcr) return DIFFERENT; |
183 | lenr -= avcr - msgr; | 181 | lenr -= avcr - msgr; |
184 | if (lenl != lenr) return DIFFERENT; | 182 | if (lenl != lenr) return DIFFERENT; |
185 | if (fastcmp<memcmp>(avcl + strlen(avc), | 183 | if (fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc), lenl)) |
186 | avcr + strlen(avc), lenl)) return DIFFERENT; | 184 | return DIFFERENT; |
187 | return SAME; | 185 | return SAME; |
188 | } | 186 | } |
189 | 187 | ||
190 | int LogBuffer::log(log_id_t log_id, log_time realtime, | 188 | int LogBuffer::log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, |
191 | uid_t uid, pid_t pid, pid_t tid, | 189 | pid_t tid, const char* msg, unsigned short len) { |
192 | const char *msg, unsigned short len) { | ||
193 | if ((log_id >= LOG_ID_MAX) || (log_id < 0)) { | 190 | if ((log_id >= LOG_ID_MAX) || (log_id < 0)) { |
194 | return -EINVAL; | 191 | return -EINVAL; |
195 | } | 192 | } |
196 | 193 | ||
197 | LogBufferElement *elem = new LogBufferElement(log_id, realtime, | 194 | LogBufferElement* elem = |
198 | uid, pid, tid, msg, len); | 195 | new LogBufferElement(log_id, realtime, uid, pid, tid, msg, len); |
199 | if (log_id != LOG_ID_SECURITY) { | 196 | if (log_id != LOG_ID_SECURITY) { |
200 | int prio = ANDROID_LOG_INFO; | 197 | int prio = ANDROID_LOG_INFO; |
201 | const char *tag = NULL; | 198 | const char* tag = NULL; |
202 | if (log_id == LOG_ID_EVENTS) { | 199 | if (log_id == LOG_ID_EVENTS) { |
203 | tag = tagToName(elem->getTag()); | 200 | tag = tagToName(elem->getTag()); |
204 | } else { | 201 | } else { |
@@ -219,7 +216,7 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, | |||
219 | pthread_mutex_lock(&mLogElementsLock); | 216 | pthread_mutex_lock(&mLogElementsLock); |
220 | LogBufferElement* currentLast = lastLoggedElements[log_id]; | 217 | LogBufferElement* currentLast = lastLoggedElements[log_id]; |
221 | if (currentLast) { | 218 | if (currentLast) { |
222 | LogBufferElement *dropped = droppedElements[log_id]; | 219 | LogBufferElement* dropped = droppedElements[log_id]; |
223 | unsigned short count = dropped ? dropped->getDropped() : 0; | 220 | unsigned short count = dropped ? dropped->getDropped() : 0; |
224 | // | 221 | // |
225 | // State Init | 222 | // State Init |
@@ -309,7 +306,7 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, | |||
309 | uint32_t swab = event->payload.data; | 306 | uint32_t swab = event->payload.data; |
310 | unsigned long long total = htole32(swab); | 307 | unsigned long long total = htole32(swab); |
311 | event = reinterpret_cast<android_log_event_int_t*>( | 308 | event = reinterpret_cast<android_log_event_int_t*>( |
312 | const_cast<char*>(elem->getMsg())); | 309 | const_cast<char*>(elem->getMsg())); |
313 | swab = event->payload.data; | 310 | swab = event->payload.data; |
314 | 311 | ||
315 | lastLoggedElements[LOG_ID_EVENTS] = elem; | 312 | lastLoggedElements[LOG_ID_EVENTS] = elem; |
@@ -346,15 +343,15 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, | |||
346 | pthread_mutex_unlock(&mLogElementsLock); | 343 | pthread_mutex_unlock(&mLogElementsLock); |
347 | return len; | 344 | return len; |
348 | } | 345 | } |
349 | if (dropped) { // State 1 or 2 | 346 | if (dropped) { // State 1 or 2 |
350 | if (count) { // State 2 | 347 | if (count) { // State 2 |
351 | log(dropped); // report chatty | 348 | log(dropped); // report chatty |
352 | } else { // State 1 | 349 | } else { // State 1 |
353 | delete dropped; | 350 | delete dropped; |
354 | } | 351 | } |
355 | droppedElements[log_id] = NULL; | 352 | droppedElements[log_id] = NULL; |
356 | log(currentLast); // report last message in the series | 353 | log(currentLast); // report last message in the series |
357 | } else { // State 0 | 354 | } else { // State 0 |
358 | delete currentLast; | 355 | delete currentLast; |
359 | } | 356 | } |
360 | } | 357 | } |
@@ -390,7 +387,7 @@ void LogBuffer::log(LogBufferElement* elem) { | |||
390 | LogTimeEntry::lock(); | 387 | LogTimeEntry::lock(); |
391 | 388 | ||
392 | LastLogTimes::iterator times = mTimes.begin(); | 389 | LastLogTimes::iterator times = mTimes.begin(); |
393 | while(times != mTimes.end()) { | 390 | while (times != mTimes.end()) { |
394 | LogTimeEntry* entry = (*times); | 391 | LogTimeEntry* entry = (*times); |
395 | if (entry->owned_Locked()) { | 392 | if (entry->owned_Locked()) { |
396 | if (!entry->mNonBlock) { | 393 | if (!entry->mNonBlock) { |
@@ -405,8 +402,7 @@ void LogBuffer::log(LogBufferElement* elem) { | |||
405 | times++; | 402 | times++; |
406 | } | 403 | } |
407 | 404 | ||
408 | if (end_always | 405 | if (end_always || (end_set && (end >= (*last)->getSequence()))) { |
409 | || (end_set && (end >= (*last)->getSequence()))) { | ||
410 | mLogElements.push_back(elem); | 406 | mLogElements.push_back(elem); |
411 | } else { | 407 | } else { |
412 | mLogElements.insert(last, elem); | 408 | mLogElements.insert(last, elem); |
@@ -444,30 +440,31 @@ void LogBuffer::maybePrune(log_id_t id) { | |||
444 | } | 440 | } |
445 | 441 | ||
446 | LogBufferElementCollection::iterator LogBuffer::erase( | 442 | LogBufferElementCollection::iterator LogBuffer::erase( |
447 | LogBufferElementCollection::iterator it, bool coalesce) { | 443 | LogBufferElementCollection::iterator it, bool coalesce) { |
448 | LogBufferElement *element = *it; | 444 | LogBufferElement* element = *it; |
449 | log_id_t id = element->getLogId(); | 445 | log_id_t id = element->getLogId(); |
450 | 446 | ||
451 | // Remove iterator references in the various lists that will become stale | 447 | // Remove iterator references in the various lists that will become stale |
452 | // after the element is erased from the main logging list. | 448 | // after the element is erased from the main logging list. |
453 | 449 | ||
454 | { // start of scope for found iterator | 450 | { // start of scope for found iterator |
455 | int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) ? | 451 | int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) |
456 | element->getTag() : element->getUid(); | 452 | ? element->getTag() |
453 | : element->getUid(); | ||
457 | LogBufferIteratorMap::iterator found = mLastWorst[id].find(key); | 454 | LogBufferIteratorMap::iterator found = mLastWorst[id].find(key); |
458 | if ((found != mLastWorst[id].end()) && (it == found->second)) { | 455 | if ((found != mLastWorst[id].end()) && (it == found->second)) { |
459 | mLastWorst[id].erase(found); | 456 | mLastWorst[id].erase(found); |
460 | } | 457 | } |
461 | } | 458 | } |
462 | 459 | ||
463 | { // start of scope for pid found iterator | 460 | { // start of scope for pid found iterator |
464 | // element->getUid() may not be AID_SYSTEM for next-best-watermark. | 461 | // element->getUid() may not be AID_SYSTEM for next-best-watermark. |
465 | // will not assume id != LOG_ID_EVENTS or LOG_ID_SECURITY for KISS and | 462 | // will not assume id != LOG_ID_EVENTS or LOG_ID_SECURITY for KISS and |
466 | // long term code stability, find() check should be fast for those ids. | 463 | // long term code stability, find() check should be fast for those ids. |
467 | LogBufferPidIteratorMap::iterator found = | 464 | LogBufferPidIteratorMap::iterator found = |
468 | mLastWorstPidOfSystem[id].find(element->getPid()); | 465 | mLastWorstPidOfSystem[id].find(element->getPid()); |
469 | if ((found != mLastWorstPidOfSystem[id].end()) | 466 | if ((found != mLastWorstPidOfSystem[id].end()) && |
470 | && (it == found->second)) { | 467 | (it == found->second)) { |
471 | mLastWorstPidOfSystem[id].erase(found); | 468 | mLastWorstPidOfSystem[id].erase(found); |
472 | } | 469 | } |
473 | } | 470 | } |
@@ -479,34 +476,35 @@ LogBufferElementCollection::iterator LogBuffer::erase( | |||
479 | } | 476 | } |
480 | #ifdef DEBUG_CHECK_FOR_STALE_ENTRIES | 477 | #ifdef DEBUG_CHECK_FOR_STALE_ENTRIES |
481 | LogBufferElementCollection::iterator bad = it; | 478 | LogBufferElementCollection::iterator bad = it; |
482 | int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) ? | 479 | int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) |
483 | element->getTag() : element->getUid(); | 480 | ? element->getTag() |
481 | : element->getUid(); | ||
484 | #endif | 482 | #endif |
485 | it = mLogElements.erase(it); | 483 | it = mLogElements.erase(it); |
486 | if (doSetLast) { | 484 | if (doSetLast) { |
487 | log_id_for_each(i) { | 485 | log_id_for_each(i) { |
488 | if (setLast[i]) { | 486 | if (setLast[i]) { |
489 | if (__predict_false(it == mLogElements.end())) { // impossible | 487 | if (__predict_false(it == mLogElements.end())) { // impossible |
490 | mLastSet[i] = false; | 488 | mLastSet[i] = false; |
491 | mLast[i] = mLogElements.begin(); | 489 | mLast[i] = mLogElements.begin(); |
492 | } else { | 490 | } else { |
493 | mLast[i] = it; // push down the road as next-best-watermark | 491 | mLast[i] = it; // push down the road as next-best-watermark |
494 | } | 492 | } |
495 | } | 493 | } |
496 | } | 494 | } |
497 | } | 495 | } |
498 | #ifdef DEBUG_CHECK_FOR_STALE_ENTRIES | 496 | #ifdef DEBUG_CHECK_FOR_STALE_ENTRIES |
499 | log_id_for_each(i) { | 497 | log_id_for_each(i) { |
500 | for(auto b : mLastWorst[i]) { | 498 | for (auto b : mLastWorst[i]) { |
501 | if (bad == b.second) { | 499 | if (bad == b.second) { |
502 | android::prdebug("stale mLastWorst[%d] key=%d mykey=%d\n", | 500 | android::prdebug("stale mLastWorst[%d] key=%d mykey=%d\n", i, |
503 | i, b.first, key); | 501 | b.first, key); |
504 | } | 502 | } |
505 | } | 503 | } |
506 | for(auto b : mLastWorstPidOfSystem[i]) { | 504 | for (auto b : mLastWorstPidOfSystem[i]) { |
507 | if (bad == b.second) { | 505 | if (bad == b.second) { |
508 | android::prdebug("stale mLastWorstPidOfSystem[%d] pid=%d\n", | 506 | android::prdebug("stale mLastWorstPidOfSystem[%d] pid=%d\n", i, |
509 | i, b.first); | 507 | b.first); |
510 | } | 508 | } |
511 | } | 509 | } |
512 | if (mLastSet[i] && (bad == mLast[i])) { | 510 | if (mLastSet[i] && (bad == mLast[i])) { |
@@ -539,32 +537,29 @@ class LogBufferElementKey { | |||
539 | uint64_t value; | 537 | uint64_t value; |
540 | } __packed; | 538 | } __packed; |
541 | 539 | ||
542 | public: | 540 | public: |
543 | LogBufferElementKey(uid_t uid, pid_t pid, pid_t tid): | 541 | LogBufferElementKey(uid_t uid, pid_t pid, pid_t tid) |
544 | uid(uid), | 542 | : uid(uid), pid(pid), tid(tid) { |
545 | pid(pid), | 543 | } |
546 | tid(tid) | 544 | explicit LogBufferElementKey(uint64_t key) : value(key) { |
547 | { | ||
548 | } | 545 | } |
549 | explicit LogBufferElementKey(uint64_t key):value(key) { } | ||
550 | 546 | ||
551 | uint64_t getKey() { return value; } | 547 | uint64_t getKey() { |
548 | return value; | ||
549 | } | ||
552 | }; | 550 | }; |
553 | 551 | ||
554 | class LogBufferElementLast { | 552 | class LogBufferElementLast { |
555 | 553 | typedef std::unordered_map<uint64_t, LogBufferElement*> LogBufferElementMap; | |
556 | typedef std::unordered_map<uint64_t, LogBufferElement *> LogBufferElementMap; | ||
557 | LogBufferElementMap map; | 554 | LogBufferElementMap map; |
558 | 555 | ||
559 | public: | 556 | public: |
560 | 557 | bool coalesce(LogBufferElement* element, unsigned short dropped) { | |
561 | bool coalesce(LogBufferElement *element, unsigned short dropped) { | 558 | LogBufferElementKey key(element->getUid(), element->getPid(), |
562 | LogBufferElementKey key(element->getUid(), | ||
563 | element->getPid(), | ||
564 | element->getTid()); | 559 | element->getTid()); |
565 | LogBufferElementMap::iterator it = map.find(key.getKey()); | 560 | LogBufferElementMap::iterator it = map.find(key.getKey()); |
566 | if (it != map.end()) { | 561 | if (it != map.end()) { |
567 | LogBufferElement *found = it->second; | 562 | LogBufferElement* found = it->second; |
568 | unsigned short moreDropped = found->getDropped(); | 563 | unsigned short moreDropped = found->getDropped(); |
569 | if ((dropped + moreDropped) > USHRT_MAX) { | 564 | if ((dropped + moreDropped) > USHRT_MAX) { |
570 | map.erase(it); | 565 | map.erase(it); |
@@ -576,9 +571,8 @@ public: | |||
576 | return false; | 571 | return false; |
577 | } | 572 | } |
578 | 573 | ||
579 | void add(LogBufferElement *element) { | 574 | void add(LogBufferElement* element) { |
580 | LogBufferElementKey key(element->getUid(), | 575 | LogBufferElementKey key(element->getUid(), element->getPid(), |
581 | element->getPid(), | ||
582 | element->getTid()); | 576 | element->getTid()); |
583 | map[key.getKey()] = element; | 577 | map[key.getKey()] = element; |
584 | } | 578 | } |
@@ -587,20 +581,19 @@ public: | |||
587 | map.clear(); | 581 | map.clear(); |
588 | } | 582 | } |
589 | 583 | ||
590 | void clear(LogBufferElement *element) { | 584 | void clear(LogBufferElement* element) { |
591 | uint64_t current = element->getRealTime().nsec() | 585 | uint64_t current = |
592 | - (EXPIRE_RATELIMIT * NS_PER_SEC); | 586 | element->getRealTime().nsec() - (EXPIRE_RATELIMIT * NS_PER_SEC); |
593 | for(LogBufferElementMap::iterator it = map.begin(); it != map.end();) { | 587 | for (LogBufferElementMap::iterator it = map.begin(); it != map.end();) { |
594 | LogBufferElement *mapElement = it->second; | 588 | LogBufferElement* mapElement = it->second; |
595 | if ((mapElement->getDropped() >= EXPIRE_THRESHOLD) | 589 | if ((mapElement->getDropped() >= EXPIRE_THRESHOLD) && |
596 | && (current > mapElement->getRealTime().nsec())) { | 590 | (current > mapElement->getRealTime().nsec())) { |
597 | it = map.erase(it); | 591 | it = map.erase(it); |
598 | } else { | 592 | } else { |
599 | ++it; | 593 | ++it; |
600 | } | 594 | } |
601 | } | 595 | } |
602 | } | 596 | } |
603 | |||
604 | }; | 597 | }; |
605 | 598 | ||
606 | // prune "pruneRows" of type "id" from the buffer. | 599 | // prune "pruneRows" of type "id" from the buffer. |
@@ -651,7 +644,7 @@ public: | |||
651 | // mLogElementsLock must be held when this function is called. | 644 | // mLogElementsLock must be held when this function is called. |
652 | // | 645 | // |
653 | bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { | 646 | bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { |
654 | LogTimeEntry *oldest = NULL; | 647 | LogTimeEntry* oldest = NULL; |
655 | bool busy = false; | 648 | bool busy = false; |
656 | bool clearAll = pruneRows == ULONG_MAX; | 649 | bool clearAll = pruneRows == ULONG_MAX; |
657 | 650 | ||
@@ -659,13 +652,12 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { | |||
659 | 652 | ||
660 | // Region locked? | 653 | // Region locked? |
661 | LastLogTimes::iterator times = mTimes.begin(); | 654 | LastLogTimes::iterator times = mTimes.begin(); |
662 | while(times != mTimes.end()) { | 655 | while (times != mTimes.end()) { |
663 | LogTimeEntry *entry = (*times); | 656 | LogTimeEntry* entry = (*times); |
664 | if (entry->owned_Locked() && entry->isWatching(id) | 657 | if (entry->owned_Locked() && entry->isWatching(id) && |
665 | && (!oldest || | 658 | (!oldest || (oldest->mStart > entry->mStart) || |
666 | (oldest->mStart > entry->mStart) || | 659 | ((oldest->mStart == entry->mStart) && |
667 | ((oldest->mStart == entry->mStart) && | 660 | (entry->mTimeout.tv_sec || entry->mTimeout.tv_nsec)))) { |
668 | (entry->mTimeout.tv_sec || entry->mTimeout.tv_nsec)))) { | ||
669 | oldest = entry; | 661 | oldest = entry; |
670 | } | 662 | } |
671 | times++; | 663 | times++; |
@@ -673,14 +665,15 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { | |||
673 | 665 | ||
674 | LogBufferElementCollection::iterator it; | 666 | LogBufferElementCollection::iterator it; |
675 | 667 | ||
676 | if (__predict_false(caller_uid != AID_ROOT)) { // unlikely | 668 | if (__predict_false(caller_uid != AID_ROOT)) { // unlikely |
677 | // Only here if clear all request from non system source, so chatty | 669 | // Only here if clear all request from non system source, so chatty |
678 | // filter logistics is not required. | 670 | // filter logistics is not required. |
679 | it = mLastSet[id] ? mLast[id] : mLogElements.begin(); | 671 | it = mLastSet[id] ? mLast[id] : mLogElements.begin(); |
680 | while (it != mLogElements.end()) { | 672 | while (it != mLogElements.end()) { |
681 | LogBufferElement *element = *it; | 673 | LogBufferElement* element = *it; |
682 | 674 | ||
683 | if ((element->getLogId() != id) || (element->getUid() != caller_uid)) { | 675 | if ((element->getLogId() != id) || |
676 | (element->getUid() != caller_uid)) { | ||
684 | ++it; | 677 | ++it; |
685 | continue; | 678 | continue; |
686 | } | 679 | } |
@@ -713,26 +706,28 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { | |||
713 | bool hasBlacklist = (id != LOG_ID_SECURITY) && mPrune.naughty(); | 706 | bool hasBlacklist = (id != LOG_ID_SECURITY) && mPrune.naughty(); |
714 | while (!clearAll && (pruneRows > 0)) { | 707 | while (!clearAll && (pruneRows > 0)) { |
715 | // recalculate the worst offender on every batched pass | 708 | // recalculate the worst offender on every batched pass |
716 | int worst = -1; // not valid for getUid() or getKey() | 709 | int worst = -1; // not valid for getUid() or getKey() |
717 | size_t worst_sizes = 0; | 710 | size_t worst_sizes = 0; |
718 | size_t second_worst_sizes = 0; | 711 | size_t second_worst_sizes = 0; |
719 | pid_t worstPid = 0; // POSIX guarantees PID != 0 | 712 | pid_t worstPid = 0; // POSIX guarantees PID != 0 |
720 | 713 | ||
721 | if (worstUidEnabledForLogid(id) && mPrune.worstUidEnabled()) { | 714 | if (worstUidEnabledForLogid(id) && mPrune.worstUidEnabled()) { |
722 | // Calculate threshold as 12.5% of available storage | 715 | // Calculate threshold as 12.5% of available storage |
723 | size_t threshold = log_buffer_size(id) / 8; | 716 | size_t threshold = log_buffer_size(id) / 8; |
724 | 717 | ||
725 | if ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) { | 718 | if ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) { |
726 | stats.sortTags(AID_ROOT, (pid_t)0, 2, id).findWorst( | 719 | stats.sortTags(AID_ROOT, (pid_t)0, 2, id) |
727 | worst, worst_sizes, second_worst_sizes, threshold); | 720 | .findWorst(worst, worst_sizes, second_worst_sizes, |
721 | threshold); | ||
728 | // per-pid filter for AID_SYSTEM sources is too complex | 722 | // per-pid filter for AID_SYSTEM sources is too complex |
729 | } else { | 723 | } else { |
730 | stats.sort(AID_ROOT, (pid_t)0, 2, id).findWorst( | 724 | stats.sort(AID_ROOT, (pid_t)0, 2, id) |
731 | worst, worst_sizes, second_worst_sizes, threshold); | 725 | .findWorst(worst, worst_sizes, second_worst_sizes, |
726 | threshold); | ||
732 | 727 | ||
733 | if ((worst == AID_SYSTEM) && mPrune.worstPidOfSystemEnabled()) { | 728 | if ((worst == AID_SYSTEM) && mPrune.worstPidOfSystemEnabled()) { |
734 | stats.sortPids(worst, (pid_t)0, 2, id).findWorst( | 729 | stats.sortPids(worst, (pid_t)0, 2, id) |
735 | worstPid, worst_sizes, second_worst_sizes); | 730 | .findWorst(worstPid, worst_sizes, second_worst_sizes); |
736 | } | 731 | } |
737 | } | 732 | } |
738 | } | 733 | } |
@@ -751,35 +746,34 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { | |||
751 | // - check age-out of preserved logs | 746 | // - check age-out of preserved logs |
752 | bool gc = pruneRows <= 1; | 747 | bool gc = pruneRows <= 1; |
753 | if (!gc && (worst != -1)) { | 748 | if (!gc && (worst != -1)) { |
754 | { // begin scope for worst found iterator | 749 | { // begin scope for worst found iterator |
755 | LogBufferIteratorMap::iterator found = mLastWorst[id].find(worst); | 750 | LogBufferIteratorMap::iterator found = |
756 | if ((found != mLastWorst[id].end()) | 751 | mLastWorst[id].find(worst); |
757 | && (found->second != mLogElements.end())) { | 752 | if ((found != mLastWorst[id].end()) && |
753 | (found->second != mLogElements.end())) { | ||
758 | leading = false; | 754 | leading = false; |
759 | it = found->second; | 755 | it = found->second; |
760 | } | 756 | } |
761 | } | 757 | } |
762 | if (worstPid) { // begin scope for pid worst found iterator | 758 | if (worstPid) { // begin scope for pid worst found iterator |
763 | // FYI: worstPid only set if !LOG_ID_EVENTS and | 759 | // FYI: worstPid only set if !LOG_ID_EVENTS and |
764 | // !LOG_ID_SECURITY, not going to make that assumption ... | 760 | // !LOG_ID_SECURITY, not going to make that assumption ... |
765 | LogBufferPidIteratorMap::iterator found | 761 | LogBufferPidIteratorMap::iterator found = |
766 | = mLastWorstPidOfSystem[id].find(worstPid); | 762 | mLastWorstPidOfSystem[id].find(worstPid); |
767 | if ((found != mLastWorstPidOfSystem[id].end()) | 763 | if ((found != mLastWorstPidOfSystem[id].end()) && |
768 | && (found->second != mLogElements.end())) { | 764 | (found->second != mLogElements.end())) { |
769 | leading = false; | 765 | leading = false; |
770 | it = found->second; | 766 | it = found->second; |
771 | } | 767 | } |
772 | } | 768 | } |
773 | } | 769 | } |
774 | static const timespec too_old = { | 770 | static const timespec too_old = { EXPIRE_HOUR_THRESHOLD * 60 * 60, 0 }; |
775 | EXPIRE_HOUR_THRESHOLD * 60 * 60, 0 | ||
776 | }; | ||
777 | LogBufferElementCollection::iterator lastt; | 771 | LogBufferElementCollection::iterator lastt; |
778 | lastt = mLogElements.end(); | 772 | lastt = mLogElements.end(); |
779 | --lastt; | 773 | --lastt; |
780 | LogBufferElementLast last; | 774 | LogBufferElementLast last; |
781 | while (it != mLogElements.end()) { | 775 | while (it != mLogElements.end()) { |
782 | LogBufferElement *element = *it; | 776 | LogBufferElement* element = *it; |
783 | 777 | ||
784 | if (oldest && (oldest->mStart <= element->getSequence())) { | 778 | if (oldest && (oldest->mStart <= element->getSequence())) { |
785 | busy = true; | 779 | busy = true; |
@@ -813,9 +807,9 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { | |||
813 | continue; | 807 | continue; |
814 | } | 808 | } |
815 | 809 | ||
816 | int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) ? | 810 | int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) |
817 | element->getTag() : | 811 | ? element->getTag() |
818 | element->getUid(); | 812 | : element->getUid(); |
819 | 813 | ||
820 | if (hasBlacklist && mPrune.naughty(element)) { | 814 | if (hasBlacklist && mPrune.naughty(element)) { |
821 | last.clear(element); | 815 | last.clear(element); |
@@ -839,32 +833,32 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { | |||
839 | continue; | 833 | continue; |
840 | } | 834 | } |
841 | 835 | ||
842 | if ((element->getRealTime() < ((*lastt)->getRealTime() - too_old)) | 836 | if ((element->getRealTime() < ((*lastt)->getRealTime() - too_old)) || |
843 | || (element->getRealTime() > (*lastt)->getRealTime())) { | 837 | (element->getRealTime() > (*lastt)->getRealTime())) { |
844 | break; | 838 | break; |
845 | } | 839 | } |
846 | 840 | ||
847 | if (dropped) { | 841 | if (dropped) { |
848 | last.add(element); | 842 | last.add(element); |
849 | if (worstPid | 843 | if (worstPid && |
850 | && ((!gc && (element->getPid() == worstPid)) | 844 | ((!gc && (element->getPid() == worstPid)) || |
851 | || (mLastWorstPidOfSystem[id].find(element->getPid()) | 845 | (mLastWorstPidOfSystem[id].find(element->getPid()) == |
852 | == mLastWorstPidOfSystem[id].end()))) { | 846 | mLastWorstPidOfSystem[id].end()))) { |
853 | // element->getUid() may not be AID_SYSTEM, next best | 847 | // element->getUid() may not be AID_SYSTEM, next best |
854 | // watermark if current one empty. id is not LOG_ID_EVENTS | 848 | // watermark if current one empty. id is not LOG_ID_EVENTS |
855 | // or LOG_ID_SECURITY because of worstPid check. | 849 | // or LOG_ID_SECURITY because of worstPid check. |
856 | mLastWorstPidOfSystem[id][element->getPid()] = it; | 850 | mLastWorstPidOfSystem[id][element->getPid()] = it; |
857 | } | 851 | } |
858 | if ((!gc && !worstPid && (key == worst)) | 852 | if ((!gc && !worstPid && (key == worst)) || |
859 | || (mLastWorst[id].find(key) == mLastWorst[id].end())) { | 853 | (mLastWorst[id].find(key) == mLastWorst[id].end())) { |
860 | mLastWorst[id][key] = it; | 854 | mLastWorst[id][key] = it; |
861 | } | 855 | } |
862 | ++it; | 856 | ++it; |
863 | continue; | 857 | continue; |
864 | } | 858 | } |
865 | 859 | ||
866 | if ((key != worst) | 860 | if ((key != worst) || |
867 | || (worstPid && (element->getPid() != worstPid))) { | 861 | (worstPid && (element->getPid() != worstPid))) { |
868 | leading = false; | 862 | leading = false; |
869 | last.clear(element); | 863 | last.clear(element); |
870 | ++it; | 864 | ++it; |
@@ -892,16 +886,16 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { | |||
892 | it = erase(it, true); | 886 | it = erase(it, true); |
893 | } else { | 887 | } else { |
894 | last.add(element); | 888 | last.add(element); |
895 | if (worstPid && (!gc | 889 | if (worstPid && |
896 | || (mLastWorstPidOfSystem[id].find(worstPid) | 890 | (!gc || (mLastWorstPidOfSystem[id].find(worstPid) == |
897 | == mLastWorstPidOfSystem[id].end()))) { | 891 | mLastWorstPidOfSystem[id].end()))) { |
898 | // element->getUid() may not be AID_SYSTEM, next best | 892 | // element->getUid() may not be AID_SYSTEM, next best |
899 | // watermark if current one empty. id is not | 893 | // watermark if current one empty. id is not |
900 | // LOG_ID_EVENTS or LOG_ID_SECURITY because of worstPid. | 894 | // LOG_ID_EVENTS or LOG_ID_SECURITY because of worstPid. |
901 | mLastWorstPidOfSystem[id][worstPid] = it; | 895 | mLastWorstPidOfSystem[id][worstPid] = it; |
902 | } | 896 | } |
903 | if ((!gc && !worstPid) || | 897 | if ((!gc && !worstPid) || |
904 | (mLastWorst[id].find(worst) == mLastWorst[id].end())) { | 898 | (mLastWorst[id].find(worst) == mLastWorst[id].end())) { |
905 | mLastWorst[id][worst] = it; | 899 | mLastWorst[id][worst] = it; |
906 | } | 900 | } |
907 | ++it; | 901 | ++it; |
@@ -915,15 +909,15 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { | |||
915 | last.clear(); | 909 | last.clear(); |
916 | 910 | ||
917 | if (!kick || !mPrune.worstUidEnabled()) { | 911 | if (!kick || !mPrune.worstUidEnabled()) { |
918 | break; // the following loop will ask bad clients to skip/drop | 912 | break; // the following loop will ask bad clients to skip/drop |
919 | } | 913 | } |
920 | } | 914 | } |
921 | 915 | ||
922 | bool whitelist = false; | 916 | bool whitelist = false; |
923 | bool hasWhitelist = (id != LOG_ID_SECURITY) && mPrune.nice() && !clearAll; | 917 | bool hasWhitelist = (id != LOG_ID_SECURITY) && mPrune.nice() && !clearAll; |
924 | it = mLastSet[id] ? mLast[id] : mLogElements.begin(); | 918 | it = mLastSet[id] ? mLast[id] : mLogElements.begin(); |
925 | while((pruneRows > 0) && (it != mLogElements.end())) { | 919 | while ((pruneRows > 0) && (it != mLogElements.end())) { |
926 | LogBufferElement *element = *it; | 920 | LogBufferElement* element = *it; |
927 | 921 | ||
928 | if (element->getLogId() != id) { | 922 | if (element->getLogId() != id) { |
929 | it++; | 923 | it++; |
@@ -966,8 +960,8 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { | |||
966 | // Do not save the whitelist if we are reader range limited | 960 | // Do not save the whitelist if we are reader range limited |
967 | if (whitelist && (pruneRows > 0)) { | 961 | if (whitelist && (pruneRows > 0)) { |
968 | it = mLastSet[id] ? mLast[id] : mLogElements.begin(); | 962 | it = mLastSet[id] ? mLast[id] : mLogElements.begin(); |
969 | while((it != mLogElements.end()) && (pruneRows > 0)) { | 963 | while ((it != mLogElements.end()) && (pruneRows > 0)) { |
970 | LogBufferElement *element = *it; | 964 | LogBufferElement* element = *it; |
971 | 965 | ||
972 | if (element->getLogId() != id) { | 966 | if (element->getLogId() != id) { |
973 | ++it; | 967 | ++it; |
@@ -1007,7 +1001,7 @@ bool LogBuffer::clear(log_id_t id, uid_t uid) { | |||
1007 | bool busy = true; | 1001 | bool busy = true; |
1008 | // If it takes more than 4 tries (seconds) to clear, then kill reader(s) | 1002 | // If it takes more than 4 tries (seconds) to clear, then kill reader(s) |
1009 | for (int retry = 4;;) { | 1003 | for (int retry = 4;;) { |
1010 | if (retry == 1) { // last pass | 1004 | if (retry == 1) { // last pass |
1011 | // Check if it is still busy after the sleep, we say prune | 1005 | // Check if it is still busy after the sleep, we say prune |
1012 | // one entry, not another clear run, so we are looking for | 1006 | // one entry, not another clear run, so we are looking for |
1013 | // the quick side effect of the return value to tell us if | 1007 | // the quick side effect of the return value to tell us if |
@@ -1023,7 +1017,7 @@ bool LogBuffer::clear(log_id_t id, uid_t uid) { | |||
1023 | LogTimeEntry::lock(); | 1017 | LogTimeEntry::lock(); |
1024 | LastLogTimes::iterator times = mTimes.begin(); | 1018 | LastLogTimes::iterator times = mTimes.begin(); |
1025 | while (times != mTimes.end()) { | 1019 | while (times != mTimes.end()) { |
1026 | LogTimeEntry *entry = (*times); | 1020 | LogTimeEntry* entry = (*times); |
1027 | // Killer punch | 1021 | // Killer punch |
1028 | if (entry->owned_Locked() && entry->isWatching(id)) { | 1022 | if (entry->owned_Locked() && entry->isWatching(id)) { |
1029 | entry->release_Locked(); | 1023 | entry->release_Locked(); |
@@ -1039,7 +1033,7 @@ bool LogBuffer::clear(log_id_t id, uid_t uid) { | |||
1039 | if (!busy || !--retry) { | 1033 | if (!busy || !--retry) { |
1040 | break; | 1034 | break; |
1041 | } | 1035 | } |
1042 | sleep (1); // Let reader(s) catch up after notification | 1036 | sleep(1); // Let reader(s) catch up after notification |
1043 | } | 1037 | } |
1044 | return busy; | 1038 | return busy; |
1045 | } | 1039 | } |
@@ -1073,9 +1067,8 @@ unsigned long LogBuffer::getSize(log_id_t id) { | |||
1073 | } | 1067 | } |
1074 | 1068 | ||
1075 | uint64_t LogBuffer::flushTo( | 1069 | uint64_t LogBuffer::flushTo( |
1076 | SocketClient *reader, const uint64_t start, | 1070 | SocketClient* reader, const uint64_t start, bool privileged, bool security, |
1077 | bool privileged, bool security, | 1071 | int (*filter)(const LogBufferElement* element, void* arg), void* arg) { |
1078 | int (*filter)(const LogBufferElement *element, void *arg), void *arg) { | ||
1079 | LogBufferElementCollection::iterator it; | 1072 | LogBufferElementCollection::iterator it; |
1080 | uint64_t max = start; | 1073 | uint64_t max = start; |
1081 | uid_t uid = reader->getUid(); | 1074 | uid_t uid = reader->getUid(); |
@@ -1088,9 +1081,10 @@ uint64_t LogBuffer::flushTo( | |||
1088 | } else { | 1081 | } else { |
1089 | // Client wants to start from some specified time. Chances are | 1082 | // Client wants to start from some specified time. Chances are |
1090 | // we are better off starting from the end of the time sorted list. | 1083 | // we are better off starting from the end of the time sorted list. |
1091 | for (it = mLogElements.end(); it != mLogElements.begin(); /* do nothing */) { | 1084 | for (it = mLogElements.end(); it != mLogElements.begin(); |
1085 | /* do nothing */) { | ||
1092 | --it; | 1086 | --it; |
1093 | LogBufferElement *element = *it; | 1087 | LogBufferElement* element = *it; |
1094 | if (element->getSequence() <= start) { | 1088 | if (element->getSequence() <= start) { |
1095 | it++; | 1089 | it++; |
1096 | break; | 1090 | break; |
@@ -1103,7 +1097,7 @@ uint64_t LogBuffer::flushTo( | |||
1103 | pid_t lastTid[LOG_ID_MAX] = { 0 }; | 1097 | pid_t lastTid[LOG_ID_MAX] = { 0 }; |
1104 | 1098 | ||
1105 | for (; it != mLogElements.end(); ++it) { | 1099 | for (; it != mLogElements.end(); ++it) { |
1106 | LogBufferElement *element = *it; | 1100 | LogBufferElement* element = *it; |
1107 | 1101 | ||
1108 | if (!privileged && (element->getUid() != uid)) { | 1102 | if (!privileged && (element->getUid() != uid)) { |
1109 | continue; | 1103 | continue; |
@@ -1134,8 +1128,8 @@ uint64_t LogBuffer::flushTo( | |||
1134 | // multiple identical squash. chatty that differs source | 1128 | // multiple identical squash. chatty that differs source |
1135 | // is due to spam filter. chatty to chatty of different | 1129 | // is due to spam filter. chatty to chatty of different |
1136 | // source is also due to spam filter. | 1130 | // source is also due to spam filter. |
1137 | lastTid[element->getLogId()] = (element->getDropped() && !sameTid) ? | 1131 | lastTid[element->getLogId()] = |
1138 | 0 : element->getTid(); | 1132 | (element->getDropped() && !sameTid) ? 0 : element->getTid(); |
1139 | 1133 | ||
1140 | pthread_mutex_unlock(&mLogElementsLock); | 1134 | pthread_mutex_unlock(&mLogElementsLock); |
1141 | 1135 | ||
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h index 9feef32e7..92b0297e2 100644 --- a/logd/LogBuffer.h +++ b/logd/LogBuffer.h | |||
@@ -27,9 +27,9 @@ | |||
27 | #include <sysutils/SocketClient.h> | 27 | #include <sysutils/SocketClient.h> |
28 | 28 | ||
29 | #include "LogBufferElement.h" | 29 | #include "LogBufferElement.h" |
30 | #include "LogStatistics.h" | ||
30 | #include "LogTags.h" | 31 | #include "LogTags.h" |
31 | #include "LogTimes.h" | 32 | #include "LogTimes.h" |
32 | #include "LogStatistics.h" | ||
33 | #include "LogWhiteBlackList.h" | 33 | #include "LogWhiteBlackList.h" |
34 | 34 | ||
35 | // | 35 | // |
@@ -41,7 +41,7 @@ | |||
41 | // | 41 | // |
42 | namespace android { | 42 | namespace android { |
43 | 43 | ||
44 | static bool isMonotonic(const log_time &mono) { | 44 | static bool isMonotonic(const log_time& mono) { |
45 | static const uint32_t EPOCH_PLUS_2_YEARS = 2 * 24 * 60 * 60 * 1461 / 4; | 45 | static const uint32_t EPOCH_PLUS_2_YEARS = 2 * 24 * 60 * 60 * 1461 / 4; |
46 | static const uint32_t EPOCH_PLUS_MINUTE = 60; | 46 | static const uint32_t EPOCH_PLUS_MINUTE = 60; |
47 | 47 | ||
@@ -70,10 +70,9 @@ static bool isMonotonic(const log_time &mono) { | |||
70 | /* dividing line half way between monotonic and realtime */ | 70 | /* dividing line half way between monotonic and realtime */ |
71 | return mono.tv_sec < ((cpu.tv_sec + now.tv_sec) / 2); | 71 | return mono.tv_sec < ((cpu.tv_sec + now.tv_sec) / 2); |
72 | } | 72 | } |
73 | |||
74 | } | 73 | } |
75 | 74 | ||
76 | typedef std::list<LogBufferElement *> LogBufferElementCollection; | 75 | typedef std::list<LogBufferElement*> LogBufferElementCollection; |
77 | 76 | ||
78 | class LogBuffer { | 77 | class LogBuffer { |
79 | LogBufferElementCollection mLogElements; | 78 | LogBufferElementCollection mLogElements; |
@@ -86,14 +85,12 @@ class LogBuffer { | |||
86 | LogBufferElementCollection::iterator mLast[LOG_ID_MAX]; | 85 | LogBufferElementCollection::iterator mLast[LOG_ID_MAX]; |
87 | bool mLastSet[LOG_ID_MAX]; | 86 | bool mLastSet[LOG_ID_MAX]; |
88 | // watermark of any worst/chatty uid processing | 87 | // watermark of any worst/chatty uid processing |
89 | typedef std::unordered_map<uid_t, | 88 | typedef std::unordered_map<uid_t, LogBufferElementCollection::iterator> |
90 | LogBufferElementCollection::iterator> | 89 | LogBufferIteratorMap; |
91 | LogBufferIteratorMap; | ||
92 | LogBufferIteratorMap mLastWorst[LOG_ID_MAX]; | 90 | LogBufferIteratorMap mLastWorst[LOG_ID_MAX]; |
93 | // watermark of any worst/chatty pid of system processing | 91 | // watermark of any worst/chatty pid of system processing |
94 | typedef std::unordered_map<pid_t, | 92 | typedef std::unordered_map<pid_t, LogBufferElementCollection::iterator> |
95 | LogBufferElementCollection::iterator> | 93 | LogBufferPidIteratorMap; |
96 | LogBufferPidIteratorMap; | ||
97 | LogBufferPidIteratorMap mLastWorstPidOfSystem[LOG_ID_MAX]; | 94 | LogBufferPidIteratorMap mLastWorstPidOfSystem[LOG_ID_MAX]; |
98 | 95 | ||
99 | unsigned long mMaxSize[LOG_ID_MAX]; | 96 | unsigned long mMaxSize[LOG_ID_MAX]; |
@@ -106,21 +103,23 @@ class LogBuffer { | |||
106 | LogBufferElement* droppedElements[LOG_ID_MAX]; | 103 | LogBufferElement* droppedElements[LOG_ID_MAX]; |
107 | void log(LogBufferElement* elem); | 104 | void log(LogBufferElement* elem); |
108 | 105 | ||
109 | public: | 106 | public: |
110 | LastLogTimes &mTimes; | 107 | LastLogTimes& mTimes; |
111 | 108 | ||
112 | explicit LogBuffer(LastLogTimes *times); | 109 | explicit LogBuffer(LastLogTimes* times); |
113 | ~LogBuffer(); | 110 | ~LogBuffer(); |
114 | void init(); | 111 | void init(); |
115 | bool isMonotonic() { return monotonic; } | 112 | bool isMonotonic() { |
113 | return monotonic; | ||
114 | } | ||
116 | 115 | ||
117 | int log(log_id_t log_id, log_time realtime, | 116 | int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, |
118 | uid_t uid, pid_t pid, pid_t tid, | 117 | const char* msg, unsigned short len); |
119 | const char *msg, unsigned short len); | 118 | uint64_t flushTo(SocketClient* writer, const uint64_t start, |
120 | uint64_t flushTo(SocketClient *writer, const uint64_t start, | ||
121 | bool privileged, bool security, | 119 | bool privileged, bool security, |
122 | int (*filter)(const LogBufferElement *element, void *arg) = NULL, | 120 | int (*filter)(const LogBufferElement* element, |
123 | void *arg = NULL); | 121 | void* arg) = NULL, |
122 | void* arg = NULL); | ||
124 | 123 | ||
125 | bool clear(log_id_t id, uid_t uid = AID_ROOT); | 124 | bool clear(log_id_t id, uid_t uid = AID_ROOT); |
126 | unsigned long getSize(log_id_t id); | 125 | unsigned long getSize(log_id_t id); |
@@ -133,27 +132,42 @@ public: | |||
133 | stats.enableStatistics(); | 132 | stats.enableStatistics(); |
134 | } | 133 | } |
135 | 134 | ||
136 | int initPrune(const char *cp) { return mPrune.init(cp); } | 135 | int initPrune(const char* cp) { |
137 | std::string formatPrune() { return mPrune.format(); } | 136 | return mPrune.init(cp); |
137 | } | ||
138 | std::string formatPrune() { | ||
139 | return mPrune.format(); | ||
140 | } | ||
138 | 141 | ||
139 | std::string formatGetEventTag(uid_t uid, | 142 | std::string formatGetEventTag(uid_t uid, const char* name, |
140 | const char *name, const char *format) { | 143 | const char* format) { |
141 | return tags.formatGetEventTag(uid, name, format); | 144 | return tags.formatGetEventTag(uid, name, format); |
142 | } | 145 | } |
143 | std::string formatEntry(uint32_t tag, uid_t uid) { | 146 | std::string formatEntry(uint32_t tag, uid_t uid) { |
144 | return tags.formatEntry(tag, uid); | 147 | return tags.formatEntry(tag, uid); |
145 | } | 148 | } |
146 | const char *tagToName(uint32_t tag) { return tags.tagToName(tag); } | 149 | const char* tagToName(uint32_t tag) { |
150 | return tags.tagToName(tag); | ||
151 | } | ||
147 | 152 | ||
148 | // helper must be protected directly or implicitly by lock()/unlock() | 153 | // helper must be protected directly or implicitly by lock()/unlock() |
149 | const char *pidToName(pid_t pid) { return stats.pidToName(pid); } | 154 | const char* pidToName(pid_t pid) { |
150 | uid_t pidToUid(pid_t pid) { return stats.pidToUid(pid); } | 155 | return stats.pidToName(pid); |
151 | const char *uidToName(uid_t uid) { return stats.uidToName(uid); } | 156 | } |
152 | void lock() { pthread_mutex_lock(&mLogElementsLock); } | 157 | uid_t pidToUid(pid_t pid) { |
153 | void unlock() { pthread_mutex_unlock(&mLogElementsLock); } | 158 | return stats.pidToUid(pid); |
154 | 159 | } | |
155 | private: | 160 | const char* uidToName(uid_t uid) { |
161 | return stats.uidToName(uid); | ||
162 | } | ||
163 | void lock() { | ||
164 | pthread_mutex_lock(&mLogElementsLock); | ||
165 | } | ||
166 | void unlock() { | ||
167 | pthread_mutex_unlock(&mLogElementsLock); | ||
168 | } | ||
156 | 169 | ||
170 | private: | ||
157 | static constexpr size_t minPrune = 4; | 171 | static constexpr size_t minPrune = 4; |
158 | static constexpr size_t maxPrune = 256; | 172 | static constexpr size_t maxPrune = 256; |
159 | 173 | ||
@@ -163,4 +177,4 @@ private: | |||
163 | LogBufferElementCollection::iterator it, bool coalesce = false); | 177 | LogBufferElementCollection::iterator it, bool coalesce = false); |
164 | }; | 178 | }; |
165 | 179 | ||
166 | #endif // _LOGD_LOG_BUFFER_H__ | 180 | #endif // _LOGD_LOG_BUFFER_H__ |
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp index a651fd4be..5ba3a1514 100644 --- a/logd/LogBufferElement.cpp +++ b/logd/LogBufferElement.cpp | |||
@@ -35,41 +35,41 @@ atomic_int_fast64_t LogBufferElement::sequence(1); | |||
35 | 35 | ||
36 | LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime, | 36 | LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime, |
37 | uid_t uid, pid_t pid, pid_t tid, | 37 | uid_t uid, pid_t pid, pid_t tid, |
38 | const char *msg, unsigned short len) : | 38 | const char* msg, unsigned short len) |
39 | mUid(uid), | 39 | : mUid(uid), |
40 | mPid(pid), | 40 | mPid(pid), |
41 | mTid(tid), | 41 | mTid(tid), |
42 | mSequence(sequence.fetch_add(1, memory_order_relaxed)), | 42 | mSequence(sequence.fetch_add(1, memory_order_relaxed)), |
43 | mRealTime(realtime), | 43 | mRealTime(realtime), |
44 | mMsgLen(len), | 44 | mMsgLen(len), |
45 | mLogId(log_id) { | 45 | mLogId(log_id) { |
46 | mMsg = new char[len]; | 46 | mMsg = new char[len]; |
47 | memcpy(mMsg, msg, len); | 47 | memcpy(mMsg, msg, len); |
48 | mTag = (isBinary() && (mMsgLen >= sizeof(uint32_t))) ? | 48 | mTag = (isBinary() && (mMsgLen >= sizeof(uint32_t))) |
49 | le32toh(reinterpret_cast<android_event_header_t *>(mMsg)->tag) : | 49 | ? le32toh(reinterpret_cast<android_event_header_t*>(mMsg)->tag) |
50 | 0; | 50 | : 0; |
51 | } | 51 | } |
52 | 52 | ||
53 | LogBufferElement::LogBufferElement(const LogBufferElement &elem) : | 53 | LogBufferElement::LogBufferElement(const LogBufferElement& elem) |
54 | mTag(elem.mTag), | 54 | : mTag(elem.mTag), |
55 | mUid(elem.mUid), | 55 | mUid(elem.mUid), |
56 | mPid(elem.mPid), | 56 | mPid(elem.mPid), |
57 | mTid(elem.mTid), | 57 | mTid(elem.mTid), |
58 | mSequence(elem.mSequence), | 58 | mSequence(elem.mSequence), |
59 | mRealTime(elem.mRealTime), | 59 | mRealTime(elem.mRealTime), |
60 | mMsgLen(elem.mMsgLen), | 60 | mMsgLen(elem.mMsgLen), |
61 | mLogId(elem.mLogId) { | 61 | mLogId(elem.mLogId) { |
62 | mMsg = new char[mMsgLen]; | 62 | mMsg = new char[mMsgLen]; |
63 | memcpy(mMsg, elem.mMsg, mMsgLen); | 63 | memcpy(mMsg, elem.mMsg, mMsgLen); |
64 | } | 64 | } |
65 | 65 | ||
66 | LogBufferElement::~LogBufferElement() { | 66 | LogBufferElement::~LogBufferElement() { |
67 | delete [] mMsg; | 67 | delete[] mMsg; |
68 | } | 68 | } |
69 | 69 | ||
70 | // caller must own and free character string | 70 | // caller must own and free character string |
71 | char *android::tidToName(pid_t tid) { | 71 | char* android::tidToName(pid_t tid) { |
72 | char *retval = NULL; | 72 | char* retval = NULL; |
73 | char buffer[256]; | 73 | char buffer[256]; |
74 | snprintf(buffer, sizeof(buffer), "/proc/%u/comm", tid); | 74 | snprintf(buffer, sizeof(buffer), "/proc/%u/comm", tid); |
75 | int fd = open(buffer, O_RDONLY); | 75 | int fd = open(buffer, O_RDONLY); |
@@ -89,7 +89,7 @@ char *android::tidToName(pid_t tid) { | |||
89 | } | 89 | } |
90 | 90 | ||
91 | // if nothing for comm, check out cmdline | 91 | // if nothing for comm, check out cmdline |
92 | char *name = android::pidToName(tid); | 92 | char* name = android::pidToName(tid); |
93 | if (!retval) { | 93 | if (!retval) { |
94 | retval = name; | 94 | retval = name; |
95 | name = NULL; | 95 | name = NULL; |
@@ -101,8 +101,8 @@ char *android::tidToName(pid_t tid) { | |||
101 | size_t retval_len = strlen(retval); | 101 | size_t retval_len = strlen(retval); |
102 | size_t name_len = strlen(name); | 102 | size_t name_len = strlen(name); |
103 | // KISS: ToDo: Only checks prefix truncated, not suffix, or both | 103 | // KISS: ToDo: Only checks prefix truncated, not suffix, or both |
104 | if ((retval_len < name_len) | 104 | if ((retval_len < name_len) && |
105 | && !fastcmp<strcmp>(retval, name + name_len - retval_len)) { | 105 | !fastcmp<strcmp>(retval, name + name_len - retval_len)) { |
106 | free(retval); | 106 | free(retval); |
107 | retval = name; | 107 | retval = name; |
108 | } else { | 108 | } else { |
@@ -113,21 +113,20 @@ char *android::tidToName(pid_t tid) { | |||
113 | } | 113 | } |
114 | 114 | ||
115 | // assumption: mMsg == NULL | 115 | // assumption: mMsg == NULL |
116 | size_t LogBufferElement::populateDroppedMessage(char*& buffer, | 116 | size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogBuffer* parent, |
117 | LogBuffer* parent, bool lastSame) { | 117 | bool lastSame) { |
118 | static const char tag[] = "chatty"; | 118 | static const char tag[] = "chatty"; |
119 | 119 | ||
120 | if (!__android_log_is_loggable_len(ANDROID_LOG_INFO, | 120 | if (!__android_log_is_loggable_len(ANDROID_LOG_INFO, tag, strlen(tag), |
121 | tag, strlen(tag), | ||
122 | ANDROID_LOG_VERBOSE)) { | 121 | ANDROID_LOG_VERBOSE)) { |
123 | return 0; | 122 | return 0; |
124 | } | 123 | } |
125 | 124 | ||
126 | static const char format_uid[] = "uid=%u%s%s %s %u line%s"; | 125 | static const char format_uid[] = "uid=%u%s%s %s %u line%s"; |
127 | parent->lock(); | 126 | parent->lock(); |
128 | const char *name = parent->uidToName(mUid); | 127 | const char* name = parent->uidToName(mUid); |
129 | parent->unlock(); | 128 | parent->unlock(); |
130 | const char *commName = android::tidToName(mTid); | 129 | const char* commName = android::tidToName(mTid); |
131 | if (!commName && (mTid != mPid)) { | 130 | if (!commName && (mTid != mPid)) { |
132 | commName = android::tidToName(mPid); | 131 | commName = android::tidToName(mPid); |
133 | } | 132 | } |
@@ -140,35 +139,35 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, | |||
140 | size_t len = strlen(name + 1); | 139 | size_t len = strlen(name + 1); |
141 | if (!strncmp(name + 1, commName + 1, len)) { | 140 | if (!strncmp(name + 1, commName + 1, len)) { |
142 | if (commName[len + 1] == '\0') { | 141 | if (commName[len + 1] == '\0') { |
143 | free(const_cast<char *>(commName)); | 142 | free(const_cast<char*>(commName)); |
144 | commName = NULL; | 143 | commName = NULL; |
145 | } else { | 144 | } else { |
146 | free(const_cast<char *>(name)); | 145 | free(const_cast<char*>(name)); |
147 | name = NULL; | 146 | name = NULL; |
148 | } | 147 | } |
149 | } | 148 | } |
150 | } | 149 | } |
151 | if (name) { | 150 | if (name) { |
152 | char *buf = NULL; | 151 | char* buf = NULL; |
153 | asprintf(&buf, "(%s)", name); | 152 | asprintf(&buf, "(%s)", name); |
154 | if (buf) { | 153 | if (buf) { |
155 | free(const_cast<char *>(name)); | 154 | free(const_cast<char*>(name)); |
156 | name = buf; | 155 | name = buf; |
157 | } | 156 | } |
158 | } | 157 | } |
159 | if (commName) { | 158 | if (commName) { |
160 | char *buf = NULL; | 159 | char* buf = NULL; |
161 | asprintf(&buf, " %s", commName); | 160 | asprintf(&buf, " %s", commName); |
162 | if (buf) { | 161 | if (buf) { |
163 | free(const_cast<char *>(commName)); | 162 | free(const_cast<char*>(commName)); |
164 | commName = buf; | 163 | commName = buf; |
165 | } | 164 | } |
166 | } | 165 | } |
167 | // identical to below to calculate the buffer size required | 166 | // identical to below to calculate the buffer size required |
168 | const char* type = lastSame ? "identical" : "expire"; | 167 | const char* type = lastSame ? "identical" : "expire"; |
169 | size_t len = snprintf(NULL, 0, format_uid, mUid, name ? name : "", | 168 | size_t len = snprintf(NULL, 0, format_uid, mUid, name ? name : "", |
170 | commName ? commName : "", type, | 169 | commName ? commName : "", type, mDropped, |
171 | mDropped, (mDropped > 1) ? "s" : ""); | 170 | (mDropped > 1) ? "s" : ""); |
172 | 171 | ||
173 | size_t hdrLen; | 172 | size_t hdrLen; |
174 | if (isBinary()) { | 173 | if (isBinary()) { |
@@ -177,17 +176,17 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, | |||
177 | hdrLen = 1 + sizeof(tag); | 176 | hdrLen = 1 + sizeof(tag); |
178 | } | 177 | } |
179 | 178 | ||
180 | buffer = static_cast<char *>(calloc(1, hdrLen + len + 1)); | 179 | buffer = static_cast<char*>(calloc(1, hdrLen + len + 1)); |
181 | if (!buffer) { | 180 | if (!buffer) { |
182 | free(const_cast<char *>(name)); | 181 | free(const_cast<char*>(name)); |
183 | free(const_cast<char *>(commName)); | 182 | free(const_cast<char*>(commName)); |
184 | return 0; | 183 | return 0; |
185 | } | 184 | } |
186 | 185 | ||
187 | size_t retval = hdrLen + len; | 186 | size_t retval = hdrLen + len; |
188 | if (isBinary()) { | 187 | if (isBinary()) { |
189 | android_log_event_string_t *event = | 188 | android_log_event_string_t* event = |
190 | reinterpret_cast<android_log_event_string_t *>(buffer); | 189 | reinterpret_cast<android_log_event_string_t*>(buffer); |
191 | 190 | ||
192 | event->header.tag = htole32(CHATTY_LOG_TAG); | 191 | event->header.tag = htole32(CHATTY_LOG_TAG); |
193 | event->type = EVENT_TYPE_STRING; | 192 | event->type = EVENT_TYPE_STRING; |
@@ -199,10 +198,10 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, | |||
199 | } | 198 | } |
200 | 199 | ||
201 | snprintf(buffer + hdrLen, len + 1, format_uid, mUid, name ? name : "", | 200 | snprintf(buffer + hdrLen, len + 1, format_uid, mUid, name ? name : "", |
202 | commName ? commName : "", type, | 201 | commName ? commName : "", type, mDropped, |
203 | mDropped, (mDropped > 1) ? "s" : ""); | 202 | (mDropped > 1) ? "s" : ""); |
204 | free(const_cast<char *>(name)); | 203 | free(const_cast<char*>(name)); |
205 | free(const_cast<char *>(commName)); | 204 | free(const_cast<char*>(commName)); |
206 | 205 | ||
207 | return retval; | 206 | return retval; |
208 | } | 207 | } |
@@ -213,9 +212,8 @@ uint64_t LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, | |||
213 | 212 | ||
214 | memset(&entry, 0, sizeof(struct logger_entry_v4)); | 213 | memset(&entry, 0, sizeof(struct logger_entry_v4)); |
215 | 214 | ||
216 | entry.hdr_size = privileged ? | 215 | entry.hdr_size = privileged ? sizeof(struct logger_entry_v4) |
217 | sizeof(struct logger_entry_v4) : | 216 | : sizeof(struct logger_entry_v3); |
218 | sizeof(struct logger_entry_v3); | ||
219 | entry.lid = mLogId; | 217 | entry.lid = mLogId; |
220 | entry.pid = mPid; | 218 | entry.pid = mPid; |
221 | entry.tid = mTid; | 219 | entry.tid = mTid; |
@@ -227,13 +225,11 @@ uint64_t LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, | |||
227 | iovec[0].iov_base = &entry; | 225 | iovec[0].iov_base = &entry; |
228 | iovec[0].iov_len = entry.hdr_size; | 226 | iovec[0].iov_len = entry.hdr_size; |
229 | 227 | ||
230 | char *buffer = NULL; | 228 | char* buffer = NULL; |
231 | 229 | ||
232 | if (!mMsg) { | 230 | if (!mMsg) { |
233 | entry.len = populateDroppedMessage(buffer, parent, lastSame); | 231 | entry.len = populateDroppedMessage(buffer, parent, lastSame); |
234 | if (!entry.len) { | 232 | if (!entry.len) return mSequence; |
235 | return mSequence; | ||
236 | } | ||
237 | iovec[1].iov_base = buffer; | 233 | iovec[1].iov_base = buffer; |
238 | } else { | 234 | } else { |
239 | entry.len = mMsgLen; | 235 | entry.len = mMsgLen; |
@@ -243,9 +239,7 @@ uint64_t LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, | |||
243 | 239 | ||
244 | uint64_t retval = reader->sendDatav(iovec, 2) ? FLUSH_ERROR : mSequence; | 240 | uint64_t retval = reader->sendDatav(iovec, 2) ? FLUSH_ERROR : mSequence; |
245 | 241 | ||
246 | if (buffer) { | 242 | if (buffer) free(buffer); |
247 | free(buffer); | ||
248 | } | ||
249 | 243 | ||
250 | return retval; | 244 | return retval; |
251 | } | 245 | } |
diff --git a/logd/LogBufferElement.h b/logd/LogBufferElement.h index bd98b9c4b..43990e835 100644 --- a/logd/LogBufferElement.h +++ b/logd/LogBufferElement.h | |||
@@ -26,69 +26,89 @@ | |||
26 | 26 | ||
27 | class LogBuffer; | 27 | class LogBuffer; |
28 | 28 | ||
29 | #define EXPIRE_HOUR_THRESHOLD 24 // Only expire chatty UID logs to preserve | 29 | #define EXPIRE_HOUR_THRESHOLD 24 // Only expire chatty UID logs to preserve |
30 | // non-chatty UIDs less than this age in hours | 30 | // non-chatty UIDs less than this age in hours |
31 | #define EXPIRE_THRESHOLD 10 // A smaller expire count is considered too | 31 | #define EXPIRE_THRESHOLD 10 // A smaller expire count is considered too |
32 | // chatty for the temporal expire messages | 32 | // chatty for the temporal expire messages |
33 | #define EXPIRE_RATELIMIT 10 // maximum rate in seconds to report expiration | 33 | #define EXPIRE_RATELIMIT 10 // maximum rate in seconds to report expiration |
34 | 34 | ||
35 | class LogBufferElement { | 35 | class LogBufferElement { |
36 | |||
37 | friend LogBuffer; | 36 | friend LogBuffer; |
38 | 37 | ||
39 | // sized to match reality of incoming log packets | 38 | // sized to match reality of incoming log packets |
40 | uint32_t mTag; // only valid for isBinary() | 39 | uint32_t mTag; // only valid for isBinary() |
41 | const uint32_t mUid; | 40 | const uint32_t mUid; |
42 | const uint32_t mPid; | 41 | const uint32_t mPid; |
43 | const uint32_t mTid; | 42 | const uint32_t mTid; |
44 | const uint64_t mSequence; | 43 | const uint64_t mSequence; |
45 | log_time mRealTime; | 44 | log_time mRealTime; |
46 | char *mMsg; | 45 | char* mMsg; |
47 | union { | 46 | union { |
48 | const uint16_t mMsgLen; // mMSg != NULL | 47 | const uint16_t mMsgLen; // mMSg != NULL |
49 | uint16_t mDropped; // mMsg == NULL | 48 | uint16_t mDropped; // mMsg == NULL |
50 | }; | 49 | }; |
51 | const uint8_t mLogId; | 50 | const uint8_t mLogId; |
52 | 51 | ||
53 | static atomic_int_fast64_t sequence; | 52 | static atomic_int_fast64_t sequence; |
54 | 53 | ||
55 | // assumption: mMsg == NULL | 54 | // assumption: mMsg == NULL |
56 | size_t populateDroppedMessage(char*& buffer, | 55 | size_t populateDroppedMessage(char*& buffer, LogBuffer* parent, |
57 | LogBuffer* parent, | ||
58 | bool lastSame); | 56 | bool lastSame); |
59 | public: | 57 | |
60 | LogBufferElement(log_id_t log_id, log_time realtime, | 58 | public: |
61 | uid_t uid, pid_t pid, pid_t tid, | 59 | LogBufferElement(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, |
62 | const char *msg, unsigned short len); | 60 | pid_t tid, const char* msg, unsigned short len); |
63 | LogBufferElement(const LogBufferElement &elem); | 61 | LogBufferElement(const LogBufferElement& elem); |
64 | virtual ~LogBufferElement(); | 62 | virtual ~LogBufferElement(); |
65 | 63 | ||
66 | bool isBinary(void) const { | 64 | bool isBinary(void) const { |
67 | return (mLogId == LOG_ID_EVENTS) || (mLogId == LOG_ID_SECURITY); | 65 | return (mLogId == LOG_ID_EVENTS) || (mLogId == LOG_ID_SECURITY); |
68 | } | 66 | } |
69 | 67 | ||
70 | log_id_t getLogId() const { return static_cast<log_id_t>(mLogId); } | 68 | log_id_t getLogId() const { |
71 | uid_t getUid(void) const { return mUid; } | 69 | return static_cast<log_id_t>(mLogId); |
72 | pid_t getPid(void) const { return mPid; } | 70 | } |
73 | pid_t getTid(void) const { return mTid; } | 71 | uid_t getUid(void) const { |
74 | uint32_t getTag() const { return mTag; } | 72 | return mUid; |
75 | unsigned short getDropped(void) const { return mMsg ? 0 : mDropped; } | 73 | } |
74 | pid_t getPid(void) const { | ||
75 | return mPid; | ||
76 | } | ||
77 | pid_t getTid(void) const { | ||
78 | return mTid; | ||
79 | } | ||
80 | uint32_t getTag() const { | ||
81 | return mTag; | ||
82 | } | ||
83 | unsigned short getDropped(void) const { | ||
84 | return mMsg ? 0 : mDropped; | ||
85 | } | ||
76 | unsigned short setDropped(unsigned short value) { | 86 | unsigned short setDropped(unsigned short value) { |
77 | if (mMsg) { | 87 | if (mMsg) { |
78 | delete [] mMsg; | 88 | delete[] mMsg; |
79 | mMsg = NULL; | 89 | mMsg = NULL; |
80 | } | 90 | } |
81 | return mDropped = value; | 91 | return mDropped = value; |
82 | } | 92 | } |
83 | unsigned short getMsgLen() const { return mMsg ? mMsgLen : 0; } | 93 | unsigned short getMsgLen() const { |
84 | const char* getMsg() const { return mMsg; } | 94 | return mMsg ? mMsgLen : 0; |
85 | uint64_t getSequence(void) const { return mSequence; } | 95 | } |
86 | static uint64_t getCurrentSequence(void) { return sequence.load(memory_order_relaxed); } | 96 | const char* getMsg() const { |
87 | log_time getRealTime(void) const { return mRealTime; } | 97 | return mMsg; |
98 | } | ||
99 | uint64_t getSequence(void) const { | ||
100 | return mSequence; | ||
101 | } | ||
102 | static uint64_t getCurrentSequence(void) { | ||
103 | return sequence.load(memory_order_relaxed); | ||
104 | } | ||
105 | log_time getRealTime(void) const { | ||
106 | return mRealTime; | ||
107 | } | ||
88 | 108 | ||
89 | static const uint64_t FLUSH_ERROR; | 109 | static const uint64_t FLUSH_ERROR; |
90 | uint64_t flushTo(SocketClient* writer, LogBuffer* parent, | 110 | uint64_t flushTo(SocketClient* writer, LogBuffer* parent, bool privileged, |
91 | bool privileged, bool lastSame); | 111 | bool lastSame); |
92 | }; | 112 | }; |
93 | 113 | ||
94 | #endif | 114 | #endif |
diff --git a/logd/LogCommand.cpp b/logd/LogCommand.cpp index 3b1757656..6d7c0a5dc 100644 --- a/logd/LogCommand.cpp +++ b/logd/LogCommand.cpp | |||
@@ -24,7 +24,7 @@ | |||
24 | #include "LogCommand.h" | 24 | #include "LogCommand.h" |
25 | #include "LogUtils.h" | 25 | #include "LogUtils.h" |
26 | 26 | ||
27 | LogCommand::LogCommand(const char *cmd) : FrameworkCommand(cmd) { | 27 | LogCommand::LogCommand(const char* cmd) : FrameworkCommand(cmd) { |
28 | } | 28 | } |
29 | 29 | ||
30 | // gets a list of supplementary group IDs associated with | 30 | // gets a list of supplementary group IDs associated with |
@@ -40,8 +40,8 @@ LogCommand::LogCommand(const char *cmd) : FrameworkCommand(cmd) { | |||
40 | // has open permissions, and one that has restricted | 40 | // has open permissions, and one that has restricted |
41 | // permissions. | 41 | // permissions. |
42 | 42 | ||
43 | static bool groupIsLog(char *buf) { | 43 | static bool groupIsLog(char* buf) { |
44 | char *ptr; | 44 | char* ptr; |
45 | static const char ws[] = " \n"; | 45 | static const char ws[] = " \n"; |
46 | 46 | ||
47 | for (buf = strtok_r(buf, ws, &ptr); buf; buf = strtok_r(NULL, ws, &ptr)) { | 47 | for (buf = strtok_r(buf, ws, &ptr); buf; buf = strtok_r(NULL, ws, &ptr)) { |
@@ -91,15 +91,14 @@ bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid) { | |||
91 | // doubt, but we expect the falses should be reduced significantly as | 91 | // doubt, but we expect the falses should be reduced significantly as |
92 | // three times is a charm. | 92 | // three times is a charm. |
93 | // | 93 | // |
94 | for (int retry = 3; | 94 | for (int retry = 3; !(ret = foundGid && foundUid && foundLog) && retry; |
95 | !(ret = foundGid && foundUid && foundLog) && retry; | 95 | --retry) { |
96 | --retry) { | 96 | FILE* file = fopen(filename, "r"); |
97 | FILE *file = fopen(filename, "r"); | ||
98 | if (!file) { | 97 | if (!file) { |
99 | continue; | 98 | continue; |
100 | } | 99 | } |
101 | 100 | ||
102 | char *line = NULL; | 101 | char* line = NULL; |
103 | size_t len = 0; | 102 | size_t len = 0; |
104 | while (getline(&line, &len, file) > 0) { | 103 | while (getline(&line, &len, file) > 0) { |
105 | static const char groups_string[] = "Groups:\t"; | 104 | static const char groups_string[] = "Groups:\t"; |
@@ -111,29 +110,25 @@ bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid) { | |||
111 | foundLog = true; | 110 | foundLog = true; |
112 | } | 111 | } |
113 | } else if (strncmp(uid_string, line, sizeof(uid_string) - 1) == 0) { | 112 | } else if (strncmp(uid_string, line, sizeof(uid_string) - 1) == 0) { |
114 | uid_t u[4] = { (uid_t) -1, (uid_t) -1, (uid_t) -1, (uid_t) -1}; | 113 | uid_t u[4] = { (uid_t)-1, (uid_t)-1, (uid_t)-1, (uid_t)-1 }; |
115 | 114 | ||
116 | sscanf(line + sizeof(uid_string) - 1, "%u\t%u\t%u\t%u", | 115 | sscanf(line + sizeof(uid_string) - 1, "%u\t%u\t%u\t%u", &u[0], |
117 | &u[0], &u[1], &u[2], &u[3]); | 116 | &u[1], &u[2], &u[3]); |
118 | 117 | ||
119 | // Protect against PID reuse by checking that UID is the same | 118 | // Protect against PID reuse by checking that UID is the same |
120 | if ((uid == u[0]) | 119 | if ((uid == u[0]) && (uid == u[1]) && (uid == u[2]) && |
121 | && (uid == u[1]) | 120 | (uid == u[3])) { |
122 | && (uid == u[2]) | ||
123 | && (uid == u[3])) { | ||
124 | foundUid = true; | 121 | foundUid = true; |
125 | } | 122 | } |
126 | } else if (strncmp(gid_string, line, sizeof(gid_string) - 1) == 0) { | 123 | } else if (strncmp(gid_string, line, sizeof(gid_string) - 1) == 0) { |
127 | gid_t g[4] = { (gid_t) -1, (gid_t) -1, (gid_t) -1, (gid_t) -1}; | 124 | gid_t g[4] = { (gid_t)-1, (gid_t)-1, (gid_t)-1, (gid_t)-1 }; |
128 | 125 | ||
129 | sscanf(line + sizeof(gid_string) - 1, "%u\t%u\t%u\t%u", | 126 | sscanf(line + sizeof(gid_string) - 1, "%u\t%u\t%u\t%u", &g[0], |
130 | &g[0], &g[1], &g[2], &g[3]); | 127 | &g[1], &g[2], &g[3]); |
131 | 128 | ||
132 | // Protect against PID reuse by checking that GID is the same | 129 | // Protect against PID reuse by checking that GID is the same |
133 | if ((gid == g[0]) | 130 | if ((gid == g[0]) && (gid == g[1]) && (gid == g[2]) && |
134 | && (gid == g[1]) | 131 | (gid == g[3])) { |
135 | && (gid == g[2]) | ||
136 | && (gid == g[3])) { | ||
137 | foundGid = true; | 132 | foundGid = true; |
138 | } | 133 | } |
139 | } | 134 | } |
@@ -145,6 +140,6 @@ bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid) { | |||
145 | return ret; | 140 | return ret; |
146 | } | 141 | } |
147 | 142 | ||
148 | bool clientHasLogCredentials(SocketClient *cli) { | 143 | bool clientHasLogCredentials(SocketClient* cli) { |
149 | return clientHasLogCredentials(cli->getUid(), cli->getGid(), cli->getPid()); | 144 | return clientHasLogCredentials(cli->getUid(), cli->getGid(), cli->getPid()); |
150 | } | 145 | } |
diff --git a/logd/LogCommand.h b/logd/LogCommand.h index 0adc2a1d7..e10ffa0e6 100644 --- a/logd/LogCommand.h +++ b/logd/LogCommand.h | |||
@@ -17,13 +17,14 @@ | |||
17 | #ifndef _LOGD_COMMAND_H | 17 | #ifndef _LOGD_COMMAND_H |
18 | #define _LOGD_COMMAND_H | 18 | #define _LOGD_COMMAND_H |
19 | 19 | ||
20 | #include <sysutils/SocketClient.h> | ||
21 | #include <sysutils/FrameworkCommand.h> | 20 | #include <sysutils/FrameworkCommand.h> |
21 | #include <sysutils/SocketClient.h> | ||
22 | 22 | ||
23 | class LogCommand : public FrameworkCommand { | 23 | class LogCommand : public FrameworkCommand { |
24 | public: | 24 | public: |
25 | explicit LogCommand(const char *cmd); | 25 | explicit LogCommand(const char* cmd); |
26 | virtual ~LogCommand() {} | 26 | virtual ~LogCommand() { |
27 | } | ||
27 | }; | 28 | }; |
28 | 29 | ||
29 | #endif | 30 | #endif |
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp index f22407929..9ae95f996 100644 --- a/logd/LogKlog.cpp +++ b/logd/LogKlog.cpp | |||
@@ -25,25 +25,22 @@ | |||
25 | #include <sys/uio.h> | 25 | #include <sys/uio.h> |
26 | #include <syslog.h> | 26 | #include <syslog.h> |
27 | 27 | ||
28 | #include <private/android_logger.h> | ||
29 | #include <private/android_filesystem_config.h> | 28 | #include <private/android_filesystem_config.h> |
29 | #include <private/android_logger.h> | ||
30 | 30 | ||
31 | #include "LogBuffer.h" | 31 | #include "LogBuffer.h" |
32 | #include "LogKlog.h" | 32 | #include "LogKlog.h" |
33 | #include "LogReader.h" | 33 | #include "LogReader.h" |
34 | 34 | ||
35 | #define KMSG_PRIORITY(PRI) \ | 35 | #define KMSG_PRIORITY(PRI) \ |
36 | '<', \ | 36 | '<', '0' + (LOG_SYSLOG | (PRI)) / 10, '0' + (LOG_SYSLOG | (PRI)) % 10, '>' |
37 | '0' + (LOG_SYSLOG | (PRI)) / 10, \ | ||
38 | '0' + (LOG_SYSLOG | (PRI)) % 10, \ | ||
39 | '>' | ||
40 | 37 | ||
41 | static const char priority_message[] = { KMSG_PRIORITY(LOG_INFO), '\0' }; | 38 | static const char priority_message[] = { KMSG_PRIORITY(LOG_INFO), '\0' }; |
42 | 39 | ||
43 | // Parsing is hard | 40 | // Parsing is hard |
44 | 41 | ||
45 | // called if we see a '<', s is the next character, returns pointer after '>' | 42 | // called if we see a '<', s is the next character, returns pointer after '>' |
46 | static char *is_prio(char *s, size_t len) { | 43 | static char* is_prio(char* s, size_t len) { |
47 | if (!len || !isdigit(*s++)) { | 44 | if (!len || !isdigit(*s++)) { |
48 | return NULL; | 45 | return NULL; |
49 | } | 46 | } |
@@ -60,7 +57,7 @@ static char *is_prio(char *s, size_t len) { | |||
60 | } | 57 | } |
61 | 58 | ||
62 | // called if we see a '[', s is the next character, returns pointer after ']' | 59 | // called if we see a '[', s is the next character, returns pointer after ']' |
63 | static char *is_timestamp(char *s, size_t len) { | 60 | static char* is_timestamp(char* s, size_t len) { |
64 | while (len && (*s == ' ')) { | 61 | while (len && (*s == ' ')) { |
65 | ++s; | 62 | ++s; |
66 | --len; | 63 | --len; |
@@ -83,19 +80,20 @@ static char *is_timestamp(char *s, size_t len) { | |||
83 | } | 80 | } |
84 | 81 | ||
85 | // Like strtok_r with "\r\n" except that we look for log signatures (regex) | 82 | // Like strtok_r with "\r\n" except that we look for log signatures (regex) |
86 | // \(\(<[0-9]\{1,4\}>\)\([[] *[0-9]+[.][0-9]+[]] \)\{0,1\}\|[[] *[0-9]+[.][0-9]+[]] \) | 83 | // \(\(<[0-9]\{1,4\}>\)\([[] *[0-9]+[.][0-9]+[]] \)\{0,1\}\|[[] |
84 | // *[0-9]+[.][0-9]+[]] \) | ||
87 | // and split if we see a second one without a newline. | 85 | // and split if we see a second one without a newline. |
88 | // We allow nuls in content, monitoring the overall length and sub-length of | 86 | // We allow nuls in content, monitoring the overall length and sub-length of |
89 | // the discovered tokens. | 87 | // the discovered tokens. |
90 | 88 | ||
91 | #define SIGNATURE_MASK 0xF0 | 89 | #define SIGNATURE_MASK 0xF0 |
92 | // <digit> following ('0' to '9' masked with ~SIGNATURE_MASK) added to signature | 90 | // <digit> following ('0' to '9' masked with ~SIGNATURE_MASK) added to signature |
93 | #define LESS_THAN_SIG SIGNATURE_MASK | 91 | #define LESS_THAN_SIG SIGNATURE_MASK |
94 | #define OPEN_BRACKET_SIG ((SIGNATURE_MASK << 1) & SIGNATURE_MASK) | 92 | #define OPEN_BRACKET_SIG ((SIGNATURE_MASK << 1) & SIGNATURE_MASK) |
95 | // space is one more than <digit> of 9 | 93 | // space is one more than <digit> of 9 |
96 | #define OPEN_BRACKET_SPACE ((char)(OPEN_BRACKET_SIG | 10)) | 94 | #define OPEN_BRACKET_SPACE ((char)(OPEN_BRACKET_SIG | 10)) |
97 | 95 | ||
98 | char *log_strntok_r(char *s, size_t *len, char **last, size_t *sublen) { | 96 | char* log_strntok_r(char* s, size_t* len, char** last, size_t* sublen) { |
99 | *sublen = 0; | 97 | *sublen = 0; |
100 | if (!*len) { | 98 | if (!*len) { |
101 | return NULL; | 99 | return NULL; |
@@ -144,32 +142,24 @@ char *log_strntok_r(char *s, size_t *len, char **last, size_t *sublen) { | |||
144 | --*len; | 142 | --*len; |
145 | size_t adjust; | 143 | size_t adjust; |
146 | switch (c) { | 144 | switch (c) { |
147 | case '\r': | 145 | case '\r': |
148 | case '\n': | 146 | case '\n': |
149 | s[-1] = '\0'; | ||
150 | *last = s; | ||
151 | return tok; | ||
152 | |||
153 | case '<': | ||
154 | peek = is_prio(s, *len); | ||
155 | if (!peek) { | ||
156 | break; | ||
157 | } | ||
158 | if (s != (tok + 1)) { // not first? | ||
159 | s[-1] = '\0'; | 147 | s[-1] = '\0'; |
160 | *s &= ~SIGNATURE_MASK; | ||
161 | *s |= LESS_THAN_SIG; // signature for '<' | ||
162 | *last = s; | 148 | *last = s; |
163 | return tok; | 149 | return tok; |
164 | } | 150 | |
165 | adjust = peek - s; | 151 | case '<': |
166 | if (adjust > *len) { | 152 | peek = is_prio(s, *len); |
167 | adjust = *len; | 153 | if (!peek) { |
168 | } | 154 | break; |
169 | *sublen += adjust; | 155 | } |
170 | *len -= adjust; | 156 | if (s != (tok + 1)) { // not first? |
171 | s = peek; | 157 | s[-1] = '\0'; |
172 | if ((*s == '[') && ((peek = is_timestamp(s + 1, *len - 1)))) { | 158 | *s &= ~SIGNATURE_MASK; |
159 | *s |= LESS_THAN_SIG; // signature for '<' | ||
160 | *last = s; | ||
161 | return tok; | ||
162 | } | ||
173 | adjust = peek - s; | 163 | adjust = peek - s; |
174 | if (adjust > *len) { | 164 | if (adjust > *len) { |
175 | adjust = *len; | 165 | adjust = *len; |
@@ -177,33 +167,41 @@ char *log_strntok_r(char *s, size_t *len, char **last, size_t *sublen) { | |||
177 | *sublen += adjust; | 167 | *sublen += adjust; |
178 | *len -= adjust; | 168 | *len -= adjust; |
179 | s = peek; | 169 | s = peek; |
180 | } | 170 | if ((*s == '[') && ((peek = is_timestamp(s + 1, *len - 1)))) { |
181 | break; | 171 | adjust = peek - s; |
182 | 172 | if (adjust > *len) { | |
183 | case '[': | 173 | adjust = *len; |
184 | peek = is_timestamp(s, *len); | 174 | } |
185 | if (!peek) { | 175 | *sublen += adjust; |
176 | *len -= adjust; | ||
177 | s = peek; | ||
178 | } | ||
186 | break; | 179 | break; |
187 | } | 180 | |
188 | if (s != (tok + 1)) { // not first? | 181 | case '[': |
189 | s[-1] = '\0'; | 182 | peek = is_timestamp(s, *len); |
190 | if (*s == ' ') { | 183 | if (!peek) { |
191 | *s = OPEN_BRACKET_SPACE; | 184 | break; |
192 | } else { | ||
193 | *s &= ~SIGNATURE_MASK; | ||
194 | *s |= OPEN_BRACKET_SIG; // signature for '[' | ||
195 | } | 185 | } |
196 | *last = s; | 186 | if (s != (tok + 1)) { // not first? |
197 | return tok; | 187 | s[-1] = '\0'; |
198 | } | 188 | if (*s == ' ') { |
199 | adjust = peek - s; | 189 | *s = OPEN_BRACKET_SPACE; |
200 | if (adjust > *len) { | 190 | } else { |
201 | adjust = *len; | 191 | *s &= ~SIGNATURE_MASK; |
202 | } | 192 | *s |= OPEN_BRACKET_SIG; // signature for '[' |
203 | *sublen += adjust; | 193 | } |
204 | *len -= adjust; | 194 | *last = s; |
205 | s = peek; | 195 | return tok; |
206 | break; | 196 | } |
197 | adjust = peek - s; | ||
198 | if (adjust > *len) { | ||
199 | adjust = *len; | ||
200 | } | ||
201 | *sublen += adjust; | ||
202 | *len -= adjust; | ||
203 | s = peek; | ||
204 | break; | ||
207 | } | 205 | } |
208 | ++*sublen; | 206 | ++*sublen; |
209 | } | 207 | } |
@@ -215,22 +213,23 @@ log_time LogKlog::correction = | |||
215 | ? log_time::EPOCH | 213 | ? log_time::EPOCH |
216 | : (log_time(CLOCK_REALTIME) - log_time(CLOCK_MONOTONIC)); | 214 | : (log_time(CLOCK_REALTIME) - log_time(CLOCK_MONOTONIC)); |
217 | 215 | ||
218 | LogKlog::LogKlog(LogBuffer *buf, LogReader *reader, int fdWrite, int fdRead, bool auditd) : | 216 | LogKlog::LogKlog(LogBuffer* buf, LogReader* reader, int fdWrite, int fdRead, |
219 | SocketListener(fdRead, false), | 217 | bool auditd) |
220 | logbuf(buf), | 218 | : SocketListener(fdRead, false), |
221 | reader(reader), | 219 | logbuf(buf), |
222 | signature(CLOCK_MONOTONIC), | 220 | reader(reader), |
223 | initialized(false), | 221 | signature(CLOCK_MONOTONIC), |
224 | enableLogging(true), | 222 | initialized(false), |
225 | auditd(auditd) { | 223 | enableLogging(true), |
224 | auditd(auditd) { | ||
226 | static const char klogd_message[] = "%slogd.klogd: %" PRIu64 "\n"; | 225 | static const char klogd_message[] = "%slogd.klogd: %" PRIu64 "\n"; |
227 | char buffer[sizeof(priority_message) + sizeof(klogd_message) + 20 - 4]; | 226 | char buffer[sizeof(priority_message) + sizeof(klogd_message) + 20 - 4]; |
228 | snprintf(buffer, sizeof(buffer), klogd_message, priority_message, | 227 | snprintf(buffer, sizeof(buffer), klogd_message, priority_message, |
229 | signature.nsec()); | 228 | signature.nsec()); |
230 | write(fdWrite, buffer, strlen(buffer)); | 229 | write(fdWrite, buffer, strlen(buffer)); |
231 | } | 230 | } |
232 | 231 | ||
233 | bool LogKlog::onDataAvailable(SocketClient *cli) { | 232 | bool LogKlog::onDataAvailable(SocketClient* cli) { |
234 | if (!initialized) { | 233 | if (!initialized) { |
235 | prctl(PR_SET_NAME, "logd.klogd"); | 234 | prctl(PR_SET_NAME, "logd.klogd"); |
236 | initialized = true; | 235 | initialized = true; |
@@ -240,10 +239,11 @@ bool LogKlog::onDataAvailable(SocketClient *cli) { | |||
240 | char buffer[LOGGER_ENTRY_MAX_PAYLOAD]; | 239 | char buffer[LOGGER_ENTRY_MAX_PAYLOAD]; |
241 | size_t len = 0; | 240 | size_t len = 0; |
242 | 241 | ||
243 | for(;;) { | 242 | for (;;) { |
244 | ssize_t retval = 0; | 243 | ssize_t retval = 0; |
245 | if ((sizeof(buffer) - 1 - len) > 0) { | 244 | if ((sizeof(buffer) - 1 - len) > 0) { |
246 | retval = read(cli->getSocket(), buffer + len, sizeof(buffer) - 1 - len); | 245 | retval = |
246 | read(cli->getSocket(), buffer + len, sizeof(buffer) - 1 - len); | ||
247 | } | 247 | } |
248 | if ((retval == 0) && (len == 0)) { | 248 | if ((retval == 0) && (len == 0)) { |
249 | break; | 249 | break; |
@@ -253,12 +253,11 @@ bool LogKlog::onDataAvailable(SocketClient *cli) { | |||
253 | } | 253 | } |
254 | len += retval; | 254 | len += retval; |
255 | bool full = len == (sizeof(buffer) - 1); | 255 | bool full = len == (sizeof(buffer) - 1); |
256 | char *ep = buffer + len; | 256 | char* ep = buffer + len; |
257 | *ep = '\0'; | 257 | *ep = '\0'; |
258 | size_t sublen; | 258 | size_t sublen; |
259 | for(char *ptr = NULL, *tok = buffer; | 259 | for (char *ptr = NULL, *tok = buffer; |
260 | ((tok = log_strntok_r(tok, &len, &ptr, &sublen))); | 260 | ((tok = log_strntok_r(tok, &len, &ptr, &sublen))); tok = NULL) { |
261 | tok = NULL) { | ||
262 | if (((tok + sublen) >= ep) && (retval != 0) && full) { | 261 | if (((tok + sublen) >= ep) && (retval != 0) && full) { |
263 | memmove(buffer, tok, sublen); | 262 | memmove(buffer, tok, sublen); |
264 | len = sublen; | 263 | len = sublen; |
@@ -273,12 +272,10 @@ bool LogKlog::onDataAvailable(SocketClient *cli) { | |||
273 | return true; | 272 | return true; |
274 | } | 273 | } |
275 | 274 | ||
276 | 275 | void LogKlog::calculateCorrection(const log_time& monotonic, | |
277 | void LogKlog::calculateCorrection(const log_time &monotonic, | 276 | const char* real_string, size_t len) { |
278 | const char *real_string, | ||
279 | size_t len) { | ||
280 | log_time real; | 277 | log_time real; |
281 | const char *ep = real.strptime(real_string, "%Y-%m-%d %H:%M:%S.%09q UTC"); | 278 | const char* ep = real.strptime(real_string, "%Y-%m-%d %H:%M:%S.%09q UTC"); |
282 | if (!ep || (ep > &real_string[len]) || (real > log_time(CLOCK_REALTIME))) { | 279 | if (!ep || (ep > &real_string[len]) || (real > log_time(CLOCK_REALTIME))) { |
283 | return; | 280 | return; |
284 | } | 281 | } |
@@ -323,10 +320,9 @@ const char* android::strnstr(const char* s, size_t len, const char* needle) { | |||
323 | return s; | 320 | return s; |
324 | } | 321 | } |
325 | 322 | ||
326 | void LogKlog::sniffTime(log_time &now, | 323 | void LogKlog::sniffTime(log_time& now, const char** buf, size_t len, |
327 | const char **buf, size_t len, | ||
328 | bool reverse) { | 324 | bool reverse) { |
329 | const char *cp = now.strptime(*buf, "[ %s.%q]"); | 325 | const char* cp = now.strptime(*buf, "[ %s.%q]"); |
330 | if (cp && (cp >= &(*buf)[len])) { | 326 | if (cp && (cp >= &(*buf)[len])) { |
331 | cp = NULL; | 327 | cp = NULL; |
332 | } | 328 | } |
@@ -346,28 +342,28 @@ void LogKlog::sniffTime(log_time &now, | |||
346 | } | 342 | } |
347 | 343 | ||
348 | const char* b; | 344 | const char* b; |
349 | if (((b = android::strnstr(cp, len, suspendStr))) | 345 | if (((b = android::strnstr(cp, len, suspendStr))) && |
350 | && ((size_t)((b += sizeof(suspendStr) - 1) - cp) < len)) { | 346 | ((size_t)((b += sizeof(suspendStr) - 1) - cp) < len)) { |
351 | len -= b - cp; | 347 | len -= b - cp; |
352 | calculateCorrection(now, b, len); | 348 | calculateCorrection(now, b, len); |
353 | } else if (((b = android::strnstr(cp, len, resumeStr))) | 349 | } else if (((b = android::strnstr(cp, len, resumeStr))) && |
354 | && ((size_t)((b += sizeof(resumeStr) - 1) - cp) < len)) { | 350 | ((size_t)((b += sizeof(resumeStr) - 1) - cp) < len)) { |
355 | len -= b - cp; | 351 | len -= b - cp; |
356 | calculateCorrection(now, b, len); | 352 | calculateCorrection(now, b, len); |
357 | } else if (((b = android::strnstr(cp, len, healthd))) | 353 | } else if (((b = android::strnstr(cp, len, healthd))) && |
358 | && ((size_t)((b += sizeof(healthd) - 1) - cp) < len) | 354 | ((size_t)((b += sizeof(healthd) - 1) - cp) < len) && |
359 | && ((b = android::strnstr(b, len -= b - cp, battery))) | 355 | ((b = android::strnstr(b, len -= b - cp, battery))) && |
360 | && ((size_t)((b += sizeof(battery) - 1) - cp) < len)) { | 356 | ((size_t)((b += sizeof(battery) - 1) - cp) < len)) { |
361 | // NB: healthd is roughly 150us late, so we use it instead to | 357 | // NB: healthd is roughly 150us late, so we use it instead to |
362 | // trigger a check for ntp-induced or hardware clock drift. | 358 | // trigger a check for ntp-induced or hardware clock drift. |
363 | log_time real(CLOCK_REALTIME); | 359 | log_time real(CLOCK_REALTIME); |
364 | log_time mono(CLOCK_MONOTONIC); | 360 | log_time mono(CLOCK_MONOTONIC); |
365 | correction = (real < mono) ? log_time::EPOCH : (real - mono); | 361 | correction = (real < mono) ? log_time::EPOCH : (real - mono); |
366 | } else if (((b = android::strnstr(cp, len, suspendedStr))) | 362 | } else if (((b = android::strnstr(cp, len, suspendedStr))) && |
367 | && ((size_t)((b += sizeof(suspendStr) - 1) - cp) < len)) { | 363 | ((size_t)((b += sizeof(suspendStr) - 1) - cp) < len)) { |
368 | len -= b - cp; | 364 | len -= b - cp; |
369 | log_time real; | 365 | log_time real; |
370 | char *endp; | 366 | char* endp; |
371 | real.tv_sec = strtol(b, &endp, 10); | 367 | real.tv_sec = strtol(b, &endp, 10); |
372 | if ((*endp == '.') && ((size_t)(endp - b) < len)) { | 368 | if ((*endp == '.') && ((size_t)(endp - b) < len)) { |
373 | unsigned long multiplier = NS_PER_SEC; | 369 | unsigned long multiplier = NS_PER_SEC; |
@@ -398,14 +394,11 @@ void LogKlog::sniffTime(log_time &now, | |||
398 | } | 394 | } |
399 | } | 395 | } |
400 | 396 | ||
401 | pid_t LogKlog::sniffPid(const char **buf, size_t len) { | 397 | pid_t LogKlog::sniffPid(const char** buf, size_t len) { |
402 | const char *cp = *buf; | 398 | const char* cp = *buf; |
403 | // HTC kernels with modified printk "c0 1648 " | 399 | // HTC kernels with modified printk "c0 1648 " |
404 | if ((len > 9) && | 400 | if ((len > 9) && (cp[0] == 'c') && isdigit(cp[1]) && |
405 | (cp[0] == 'c') && | 401 | (isdigit(cp[2]) || (cp[2] == ' ')) && (cp[3] == ' ')) { |
406 | isdigit(cp[1]) && | ||
407 | (isdigit(cp[2]) || (cp[2] == ' ')) && | ||
408 | (cp[3] == ' ')) { | ||
409 | bool gotDigit = false; | 402 | bool gotDigit = false; |
410 | int i; | 403 | int i; |
411 | for (i = 4; i < 9; ++i) { | 404 | for (i = 4; i < 9; ++i) { |
@@ -419,7 +412,7 @@ pid_t LogKlog::sniffPid(const char **buf, size_t len) { | |||
419 | int pid = 0; | 412 | int pid = 0; |
420 | char dummy; | 413 | char dummy; |
421 | if (sscanf(cp + 4, "%d%c", &pid, &dummy) == 2) { | 414 | if (sscanf(cp + 4, "%d%c", &pid, &dummy) == 2) { |
422 | *buf = cp + 10; // skip-it-all | 415 | *buf = cp + 10; // skip-it-all |
423 | return pid; | 416 | return pid; |
424 | } | 417 | } |
425 | } | 418 | } |
@@ -432,7 +425,7 @@ pid_t LogKlog::sniffPid(const char **buf, size_t len) { | |||
432 | if (sscanf(cp, "[%d:%*[a-z_./0-9:A-Z]]%c", &pid, &dummy) == 2) { | 425 | if (sscanf(cp, "[%d:%*[a-z_./0-9:A-Z]]%c", &pid, &dummy) == 2) { |
433 | return pid; | 426 | return pid; |
434 | } | 427 | } |
435 | break; // Only the first one | 428 | break; // Only the first one |
436 | } | 429 | } |
437 | ++cp; | 430 | ++cp; |
438 | --len; | 431 | --len; |
@@ -441,12 +434,12 @@ pid_t LogKlog::sniffPid(const char **buf, size_t len) { | |||
441 | } | 434 | } |
442 | 435 | ||
443 | // kernel log prefix, convert to a kernel log priority number | 436 | // kernel log prefix, convert to a kernel log priority number |
444 | static int parseKernelPrio(const char **buf, size_t len) { | 437 | static int parseKernelPrio(const char** buf, size_t len) { |
445 | int pri = LOG_USER | LOG_INFO; | 438 | int pri = LOG_USER | LOG_INFO; |
446 | const char *cp = *buf; | 439 | const char* cp = *buf; |
447 | if (len && (*cp == '<')) { | 440 | if (len && (*cp == '<')) { |
448 | pri = 0; | 441 | pri = 0; |
449 | while(--len && isdigit(*++cp)) { | 442 | while (--len && isdigit(*++cp)) { |
450 | pri = (pri * 10) + *cp - '0'; | 443 | pri = (pri * 10) + *cp - '0'; |
451 | } | 444 | } |
452 | if (len && (*cp == '>')) { | 445 | if (len && (*cp == '>')) { |
@@ -502,42 +495,42 @@ void LogKlog::synchronize(const char* buf, size_t len) { | |||
502 | 495 | ||
503 | // Convert kernel log priority number into an Android Logger priority number | 496 | // Convert kernel log priority number into an Android Logger priority number |
504 | static int convertKernelPrioToAndroidPrio(int pri) { | 497 | static int convertKernelPrioToAndroidPrio(int pri) { |
505 | switch(pri & LOG_PRIMASK) { | 498 | switch (pri & LOG_PRIMASK) { |
506 | case LOG_EMERG: | 499 | case LOG_EMERG: |
507 | // FALLTHRU | 500 | // FALLTHRU |
508 | case LOG_ALERT: | 501 | case LOG_ALERT: |
509 | // FALLTHRU | 502 | // FALLTHRU |
510 | case LOG_CRIT: | 503 | case LOG_CRIT: |
511 | return ANDROID_LOG_FATAL; | 504 | return ANDROID_LOG_FATAL; |
512 | 505 | ||
513 | case LOG_ERR: | 506 | case LOG_ERR: |
514 | return ANDROID_LOG_ERROR; | 507 | return ANDROID_LOG_ERROR; |
515 | 508 | ||
516 | case LOG_WARNING: | 509 | case LOG_WARNING: |
517 | return ANDROID_LOG_WARN; | 510 | return ANDROID_LOG_WARN; |
518 | 511 | ||
519 | default: | 512 | default: |
520 | // FALLTHRU | 513 | // FALLTHRU |
521 | case LOG_NOTICE: | 514 | case LOG_NOTICE: |
522 | // FALLTHRU | 515 | // FALLTHRU |
523 | case LOG_INFO: | 516 | case LOG_INFO: |
524 | break; | 517 | break; |
525 | 518 | ||
526 | case LOG_DEBUG: | 519 | case LOG_DEBUG: |
527 | return ANDROID_LOG_DEBUG; | 520 | return ANDROID_LOG_DEBUG; |
528 | } | 521 | } |
529 | 522 | ||
530 | return ANDROID_LOG_INFO; | 523 | return ANDROID_LOG_INFO; |
531 | } | 524 | } |
532 | 525 | ||
533 | static const char *strnrchr(const char *s, size_t len, char c) { | 526 | static const char* strnrchr(const char* s, size_t len, char c) { |
534 | const char *save = NULL; | 527 | const char* save = NULL; |
535 | for (;len; ++s, len--) { | 528 | for (; len; ++s, len--) { |
536 | if (*s == c) { | 529 | if (*s == c) { |
537 | save = s; | 530 | save = s; |
531 | } | ||
538 | } | 532 | } |
539 | } | 533 | return save; |
540 | return save; | ||
541 | } | 534 | } |
542 | 535 | ||
543 | // | 536 | // |
@@ -621,38 +614,41 @@ int LogKlog::log(const char* buf, size_t len) { | |||
621 | while ((p < &buf[len]) && (isspace(*p) || !*p)) { | 614 | while ((p < &buf[len]) && (isspace(*p) || !*p)) { |
622 | ++p; | 615 | ++p; |
623 | } | 616 | } |
624 | if (p >= &buf[len]) { // timestamp, no content | 617 | if (p >= &buf[len]) { // timestamp, no content |
625 | return 0; | 618 | return 0; |
626 | } | 619 | } |
627 | start = p; | 620 | start = p; |
628 | const char *tag = ""; | 621 | const char* tag = ""; |
629 | const char *etag = tag; | 622 | const char* etag = tag; |
630 | size_t taglen = len - (p - buf); | 623 | size_t taglen = len - (p - buf); |
631 | const char *bt = p; | 624 | const char* bt = p; |
632 | 625 | ||
633 | static const char infoBrace[] = "[INFO]"; | 626 | static const char infoBrace[] = "[INFO]"; |
634 | static const size_t infoBraceLen = strlen(infoBrace); | 627 | static const size_t infoBraceLen = strlen(infoBrace); |
635 | if ((taglen >= infoBraceLen) && !fastcmp<strncmp>(p, infoBrace, infoBraceLen)) { | 628 | if ((taglen >= infoBraceLen) && |
629 | !fastcmp<strncmp>(p, infoBrace, infoBraceLen)) { | ||
636 | // <PRI>[<TIME>] "[INFO]"<tag> ":" message | 630 | // <PRI>[<TIME>] "[INFO]"<tag> ":" message |
637 | bt = p + infoBraceLen; | 631 | bt = p + infoBraceLen; |
638 | taglen -= infoBraceLen; | 632 | taglen -= infoBraceLen; |
639 | } | 633 | } |
640 | 634 | ||
641 | const char *et; | 635 | const char* et; |
642 | for (et = bt; taglen && *et && (*et != ':') && !isspace(*et); ++et, --taglen) { | 636 | for (et = bt; taglen && *et && (*et != ':') && !isspace(*et); |
643 | // skip ':' within [ ... ] | 637 | ++et, --taglen) { |
644 | if (*et == '[') { | 638 | // skip ':' within [ ... ] |
645 | while (taglen && *et && *et != ']') { | 639 | if (*et == '[') { |
646 | ++et; | 640 | while (taglen && *et && *et != ']') { |
647 | --taglen; | 641 | ++et; |
648 | } | 642 | --taglen; |
649 | if (!taglen) { | 643 | } |
650 | break; | 644 | if (!taglen) { |
651 | } | 645 | break; |
652 | } | 646 | } |
647 | } | ||
648 | } | ||
649 | const char* cp; | ||
650 | for (cp = et; taglen && isspace(*cp); ++cp, --taglen) { | ||
653 | } | 651 | } |
654 | const char *cp; | ||
655 | for (cp = et; taglen && isspace(*cp); ++cp, --taglen); | ||
656 | 652 | ||
657 | // Validate tag | 653 | // Validate tag |
658 | size_t size = et - bt; | 654 | size_t size = et - bt; |
@@ -667,18 +663,20 @@ int LogKlog::log(const char* buf, size_t len) { | |||
667 | p = cp + 1; | 663 | p = cp + 1; |
668 | } else if ((taglen > size) && (tolower(*bt) == tolower(*cp))) { | 664 | } else if ((taglen > size) && (tolower(*bt) == tolower(*cp))) { |
669 | // clean up any tag stutter | 665 | // clean up any tag stutter |
670 | if (!fastcmp<strncasecmp>(bt + 1, cp + 1, size - 1)) { // no match | 666 | if (!fastcmp<strncasecmp>(bt + 1, cp + 1, size - 1)) { // no match |
671 | // <PRI>[<TIME>] <tag> <tag> : message | 667 | // <PRI>[<TIME>] <tag> <tag> : message |
672 | // <PRI>[<TIME>] <tag> <tag>: message | 668 | // <PRI>[<TIME>] <tag> <tag>: message |
673 | // <PRI>[<TIME>] <tag> '<tag>.<num>' : message | 669 | // <PRI>[<TIME>] <tag> '<tag>.<num>' : message |
674 | // <PRI>[<TIME>] <tag> '<tag><num>' : message | 670 | // <PRI>[<TIME>] <tag> '<tag><num>' : message |
675 | // <PRI>[<TIME>] <tag> '<tag><stuff>' : message | 671 | // <PRI>[<TIME>] <tag> '<tag><stuff>' : message |
676 | const char *b = cp; | 672 | const char* b = cp; |
677 | cp += size; | 673 | cp += size; |
678 | taglen -= size; | 674 | taglen -= size; |
679 | while (--taglen && !isspace(*++cp) && (*cp != ':')); | 675 | while (--taglen && !isspace(*++cp) && (*cp != ':')) { |
680 | const char *e; | 676 | } |
681 | for (e = cp; taglen && isspace(*cp); ++cp, --taglen); | 677 | const char* e; |
678 | for (e = cp; taglen && isspace(*cp); ++cp, --taglen) { | ||
679 | } | ||
682 | if (taglen && (*cp == ':')) { | 680 | if (taglen && (*cp == ':')) { |
683 | tag = b; | 681 | tag = b; |
684 | etag = e; | 682 | etag = e; |
@@ -689,15 +687,17 @@ int LogKlog::log(const char* buf, size_t len) { | |||
689 | static const char host[] = "_host"; | 687 | static const char host[] = "_host"; |
690 | static const size_t hostlen = strlen(host); | 688 | static const size_t hostlen = strlen(host); |
691 | if ((size > hostlen) && | 689 | if ((size > hostlen) && |
692 | !fastcmp<strncmp>(bt + size - hostlen, host, hostlen) && | 690 | !fastcmp<strncmp>(bt + size - hostlen, host, hostlen) && |
693 | !fastcmp<strncmp>(bt + 1, cp + 1, size - hostlen - 1)) { | 691 | !fastcmp<strncmp>(bt + 1, cp + 1, size - hostlen - 1)) { |
694 | const char *b = cp; | 692 | const char* b = cp; |
695 | cp += size - hostlen; | 693 | cp += size - hostlen; |
696 | taglen -= size - hostlen; | 694 | taglen -= size - hostlen; |
697 | if (*cp == '.') { | 695 | if (*cp == '.') { |
698 | while (--taglen && !isspace(*++cp) && (*cp != ':')); | 696 | while (--taglen && !isspace(*++cp) && (*cp != ':')) { |
699 | const char *e; | 697 | } |
700 | for (e = cp; taglen && isspace(*cp); ++cp, --taglen); | 698 | const char* e; |
699 | for (e = cp; taglen && isspace(*cp); ++cp, --taglen) { | ||
700 | } | ||
701 | if (taglen && (*cp == ':')) { | 701 | if (taglen && (*cp == ':')) { |
702 | tag = b; | 702 | tag = b; |
703 | etag = e; | 703 | etag = e; |
@@ -709,10 +709,13 @@ int LogKlog::log(const char* buf, size_t len) { | |||
709 | } | 709 | } |
710 | } | 710 | } |
711 | } else { | 711 | } else { |
712 | // <PRI>[<TIME>] <tag> <stuff>' : message | 712 | // <PRI>[<TIME>] <tag> <stuff>' : message |
713 | twoWord: while (--taglen && !isspace(*++cp) && (*cp != ':')); | 713 | twoWord: |
714 | const char *e; | 714 | while (--taglen && !isspace(*++cp) && (*cp != ':')) { |
715 | for (e = cp; taglen && isspace(*cp); ++cp, --taglen); | 715 | } |
716 | const char* e; | ||
717 | for (e = cp; taglen && isspace(*cp); ++cp, --taglen) { | ||
718 | } | ||
716 | // Two words | 719 | // Two words |
717 | if (taglen && (*cp == ':')) { | 720 | if (taglen && (*cp == ':')) { |
718 | tag = bt; | 721 | tag = bt; |
@@ -720,7 +723,7 @@ twoWord: while (--taglen && !isspace(*++cp) && (*cp != ':')); | |||
720 | p = cp + 1; | 723 | p = cp + 1; |
721 | } | 724 | } |
722 | } | 725 | } |
723 | } // else no tag | 726 | } // else no tag |
724 | 727 | ||
725 | static const char cpu[] = "CPU"; | 728 | static const char cpu[] = "CPU"; |
726 | static const size_t cpuLen = strlen(cpu); | 729 | static const size_t cpuLen = strlen(cpu); |
@@ -732,16 +735,17 @@ twoWord: while (--taglen && !isspace(*++cp) && (*cp != ':')); | |||
732 | static const size_t infoLen = strlen(info); | 735 | static const size_t infoLen = strlen(info); |
733 | 736 | ||
734 | size = etag - tag; | 737 | size = etag - tag; |
735 | if ((size <= 1) | 738 | if ((size <= 1) || |
736 | // register names like x9 | 739 | // register names like x9 |
737 | || ((size == 2) && (isdigit(tag[0]) || isdigit(tag[1]))) | 740 | ((size == 2) && (isdigit(tag[0]) || isdigit(tag[1]))) || |
738 | // register names like x18 but not driver names like en0 | 741 | // register names like x18 but not driver names like en0 |
739 | || ((size == 3) && (isdigit(tag[1]) && isdigit(tag[2]))) | 742 | ((size == 3) && (isdigit(tag[1]) && isdigit(tag[2]))) || |
740 | // blacklist | 743 | // blacklist |
741 | || ((size == cpuLen) && !fastcmp<strncmp>(tag, cpu, cpuLen)) | 744 | ((size == cpuLen) && !fastcmp<strncmp>(tag, cpu, cpuLen)) || |
742 | || ((size == warningLen) && !fastcmp<strncasecmp>(tag, warning, warningLen)) | 745 | ((size == warningLen) && |
743 | || ((size == errorLen) && !fastcmp<strncasecmp>(tag, error, errorLen)) | 746 | !fastcmp<strncasecmp>(tag, warning, warningLen)) || |
744 | || ((size == infoLen) && !fastcmp<strncasecmp>(tag, info, infoLen))) { | 747 | ((size == errorLen) && !fastcmp<strncasecmp>(tag, error, errorLen)) || |
748 | ((size == infoLen) && !fastcmp<strncasecmp>(tag, info, infoLen))) { | ||
745 | p = start; | 749 | p = start; |
746 | etag = tag = ""; | 750 | etag = tag = ""; |
747 | } | 751 | } |
@@ -750,7 +754,7 @@ twoWord: while (--taglen && !isspace(*++cp) && (*cp != ':')); | |||
750 | // eg: [143:healthd]healthd -> [143:healthd] | 754 | // eg: [143:healthd]healthd -> [143:healthd] |
751 | taglen = etag - tag; | 755 | taglen = etag - tag; |
752 | // Mediatek-special printk induced stutter | 756 | // Mediatek-special printk induced stutter |
753 | const char *mp = strnrchr(tag, ']', taglen); | 757 | const char* mp = strnrchr(tag, ']', taglen); |
754 | if (mp && (++mp < etag)) { | 758 | if (mp && (++mp < etag)) { |
755 | size_t s = etag - mp; | 759 | size_t s = etag - mp; |
756 | if (((s + s) < taglen) && !fastcmp<memcmp>(mp, mp - 1 - s, s)) { | 760 | if (((s + s) < taglen) && !fastcmp<memcmp>(mp, mp - 1 - s, s)) { |
@@ -767,7 +771,7 @@ twoWord: while (--taglen && !isspace(*++cp) && (*cp != ':')); | |||
767 | } | 771 | } |
768 | // truncate trailing space or nuls | 772 | // truncate trailing space or nuls |
769 | size_t b = len - (p - buf); | 773 | size_t b = len - (p - buf); |
770 | while (b && (isspace(p[b-1]) || !p[b-1])) { | 774 | while (b && (isspace(p[b - 1]) || !p[b - 1])) { |
771 | --b; | 775 | --b; |
772 | } | 776 | } |
773 | // trick ... allow tag with empty content to be logged. log() drops empty | 777 | // trick ... allow tag with empty content to be logged. log() drops empty |
@@ -796,7 +800,7 @@ twoWord: while (--taglen && !isspace(*++cp) && (*cp != ':')); | |||
796 | // truncating length argument to logbuf->log() below. Gain is protection | 800 | // truncating length argument to logbuf->log() below. Gain is protection |
797 | // of stack sanity and speedup, loss is truncated long-line content. | 801 | // of stack sanity and speedup, loss is truncated long-line content. |
798 | char newstr[n]; | 802 | char newstr[n]; |
799 | char *np = newstr; | 803 | char* np = newstr; |
800 | 804 | ||
801 | // Convert priority into single-byte Android logger priority | 805 | // Convert priority into single-byte Android logger priority |
802 | *np = convertKernelPrioToAndroidPrio(pri); | 806 | *np = convertKernelPrioToAndroidPrio(pri); |
@@ -828,10 +832,10 @@ twoWord: while (--taglen && !isspace(*++cp) && (*cp != ':')); | |||
828 | unsigned abs0 = (diff0 < 0) ? -diff0 : diff0; | 832 | unsigned abs0 = (diff0 < 0) ? -diff0 : diff0; |
829 | int diff1 = (vote_time[1] - vote_time[2]) / near_seconds; | 833 | int diff1 = (vote_time[1] - vote_time[2]) / near_seconds; |
830 | unsigned abs1 = (diff1 < 0) ? -diff1 : diff1; | 834 | unsigned abs1 = (diff1 < 0) ? -diff1 : diff1; |
831 | if ((abs1 <= 1) && // last two were in agreement on timezone | 835 | if ((abs1 <= 1) && // last two were in agreement on timezone |
832 | ((abs0 + 1) % (timezones_seconds / near_seconds)) <= 2) { | 836 | ((abs0 + 1) % (timezones_seconds / near_seconds)) <= 2) { |
833 | abs0 = (abs0 + 1) / (timezones_seconds / near_seconds) * | 837 | abs0 = (abs0 + 1) / (timezones_seconds / near_seconds) * |
834 | timezones_seconds; | 838 | timezones_seconds; |
835 | now.tv_sec -= (diff0 < 0) ? -abs0 : abs0; | 839 | now.tv_sec -= (diff0 < 0) ? -abs0 : abs0; |
836 | } | 840 | } |
837 | } | 841 | } |
@@ -839,7 +843,7 @@ twoWord: while (--taglen && !isspace(*++cp) && (*cp != ':')); | |||
839 | 843 | ||
840 | // Log message | 844 | // Log message |
841 | int rc = logbuf->log(LOG_ID_KERNEL, now, uid, pid, tid, newstr, | 845 | int rc = logbuf->log(LOG_ID_KERNEL, now, uid, pid, tid, newstr, |
842 | (unsigned short) n); | 846 | (unsigned short)n); |
843 | 847 | ||
844 | // notify readers | 848 | // notify readers |
845 | if (!rc) { | 849 | if (!rc) { |
diff --git a/logd/LogKlog.h b/logd/LogKlog.h index 11d88af18..976afc8af 100644 --- a/logd/LogKlog.h +++ b/logd/LogKlog.h | |||
@@ -20,14 +20,14 @@ | |||
20 | #include <private/android_logger.h> | 20 | #include <private/android_logger.h> |
21 | #include <sysutils/SocketListener.h> | 21 | #include <sysutils/SocketListener.h> |
22 | 22 | ||
23 | char *log_strntok_r(char *s, size_t *len, char **saveptr, size_t *sublen); | 23 | char* log_strntok_r(char* s, size_t* len, char** saveptr, size_t* sublen); |
24 | 24 | ||
25 | class LogBuffer; | 25 | class LogBuffer; |
26 | class LogReader; | 26 | class LogReader; |
27 | 27 | ||
28 | class LogKlog : public SocketListener { | 28 | class LogKlog : public SocketListener { |
29 | LogBuffer *logbuf; | 29 | LogBuffer* logbuf; |
30 | LogReader *reader; | 30 | LogReader* reader; |
31 | const log_time signature; | 31 | const log_time signature; |
32 | // Set once thread is started, separates KLOG_ACTION_READ_ALL | 32 | // Set once thread is started, separates KLOG_ACTION_READ_ALL |
33 | // and KLOG_ACTION_READ phases. | 33 | // and KLOG_ACTION_READ phases. |
@@ -40,22 +40,28 @@ class LogKlog : public SocketListener { | |||
40 | 40 | ||
41 | static log_time correction; | 41 | static log_time correction; |
42 | 42 | ||
43 | public: | 43 | public: |
44 | LogKlog(LogBuffer *buf, LogReader *reader, int fdWrite, int fdRead, bool auditd); | 44 | LogKlog(LogBuffer* buf, LogReader* reader, int fdWrite, int fdRead, |
45 | int log(const char *buf, size_t len); | 45 | bool auditd); |
46 | void synchronize(const char *buf, size_t len); | 46 | int log(const char* buf, size_t len); |
47 | void synchronize(const char* buf, size_t len); | ||
47 | 48 | ||
48 | bool isMonotonic() { return logbuf->isMonotonic(); } | 49 | bool isMonotonic() { |
49 | static void convertMonotonicToReal(log_time &real) { real += correction; } | 50 | return logbuf->isMonotonic(); |
50 | static void convertRealToMonotonic(log_time &real) { real -= correction; } | 51 | } |
51 | 52 | static void convertMonotonicToReal(log_time& real) { | |
52 | protected: | 53 | real += correction; |
53 | void sniffTime(log_time &now, const char **buf, size_t len, bool reverse); | 54 | } |
54 | pid_t sniffPid(const char **buf, size_t len); | 55 | static void convertRealToMonotonic(log_time& real) { |
55 | void calculateCorrection(const log_time &monotonic, | 56 | real -= correction; |
56 | const char *real_string, size_t len); | 57 | } |
57 | virtual bool onDataAvailable(SocketClient *cli); | ||
58 | 58 | ||
59 | protected: | ||
60 | void sniffTime(log_time& now, const char** buf, size_t len, bool reverse); | ||
61 | pid_t sniffPid(const char** buf, size_t len); | ||
62 | void calculateCorrection(const log_time& monotonic, const char* real_string, | ||
63 | size_t len); | ||
64 | virtual bool onDataAvailable(SocketClient* cli); | ||
59 | }; | 65 | }; |
60 | 66 | ||
61 | #endif | 67 | #endif |
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp index 4a30e6dac..dadc75f4c 100644 --- a/logd/LogListener.cpp +++ b/logd/LogListener.cpp | |||
@@ -30,32 +30,24 @@ | |||
30 | #include "LogListener.h" | 30 | #include "LogListener.h" |
31 | #include "LogUtils.h" | 31 | #include "LogUtils.h" |
32 | 32 | ||
33 | LogListener::LogListener(LogBuffer *buf, LogReader *reader) : | 33 | LogListener::LogListener(LogBuffer* buf, LogReader* reader) |
34 | SocketListener(getLogSocket(), false), | 34 | : SocketListener(getLogSocket(), false), logbuf(buf), reader(reader) { |
35 | logbuf(buf), | ||
36 | reader(reader) { | ||
37 | } | 35 | } |
38 | 36 | ||
39 | bool LogListener::onDataAvailable(SocketClient *cli) { | 37 | bool LogListener::onDataAvailable(SocketClient* cli) { |
40 | static bool name_set; | 38 | static bool name_set; |
41 | if (!name_set) { | 39 | if (!name_set) { |
42 | prctl(PR_SET_NAME, "logd.writer"); | 40 | prctl(PR_SET_NAME, "logd.writer"); |
43 | name_set = true; | 41 | name_set = true; |
44 | } | 42 | } |
45 | 43 | ||
46 | char buffer[sizeof_log_id_t + sizeof(uint16_t) + sizeof(log_time) | 44 | char buffer[sizeof_log_id_t + sizeof(uint16_t) + sizeof(log_time) + |
47 | + LOGGER_ENTRY_MAX_PAYLOAD]; | 45 | LOGGER_ENTRY_MAX_PAYLOAD]; |
48 | struct iovec iov = { buffer, sizeof(buffer) }; | 46 | struct iovec iov = { buffer, sizeof(buffer) }; |
49 | 47 | ||
50 | alignas(4) char control[CMSG_SPACE(sizeof(struct ucred))]; | 48 | alignas(4) char control[CMSG_SPACE(sizeof(struct ucred))]; |
51 | struct msghdr hdr = { | 49 | struct msghdr hdr = { |
52 | NULL, | 50 | NULL, 0, &iov, 1, control, sizeof(control), 0, |
53 | 0, | ||
54 | &iov, | ||
55 | 1, | ||
56 | control, | ||
57 | sizeof(control), | ||
58 | 0, | ||
59 | }; | 51 | }; |
60 | 52 | ||
61 | int socket = cli->getSocket(); | 53 | int socket = cli->getSocket(); |
@@ -68,13 +60,13 @@ bool LogListener::onDataAvailable(SocketClient *cli) { | |||
68 | return false; | 60 | return false; |
69 | } | 61 | } |
70 | 62 | ||
71 | struct ucred *cred = NULL; | 63 | struct ucred* cred = NULL; |
72 | 64 | ||
73 | struct cmsghdr *cmsg = CMSG_FIRSTHDR(&hdr); | 65 | struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr); |
74 | while (cmsg != NULL) { | 66 | while (cmsg != NULL) { |
75 | if (cmsg->cmsg_level == SOL_SOCKET | 67 | if (cmsg->cmsg_level == SOL_SOCKET && |
76 | && cmsg->cmsg_type == SCM_CREDENTIALS) { | 68 | cmsg->cmsg_type == SCM_CREDENTIALS) { |
77 | cred = (struct ucred *)CMSG_DATA(cmsg); | 69 | cred = (struct ucred*)CMSG_DATA(cmsg); |
78 | break; | 70 | break; |
79 | } | 71 | } |
80 | cmsg = CMSG_NXTHDR(&hdr, cmsg); | 72 | cmsg = CMSG_NXTHDR(&hdr, cmsg); |
@@ -91,26 +83,29 @@ bool LogListener::onDataAvailable(SocketClient *cli) { | |||
91 | return false; | 83 | return false; |
92 | } | 84 | } |
93 | 85 | ||
94 | android_log_header_t *header = reinterpret_cast<android_log_header_t *>(buffer); | 86 | android_log_header_t* header = |
95 | if (/* header->id < LOG_ID_MIN || */ header->id >= LOG_ID_MAX || header->id == LOG_ID_KERNEL) { | 87 | reinterpret_cast<android_log_header_t*>(buffer); |
88 | if (/* header->id < LOG_ID_MIN || */ header->id >= LOG_ID_MAX || | ||
89 | header->id == LOG_ID_KERNEL) { | ||
96 | return false; | 90 | return false; |
97 | } | 91 | } |
98 | 92 | ||
99 | if ((header->id == LOG_ID_SECURITY) && | 93 | if ((header->id == LOG_ID_SECURITY) && |
100 | (!__android_log_security() || | 94 | (!__android_log_security() || |
101 | !clientHasLogCredentials(cred->uid, cred->gid, cred->pid))) { | 95 | !clientHasLogCredentials(cred->uid, cred->gid, cred->pid))) { |
102 | return false; | 96 | return false; |
103 | } | 97 | } |
104 | 98 | ||
105 | char *msg = ((char *)buffer) + sizeof(android_log_header_t); | 99 | char* msg = ((char*)buffer) + sizeof(android_log_header_t); |
106 | n -= sizeof(android_log_header_t); | 100 | n -= sizeof(android_log_header_t); |
107 | 101 | ||
108 | // NB: hdr.msg_flags & MSG_TRUNC is not tested, silently passing a | 102 | // NB: hdr.msg_flags & MSG_TRUNC is not tested, silently passing a |
109 | // truncated message to the logs. | 103 | // truncated message to the logs. |
110 | 104 | ||
111 | if (logbuf->log((log_id_t)header->id, header->realtime, | 105 | if (logbuf->log((log_id_t)header->id, header->realtime, cred->uid, |
112 | cred->uid, cred->pid, header->tid, msg, | 106 | cred->pid, header->tid, msg, |
113 | ((size_t) n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX) >= 0) { | 107 | ((size_t)n <= USHRT_MAX) ? (unsigned short)n : USHRT_MAX) >= |
108 | 0) { | ||
114 | reader->notifyNewLog(); | 109 | reader->notifyNewLog(); |
115 | } | 110 | } |
116 | 111 | ||
@@ -122,9 +117,8 @@ int LogListener::getLogSocket() { | |||
122 | int sock = android_get_control_socket(socketName); | 117 | int sock = android_get_control_socket(socketName); |
123 | 118 | ||
124 | if (sock < 0) { | 119 | if (sock < 0) { |
125 | sock = socket_local_server(socketName, | 120 | sock = socket_local_server( |
126 | ANDROID_SOCKET_NAMESPACE_RESERVED, | 121 | socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_DGRAM); |
127 | SOCK_DGRAM); | ||
128 | } | 122 | } |
129 | 123 | ||
130 | int on = 1; | 124 | int on = 1; |
diff --git a/logd/LogListener.h b/logd/LogListener.h index 7099e1325..2973b8bd3 100644 --- a/logd/LogListener.h +++ b/logd/LogListener.h | |||
@@ -21,16 +21,16 @@ | |||
21 | #include "LogReader.h" | 21 | #include "LogReader.h" |
22 | 22 | ||
23 | class LogListener : public SocketListener { | 23 | class LogListener : public SocketListener { |
24 | LogBuffer *logbuf; | 24 | LogBuffer* logbuf; |
25 | LogReader *reader; | 25 | LogReader* reader; |
26 | 26 | ||
27 | public: | 27 | public: |
28 | LogListener(LogBuffer *buf, LogReader *reader); | 28 | LogListener(LogBuffer* buf, LogReader* reader); |
29 | 29 | ||
30 | protected: | 30 | protected: |
31 | virtual bool onDataAvailable(SocketClient *cli); | 31 | virtual bool onDataAvailable(SocketClient* cli); |
32 | 32 | ||
33 | private: | 33 | private: |
34 | static int getLogSocket(); | 34 | static int getLogSocket(); |
35 | }; | 35 | }; |
36 | 36 | ||
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp index 1b50b4ef2..76f5798c6 100644 --- a/logd/LogReader.cpp +++ b/logd/LogReader.cpp | |||
@@ -29,9 +29,8 @@ | |||
29 | #include "LogReader.h" | 29 | #include "LogReader.h" |
30 | #include "LogUtils.h" | 30 | #include "LogUtils.h" |
31 | 31 | ||
32 | LogReader::LogReader(LogBuffer *logbuf) : | 32 | LogReader::LogReader(LogBuffer* logbuf) |
33 | SocketListener(getLogSocket(), true), | 33 | : SocketListener(getLogSocket(), true), mLogbuf(*logbuf) { |
34 | mLogbuf(*logbuf) { | ||
35 | } | 34 | } |
36 | 35 | ||
37 | // When we are notified a new log entry is available, inform | 36 | // When we are notified a new log entry is available, inform |
@@ -41,7 +40,7 @@ void LogReader::notifyNewLog() { | |||
41 | runOnEachSocket(&command); | 40 | runOnEachSocket(&command); |
42 | } | 41 | } |
43 | 42 | ||
44 | bool LogReader::onDataAvailable(SocketClient *cli) { | 43 | bool LogReader::onDataAvailable(SocketClient* cli) { |
45 | static bool name_set; | 44 | static bool name_set; |
46 | if (!name_set) { | 45 | if (!name_set) { |
47 | prctl(PR_SET_NAME, "logd.reader"); | 46 | prctl(PR_SET_NAME, "logd.reader"); |
@@ -59,7 +58,7 @@ bool LogReader::onDataAvailable(SocketClient *cli) { | |||
59 | 58 | ||
60 | unsigned long tail = 0; | 59 | unsigned long tail = 0; |
61 | static const char _tail[] = " tail="; | 60 | static const char _tail[] = " tail="; |
62 | char *cp = strstr(buffer, _tail); | 61 | char* cp = strstr(buffer, _tail); |
63 | if (cp) { | 62 | if (cp) { |
64 | tail = atol(cp + sizeof(_tail) - 1); | 63 | tail = atol(cp + sizeof(_tail) - 1); |
65 | } | 64 | } |
@@ -124,32 +123,33 @@ bool LogReader::onDataAvailable(SocketClient *cli) { | |||
124 | const pid_t mPid; | 123 | const pid_t mPid; |
125 | const unsigned mLogMask; | 124 | const unsigned mLogMask; |
126 | bool startTimeSet; | 125 | bool startTimeSet; |
127 | log_time &start; | 126 | log_time& start; |
128 | uint64_t &sequence; | 127 | uint64_t& sequence; |
129 | uint64_t last; | 128 | uint64_t last; |
130 | bool isMonotonic; | 129 | bool isMonotonic; |
131 | 130 | ||
132 | public: | 131 | public: |
133 | LogFindStart(unsigned logMask, pid_t pid, log_time &start, uint64_t &sequence, bool isMonotonic) : | 132 | LogFindStart(unsigned logMask, pid_t pid, log_time& start, |
134 | mPid(pid), | 133 | uint64_t& sequence, bool isMonotonic) |
135 | mLogMask(logMask), | 134 | : mPid(pid), |
136 | startTimeSet(false), | 135 | mLogMask(logMask), |
137 | start(start), | 136 | startTimeSet(false), |
138 | sequence(sequence), | 137 | start(start), |
139 | last(sequence), | 138 | sequence(sequence), |
140 | isMonotonic(isMonotonic) { | 139 | last(sequence), |
140 | isMonotonic(isMonotonic) { | ||
141 | } | 141 | } |
142 | 142 | ||
143 | static int callback(const LogBufferElement *element, void *obj) { | 143 | static int callback(const LogBufferElement* element, void* obj) { |
144 | LogFindStart *me = reinterpret_cast<LogFindStart *>(obj); | 144 | LogFindStart* me = reinterpret_cast<LogFindStart*>(obj); |
145 | if ((!me->mPid || (me->mPid == element->getPid())) | 145 | if ((!me->mPid || (me->mPid == element->getPid())) && |
146 | && (me->mLogMask & (1 << element->getLogId()))) { | 146 | (me->mLogMask & (1 << element->getLogId()))) { |
147 | if (me->start == element->getRealTime()) { | 147 | if (me->start == element->getRealTime()) { |
148 | me->sequence = element->getSequence(); | 148 | me->sequence = element->getSequence(); |
149 | me->startTimeSet = true; | 149 | me->startTimeSet = true; |
150 | return -1; | 150 | return -1; |
151 | } else if (!me->isMonotonic || | 151 | } else if (!me->isMonotonic || |
152 | android::isMonotonic(element->getRealTime())) { | 152 | android::isMonotonic(element->getRealTime())) { |
153 | if (me->start < element->getRealTime()) { | 153 | if (me->start < element->getRealTime()) { |
154 | me->sequence = me->last; | 154 | me->sequence = me->last; |
155 | me->startTimeSet = true; | 155 | me->startTimeSet = true; |
@@ -163,7 +163,9 @@ bool LogReader::onDataAvailable(SocketClient *cli) { | |||
163 | return false; | 163 | return false; |
164 | } | 164 | } |
165 | 165 | ||
166 | bool found() { return startTimeSet; } | 166 | bool found() { |
167 | return startTimeSet; | ||
168 | } | ||
167 | } logFindStart(logMask, pid, start, sequence, | 169 | } logFindStart(logMask, pid, start, sequence, |
168 | logbuf().isMonotonic() && android::isMonotonic(start)); | 170 | logbuf().isMonotonic() && android::isMonotonic(start)); |
169 | 171 | ||
@@ -184,18 +186,19 @@ bool LogReader::onDataAvailable(SocketClient *cli) { | |||
184 | 186 | ||
185 | // Set acceptable upper limit to wait for slow reader processing b/27242723 | 187 | // Set acceptable upper limit to wait for slow reader processing b/27242723 |
186 | struct timeval t = { LOGD_SNDTIMEO, 0 }; | 188 | struct timeval t = { LOGD_SNDTIMEO, 0 }; |
187 | setsockopt(cli->getSocket(), SOL_SOCKET, SO_SNDTIMEO, (const char *)&t, sizeof(t)); | 189 | setsockopt(cli->getSocket(), SOL_SOCKET, SO_SNDTIMEO, (const char*)&t, |
190 | sizeof(t)); | ||
188 | 191 | ||
189 | command.runSocketCommand(cli); | 192 | command.runSocketCommand(cli); |
190 | return true; | 193 | return true; |
191 | } | 194 | } |
192 | 195 | ||
193 | void LogReader::doSocketDelete(SocketClient *cli) { | 196 | void LogReader::doSocketDelete(SocketClient* cli) { |
194 | LastLogTimes × = mLogbuf.mTimes; | 197 | LastLogTimes& times = mLogbuf.mTimes; |
195 | LogTimeEntry::lock(); | 198 | LogTimeEntry::lock(); |
196 | LastLogTimes::iterator it = times.begin(); | 199 | LastLogTimes::iterator it = times.begin(); |
197 | while(it != times.end()) { | 200 | while (it != times.end()) { |
198 | LogTimeEntry *entry = (*it); | 201 | LogTimeEntry* entry = (*it); |
199 | if (entry->mClient == cli) { | 202 | if (entry->mClient == cli) { |
200 | times.erase(it); | 203 | times.erase(it); |
201 | entry->release_Locked(); | 204 | entry->release_Locked(); |
@@ -211,9 +214,8 @@ int LogReader::getLogSocket() { | |||
211 | int sock = android_get_control_socket(socketName); | 214 | int sock = android_get_control_socket(socketName); |
212 | 215 | ||
213 | if (sock < 0) { | 216 | if (sock < 0) { |
214 | sock = socket_local_server(socketName, | 217 | sock = socket_local_server( |
215 | ANDROID_SOCKET_NAMESPACE_RESERVED, | 218 | socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET); |
216 | SOCK_SEQPACKET); | ||
217 | } | 219 | } |
218 | 220 | ||
219 | return sock; | 221 | return sock; |
diff --git a/logd/LogReader.h b/logd/LogReader.h index fdcedf152..271e08cdc 100644 --- a/logd/LogReader.h +++ b/logd/LogReader.h | |||
@@ -24,22 +24,23 @@ | |||
24 | class LogBuffer; | 24 | class LogBuffer; |
25 | 25 | ||
26 | class LogReader : public SocketListener { | 26 | class LogReader : public SocketListener { |
27 | LogBuffer &mLogbuf; | 27 | LogBuffer& mLogbuf; |
28 | 28 | ||
29 | public: | 29 | public: |
30 | explicit LogReader(LogBuffer *logbuf); | 30 | explicit LogReader(LogBuffer* logbuf); |
31 | void notifyNewLog(); | 31 | void notifyNewLog(); |
32 | 32 | ||
33 | LogBuffer &logbuf(void) const { return mLogbuf; } | 33 | LogBuffer& logbuf(void) const { |
34 | return mLogbuf; | ||
35 | } | ||
34 | 36 | ||
35 | protected: | 37 | protected: |
36 | virtual bool onDataAvailable(SocketClient *cli); | 38 | virtual bool onDataAvailable(SocketClient* cli); |
37 | 39 | ||
38 | private: | 40 | private: |
39 | static int getLogSocket(); | 41 | static int getLogSocket(); |
40 | 42 | ||
41 | void doSocketDelete(SocketClient *cli); | 43 | void doSocketDelete(SocketClient* cli); |
42 | |||
43 | }; | 44 | }; |
44 | 45 | ||
45 | #endif | 46 | #endif |
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp index 7e0a6b7e1..cc30f7783 100644 --- a/logd/LogStatistics.cpp +++ b/logd/LogStatistics.cpp | |||
@@ -41,12 +41,14 @@ LogStatistics::LogStatistics() : enable(false) { | |||
41 | 41 | ||
42 | namespace android { | 42 | namespace android { |
43 | 43 | ||
44 | size_t sizesTotal() { return LogStatistics::sizesTotal(); } | 44 | size_t sizesTotal() { |
45 | return LogStatistics::sizesTotal(); | ||
46 | } | ||
45 | 47 | ||
46 | // caller must own and free character string | 48 | // caller must own and free character string |
47 | char *pidToName(pid_t pid) { | 49 | char* pidToName(pid_t pid) { |
48 | char *retval = NULL; | 50 | char* retval = NULL; |
49 | if (pid == 0) { // special case from auditd/klogd for kernel | 51 | if (pid == 0) { // special case from auditd/klogd for kernel |
50 | retval = strdup("logd"); | 52 | retval = strdup("logd"); |
51 | } else { | 53 | } else { |
52 | char buffer[512]; | 54 | char buffer[512]; |
@@ -55,7 +57,7 @@ char *pidToName(pid_t pid) { | |||
55 | if (fd >= 0) { | 57 | if (fd >= 0) { |
56 | ssize_t ret = read(fd, buffer, sizeof(buffer)); | 58 | ssize_t ret = read(fd, buffer, sizeof(buffer)); |
57 | if (ret > 0) { | 59 | if (ret > 0) { |
58 | buffer[sizeof(buffer)-1] = '\0'; | 60 | buffer[sizeof(buffer) - 1] = '\0'; |
59 | // frameworks intermediate state | 61 | // frameworks intermediate state |
60 | if (fastcmp<strcmp>(buffer, "<pre-initialized>")) { | 62 | if (fastcmp<strcmp>(buffer, "<pre-initialized>")) { |
61 | retval = strdup(buffer); | 63 | retval = strdup(buffer); |
@@ -66,10 +68,9 @@ char *pidToName(pid_t pid) { | |||
66 | } | 68 | } |
67 | return retval; | 69 | return retval; |
68 | } | 70 | } |
69 | |||
70 | } | 71 | } |
71 | 72 | ||
72 | void LogStatistics::add(LogBufferElement *element) { | 73 | void LogStatistics::add(LogBufferElement* element) { |
73 | log_id_t log_id = element->getLogId(); | 74 | log_id_t log_id = element->getLogId(); |
74 | unsigned short size = element->getMsgLen(); | 75 | unsigned short size = element->getMsgLen(); |
75 | mSizes[log_id] += size; | 76 | mSizes[log_id] += size; |
@@ -114,7 +115,7 @@ void LogStatistics::add(LogBufferElement *element) { | |||
114 | } | 115 | } |
115 | } | 116 | } |
116 | 117 | ||
117 | void LogStatistics::subtract(LogBufferElement *element) { | 118 | void LogStatistics::subtract(LogBufferElement* element) { |
118 | log_id_t log_id = element->getLogId(); | 119 | log_id_t log_id = element->getLogId(); |
119 | unsigned short size = element->getMsgLen(); | 120 | unsigned short size = element->getMsgLen(); |
120 | mSizes[log_id] -= size; | 121 | mSizes[log_id] -= size; |
@@ -151,7 +152,7 @@ void LogStatistics::subtract(LogBufferElement *element) { | |||
151 | 152 | ||
152 | // Atomically set an entry to drop | 153 | // Atomically set an entry to drop |
153 | // entry->setDropped(1) must follow this call, caller should do this explicitly. | 154 | // entry->setDropped(1) must follow this call, caller should do this explicitly. |
154 | void LogStatistics::drop(LogBufferElement *element) { | 155 | void LogStatistics::drop(LogBufferElement* element) { |
155 | log_id_t log_id = element->getLogId(); | 156 | log_id_t log_id = element->getLogId(); |
156 | unsigned short size = element->getMsgLen(); | 157 | unsigned short size = element->getMsgLen(); |
157 | mSizes[log_id] -= size; | 158 | mSizes[log_id] -= size; |
@@ -180,7 +181,7 @@ void LogStatistics::drop(LogBufferElement *element) { | |||
180 | } | 181 | } |
181 | 182 | ||
182 | // caller must own and free character string | 183 | // caller must own and free character string |
183 | const char *LogStatistics::uidToName(uid_t uid) const { | 184 | const char* LogStatistics::uidToName(uid_t uid) const { |
184 | // Local hard coded favourites | 185 | // Local hard coded favourites |
185 | if (uid == AID_LOGD) { | 186 | if (uid == AID_LOGD) { |
186 | return strdup("auditd"); | 187 | return strdup("auditd"); |
@@ -189,7 +190,7 @@ const char *LogStatistics::uidToName(uid_t uid) const { | |||
189 | // Android system | 190 | // Android system |
190 | if (uid < AID_APP) { | 191 | if (uid < AID_APP) { |
191 | // in bionic, thread safe as long as we copy the results | 192 | // in bionic, thread safe as long as we copy the results |
192 | struct passwd *pwd = getpwuid(uid); | 193 | struct passwd* pwd = getpwuid(uid); |
193 | if (pwd) { | 194 | if (pwd) { |
194 | return strdup(pwd->pw_name); | 195 | return strdup(pwd->pw_name); |
195 | } | 196 | } |
@@ -197,7 +198,7 @@ const char *LogStatistics::uidToName(uid_t uid) const { | |||
197 | 198 | ||
198 | // Parse /data/system/packages.list | 199 | // Parse /data/system/packages.list |
199 | uid_t userId = uid % AID_USER_OFFSET; | 200 | uid_t userId = uid % AID_USER_OFFSET; |
200 | const char *name = android::uidToName(userId); | 201 | const char* name = android::uidToName(userId); |
201 | if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) { | 202 | if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) { |
202 | name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP)); | 203 | name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP)); |
203 | } | 204 | } |
@@ -207,24 +208,25 @@ const char *LogStatistics::uidToName(uid_t uid) const { | |||
207 | 208 | ||
208 | // Android application | 209 | // Android application |
209 | if (uid >= AID_APP) { | 210 | if (uid >= AID_APP) { |
210 | struct passwd *pwd = getpwuid(uid); | 211 | struct passwd* pwd = getpwuid(uid); |
211 | if (pwd) { | 212 | if (pwd) { |
212 | return strdup(pwd->pw_name); | 213 | return strdup(pwd->pw_name); |
213 | } | 214 | } |
214 | } | 215 | } |
215 | 216 | ||
216 | // report uid -> pid(s) -> pidToName if unique | 217 | // report uid -> pid(s) -> pidToName if unique |
217 | for(pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end(); ++it) { | 218 | for (pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end(); |
218 | const PidEntry &entry = it->second; | 219 | ++it) { |
220 | const PidEntry& entry = it->second; | ||
219 | 221 | ||
220 | if (entry.getUid() == uid) { | 222 | if (entry.getUid() == uid) { |
221 | const char *nameTmp = entry.getName(); | 223 | const char* nameTmp = entry.getName(); |
222 | 224 | ||
223 | if (nameTmp) { | 225 | if (nameTmp) { |
224 | if (!name) { | 226 | if (!name) { |
225 | name = strdup(nameTmp); | 227 | name = strdup(nameTmp); |
226 | } else if (fastcmp<strcmp>(name, nameTmp)) { | 228 | } else if (fastcmp<strcmp>(name, nameTmp)) { |
227 | free(const_cast<char *>(name)); | 229 | free(const_cast<char*>(name)); |
228 | name = NULL; | 230 | name = NULL; |
229 | break; | 231 | break; |
230 | } | 232 | } |
@@ -236,26 +238,24 @@ const char *LogStatistics::uidToName(uid_t uid) const { | |||
236 | return name; | 238 | return name; |
237 | } | 239 | } |
238 | 240 | ||
239 | std::string UidEntry::formatHeader(const std::string &name, log_id_t id) const { | 241 | std::string UidEntry::formatHeader(const std::string& name, log_id_t id) const { |
240 | bool isprune = worstUidEnabledForLogid(id); | 242 | bool isprune = worstUidEnabledForLogid(id); |
241 | return formatLine(android::base::StringPrintf( | 243 | return formatLine(android::base::StringPrintf(name.c_str(), |
242 | name.c_str(), android_log_id_to_name(id)), | 244 | android_log_id_to_name(id)), |
243 | std::string("Size"), | 245 | std::string("Size"), |
244 | std::string(isprune ? "+/- Pruned" : "")) | 246 | std::string(isprune ? "+/- Pruned" : "")) + |
245 | + formatLine(std::string("UID PACKAGE"), | 247 | formatLine(std::string("UID PACKAGE"), std::string("BYTES"), |
246 | std::string("BYTES"), | ||
247 | std::string(isprune ? "NUM" : "")); | 248 | std::string(isprune ? "NUM" : "")); |
248 | } | 249 | } |
249 | 250 | ||
250 | std::string UidEntry::format(const LogStatistics &stat, log_id_t id) const { | 251 | std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const { |
251 | uid_t uid = getUid(); | 252 | uid_t uid = getUid(); |
252 | std::string name = android::base::StringPrintf("%u", uid); | 253 | std::string name = android::base::StringPrintf("%u", uid); |
253 | const char *nameTmp = stat.uidToName(uid); | 254 | const char* nameTmp = stat.uidToName(uid); |
254 | if (nameTmp) { | 255 | if (nameTmp) { |
255 | name += android::base::StringPrintf( | 256 | name += android::base::StringPrintf( |
256 | "%*s%s", (int)std::max(6 - name.length(), (size_t)1), | 257 | "%*s%s", (int)std::max(6 - name.length(), (size_t)1), "", nameTmp); |
257 | "", nameTmp); | 258 | free(const_cast<char*>(nameTmp)); |
258 | free(const_cast<char *>(nameTmp)); | ||
259 | } | 259 | } |
260 | 260 | ||
261 | std::string size = android::base::StringPrintf("%zu", getSizes()); | 261 | std::string size = android::base::StringPrintf("%zu", getSizes()); |
@@ -263,15 +263,16 @@ std::string UidEntry::format(const LogStatistics &stat, log_id_t id) const { | |||
263 | std::string pruned = ""; | 263 | std::string pruned = ""; |
264 | if (worstUidEnabledForLogid(id)) { | 264 | if (worstUidEnabledForLogid(id)) { |
265 | size_t totalDropped = 0; | 265 | size_t totalDropped = 0; |
266 | for (LogStatistics::uidTable_t::const_iterator it = stat.uidTable[id].begin(); | 266 | for (LogStatistics::uidTable_t::const_iterator it = |
267 | it != stat.uidTable[id].end(); ++it) { | 267 | stat.uidTable[id].begin(); |
268 | it != stat.uidTable[id].end(); ++it) { | ||
268 | totalDropped += it->second.getDropped(); | 269 | totalDropped += it->second.getDropped(); |
269 | } | 270 | } |
270 | size_t sizes = stat.sizes(id); | 271 | size_t sizes = stat.sizes(id); |
271 | size_t totalSize = stat.sizesTotal(id); | 272 | size_t totalSize = stat.sizesTotal(id); |
272 | size_t totalElements = stat.elementsTotal(id); | 273 | size_t totalElements = stat.elementsTotal(id); |
273 | float totalVirtualSize = (float)sizes + (float)totalDropped * totalSize | 274 | float totalVirtualSize = |
274 | / totalElements; | 275 | (float)sizes + (float)totalDropped * totalSize / totalElements; |
275 | size_t entrySize = getSizes(); | 276 | size_t entrySize = getSizes(); |
276 | float virtualEntrySize = entrySize; | 277 | float virtualEntrySize = entrySize; |
277 | int realPermille = virtualEntrySize * 1000.0 / sizes; | 278 | int realPermille = virtualEntrySize * 1000.0 / sizes; |
@@ -281,31 +282,29 @@ std::string UidEntry::format(const LogStatistics &stat, log_id_t id) const { | |||
281 | virtualEntrySize += (float)dropped * totalSize / totalElements; | 282 | virtualEntrySize += (float)dropped * totalSize / totalElements; |
282 | } | 283 | } |
283 | int virtualPermille = virtualEntrySize * 1000.0 / totalVirtualSize; | 284 | int virtualPermille = virtualEntrySize * 1000.0 / totalVirtualSize; |
284 | int permille = (realPermille - virtualPermille) * 1000L | 285 | int permille = |
285 | / (virtualPermille ?: 1); | 286 | (realPermille - virtualPermille) * 1000L / (virtualPermille ?: 1); |
286 | if ((permille < -1) || (1 < permille)) { | 287 | if ((permille < -1) || (1 < permille)) { |
287 | std::string change; | 288 | std::string change; |
288 | const char *units = "%"; | 289 | const char* units = "%"; |
289 | const char *prefix = (permille > 0) ? "+" : ""; | 290 | const char* prefix = (permille > 0) ? "+" : ""; |
290 | 291 | ||
291 | if (permille > 999) { | 292 | if (permille > 999) { |
292 | permille = (permille + 1000) / 100; // Now tenths fold | 293 | permille = (permille + 1000) / 100; // Now tenths fold |
293 | units = "X"; | 294 | units = "X"; |
294 | prefix = ""; | 295 | prefix = ""; |
295 | } | 296 | } |
296 | if ((-99 < permille) && (permille < 99)) { | 297 | if ((-99 < permille) && (permille < 99)) { |
297 | change = android::base::StringPrintf("%s%d.%u%s", | 298 | change = android::base::StringPrintf( |
298 | prefix, | 299 | "%s%d.%u%s", prefix, permille / 10, |
299 | permille / 10, | ||
300 | ((permille < 0) ? (-permille % 10) : (permille % 10)), | 300 | ((permille < 0) ? (-permille % 10) : (permille % 10)), |
301 | units); | 301 | units); |
302 | } else { | 302 | } else { |
303 | change = android::base::StringPrintf("%s%d%s", | 303 | change = android::base::StringPrintf( |
304 | prefix, | 304 | "%s%d%s", prefix, (permille + 5) / 10, units); |
305 | (permille + 5) / 10, units); | ||
306 | } | 305 | } |
307 | ssize_t spaces = EntryBaseConstants::pruned_len | 306 | ssize_t spaces = EntryBaseConstants::pruned_len - 2 - |
308 | - 2 - pruned.length() - change.length(); | 307 | pruned.length() - change.length(); |
309 | if ((spaces <= 0) && pruned.length()) { | 308 | if ((spaces <= 0) && pruned.length()) { |
310 | spaces = 1; | 309 | spaces = 1; |
311 | } | 310 | } |
@@ -323,8 +322,8 @@ std::string UidEntry::format(const LogStatistics &stat, log_id_t id) const { | |||
323 | } | 322 | } |
324 | 323 | ||
325 | static const size_t maximum_sorted_entries = 32; | 324 | static const size_t maximum_sorted_entries = 32; |
326 | std::unique_ptr<const PidEntry *[]> sorted | 325 | std::unique_ptr<const PidEntry* []> sorted = |
327 | = stat.pidSystemTable[id].sort(uid, (pid_t)0, maximum_sorted_entries); | 326 | stat.pidSystemTable[id].sort(uid, (pid_t)0, maximum_sorted_entries); |
328 | 327 | ||
329 | if (!sorted.get()) { | 328 | if (!sorted.get()) { |
330 | return output; | 329 | return output; |
@@ -333,7 +332,7 @@ std::string UidEntry::format(const LogStatistics &stat, log_id_t id) const { | |||
333 | size_t index; | 332 | size_t index; |
334 | bool hasDropped = false; | 333 | bool hasDropped = false; |
335 | for (index = 0; index < maximum_sorted_entries; ++index) { | 334 | for (index = 0; index < maximum_sorted_entries; ++index) { |
336 | const PidEntry *entry = sorted[index]; | 335 | const PidEntry* entry = sorted[index]; |
337 | if (!entry) { | 336 | if (!entry) { |
338 | break; | 337 | break; |
339 | } | 338 | } |
@@ -345,43 +344,39 @@ std::string UidEntry::format(const LogStatistics &stat, log_id_t id) const { | |||
345 | } | 344 | } |
346 | byPid += entry->format(stat, id); | 345 | byPid += entry->format(stat, id); |
347 | } | 346 | } |
348 | if (index > 1) { // print this only if interesting | 347 | if (index > 1) { // print this only if interesting |
349 | std::string ditto("\" "); | 348 | std::string ditto("\" "); |
350 | output += formatLine(std::string(" PID/UID COMMAND LINE"), | 349 | output += formatLine(std::string(" PID/UID COMMAND LINE"), ditto, |
351 | ditto, hasDropped ? ditto : std::string("")); | 350 | hasDropped ? ditto : std::string("")); |
352 | output += byPid; | 351 | output += byPid; |
353 | } | 352 | } |
354 | 353 | ||
355 | return output; | 354 | return output; |
356 | } | 355 | } |
357 | 356 | ||
358 | std::string PidEntry::formatHeader(const std::string &name, log_id_t /* id */) const { | 357 | std::string PidEntry::formatHeader(const std::string& name, |
359 | return formatLine(name, | 358 | log_id_t /* id */) const { |
360 | std::string("Size"), | 359 | return formatLine(name, std::string("Size"), std::string("Pruned")) + |
361 | std::string("Pruned")) | 360 | formatLine(std::string(" PID/UID COMMAND LINE"), |
362 | + formatLine(std::string(" PID/UID COMMAND LINE"), | 361 | std::string("BYTES"), std::string("NUM")); |
363 | std::string("BYTES"), | ||
364 | std::string("NUM")); | ||
365 | } | 362 | } |
366 | 363 | ||
367 | std::string PidEntry::format(const LogStatistics &stat, log_id_t /* id */) const { | 364 | std::string PidEntry::format(const LogStatistics& stat, |
365 | log_id_t /* id */) const { | ||
368 | uid_t uid = getUid(); | 366 | uid_t uid = getUid(); |
369 | pid_t pid = getPid(); | 367 | pid_t pid = getPid(); |
370 | std::string name = android::base::StringPrintf("%5u/%u", pid, uid); | 368 | std::string name = android::base::StringPrintf("%5u/%u", pid, uid); |
371 | const char *nameTmp = getName(); | 369 | const char* nameTmp = getName(); |
372 | if (nameTmp) { | 370 | if (nameTmp) { |
373 | name += android::base::StringPrintf( | 371 | name += android::base::StringPrintf( |
374 | "%*s%s", (int)std::max(12 - name.length(), (size_t)1), | 372 | "%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", nameTmp); |
375 | "", nameTmp); | ||
376 | } else if ((nameTmp = stat.uidToName(uid))) { | 373 | } else if ((nameTmp = stat.uidToName(uid))) { |
377 | name += android::base::StringPrintf( | 374 | name += android::base::StringPrintf( |
378 | "%*s%s", (int)std::max(12 - name.length(), (size_t)1), | 375 | "%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", nameTmp); |
379 | "", nameTmp); | 376 | free(const_cast<char*>(nameTmp)); |
380 | free(const_cast<char *>(nameTmp)); | ||
381 | } | 377 | } |
382 | 378 | ||
383 | std::string size = android::base::StringPrintf("%zu", | 379 | std::string size = android::base::StringPrintf("%zu", getSizes()); |
384 | getSizes()); | ||
385 | 380 | ||
386 | std::string pruned = ""; | 381 | std::string pruned = ""; |
387 | size_t dropped = getDropped(); | 382 | size_t dropped = getDropped(); |
@@ -392,36 +387,31 @@ std::string PidEntry::format(const LogStatistics &stat, log_id_t /* id */) const | |||
392 | return formatLine(name, size, pruned); | 387 | return formatLine(name, size, pruned); |
393 | } | 388 | } |
394 | 389 | ||
395 | std::string TidEntry::formatHeader(const std::string &name, log_id_t /* id */) const { | 390 | std::string TidEntry::formatHeader(const std::string& name, |
396 | return formatLine(name, | 391 | log_id_t /* id */) const { |
397 | std::string("Size"), | 392 | return formatLine(name, std::string("Size"), std::string("Pruned")) + |
398 | std::string("Pruned")) | 393 | formatLine(std::string(" TID/UID COMM"), std::string("BYTES"), |
399 | + formatLine(std::string(" TID/UID COMM"), | ||
400 | std::string("BYTES"), | ||
401 | std::string("NUM")); | 394 | std::string("NUM")); |
402 | } | 395 | } |
403 | 396 | ||
404 | std::string TidEntry::format(const LogStatistics &stat, log_id_t /* id */) const { | 397 | std::string TidEntry::format(const LogStatistics& stat, |
398 | log_id_t /* id */) const { | ||
405 | uid_t uid = getUid(); | 399 | uid_t uid = getUid(); |
406 | std::string name = android::base::StringPrintf("%5u/%u", | 400 | std::string name = android::base::StringPrintf("%5u/%u", getTid(), uid); |
407 | getTid(), uid); | 401 | const char* nameTmp = getName(); |
408 | const char *nameTmp = getName(); | ||
409 | if (nameTmp) { | 402 | if (nameTmp) { |
410 | name += android::base::StringPrintf( | 403 | name += android::base::StringPrintf( |
411 | "%*s%s", (int)std::max(12 - name.length(), (size_t)1), | 404 | "%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", nameTmp); |
412 | "", nameTmp); | ||
413 | } else if ((nameTmp = stat.uidToName(uid))) { | 405 | } else if ((nameTmp = stat.uidToName(uid))) { |
414 | // if we do not have a PID name, lets punt to try UID name? | 406 | // if we do not have a PID name, lets punt to try UID name? |
415 | name += android::base::StringPrintf( | 407 | name += android::base::StringPrintf( |
416 | "%*s%s", (int)std::max(12 - name.length(), (size_t)1), | 408 | "%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", nameTmp); |
417 | "", nameTmp); | 409 | free(const_cast<char*>(nameTmp)); |
418 | free(const_cast<char *>(nameTmp)); | ||
419 | // We tried, better to not have a name at all, we still | 410 | // We tried, better to not have a name at all, we still |
420 | // have TID/UID by number to report in any case. | 411 | // have TID/UID by number to report in any case. |
421 | } | 412 | } |
422 | 413 | ||
423 | std::string size = android::base::StringPrintf("%zu", | 414 | std::string size = android::base::StringPrintf("%zu", getSizes()); |
424 | getSizes()); | ||
425 | 415 | ||
426 | std::string pruned = ""; | 416 | std::string pruned = ""; |
427 | size_t dropped = getDropped(); | 417 | size_t dropped = getDropped(); |
@@ -432,35 +422,30 @@ std::string TidEntry::format(const LogStatistics &stat, log_id_t /* id */) const | |||
432 | return formatLine(name, size, pruned); | 422 | return formatLine(name, size, pruned); |
433 | } | 423 | } |
434 | 424 | ||
435 | std::string TagEntry::formatHeader(const std::string &name, log_id_t id) const { | 425 | std::string TagEntry::formatHeader(const std::string& name, log_id_t id) const { |
436 | bool isprune = worstUidEnabledForLogid(id); | 426 | bool isprune = worstUidEnabledForLogid(id); |
437 | return formatLine(name, | 427 | return formatLine(name, std::string("Size"), |
438 | std::string("Size"), | 428 | std::string(isprune ? "Prune" : "")) + |
439 | std::string(isprune ? "Prune" : "")) | 429 | formatLine(std::string(" TAG/UID TAGNAME"), |
440 | + formatLine(std::string(" TAG/UID TAGNAME"), | 430 | std::string("BYTES"), std::string(isprune ? "NUM" : "")); |
441 | std::string("BYTES"), | ||
442 | std::string(isprune ? "NUM" : "")); | ||
443 | } | 431 | } |
444 | 432 | ||
445 | std::string TagEntry::format(const LogStatistics & /* stat */, log_id_t /* id */) const { | 433 | std::string TagEntry::format(const LogStatistics& /* stat */, |
434 | log_id_t /* id */) const { | ||
446 | std::string name; | 435 | std::string name; |
447 | uid_t uid = getUid(); | 436 | uid_t uid = getUid(); |
448 | if (uid == (uid_t)-1) { | 437 | if (uid == (uid_t)-1) { |
449 | name = android::base::StringPrintf("%7u", | 438 | name = android::base::StringPrintf("%7u", getKey()); |
450 | getKey()); | ||
451 | } else { | 439 | } else { |
452 | name = android::base::StringPrintf("%7u/%u", | 440 | name = android::base::StringPrintf("%7u/%u", getKey(), uid); |
453 | getKey(), uid); | ||
454 | } | 441 | } |
455 | const char *nameTmp = getName(); | 442 | const char* nameTmp = getName(); |
456 | if (nameTmp) { | 443 | if (nameTmp) { |
457 | name += android::base::StringPrintf( | 444 | name += android::base::StringPrintf( |
458 | "%*s%s", (int)std::max(14 - name.length(), (size_t)1), | 445 | "%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", nameTmp); |
459 | "", nameTmp); | ||
460 | } | 446 | } |
461 | 447 | ||
462 | std::string size = android::base::StringPrintf("%zu", | 448 | std::string size = android::base::StringPrintf("%zu", getSizes()); |
463 | getSizes()); | ||
464 | 449 | ||
465 | std::string pruned = ""; | 450 | std::string pruned = ""; |
466 | size_t dropped = getDropped(); | 451 | size_t dropped = getDropped(); |
@@ -506,11 +491,13 @@ std::string LogStatistics::format(uid_t uid, pid_t pid, | |||
506 | totalSize += szs; | 491 | totalSize += szs; |
507 | size_t els = elementsTotal(id); | 492 | size_t els = elementsTotal(id); |
508 | totalEls += els; | 493 | totalEls += els; |
509 | output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els); | 494 | output += |
495 | android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els); | ||
510 | spaces += spaces_total + oldLength - output.length(); | 496 | spaces += spaces_total + oldLength - output.length(); |
511 | } | 497 | } |
512 | if (spaces < 0) spaces = 0; | 498 | if (spaces < 0) spaces = 0; |
513 | output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, totalEls); | 499 | output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, |
500 | totalEls); | ||
514 | 501 | ||
515 | static const char NowStr[] = "\nNow"; | 502 | static const char NowStr[] = "\nNow"; |
516 | spaces = 10 - strlen(NowStr); | 503 | spaces = 10 - strlen(NowStr); |
@@ -528,13 +515,15 @@ std::string LogStatistics::format(uid_t uid, pid_t pid, | |||
528 | size_t szs = sizes(id); | 515 | size_t szs = sizes(id); |
529 | totalSize += szs; | 516 | totalSize += szs; |
530 | totalEls += els; | 517 | totalEls += els; |
531 | output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els); | 518 | output += |
519 | android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els); | ||
532 | spaces -= output.length() - oldLength; | 520 | spaces -= output.length() - oldLength; |
533 | } | 521 | } |
534 | spaces += spaces_total; | 522 | spaces += spaces_total; |
535 | } | 523 | } |
536 | if (spaces < 0) spaces = 0; | 524 | if (spaces < 0) spaces = 0; |
537 | output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, totalEls); | 525 | output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, |
526 | totalEls); | ||
538 | 527 | ||
539 | static const char OverheadStr[] = "\nOverhead"; | 528 | static const char OverheadStr[] = "\nOverhead"; |
540 | spaces = 10 - strlen(OverheadStr); | 529 | spaces = 10 - strlen(OverheadStr); |
@@ -551,7 +540,7 @@ std::string LogStatistics::format(uid_t uid, pid_t pid, | |||
551 | // estimate the std::list overhead. | 540 | // estimate the std::list overhead. |
552 | static const size_t overhead = | 541 | static const size_t overhead = |
553 | ((sizeof(LogBufferElement) + sizeof(uint64_t) - 1) & | 542 | ((sizeof(LogBufferElement) + sizeof(uint64_t) - 1) & |
554 | -sizeof(uint64_t)) + | 543 | -sizeof(uint64_t)) + |
555 | sizeof(std::list<LogBufferElement*>); | 544 | sizeof(std::list<LogBufferElement*>); |
556 | size_t szs = sizes(id) + els * overhead; | 545 | size_t szs = sizes(id) + els * overhead; |
557 | totalSize += szs; | 546 | totalSize += szs; |
@@ -572,16 +561,14 @@ std::string LogStatistics::format(uid_t uid, pid_t pid, | |||
572 | log_id_for_each(id) { | 561 | log_id_for_each(id) { |
573 | if (!(logMask & (1 << id))) continue; | 562 | if (!(logMask & (1 << id))) continue; |
574 | 563 | ||
575 | name = (uid == AID_ROOT) | 564 | name = (uid == AID_ROOT) ? "Chattiest UIDs in %s log buffer:" |
576 | ? "Chattiest UIDs in %s log buffer:" | 565 | : "Logging for your UID in %s log buffer:"; |
577 | : "Logging for your UID in %s log buffer:"; | ||
578 | output += uidTable[id].format(*this, uid, pid, name, id); | 566 | output += uidTable[id].format(*this, uid, pid, name, id); |
579 | } | 567 | } |
580 | 568 | ||
581 | if (enable) { | 569 | if (enable) { |
582 | name = ((uid == AID_ROOT) && !pid) | 570 | name = ((uid == AID_ROOT) && !pid) ? "Chattiest PIDs:" |
583 | ? "Chattiest PIDs:" | 571 | : "Logging for this PID:"; |
584 | : "Logging for this PID:"; | ||
585 | output += pidTable.format(*this, uid, pid, name); | 572 | output += pidTable.format(*this, uid, pid, name); |
586 | name = "Chattiest TIDs"; | 573 | name = "Chattiest TIDs"; |
587 | if (pid) name += android::base::StringPrintf(" for PID %d", pid); | 574 | if (pid) name += android::base::StringPrintf(" for PID %d", pid); |
@@ -600,7 +587,8 @@ std::string LogStatistics::format(uid_t uid, pid_t pid, | |||
600 | name = "Chattiest security log buffer TAGs"; | 587 | name = "Chattiest security log buffer TAGs"; |
601 | if (pid) name += android::base::StringPrintf(" for PID %d", pid); | 588 | if (pid) name += android::base::StringPrintf(" for PID %d", pid); |
602 | name += ":"; | 589 | name += ":"; |
603 | output += securityTagTable.format(*this, uid, pid, name, LOG_ID_SECURITY); | 590 | output += |
591 | securityTagTable.format(*this, uid, pid, name, LOG_ID_SECURITY); | ||
604 | } | 592 | } |
605 | 593 | ||
606 | return output; | 594 | return output; |
@@ -611,7 +599,7 @@ namespace android { | |||
611 | uid_t pidToUid(pid_t pid) { | 599 | uid_t pidToUid(pid_t pid) { |
612 | char buffer[512]; | 600 | char buffer[512]; |
613 | snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid); | 601 | snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid); |
614 | FILE *fp = fopen(buffer, "r"); | 602 | FILE* fp = fopen(buffer, "r"); |
615 | if (fp) { | 603 | if (fp) { |
616 | while (fgets(buffer, sizeof(buffer), fp)) { | 604 | while (fgets(buffer, sizeof(buffer), fp)) { |
617 | int uid; | 605 | int uid; |
@@ -622,9 +610,8 @@ uid_t pidToUid(pid_t pid) { | |||
622 | } | 610 | } |
623 | fclose(fp); | 611 | fclose(fp); |
624 | } | 612 | } |
625 | return AID_LOGD; // associate this with the logger | 613 | return AID_LOGD; // associate this with the logger |
626 | } | 614 | } |
627 | |||
628 | } | 615 | } |
629 | 616 | ||
630 | uid_t LogStatistics::pidToUid(pid_t pid) { | 617 | uid_t LogStatistics::pidToUid(pid_t pid) { |
@@ -632,10 +619,10 @@ uid_t LogStatistics::pidToUid(pid_t pid) { | |||
632 | } | 619 | } |
633 | 620 | ||
634 | // caller must free character string | 621 | // caller must free character string |
635 | const char *LogStatistics::pidToName(pid_t pid) const { | 622 | const char* LogStatistics::pidToName(pid_t pid) const { |
636 | // An inconvenient truth ... getName() can alter the object | 623 | // An inconvenient truth ... getName() can alter the object |
637 | pidTable_t &writablePidTable = const_cast<pidTable_t &>(pidTable); | 624 | pidTable_t& writablePidTable = const_cast<pidTable_t&>(pidTable); |
638 | const char *name = writablePidTable.add(pid)->second.getName(); | 625 | const char* name = writablePidTable.add(pid)->second.getName(); |
639 | if (!name) { | 626 | if (!name) { |
640 | return NULL; | 627 | return NULL; |
641 | } | 628 | } |
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h index 777dc33a5..066b7de42 100644 --- a/logd/LogStatistics.h +++ b/logd/LogStatistics.h | |||
@@ -21,26 +21,25 @@ | |||
21 | #include <stdlib.h> | 21 | #include <stdlib.h> |
22 | #include <sys/types.h> | 22 | #include <sys/types.h> |
23 | 23 | ||
24 | #include <algorithm> // std::max | 24 | #include <algorithm> // std::max |
25 | #include <memory> | 25 | #include <memory> |
26 | #include <string> // std::string | 26 | #include <string> // std::string |
27 | #include <unordered_map> | 27 | #include <unordered_map> |
28 | 28 | ||
29 | #include <android/log.h> | ||
30 | #include <android-base/stringprintf.h> | 29 | #include <android-base/stringprintf.h> |
30 | #include <android/log.h> | ||
31 | #include <private/android_filesystem_config.h> | 31 | #include <private/android_filesystem_config.h> |
32 | 32 | ||
33 | #include "LogBufferElement.h" | 33 | #include "LogBufferElement.h" |
34 | #include "LogUtils.h" | 34 | #include "LogUtils.h" |
35 | 35 | ||
36 | #define log_id_for_each(i) \ | 36 | #define log_id_for_each(i) \ |
37 | for (log_id_t i = LOG_ID_MIN; (i) < LOG_ID_MAX; (i) = (log_id_t) ((i) + 1)) | 37 | for (log_id_t i = LOG_ID_MIN; (i) < LOG_ID_MAX; (i) = (log_id_t)((i) + 1)) |
38 | 38 | ||
39 | class LogStatistics; | 39 | class LogStatistics; |
40 | 40 | ||
41 | template <typename TKey, typename TEntry> | 41 | template <typename TKey, typename TEntry> |
42 | class LogHashtable { | 42 | class LogHashtable { |
43 | |||
44 | std::unordered_map<TKey, TEntry> map; | 43 | std::unordered_map<TKey, TEntry> map; |
45 | 44 | ||
46 | size_t bucket_size() const { | 45 | size_t bucket_size() const { |
@@ -58,9 +57,10 @@ class LogHashtable { | |||
58 | static const size_t unordered_map_per_entry_overhead = sizeof(void*); | 57 | static const size_t unordered_map_per_entry_overhead = sizeof(void*); |
59 | static const size_t unordered_map_bucket_overhead = sizeof(void*); | 58 | static const size_t unordered_map_bucket_overhead = sizeof(void*); |
60 | 59 | ||
61 | public: | 60 | public: |
62 | 61 | size_t size() const { | |
63 | size_t size() const { return map.size(); } | 62 | return map.size(); |
63 | } | ||
64 | 64 | ||
65 | // Estimate unordered_map memory usage. | 65 | // Estimate unordered_map memory usage. |
66 | size_t sizeOf() const { | 66 | size_t sizeOf() const { |
@@ -70,20 +70,21 @@ public: | |||
70 | } | 70 | } |
71 | 71 | ||
72 | typedef typename std::unordered_map<TKey, TEntry>::iterator iterator; | 72 | typedef typename std::unordered_map<TKey, TEntry>::iterator iterator; |
73 | typedef typename std::unordered_map<TKey, TEntry>::const_iterator const_iterator; | 73 | typedef |
74 | typename std::unordered_map<TKey, TEntry>::const_iterator const_iterator; | ||
74 | 75 | ||
75 | std::unique_ptr<const TEntry *[]> sort(uid_t uid, pid_t pid, | 76 | std::unique_ptr<const TEntry* []> sort(uid_t uid, pid_t pid, |
76 | size_t len) const { | 77 | size_t len) const { |
77 | if (!len) { | 78 | if (!len) { |
78 | std::unique_ptr<const TEntry *[]> sorted(NULL); | 79 | std::unique_ptr<const TEntry* []> sorted(NULL); |
79 | return sorted; | 80 | return sorted; |
80 | } | 81 | } |
81 | 82 | ||
82 | const TEntry **retval = new const TEntry* [len]; | 83 | const TEntry** retval = new const TEntry*[len]; |
83 | memset(retval, 0, sizeof(*retval) * len); | 84 | memset(retval, 0, sizeof(*retval) * len); |
84 | 85 | ||
85 | for(const_iterator it = map.begin(); it != map.end(); ++it) { | 86 | for (const_iterator it = map.begin(); it != map.end(); ++it) { |
86 | const TEntry &entry = it->second; | 87 | const TEntry& entry = it->second; |
87 | 88 | ||
88 | if ((uid != AID_ROOT) && (uid != entry.getUid())) { | 89 | if ((uid != AID_ROOT) && (uid != entry.getUid())) { |
89 | continue; | 90 | continue; |
@@ -94,8 +95,8 @@ public: | |||
94 | 95 | ||
95 | size_t sizes = entry.getSizes(); | 96 | size_t sizes = entry.getSizes(); |
96 | ssize_t index = len - 1; | 97 | ssize_t index = len - 1; |
97 | while ((!retval[index] || (sizes > retval[index]->getSizes())) | 98 | while ((!retval[index] || (sizes > retval[index]->getSizes())) && |
98 | && (--index >= 0)) | 99 | (--index >= 0)) |
99 | ; | 100 | ; |
100 | if (++index < (ssize_t)len) { | 101 | if (++index < (ssize_t)len) { |
101 | size_t num = len - index - 1; | 102 | size_t num = len - index - 1; |
@@ -106,11 +107,11 @@ public: | |||
106 | retval[index] = &entry; | 107 | retval[index] = &entry; |
107 | } | 108 | } |
108 | } | 109 | } |
109 | std::unique_ptr<const TEntry *[]> sorted(retval); | 110 | std::unique_ptr<const TEntry* []> sorted(retval); |
110 | return sorted; | 111 | return sorted; |
111 | } | 112 | } |
112 | 113 | ||
113 | inline iterator add(TKey key, LogBufferElement *element) { | 114 | inline iterator add(TKey key, LogBufferElement* element) { |
114 | iterator it = map.find(key); | 115 | iterator it = map.find(key); |
115 | if (it == map.end()) { | 116 | if (it == map.end()) { |
116 | it = map.insert(std::make_pair(key, TEntry(element))).first; | 117 | it = map.insert(std::make_pair(key, TEntry(element))).first; |
@@ -130,41 +131,46 @@ public: | |||
130 | return it; | 131 | return it; |
131 | } | 132 | } |
132 | 133 | ||
133 | void subtract(TKey key, LogBufferElement *element) { | 134 | void subtract(TKey key, LogBufferElement* element) { |
134 | iterator it = map.find(key); | 135 | iterator it = map.find(key); |
135 | if ((it != map.end()) && it->second.subtract(element)) { | 136 | if ((it != map.end()) && it->second.subtract(element)) { |
136 | map.erase(it); | 137 | map.erase(it); |
137 | } | 138 | } |
138 | } | 139 | } |
139 | 140 | ||
140 | inline void drop(TKey key, LogBufferElement *element) { | 141 | inline void drop(TKey key, LogBufferElement* element) { |
141 | iterator it = map.find(key); | 142 | iterator it = map.find(key); |
142 | if (it != map.end()) { | 143 | if (it != map.end()) { |
143 | it->second.drop(element); | 144 | it->second.drop(element); |
144 | } | 145 | } |
145 | } | 146 | } |
146 | 147 | ||
147 | inline iterator begin() { return map.begin(); } | 148 | inline iterator begin() { |
148 | inline const_iterator begin() const { return map.begin(); } | 149 | return map.begin(); |
149 | inline iterator end() { return map.end(); } | 150 | } |
150 | inline const_iterator end() const { return map.end(); } | 151 | inline const_iterator begin() const { |
152 | return map.begin(); | ||
153 | } | ||
154 | inline iterator end() { | ||
155 | return map.end(); | ||
156 | } | ||
157 | inline const_iterator end() const { | ||
158 | return map.end(); | ||
159 | } | ||
151 | 160 | ||
152 | std::string format( | 161 | std::string format(const LogStatistics& stat, uid_t uid, pid_t pid, |
153 | const LogStatistics &stat, | 162 | const std::string& name = std::string(""), |
154 | uid_t uid, | 163 | log_id_t id = LOG_ID_MAX) const { |
155 | pid_t pid, | ||
156 | const std::string &name = std::string(""), | ||
157 | log_id_t id = LOG_ID_MAX) const { | ||
158 | static const size_t maximum_sorted_entries = 32; | 164 | static const size_t maximum_sorted_entries = 32; |
159 | std::string output; | 165 | std::string output; |
160 | std::unique_ptr<const TEntry *[]> sorted = sort(uid, pid, | 166 | std::unique_ptr<const TEntry* []> sorted = |
161 | maximum_sorted_entries); | 167 | sort(uid, pid, maximum_sorted_entries); |
162 | if (!sorted.get()) { | 168 | if (!sorted.get()) { |
163 | return output; | 169 | return output; |
164 | } | 170 | } |
165 | bool headerPrinted = false; | 171 | bool headerPrinted = false; |
166 | for (size_t index = 0; index < maximum_sorted_entries; ++index) { | 172 | for (size_t index = 0; index < maximum_sorted_entries; ++index) { |
167 | const TEntry *entry = sorted[index]; | 173 | const TEntry* entry = sorted[index]; |
168 | if (!entry) { | 174 | if (!entry) { |
169 | break; | 175 | break; |
170 | } | 176 | } |
@@ -180,42 +186,45 @@ public: | |||
180 | } | 186 | } |
181 | return output; | 187 | return output; |
182 | } | 188 | } |
183 | |||
184 | }; | 189 | }; |
185 | 190 | ||
186 | namespace EntryBaseConstants { | 191 | namespace EntryBaseConstants { |
187 | static constexpr size_t pruned_len = 14; | 192 | static constexpr size_t pruned_len = 14; |
188 | static constexpr size_t total_len = 80; | 193 | static constexpr size_t total_len = 80; |
189 | } | 194 | } |
190 | 195 | ||
191 | struct EntryBase { | 196 | struct EntryBase { |
192 | size_t size; | 197 | size_t size; |
193 | 198 | ||
194 | EntryBase():size(0) { } | 199 | EntryBase() : size(0) { |
195 | explicit EntryBase(LogBufferElement *element):size(element->getMsgLen()) { } | 200 | } |
201 | explicit EntryBase(LogBufferElement* element) : size(element->getMsgLen()) { | ||
202 | } | ||
196 | 203 | ||
197 | size_t getSizes() const { return size; } | 204 | size_t getSizes() const { |
205 | return size; | ||
206 | } | ||
198 | 207 | ||
199 | inline void add(LogBufferElement *element) { size += element->getMsgLen(); } | 208 | inline void add(LogBufferElement* element) { |
200 | inline bool subtract(LogBufferElement *element) { | 209 | size += element->getMsgLen(); |
210 | } | ||
211 | inline bool subtract(LogBufferElement* element) { | ||
201 | size -= element->getMsgLen(); | 212 | size -= element->getMsgLen(); |
202 | return !size; | 213 | return !size; |
203 | } | 214 | } |
204 | 215 | ||
205 | static std::string formatLine( | 216 | static std::string formatLine(const std::string& name, |
206 | const std::string &name, | 217 | const std::string& size, |
207 | const std::string &size, | 218 | const std::string& pruned) { |
208 | const std::string &pruned) { | 219 | ssize_t drop_len = |
209 | ssize_t drop_len = std::max(pruned.length() + 1, | 220 | std::max(pruned.length() + 1, EntryBaseConstants::pruned_len); |
210 | EntryBaseConstants::pruned_len); | 221 | ssize_t size_len = |
211 | ssize_t size_len = std::max(size.length() + 1, | 222 | std::max(size.length() + 1, EntryBaseConstants::total_len - |
212 | EntryBaseConstants::total_len | 223 | name.length() - drop_len - 1); |
213 | - name.length() - drop_len - 1); | 224 | |
214 | 225 | std::string ret = android::base::StringPrintf( | |
215 | std::string ret = android::base::StringPrintf("%s%*s%*s", | 226 | "%s%*s%*s", name.c_str(), (int)size_len, size.c_str(), |
216 | name.c_str(), | 227 | (int)drop_len, pruned.c_str()); |
217 | (int)size_len, size.c_str(), | ||
218 | (int)drop_len, pruned.c_str()); | ||
219 | // remove any trailing spaces | 228 | // remove any trailing spaces |
220 | size_t pos = ret.size(); | 229 | size_t pos = ret.size(); |
221 | size_t len = 0; | 230 | size_t len = 0; |
@@ -228,23 +237,25 @@ struct EntryBase { | |||
228 | struct EntryBaseDropped : public EntryBase { | 237 | struct EntryBaseDropped : public EntryBase { |
229 | size_t dropped; | 238 | size_t dropped; |
230 | 239 | ||
231 | EntryBaseDropped():dropped(0) { } | 240 | EntryBaseDropped() : dropped(0) { |
232 | explicit EntryBaseDropped(LogBufferElement *element): | 241 | } |
233 | EntryBase(element), | 242 | explicit EntryBaseDropped(LogBufferElement* element) |
234 | dropped(element->getDropped()) { | 243 | : EntryBase(element), dropped(element->getDropped()) { |
235 | } | 244 | } |
236 | 245 | ||
237 | size_t getDropped() const { return dropped; } | 246 | size_t getDropped() const { |
247 | return dropped; | ||
248 | } | ||
238 | 249 | ||
239 | inline void add(LogBufferElement *element) { | 250 | inline void add(LogBufferElement* element) { |
240 | dropped += element->getDropped(); | 251 | dropped += element->getDropped(); |
241 | EntryBase::add(element); | 252 | EntryBase::add(element); |
242 | } | 253 | } |
243 | inline bool subtract(LogBufferElement *element) { | 254 | inline bool subtract(LogBufferElement* element) { |
244 | dropped -= element->getDropped(); | 255 | dropped -= element->getDropped(); |
245 | return EntryBase::subtract(element) && !dropped; | 256 | return EntryBase::subtract(element) && !dropped; |
246 | } | 257 | } |
247 | inline void drop(LogBufferElement *element) { | 258 | inline void drop(LogBufferElement* element) { |
248 | dropped += 1; | 259 | dropped += 1; |
249 | EntryBase::subtract(element); | 260 | EntryBase::subtract(element); |
250 | } | 261 | } |
@@ -254,25 +265,31 @@ struct UidEntry : public EntryBaseDropped { | |||
254 | const uid_t uid; | 265 | const uid_t uid; |
255 | pid_t pid; | 266 | pid_t pid; |
256 | 267 | ||
257 | explicit UidEntry(LogBufferElement *element): | 268 | explicit UidEntry(LogBufferElement* element) |
258 | EntryBaseDropped(element), | 269 | : EntryBaseDropped(element), |
259 | uid(element->getUid()), | 270 | uid(element->getUid()), |
260 | pid(element->getPid()) { | 271 | pid(element->getPid()) { |
261 | } | 272 | } |
262 | 273 | ||
263 | inline const uid_t&getKey() const { return uid; } | 274 | inline const uid_t& getKey() const { |
264 | inline const uid_t&getUid() const { return getKey(); } | 275 | return uid; |
265 | inline const pid_t&getPid() const { return pid; } | 276 | } |
277 | inline const uid_t& getUid() const { | ||
278 | return getKey(); | ||
279 | } | ||
280 | inline const pid_t& getPid() const { | ||
281 | return pid; | ||
282 | } | ||
266 | 283 | ||
267 | inline void add(LogBufferElement *element) { | 284 | inline void add(LogBufferElement* element) { |
268 | if (pid != element->getPid()) { | 285 | if (pid != element->getPid()) { |
269 | pid = -1; | 286 | pid = -1; |
270 | } | 287 | } |
271 | EntryBaseDropped::add(element); | 288 | EntryBaseDropped::add(element); |
272 | } | 289 | } |
273 | 290 | ||
274 | std::string formatHeader(const std::string &name, log_id_t id) const; | 291 | std::string formatHeader(const std::string& name, log_id_t id) const; |
275 | std::string format(const LogStatistics &stat, log_id_t id) const; | 292 | std::string format(const LogStatistics& stat, log_id_t id) const; |
276 | }; | 293 | }; |
277 | 294 | ||
278 | namespace android { | 295 | namespace android { |
@@ -282,32 +299,42 @@ uid_t pidToUid(pid_t pid); | |||
282 | struct PidEntry : public EntryBaseDropped { | 299 | struct PidEntry : public EntryBaseDropped { |
283 | const pid_t pid; | 300 | const pid_t pid; |
284 | uid_t uid; | 301 | uid_t uid; |
285 | char *name; | 302 | char* name; |
286 | 303 | ||
287 | explicit PidEntry(pid_t pid): | 304 | explicit PidEntry(pid_t pid) |
288 | EntryBaseDropped(), | 305 | : EntryBaseDropped(), |
289 | pid(pid), | 306 | pid(pid), |
290 | uid(android::pidToUid(pid)), | 307 | uid(android::pidToUid(pid)), |
291 | name(android::pidToName(pid)) { | 308 | name(android::pidToName(pid)) { |
309 | } | ||
310 | explicit PidEntry(LogBufferElement* element) | ||
311 | : EntryBaseDropped(element), | ||
312 | pid(element->getPid()), | ||
313 | uid(element->getUid()), | ||
314 | name(android::pidToName(pid)) { | ||
292 | } | 315 | } |
293 | explicit PidEntry(LogBufferElement *element): | 316 | PidEntry(const PidEntry& element) |
294 | EntryBaseDropped(element), | 317 | : EntryBaseDropped(element), |
295 | pid(element->getPid()), | 318 | pid(element.pid), |
296 | uid(element->getUid()), | 319 | uid(element.uid), |
297 | name(android::pidToName(pid)) { | 320 | name(element.name ? strdup(element.name) : NULL) { |
298 | } | 321 | } |
299 | PidEntry(const PidEntry &element): | 322 | ~PidEntry() { |
300 | EntryBaseDropped(element), | 323 | free(name); |
301 | pid(element.pid), | ||
302 | uid(element.uid), | ||
303 | name(element.name ? strdup(element.name) : NULL) { | ||
304 | } | 324 | } |
305 | ~PidEntry() { free(name); } | ||
306 | 325 | ||
307 | const pid_t&getKey() const { return pid; } | 326 | const pid_t& getKey() const { |
308 | const pid_t&getPid() const { return getKey(); } | 327 | return pid; |
309 | const uid_t&getUid() const { return uid; } | 328 | } |
310 | const char*getName() const { return name; } | 329 | const pid_t& getPid() const { |
330 | return getKey(); | ||
331 | } | ||
332 | const uid_t& getUid() const { | ||
333 | return uid; | ||
334 | } | ||
335 | const char* getName() const { | ||
336 | return name; | ||
337 | } | ||
311 | 338 | ||
312 | inline void add(pid_t newPid) { | 339 | inline void add(pid_t newPid) { |
313 | if (name && !fastcmp<strncmp>(name, "zygote", 6)) { | 340 | if (name && !fastcmp<strncmp>(name, "zygote", 6)) { |
@@ -319,7 +346,7 @@ struct PidEntry : public EntryBaseDropped { | |||
319 | } | 346 | } |
320 | } | 347 | } |
321 | 348 | ||
322 | inline void add(LogBufferElement *element) { | 349 | inline void add(LogBufferElement* element) { |
323 | uid_t incomingUid = element->getUid(); | 350 | uid_t incomingUid = element->getUid(); |
324 | if (getUid() != incomingUid) { | 351 | if (getUid() != incomingUid) { |
325 | uid = incomingUid; | 352 | uid = incomingUid; |
@@ -331,44 +358,56 @@ struct PidEntry : public EntryBaseDropped { | |||
331 | EntryBaseDropped::add(element); | 358 | EntryBaseDropped::add(element); |
332 | } | 359 | } |
333 | 360 | ||
334 | std::string formatHeader(const std::string &name, log_id_t id) const; | 361 | std::string formatHeader(const std::string& name, log_id_t id) const; |
335 | std::string format(const LogStatistics &stat, log_id_t id) const; | 362 | std::string format(const LogStatistics& stat, log_id_t id) const; |
336 | }; | 363 | }; |
337 | 364 | ||
338 | struct TidEntry : public EntryBaseDropped { | 365 | struct TidEntry : public EntryBaseDropped { |
339 | const pid_t tid; | 366 | const pid_t tid; |
340 | pid_t pid; | 367 | pid_t pid; |
341 | uid_t uid; | 368 | uid_t uid; |
342 | char *name; | 369 | char* name; |
343 | 370 | ||
344 | TidEntry(pid_t tid, pid_t pid): | 371 | TidEntry(pid_t tid, pid_t pid) |
345 | EntryBaseDropped(), | 372 | : EntryBaseDropped(), |
346 | tid(tid), | 373 | tid(tid), |
347 | pid(pid), | 374 | pid(pid), |
348 | uid(android::pidToUid(tid)), | 375 | uid(android::pidToUid(tid)), |
349 | name(android::tidToName(tid)) { | 376 | name(android::tidToName(tid)) { |
350 | } | 377 | } |
351 | explicit TidEntry(LogBufferElement *element): | 378 | explicit TidEntry(LogBufferElement* element) |
352 | EntryBaseDropped(element), | 379 | : EntryBaseDropped(element), |
353 | tid(element->getTid()), | 380 | tid(element->getTid()), |
354 | pid(element->getPid()), | 381 | pid(element->getPid()), |
355 | uid(element->getUid()), | 382 | uid(element->getUid()), |
356 | name(android::tidToName(tid)) { | 383 | name(android::tidToName(tid)) { |
357 | } | 384 | } |
358 | TidEntry(const TidEntry &element): | 385 | TidEntry(const TidEntry& element) |
359 | EntryBaseDropped(element), | 386 | : EntryBaseDropped(element), |
360 | tid(element.tid), | 387 | tid(element.tid), |
361 | pid(element.pid), | 388 | pid(element.pid), |
362 | uid(element.uid), | 389 | uid(element.uid), |
363 | name(element.name ? strdup(element.name) : NULL) { | 390 | name(element.name ? strdup(element.name) : NULL) { |
364 | } | 391 | } |
365 | ~TidEntry() { free(name); } | 392 | ~TidEntry() { |
366 | 393 | free(name); | |
367 | const pid_t&getKey() const { return tid; } | 394 | } |
368 | const pid_t&getTid() const { return getKey(); } | 395 | |
369 | const pid_t&getPid() const { return pid; } | 396 | const pid_t& getKey() const { |
370 | const uid_t&getUid() const { return uid; } | 397 | return tid; |
371 | const char*getName() const { return name; } | 398 | } |
399 | const pid_t& getTid() const { | ||
400 | return getKey(); | ||
401 | } | ||
402 | const pid_t& getPid() const { | ||
403 | return pid; | ||
404 | } | ||
405 | const uid_t& getUid() const { | ||
406 | return uid; | ||
407 | } | ||
408 | const char* getName() const { | ||
409 | return name; | ||
410 | } | ||
372 | 411 | ||
373 | inline void add(pid_t incomingTid) { | 412 | inline void add(pid_t incomingTid) { |
374 | if (name && !fastcmp<strncmp>(name, "zygote", 6)) { | 413 | if (name && !fastcmp<strncmp>(name, "zygote", 6)) { |
@@ -380,7 +419,7 @@ struct TidEntry : public EntryBaseDropped { | |||
380 | } | 419 | } |
381 | } | 420 | } |
382 | 421 | ||
383 | inline void add(LogBufferElement *element) { | 422 | inline void add(LogBufferElement* element) { |
384 | uid_t incomingUid = element->getUid(); | 423 | uid_t incomingUid = element->getUid(); |
385 | pid_t incomingPid = element->getPid(); | 424 | pid_t incomingPid = element->getPid(); |
386 | if ((getUid() != incomingUid) || (getPid() != incomingPid)) { | 425 | if ((getUid() != incomingUid) || (getPid() != incomingPid)) { |
@@ -394,8 +433,8 @@ struct TidEntry : public EntryBaseDropped { | |||
394 | EntryBaseDropped::add(element); | 433 | EntryBaseDropped::add(element); |
395 | } | 434 | } |
396 | 435 | ||
397 | std::string formatHeader(const std::string &name, log_id_t id) const; | 436 | std::string formatHeader(const std::string& name, log_id_t id) const; |
398 | std::string format(const LogStatistics &stat, log_id_t id) const; | 437 | std::string format(const LogStatistics& stat, log_id_t id) const; |
399 | }; | 438 | }; |
400 | 439 | ||
401 | struct TagEntry : public EntryBaseDropped { | 440 | struct TagEntry : public EntryBaseDropped { |
@@ -403,19 +442,27 @@ struct TagEntry : public EntryBaseDropped { | |||
403 | pid_t pid; | 442 | pid_t pid; |
404 | uid_t uid; | 443 | uid_t uid; |
405 | 444 | ||
406 | explicit TagEntry(LogBufferElement *element): | 445 | explicit TagEntry(LogBufferElement* element) |
407 | EntryBaseDropped(element), | 446 | : EntryBaseDropped(element), |
408 | tag(element->getTag()), | 447 | tag(element->getTag()), |
409 | pid(element->getPid()), | 448 | pid(element->getPid()), |
410 | uid(element->getUid()) { | 449 | uid(element->getUid()) { |
411 | } | 450 | } |
412 | 451 | ||
413 | const uint32_t&getKey() const { return tag; } | 452 | const uint32_t& getKey() const { |
414 | const pid_t&getPid() const { return pid; } | 453 | return tag; |
415 | const uid_t&getUid() const { return uid; } | 454 | } |
416 | const char*getName() const { return android::tagToName(tag); } | 455 | const pid_t& getPid() const { |
456 | return pid; | ||
457 | } | ||
458 | const uid_t& getUid() const { | ||
459 | return uid; | ||
460 | } | ||
461 | const char* getName() const { | ||
462 | return android::tagToName(tag); | ||
463 | } | ||
417 | 464 | ||
418 | inline void add(LogBufferElement *element) { | 465 | inline void add(LogBufferElement* element) { |
419 | if (uid != element->getUid()) { | 466 | if (uid != element->getUid()) { |
420 | uid = -1; | 467 | uid = -1; |
421 | } | 468 | } |
@@ -425,27 +472,27 @@ struct TagEntry : public EntryBaseDropped { | |||
425 | EntryBaseDropped::add(element); | 472 | EntryBaseDropped::add(element); |
426 | } | 473 | } |
427 | 474 | ||
428 | std::string formatHeader(const std::string &name, log_id_t id) const; | 475 | std::string formatHeader(const std::string& name, log_id_t id) const; |
429 | std::string format(const LogStatistics &stat, log_id_t id) const; | 476 | std::string format(const LogStatistics& stat, log_id_t id) const; |
430 | }; | 477 | }; |
431 | 478 | ||
432 | template <typename TEntry> | 479 | template <typename TEntry> |
433 | class LogFindWorst { | 480 | class LogFindWorst { |
434 | std::unique_ptr<const TEntry *[]> sorted; | 481 | std::unique_ptr<const TEntry* []> sorted; |
435 | 482 | ||
436 | public: | 483 | public: |
437 | 484 | explicit LogFindWorst(std::unique_ptr<const TEntry* []>&& sorted) | |
438 | explicit LogFindWorst(std::unique_ptr<const TEntry *[]> &&sorted) : sorted(std::move(sorted)) { } | 485 | : sorted(std::move(sorted)) { |
486 | } | ||
439 | 487 | ||
440 | void findWorst(int &worst, | 488 | void findWorst(int& worst, size_t& worst_sizes, size_t& second_worst_sizes, |
441 | size_t &worst_sizes, size_t &second_worst_sizes, | 489 | size_t threshold) { |
442 | size_t threshold) { | ||
443 | if (sorted.get() && sorted[0] && sorted[1]) { | 490 | if (sorted.get() && sorted[0] && sorted[1]) { |
444 | worst_sizes = sorted[0]->getSizes(); | 491 | worst_sizes = sorted[0]->getSizes(); |
445 | if ((worst_sizes > threshold) | 492 | if ((worst_sizes > threshold) |
446 | // Allow time horizon to extend roughly tenfold, assume | 493 | // Allow time horizon to extend roughly tenfold, assume |
447 | // average entry length is 100 characters. | 494 | // average entry length is 100 characters. |
448 | && (worst_sizes > (10 * sorted[0]->getDropped()))) { | 495 | && (worst_sizes > (10 * sorted[0]->getDropped()))) { |
449 | worst = sorted[0]->getKey(); | 496 | worst = sorted[0]->getKey(); |
450 | second_worst_sizes = sorted[1]->getSizes(); | 497 | second_worst_sizes = sorted[1]->getSizes(); |
451 | if (second_worst_sizes < threshold) { | 498 | if (second_worst_sizes < threshold) { |
@@ -455,13 +502,11 @@ public: | |||
455 | } | 502 | } |
456 | } | 503 | } |
457 | 504 | ||
458 | void findWorst(int &worst, | 505 | void findWorst(int& worst, size_t worst_sizes, size_t& second_worst_sizes) { |
459 | size_t worst_sizes, size_t &second_worst_sizes) { | ||
460 | if (sorted.get() && sorted[0] && sorted[1]) { | 506 | if (sorted.get() && sorted[0] && sorted[1]) { |
461 | worst = sorted[0]->getKey(); | 507 | worst = sorted[0]->getKey(); |
462 | second_worst_sizes = worst_sizes | 508 | second_worst_sizes = |
463 | - sorted[0]->getSizes() | 509 | worst_sizes - sorted[0]->getSizes() + sorted[1]->getSizes(); |
464 | + sorted[1]->getSizes(); | ||
465 | } | 510 | } |
466 | } | 511 | } |
467 | }; | 512 | }; |
@@ -506,11 +551,11 @@ class LogStatistics { | |||
506 | tagTable.sizeOf() + securityTagTable.sizeOf() + | 551 | tagTable.sizeOf() + securityTagTable.sizeOf() + |
507 | (pidTable.size() * sizeof(pidTable_t::iterator)) + | 552 | (pidTable.size() * sizeof(pidTable_t::iterator)) + |
508 | (tagTable.size() * sizeof(tagTable_t::iterator)); | 553 | (tagTable.size() * sizeof(tagTable_t::iterator)); |
509 | for(auto it : pidTable) { | 554 | for (auto it : pidTable) { |
510 | const char* name = it.second.getName(); | 555 | const char* name = it.second.getName(); |
511 | if (name) size += strlen(name) + 1; | 556 | if (name) size += strlen(name) + 1; |
512 | } | 557 | } |
513 | for(auto it : tidTable) { | 558 | for (auto it : tidTable) { |
514 | const char* name = it.second.getName(); | 559 | const char* name = it.second.getName(); |
515 | if (name) size += strlen(name) + 1; | 560 | if (name) size += strlen(name) + 1; |
516 | } | 561 | } |
@@ -518,23 +563,25 @@ class LogStatistics { | |||
518 | size += uidTable[id].sizeOf(); | 563 | size += uidTable[id].sizeOf(); |
519 | size += uidTable[id].size() * sizeof(uidTable_t::iterator); | 564 | size += uidTable[id].size() * sizeof(uidTable_t::iterator); |
520 | size += pidSystemTable[id].sizeOf(); | 565 | size += pidSystemTable[id].sizeOf(); |
521 | size += pidSystemTable[id].size() * sizeof(pidSystemTable_t::iterator); | 566 | size += |
567 | pidSystemTable[id].size() * sizeof(pidSystemTable_t::iterator); | ||
522 | } | 568 | } |
523 | return size; | 569 | return size; |
524 | } | 570 | } |
525 | 571 | ||
526 | public: | 572 | public: |
527 | |||
528 | LogStatistics(); | 573 | LogStatistics(); |
529 | 574 | ||
530 | void enableStatistics() { enable = true; } | 575 | void enableStatistics() { |
576 | enable = true; | ||
577 | } | ||
531 | 578 | ||
532 | void add(LogBufferElement *entry); | 579 | void add(LogBufferElement* entry); |
533 | void subtract(LogBufferElement *entry); | 580 | void subtract(LogBufferElement* entry); |
534 | // entry->setDropped(1) must follow this call | 581 | // entry->setDropped(1) must follow this call |
535 | void drop(LogBufferElement *entry); | 582 | void drop(LogBufferElement* entry); |
536 | // Correct for coalescing two entries referencing dropped content | 583 | // Correct for coalescing two entries referencing dropped content |
537 | void erase(LogBufferElement *element) { | 584 | void erase(LogBufferElement* element) { |
538 | log_id_t log_id = element->getLogId(); | 585 | log_id_t log_id = element->getLogId(); |
539 | --mElements[log_id]; | 586 | --mElements[log_id]; |
540 | --mDroppedElements[log_id]; | 587 | --mDroppedElements[log_id]; |
@@ -543,7 +590,8 @@ public: | |||
543 | LogFindWorst<UidEntry> sort(uid_t uid, pid_t pid, size_t len, log_id id) { | 590 | LogFindWorst<UidEntry> sort(uid_t uid, pid_t pid, size_t len, log_id id) { |
544 | return LogFindWorst<UidEntry>(uidTable[id].sort(uid, pid, len)); | 591 | return LogFindWorst<UidEntry>(uidTable[id].sort(uid, pid, len)); |
545 | } | 592 | } |
546 | LogFindWorst<PidEntry> sortPids(uid_t uid, pid_t pid, size_t len, log_id id) { | 593 | LogFindWorst<PidEntry> sortPids(uid_t uid, pid_t pid, size_t len, |
594 | log_id id) { | ||
547 | return LogFindWorst<PidEntry>(pidSystemTable[id].sort(uid, pid, len)); | 595 | return LogFindWorst<PidEntry>(pidSystemTable[id].sort(uid, pid, len)); |
548 | } | 596 | } |
549 | LogFindWorst<TagEntry> sortTags(uid_t uid, pid_t pid, size_t len, log_id) { | 597 | LogFindWorst<TagEntry> sortTags(uid_t uid, pid_t pid, size_t len, log_id) { |
@@ -551,21 +599,31 @@ public: | |||
551 | } | 599 | } |
552 | 600 | ||
553 | // fast track current value by id only | 601 | // fast track current value by id only |
554 | size_t sizes(log_id_t id) const { return mSizes[id]; } | 602 | size_t sizes(log_id_t id) const { |
555 | size_t elements(log_id_t id) const { return mElements[id]; } | 603 | return mSizes[id]; |
604 | } | ||
605 | size_t elements(log_id_t id) const { | ||
606 | return mElements[id]; | ||
607 | } | ||
556 | size_t realElements(log_id_t id) const { | 608 | size_t realElements(log_id_t id) const { |
557 | return mElements[id] - mDroppedElements[id]; | 609 | return mElements[id] - mDroppedElements[id]; |
558 | } | 610 | } |
559 | size_t sizesTotal(log_id_t id) const { return mSizesTotal[id]; } | 611 | size_t sizesTotal(log_id_t id) const { |
560 | size_t elementsTotal(log_id_t id) const { return mElementsTotal[id]; } | 612 | return mSizesTotal[id]; |
561 | static size_t sizesTotal() { return SizesTotal; } | 613 | } |
614 | size_t elementsTotal(log_id_t id) const { | ||
615 | return mElementsTotal[id]; | ||
616 | } | ||
617 | static size_t sizesTotal() { | ||
618 | return SizesTotal; | ||
619 | } | ||
562 | 620 | ||
563 | std::string format(uid_t uid, pid_t pid, unsigned int logMask) const; | 621 | std::string format(uid_t uid, pid_t pid, unsigned int logMask) const; |
564 | 622 | ||
565 | // helper (must be locked directly or implicitly by mLogElementsLock) | 623 | // helper (must be locked directly or implicitly by mLogElementsLock) |
566 | const char *pidToName(pid_t pid) const; | 624 | const char* pidToName(pid_t pid) const; |
567 | uid_t pidToUid(pid_t pid); | 625 | uid_t pidToUid(pid_t pid); |
568 | const char *uidToName(uid_t uid) const; | 626 | const char* uidToName(uid_t uid) const; |
569 | }; | 627 | }; |
570 | 628 | ||
571 | #endif // _LOGD_LOG_STATISTICS_H__ | 629 | #endif // _LOGD_LOG_STATISTICS_H__ |
diff --git a/logd/LogTags.cpp b/logd/LogTags.cpp index 64aa219e9..67649b1e7 100644 --- a/logd/LogTags.cpp +++ b/logd/LogTags.cpp | |||
@@ -50,11 +50,13 @@ static uid_t sniffUid(const char* comment, const char* endp) { | |||
50 | if (!comment) return AID_ROOT; | 50 | if (!comment) return AID_ROOT; |
51 | 51 | ||
52 | if (*comment == '#') ++comment; | 52 | if (*comment == '#') ++comment; |
53 | while ((comment < endp) && (*comment != '\n') && isspace(*comment)) ++comment; | 53 | while ((comment < endp) && (*comment != '\n') && isspace(*comment)) |
54 | ++comment; | ||
54 | static const char uid_str[] = "uid="; | 55 | static const char uid_str[] = "uid="; |
55 | if (((comment + strlen(uid_str)) >= endp) || | 56 | if (((comment + strlen(uid_str)) >= endp) || |
56 | fastcmp<strncmp>(comment, uid_str, strlen(uid_str)) || | 57 | fastcmp<strncmp>(comment, uid_str, strlen(uid_str)) || |
57 | !isdigit(comment[strlen(uid_str)])) return AID_ROOT; | 58 | !isdigit(comment[strlen(uid_str)])) |
59 | return AID_ROOT; | ||
58 | char* cp; | 60 | char* cp; |
59 | unsigned long Uid = strtoul(comment + 4, &cp, 10); | 61 | unsigned long Uid = strtoul(comment + 4, &cp, 10); |
60 | if ((cp > endp) || (Uid >= INT_MAX)) return AID_ROOT; | 62 | if ((cp > endp) || (Uid >= INT_MAX)) return AID_ROOT; |
@@ -86,34 +88,32 @@ bool LogTags::RebuildFileEventLogTags(const char* filename, bool warn) { | |||
86 | } | 88 | } |
87 | 89 | ||
88 | // dump what we already know back into the file? | 90 | // dump what we already know back into the file? |
89 | fd = TEMP_FAILURE_RETRY(open(filename, | 91 | fd = TEMP_FAILURE_RETRY(open( |
90 | O_WRONLY | O_TRUNC | O_CLOEXEC | | 92 | filename, O_WRONLY | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY)); |
91 | O_NOFOLLOW | O_BINARY)); | ||
92 | if (fd >= 0) { | 93 | if (fd >= 0) { |
93 | time_t now = time(NULL); | 94 | time_t now = time(NULL); |
94 | struct tm tm; | 95 | struct tm tm; |
95 | localtime_r(&now, &tm); | 96 | localtime_r(&now, &tm); |
96 | char timebuf[20]; | 97 | char timebuf[20]; |
97 | size_t len = strftime(timebuf, sizeof(timebuf), | 98 | size_t len = |
98 | "%Y-%m-%d %H:%M:%S", &tm); | 99 | strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", &tm); |
99 | android::base::WriteStringToFd( | 100 | android::base::WriteStringToFd( |
100 | android::base::StringPrintf( | 101 | android::base::StringPrintf( |
101 | "# Rebuilt %.20s, content owned by logd\n", timebuf), | 102 | "# Rebuilt %.20s, content owned by logd\n", timebuf), |
102 | fd); | 103 | fd); |
103 | for (const auto& it : tag2total) { | 104 | for (const auto& it : tag2total) { |
104 | android::base::WriteStringToFd(formatEntry_locked(it.first, | 105 | android::base::WriteStringToFd( |
105 | AID_ROOT), | 106 | formatEntry_locked(it.first, AID_ROOT), fd); |
106 | fd); | ||
107 | } | 107 | } |
108 | TEMP_FAILURE_RETRY(close(fd)); | 108 | TEMP_FAILURE_RETRY(close(fd)); |
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
112 | if (warn) { | 112 | if (warn) { |
113 | android::prdebug(((fd < 0) ? | 113 | android::prdebug( |
114 | "%s failed to rebuild" : | 114 | ((fd < 0) ? "%s failed to rebuild" |
115 | "%s missing, damaged or truncated; rebuilt"), | 115 | : "%s missing, damaged or truncated; rebuilt"), |
116 | filename); | 116 | filename); |
117 | } | 117 | } |
118 | 118 | ||
119 | if (fd >= 0) { | 119 | if (fd >= 0) { |
@@ -126,10 +126,9 @@ bool LogTags::RebuildFileEventLogTags(const char* filename, bool warn) { | |||
126 | return true; | 126 | return true; |
127 | } | 127 | } |
128 | 128 | ||
129 | void LogTags::AddEventLogTags(uint32_t tag, uid_t uid, | 129 | void LogTags::AddEventLogTags(uint32_t tag, uid_t uid, const std::string& Name, |
130 | const std::string& Name, | 130 | const std::string& Format, const char* source, |
131 | const std::string& Format, | 131 | bool warn) { |
132 | const char* source, bool warn) { | ||
133 | std::string Key = Name; | 132 | std::string Key = Name; |
134 | if (Format.length()) Key += "+" + Format; | 133 | if (Format.length()) Key += "+" + Format; |
135 | 134 | ||
@@ -178,8 +177,8 @@ void LogTags::AddEventLogTags(uint32_t tag, uid_t uid, | |||
178 | WritePersistEventLogTags(tag, uid, source); | 177 | WritePersistEventLogTags(tag, uid, source); |
179 | } else if (warn && !newOne && source) { | 178 | } else if (warn && !newOne && source) { |
180 | // For the files, we want to report dupes. | 179 | // For the files, we want to report dupes. |
181 | android::prdebug("Multiple tag %" PRIu32 " %s %s %s", tag, | 180 | android::prdebug("Multiple tag %" PRIu32 " %s %s %s", tag, Name.c_str(), |
182 | Name.c_str(), Format.c_str(), source); | 181 | Format.c_str(), source); |
183 | } | 182 | } |
184 | } | 183 | } |
185 | 184 | ||
@@ -193,7 +192,7 @@ void LogTags::ReadFileEventLogTags(const char* filename, bool warn) { | |||
193 | } | 192 | } |
194 | std::string content; | 193 | std::string content; |
195 | if (android::base::ReadFileToString(filename, &content)) { | 194 | if (android::base::ReadFileToString(filename, &content)) { |
196 | char* cp = (char*) content.c_str(); | 195 | char* cp = (char*)content.c_str(); |
197 | char* endp = cp + content.length(); | 196 | char* endp = cp + content.length(); |
198 | 197 | ||
199 | { | 198 | { |
@@ -228,16 +227,19 @@ void LogTags::ReadFileEventLogTags(const char* filename, bool warn) { | |||
228 | std::string Name(name, cp - name); | 227 | std::string Name(name, cp - name); |
229 | #ifdef ALLOW_NOISY_LOGGING_OF_PROBLEM_WITH_LOTS_OF_TECHNICAL_DEBT | 228 | #ifdef ALLOW_NOISY_LOGGING_OF_PROBLEM_WITH_LOTS_OF_TECHNICAL_DEBT |
230 | static const size_t maximum_official_tag_name_size = 24; | 229 | static const size_t maximum_official_tag_name_size = 24; |
231 | if (warn && (Name.length() > maximum_official_tag_name_size)) { | 230 | if (warn && |
232 | android::prdebug("tag name too long %s", Name.c_str()); | 231 | (Name.length() > maximum_official_tag_name_size)) { |
232 | android::prdebug("tag name too long %s", Name.c_str()); | ||
233 | } | 233 | } |
234 | #endif | 234 | #endif |
235 | if (hasAlpha && ((cp >= endp) || (*cp == '#') || isspace(*cp))) { | 235 | if (hasAlpha && |
236 | ((cp >= endp) || (*cp == '#') || isspace(*cp))) { | ||
236 | if (Tag > emptyTag) { | 237 | if (Tag > emptyTag) { |
237 | if (*cp != '\n') lineStart = NULL; | 238 | if (*cp != '\n') lineStart = NULL; |
238 | continue; | 239 | continue; |
239 | } | 240 | } |
240 | while ((cp < endp) && (*cp != '\n') && isspace(*cp)) ++cp; | 241 | while ((cp < endp) && (*cp != '\n') && isspace(*cp)) |
242 | ++cp; | ||
241 | const char* format = cp; | 243 | const char* format = cp; |
242 | uid_t uid = AID_ROOT; | 244 | uid_t uid = AID_ROOT; |
243 | while ((cp < endp) && (*cp != '\n')) { | 245 | while ((cp < endp) && (*cp != '\n')) { |
@@ -263,7 +265,9 @@ void LogTags::ReadFileEventLogTags(const char* filename, bool warn) { | |||
263 | } | 265 | } |
264 | lineStart = NULL; | 266 | lineStart = NULL; |
265 | } | 267 | } |
266 | } else if (!isspace(*cp)) break; | 268 | } else if (!isspace(*cp)) { |
269 | break; | ||
270 | } | ||
267 | } | 271 | } |
268 | cp++; | 272 | cp++; |
269 | } | 273 | } |
@@ -273,8 +277,7 @@ void LogTags::ReadFileEventLogTags(const char* filename, bool warn) { | |||
273 | } | 277 | } |
274 | 278 | ||
275 | // Extract a 4-byte value from a byte stream. | 279 | // Extract a 4-byte value from a byte stream. |
276 | static inline uint32_t get4LE(const char* msg) | 280 | static inline uint32_t get4LE(const char* msg) { |
277 | { | ||
278 | const uint8_t* src = reinterpret_cast<const uint8_t*>(msg); | 281 | const uint8_t* src = reinterpret_cast<const uint8_t*>(msg); |
279 | return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); | 282 | return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); |
280 | } | 283 | } |
@@ -284,8 +287,8 @@ static inline uint32_t get4LE(const char* msg) | |||
284 | // database with any found. | 287 | // database with any found. |
285 | void LogTags::ReadPersistEventLogTags() { | 288 | void LogTags::ReadPersistEventLogTags() { |
286 | struct logger_list* logger_list = android_logger_list_alloc( | 289 | struct logger_list* logger_list = android_logger_list_alloc( |
287 | ANDROID_LOG_RDONLY | ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK, | 290 | ANDROID_LOG_RDONLY | ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK, 0, |
288 | 0, (pid_t)0); | 291 | (pid_t)0); |
289 | if (!logger_list) return; | 292 | if (!logger_list) return; |
290 | 293 | ||
291 | struct logger* e = android_logger_open(logger_list, LOG_ID_EVENTS); | 294 | struct logger* e = android_logger_open(logger_list, LOG_ID_EVENTS); |
@@ -305,8 +308,9 @@ void LogTags::ReadPersistEventLogTags() { | |||
305 | if (log_msg.entry.len <= sizeof(uint32_t)) continue; | 308 | if (log_msg.entry.len <= sizeof(uint32_t)) continue; |
306 | uint32_t Tag = get4LE(msg); | 309 | uint32_t Tag = get4LE(msg); |
307 | if (Tag != TAG_DEF_LOG_TAG) continue; | 310 | if (Tag != TAG_DEF_LOG_TAG) continue; |
308 | uid_t uid = (log_msg.entry.hdr_size >= sizeof(logger_entry_v4)) ? | 311 | uid_t uid = (log_msg.entry.hdr_size >= sizeof(logger_entry_v4)) |
309 | log_msg.entry.uid : AID_ROOT; | 312 | ? log_msg.entry.uid |
313 | : AID_ROOT; | ||
310 | 314 | ||
311 | std::string Name; | 315 | std::string Name; |
312 | std::string Format; | 316 | std::string Format; |
@@ -433,8 +437,7 @@ uint32_t LogTags::nameToTag(const char* name) const { | |||
433 | // writer lock. We use this call to invent a new deterministically | 437 | // writer lock. We use this call to invent a new deterministically |
434 | // random tag, unique is cleared if no conflicts. If format is NULL, | 438 | // random tag, unique is cleared if no conflicts. If format is NULL, |
435 | // we are in readonly mode. | 439 | // we are in readonly mode. |
436 | uint32_t LogTags::nameToTag_locked(const std::string& name, | 440 | uint32_t LogTags::nameToTag_locked(const std::string& name, const char* format, |
437 | const char* format, | ||
438 | bool& unique) { | 441 | bool& unique) { |
439 | key2tag_const_iterator ik; | 442 | key2tag_const_iterator ik; |
440 | 443 | ||
@@ -462,7 +465,7 @@ uint32_t LogTags::nameToTag_locked(const std::string& name, | |||
462 | size_t Hash = key2tag.hash_function()(Key); | 465 | size_t Hash = key2tag.hash_function()(Key); |
463 | uint32_t Tag = Hash; | 466 | uint32_t Tag = Hash; |
464 | // This sets an upper limit on the conflics we are allowed to deal with. | 467 | // This sets an upper limit on the conflics we are allowed to deal with. |
465 | for (unsigned i = 0; i < 256; ) { | 468 | for (unsigned i = 0; i < 256;) { |
466 | tag2name_const_iterator it = tag2name.find(Tag); | 469 | tag2name_const_iterator it = tag2name.find(Tag); |
467 | if (it == tag2name.end()) return Tag; | 470 | if (it == tag2name.end()) return Tag; |
468 | std::string localKey(it->second); | 471 | std::string localKey(it->second); |
@@ -471,15 +474,14 @@ uint32_t LogTags::nameToTag_locked(const std::string& name, | |||
471 | localKey += "+" + iform->second; | 474 | localKey += "+" + iform->second; |
472 | } | 475 | } |
473 | unique = !!it->second.compare(localKey); | 476 | unique = !!it->second.compare(localKey); |
474 | if (!unique) return Tag; // unlikely except in a race | 477 | if (!unique) return Tag; // unlikely except in a race |
475 | 478 | ||
476 | ++i; | 479 | ++i; |
477 | // Algorithm to convert hash to next tag | 480 | // Algorithm to convert hash to next tag |
478 | if (i < 32) { | 481 | if (i < 32) { |
479 | Tag = (Hash >> i); | 482 | Tag = (Hash >> i); |
480 | // size_t is 32 bits, or upper word zero, rotate | 483 | // size_t is 32 bits, or upper word zero, rotate |
481 | if ((sizeof(Hash) <= 4) || | 484 | if ((sizeof(Hash) <= 4) || ((Hash & (uint64_t(-1LL) << 32)) == 0)) { |
482 | ((Hash & (uint64_t(-1LL) << 32)) == 0)) { | ||
483 | Tag |= Hash << (32 - i); | 485 | Tag |= Hash << (32 - i); |
484 | } | 486 | } |
485 | } else { | 487 | } else { |
@@ -501,7 +503,7 @@ void LogTags::WritePmsgEventLogTags(uint32_t tag, uid_t uid) { | |||
501 | android::RWLock::AutoRLock readLock(rwlock); | 503 | android::RWLock::AutoRLock readLock(rwlock); |
502 | 504 | ||
503 | tag2total_const_iterator itot = tag2total.find(tag); | 505 | tag2total_const_iterator itot = tag2total.find(tag); |
504 | if (itot == tag2total.end()) return; // source is a static entry | 506 | if (itot == tag2total.end()) return; // source is a static entry |
505 | 507 | ||
506 | size_t lastTotal = itot->second; | 508 | size_t lastTotal = itot->second; |
507 | 509 | ||
@@ -525,7 +527,7 @@ void LogTags::WritePmsgEventLogTags(uint32_t tag, uid_t uid) { | |||
525 | __android_log_event_list ctx(TAG_DEF_LOG_TAG); | 527 | __android_log_event_list ctx(TAG_DEF_LOG_TAG); |
526 | ctx << tag << Name << Format; | 528 | ctx << tag << Name << Format; |
527 | std::string buffer(ctx); | 529 | std::string buffer(ctx); |
528 | if (buffer.length() <= 0) return; // unlikely | 530 | if (buffer.length() <= 0) return; // unlikely |
529 | 531 | ||
530 | /* | 532 | /* |
531 | * struct { | 533 | * struct { |
@@ -562,18 +564,17 @@ void LogTags::WritePmsgEventLogTags(uint32_t tag, uid_t uid) { | |||
562 | 564 | ||
563 | android_pmsg_log_header_t pmsgHeader = { | 565 | android_pmsg_log_header_t pmsgHeader = { |
564 | .magic = LOGGER_MAGIC, | 566 | .magic = LOGGER_MAGIC, |
565 | .len = (uint16_t)(sizeof(pmsgHeader) + sizeof(header) + | 567 | .len = (uint16_t)(sizeof(pmsgHeader) + sizeof(header) + sizeof(outTag) + |
566 | sizeof(outTag) + buffer.length()), | 568 | buffer.length()), |
567 | .uid = (uint16_t)AID_ROOT, | 569 | .uid = (uint16_t)AID_ROOT, |
568 | .pid = (uint16_t)getpid(), | 570 | .pid = (uint16_t)getpid(), |
569 | }; | 571 | }; |
570 | 572 | ||
571 | struct iovec Vec[] = { | 573 | struct iovec Vec[] = { { (unsigned char*)&pmsgHeader, sizeof(pmsgHeader) }, |
572 | { (unsigned char*)&pmsgHeader, sizeof(pmsgHeader) }, | 574 | { (unsigned char*)&header, sizeof(header) }, |
573 | { (unsigned char*)&header, sizeof(header) }, | 575 | { (unsigned char*)&outTag, sizeof(outTag) }, |
574 | { (unsigned char*)&outTag, sizeof(outTag) }, | 576 | { (unsigned char*)const_cast<char*>(buffer.data()), |
575 | { (unsigned char*)const_cast<char*>(buffer.data()), buffer.length() } | 577 | buffer.length() } }; |
576 | }; | ||
577 | 578 | ||
578 | tag2uid_const_iterator ut = tag2uid.find(tag); | 579 | tag2uid_const_iterator ut = tag2uid.find(tag); |
579 | if (ut == tag2uid.end()) { | 580 | if (ut == tag2uid.end()) { |
@@ -582,7 +583,7 @@ void LogTags::WritePmsgEventLogTags(uint32_t tag, uid_t uid) { | |||
582 | pmsgHeader.uid = (uint16_t)uid; | 583 | pmsgHeader.uid = (uint16_t)uid; |
583 | TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec))); | 584 | TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec))); |
584 | } else { | 585 | } else { |
585 | for (auto &it : ut->second) { | 586 | for (auto& it : ut->second) { |
586 | pmsgHeader.uid = (uint16_t)it; | 587 | pmsgHeader.uid = (uint16_t)it; |
587 | TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec))); | 588 | TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec))); |
588 | } | 589 | } |
@@ -590,8 +591,8 @@ void LogTags::WritePmsgEventLogTags(uint32_t tag, uid_t uid) { | |||
590 | } | 591 | } |
591 | 592 | ||
592 | void LogTags::WriteDynamicEventLogTags(uint32_t tag, uid_t uid) { | 593 | void LogTags::WriteDynamicEventLogTags(uint32_t tag, uid_t uid) { |
593 | static const int mode = O_WRONLY | O_APPEND | | 594 | static const int mode = |
594 | O_CLOEXEC | O_NOFOLLOW | O_BINARY; | 595 | O_WRONLY | O_APPEND | O_CLOEXEC | O_NOFOLLOW | O_BINARY; |
595 | 596 | ||
596 | int fd = openFile(dynamic_event_log_tags, mode, true); | 597 | int fd = openFile(dynamic_event_log_tags, mode, true); |
597 | if (fd < 0) return; | 598 | if (fd < 0) return; |
@@ -612,8 +613,8 @@ void LogTags::WriteDynamicEventLogTags(uint32_t tag, uid_t uid) { | |||
612 | } | 613 | } |
613 | 614 | ||
614 | void LogTags::WriteDebugEventLogTags(uint32_t tag, uid_t uid) { | 615 | void LogTags::WriteDebugEventLogTags(uint32_t tag, uid_t uid) { |
615 | static const int mode = O_WRONLY | O_APPEND | | 616 | static const int mode = |
616 | O_CLOEXEC | O_NOFOLLOW | O_BINARY; | 617 | O_WRONLY | O_APPEND | O_CLOEXEC | O_NOFOLLOW | O_BINARY; |
617 | 618 | ||
618 | static bool one = true; | 619 | static bool one = true; |
619 | int fd = openFile(debug_event_log_tags, mode, one); | 620 | int fd = openFile(debug_event_log_tags, mode, one); |
@@ -636,16 +637,14 @@ void LogTags::WriteDebugEventLogTags(uint32_t tag, uid_t uid) { | |||
636 | } | 637 | } |
637 | 638 | ||
638 | // How we maintain some runtime or reboot stickiness | 639 | // How we maintain some runtime or reboot stickiness |
639 | void LogTags::WritePersistEventLogTags(uint32_t tag, | 640 | void LogTags::WritePersistEventLogTags(uint32_t tag, uid_t uid, |
640 | uid_t uid, const char* source) { | 641 | const char* source) { |
641 | // very unlikely | 642 | // very unlikely |
642 | bool etc = source && !strcmp(source, system_event_log_tags); | 643 | bool etc = source && !strcmp(source, system_event_log_tags); |
643 | if (etc) return; | 644 | if (etc) return; |
644 | 645 | ||
645 | bool dynamic = source && !strcmp(source, dynamic_event_log_tags); | 646 | bool dynamic = source && !strcmp(source, dynamic_event_log_tags); |
646 | bool debug = (!dynamic && | 647 | bool debug = (!dynamic && source && !strcmp(source, debug_event_log_tags)) || |
647 | source && | ||
648 | !strcmp(source, debug_event_log_tags)) || | ||
649 | !__android_log_is_debuggable(); | 648 | !__android_log_is_debuggable(); |
650 | 649 | ||
651 | WritePmsgEventLogTags(tag, uid); | 650 | WritePmsgEventLogTags(tag, uid); |
@@ -658,7 +657,7 @@ void LogTags::WritePersistEventLogTags(uint32_t tag, | |||
658 | if (itot != tag2total.end()) lastTotal = itot->second; | 657 | if (itot != tag2total.end()) lastTotal = itot->second; |
659 | } | 658 | } |
660 | 659 | ||
661 | if (lastTotal == 0) { // denotes first time for this one | 660 | if (lastTotal == 0) { // denotes first time for this one |
662 | if (!dynamic || !RebuildFileEventLogTags(dynamic_event_log_tags)) { | 661 | if (!dynamic || !RebuildFileEventLogTags(dynamic_event_log_tags)) { |
663 | WriteDynamicEventLogTags(tag, uid); | 662 | WriteDynamicEventLogTags(tag, uid); |
664 | } | 663 | } |
@@ -694,9 +693,9 @@ uint32_t LogTags::nameToTag(uid_t uid, const char* name, const char* format) { | |||
694 | tag2uid_const_iterator ut = tag2uid.find(Tag); | 693 | tag2uid_const_iterator ut = tag2uid.find(Tag); |
695 | if (updateUid) { | 694 | if (updateUid) { |
696 | if ((ut != tag2uid.end()) && | 695 | if ((ut != tag2uid.end()) && |
697 | (ut->second.find(uid) == ut->second.end())) { | 696 | (ut->second.find(uid) == ut->second.end())) { |
698 | unique = write; // write passthrough to update uid counts | 697 | unique = write; // write passthrough to update uid counts |
699 | if (!write) Tag = emptyTag; // deny read access | 698 | if (!write) Tag = emptyTag; // deny read access |
700 | } | 699 | } |
701 | } else { | 700 | } else { |
702 | unique = write && (ut != tag2uid.end()); | 701 | unique = write && (ut != tag2uid.end()); |
@@ -705,7 +704,7 @@ uint32_t LogTags::nameToTag(uid_t uid, const char* name, const char* format) { | |||
705 | } | 704 | } |
706 | 705 | ||
707 | if (Tag == emptyTag) return Tag; | 706 | if (Tag == emptyTag) return Tag; |
708 | WritePmsgEventLogTags(Tag, uid); // record references periodically | 707 | WritePmsgEventLogTags(Tag, uid); // record references periodically |
709 | if (!unique) return Tag; | 708 | if (!unique) return Tag; |
710 | 709 | ||
711 | bool updateWrite = false; | 710 | bool updateWrite = false; |
@@ -728,7 +727,9 @@ uint32_t LogTags::nameToTag(uid_t uid, const char* name, const char* format) { | |||
728 | if (updateUid) { | 727 | if (updateUid) { |
729 | // Add it to the uid list | 728 | // Add it to the uid list |
730 | if ((ut == tag2uid.end()) || | 729 | if ((ut == tag2uid.end()) || |
731 | (ut->second.find(uid) != ut->second.end())) return Tag; | 730 | (ut->second.find(uid) != ut->second.end())) { |
731 | return Tag; | ||
732 | } | ||
732 | const_cast<uid_list&>(ut->second).emplace(uid); | 733 | const_cast<uid_list&>(ut->second).emplace(uid); |
733 | updateWrite = true; | 734 | updateWrite = true; |
734 | } else { | 735 | } else { |
@@ -791,8 +792,7 @@ uint32_t LogTags::nameToTag(uid_t uid, const char* name, const char* format) { | |||
791 | return Tag; | 792 | return Tag; |
792 | } | 793 | } |
793 | 794 | ||
794 | std::string LogTags::formatEntry(uint32_t tag, uid_t uid, | 795 | std::string LogTags::formatEntry(uint32_t tag, uid_t uid, const char* name, |
795 | const char* name, | ||
796 | const char* format) { | 796 | const char* format) { |
797 | if (!format || !format[0]) { | 797 | if (!format || !format[0]) { |
798 | return android::base::StringPrintf("%" PRIu32 "\t%s\n", tag, name); | 798 | return android::base::StringPrintf("%" PRIu32 "\t%s\n", tag, name); |
@@ -802,9 +802,8 @@ std::string LogTags::formatEntry(uint32_t tag, uid_t uid, | |||
802 | if (len > strlen(tabs)) len = strlen(tabs); | 802 | if (len > strlen(tabs)) len = strlen(tabs); |
803 | std::string Uid; | 803 | std::string Uid; |
804 | if (uid != AID_ROOT) Uid = android::base::StringPrintf(" # uid=%u", uid); | 804 | if (uid != AID_ROOT) Uid = android::base::StringPrintf(" # uid=%u", uid); |
805 | return android::base::StringPrintf("%" PRIu32 "\t%s%s\t%s%s\n", | 805 | return android::base::StringPrintf("%" PRIu32 "\t%s%s\t%s%s\n", tag, name, |
806 | tag, name, &tabs[len], format, | 806 | &tabs[len], format, Uid.c_str()); |
807 | Uid.c_str()); | ||
808 | } | 807 | } |
809 | 808 | ||
810 | std::string LogTags::formatEntry_locked(uint32_t tag, uid_t uid, | 809 | std::string LogTags::formatEntry_locked(uint32_t tag, uid_t uid, |
@@ -830,7 +829,7 @@ std::string LogTags::formatEntry_locked(uint32_t tag, uid_t uid, | |||
830 | 829 | ||
831 | // Show all, one for each registered uid (we are group root) | 830 | // Show all, one for each registered uid (we are group root) |
832 | std::string ret; | 831 | std::string ret; |
833 | for (auto &it : ut->second) { | 832 | for (auto& it : ut->second) { |
834 | ret += formatEntry(tag, it, name, format); | 833 | ret += formatEntry(tag, it, name, format); |
835 | } | 834 | } |
836 | return ret; | 835 | return ret; |
@@ -841,8 +840,8 @@ std::string LogTags::formatEntry(uint32_t tag, uid_t uid) { | |||
841 | return formatEntry_locked(tag, uid); | 840 | return formatEntry_locked(tag, uid); |
842 | } | 841 | } |
843 | 842 | ||
844 | std::string LogTags::formatGetEventTag(uid_t uid, | 843 | std::string LogTags::formatGetEventTag(uid_t uid, const char* name, |
845 | const char* name, const char* format) { | 844 | const char* format) { |
846 | bool all = name && (name[0] == '*') && !name[1]; | 845 | bool all = name && (name[0] == '*') && !name[1]; |
847 | bool list = !name || all; | 846 | bool list = !name || all; |
848 | std::string ret; | 847 | std::string ret; |
@@ -864,7 +863,7 @@ std::string LogTags::formatGetEventTag(uid_t uid, | |||
864 | // first uid in list so as to manufacture an accurate reference | 863 | // first uid in list so as to manufacture an accurate reference |
865 | tag2uid_const_iterator ut = tag2uid.find(tag); | 864 | tag2uid_const_iterator ut = tag2uid.find(tag); |
866 | if ((ut != tag2uid.end()) && | 865 | if ((ut != tag2uid.end()) && |
867 | (ut->second.begin() != ut->second.end())) { | 866 | (ut->second.begin() != ut->second.end())) { |
868 | uid = *(ut->second.begin()); | 867 | uid = *(ut->second.begin()); |
869 | } | 868 | } |
870 | } | 869 | } |
diff --git a/logd/LogTags.h b/logd/LogTags.h index 4457c462f..203318d91 100644 --- a/logd/LogTags.h +++ b/logd/LogTags.h | |||
@@ -17,9 +17,9 @@ | |||
17 | #ifndef _LOGD_LOG_TAGS_H__ | 17 | #ifndef _LOGD_LOG_TAGS_H__ |
18 | #define _LOGD_LOG_TAGS_H__ | 18 | #define _LOGD_LOG_TAGS_H__ |
19 | 19 | ||
20 | #include <string> | ||
20 | #include <unordered_map> | 21 | #include <unordered_map> |
21 | #include <unordered_set> | 22 | #include <unordered_set> |
22 | #include <string> | ||
23 | 23 | ||
24 | #include <utils/RWLock.h> | 24 | #include <utils/RWLock.h> |
25 | 25 | ||
@@ -35,64 +35,70 @@ class LogTags { | |||
35 | 35 | ||
36 | // key is Name + "+" + Format | 36 | // key is Name + "+" + Format |
37 | std::unordered_map<std::string, uint32_t> key2tag; | 37 | std::unordered_map<std::string, uint32_t> key2tag; |
38 | typedef std::unordered_map<std::string, uint32_t>::const_iterator key2tag_const_iterator; | 38 | typedef std::unordered_map<std::string, uint32_t>::const_iterator |
39 | key2tag_const_iterator; | ||
39 | 40 | ||
40 | // Allows us to manage access permissions based on uid registrants | 41 | // Allows us to manage access permissions based on uid registrants |
41 | // Global entries are specifically erased. | 42 | // Global entries are specifically erased. |
42 | typedef std::unordered_set<uid_t> uid_list; | 43 | typedef std::unordered_set<uid_t> uid_list; |
43 | std::unordered_map<uint32_t, uid_list> tag2uid; | 44 | std::unordered_map<uint32_t, uid_list> tag2uid; |
44 | typedef std::unordered_map<uint32_t, uid_list>::const_iterator tag2uid_const_iterator; | 45 | typedef std::unordered_map<uint32_t, uid_list>::const_iterator |
46 | tag2uid_const_iterator; | ||
45 | 47 | ||
46 | std::unordered_map<uint32_t, std::string> tag2name; | 48 | std::unordered_map<uint32_t, std::string> tag2name; |
47 | typedef std::unordered_map<uint32_t, std::string>::const_iterator tag2name_const_iterator; | 49 | typedef std::unordered_map<uint32_t, std::string>::const_iterator |
50 | tag2name_const_iterator; | ||
48 | 51 | ||
49 | std::unordered_map<uint32_t, std::string> tag2format; | 52 | std::unordered_map<uint32_t, std::string> tag2format; |
50 | typedef std::unordered_map<uint32_t, std::string>::const_iterator tag2format_const_iterator; | 53 | typedef std::unordered_map<uint32_t, std::string>::const_iterator |
54 | tag2format_const_iterator; | ||
51 | 55 | ||
52 | static const size_t max_per_uid = 256; // Put a cap on the tags per uid | 56 | static const size_t max_per_uid = 256; // Put a cap on the tags per uid |
53 | std::unordered_map<uid_t, size_t> uid2count; | 57 | std::unordered_map<uid_t, size_t> uid2count; |
54 | typedef std::unordered_map<uid_t, size_t>::const_iterator uid2count_const_iterator; | 58 | typedef std::unordered_map<uid_t, size_t>::const_iterator |
59 | uid2count_const_iterator; | ||
55 | 60 | ||
56 | // Dynamic entries are assigned | 61 | // Dynamic entries are assigned |
57 | std::unordered_map<uint32_t, size_t> tag2total; | 62 | std::unordered_map<uint32_t, size_t> tag2total; |
58 | typedef std::unordered_map<uint32_t, size_t>::const_iterator tag2total_const_iterator; | 63 | typedef std::unordered_map<uint32_t, size_t>::const_iterator |
64 | tag2total_const_iterator; | ||
59 | 65 | ||
60 | // emplace unique tag | 66 | // emplace unique tag |
61 | uint32_t nameToTag(uid_t uid, const char* name, const char* format); | 67 | uint32_t nameToTag(uid_t uid, const char* name, const char* format); |
62 | // find unique or associated tag | 68 | // find unique or associated tag |
63 | uint32_t nameToTag_locked(const std::string& name, const char* format, bool &unique); | 69 | uint32_t nameToTag_locked(const std::string& name, const char* format, |
70 | bool& unique); | ||
64 | 71 | ||
65 | // Record expected file watermarks to detect corruption. | 72 | // Record expected file watermarks to detect corruption. |
66 | std::unordered_map<std::string, size_t> file2watermark; | 73 | std::unordered_map<std::string, size_t> file2watermark; |
67 | typedef std::unordered_map<std::string, size_t>::const_iterator file2watermark_const_iterator; | 74 | typedef std::unordered_map<std::string, size_t>::const_iterator |
75 | file2watermark_const_iterator; | ||
68 | 76 | ||
69 | void ReadPersistEventLogTags(); | 77 | void ReadPersistEventLogTags(); |
70 | 78 | ||
71 | // format helpers | 79 | // format helpers |
72 | // format a single entry, does not need object data | 80 | // format a single entry, does not need object data |
73 | static std::string formatEntry(uint32_t tag, uid_t uid, | 81 | static std::string formatEntry(uint32_t tag, uid_t uid, const char* name, |
74 | const char* name, const char* format); | 82 | const char* format); |
75 | // caller locks, database lookup, authenticate against uid | 83 | // caller locks, database lookup, authenticate against uid |
76 | std::string formatEntry_locked(uint32_t tag, uid_t uid, | 84 | std::string formatEntry_locked(uint32_t tag, uid_t uid, |
77 | bool authenticate = true); | 85 | bool authenticate = true); |
78 | 86 | ||
79 | bool RebuildFileEventLogTags(const char* filename, bool warn = true); | 87 | bool RebuildFileEventLogTags(const char* filename, bool warn = true); |
80 | 88 | ||
81 | void AddEventLogTags(uint32_t tag, uid_t uid, | 89 | void AddEventLogTags(uint32_t tag, uid_t uid, const std::string& Name, |
82 | const std::string& Name, const std::string& Format, | 90 | const std::string& Format, const char* source = NULL, |
83 | const char* source = NULL, bool warn = false); | 91 | bool warn = false); |
84 | 92 | ||
85 | void WriteDynamicEventLogTags(uint32_t tag, uid_t uid); | 93 | void WriteDynamicEventLogTags(uint32_t tag, uid_t uid); |
86 | void WriteDebugEventLogTags(uint32_t tag, uid_t uid); | 94 | void WriteDebugEventLogTags(uint32_t tag, uid_t uid); |
87 | // push tag details to persistent storage | 95 | // push tag details to persistent storage |
88 | void WritePersistEventLogTags(uint32_t tag, | 96 | void WritePersistEventLogTags(uint32_t tag, uid_t uid = AID_ROOT, |
89 | uid_t uid = AID_ROOT, | ||
90 | const char* source = NULL); | 97 | const char* source = NULL); |
91 | 98 | ||
92 | static const uint32_t emptyTag = uint32_t(-1); | 99 | static const uint32_t emptyTag = uint32_t(-1); |
93 | 100 | ||
94 | public: | 101 | public: |
95 | |||
96 | static const char system_event_log_tags[]; | 102 | static const char system_event_log_tags[]; |
97 | static const char dynamic_event_log_tags[]; | 103 | static const char dynamic_event_log_tags[]; |
98 | // Only for userdebug and eng | 104 | // Only for userdebug and eng |
@@ -111,9 +117,8 @@ public: | |||
111 | uint32_t nameToTag(const char* name) const; | 117 | uint32_t nameToTag(const char* name) const; |
112 | 118 | ||
113 | // emplace tag if necessary, provide event-log-tag formated output in string | 119 | // emplace tag if necessary, provide event-log-tag formated output in string |
114 | std::string formatGetEventTag(uid_t uid, | 120 | std::string formatGetEventTag(uid_t uid, const char* name, |
115 | const char* name, | ||
116 | const char* format); | 121 | const char* format); |
117 | }; | 122 | }; |
118 | 123 | ||
119 | #endif // _LOGD_LOG_TAGS_H__ | 124 | #endif // _LOGD_LOG_TAGS_H__ |
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp index 2a04880e4..bdaeb751c 100644 --- a/logd/LogTimes.cpp +++ b/logd/LogTimes.cpp | |||
@@ -19,30 +19,30 @@ | |||
19 | 19 | ||
20 | #include "FlushCommand.h" | 20 | #include "FlushCommand.h" |
21 | #include "LogBuffer.h" | 21 | #include "LogBuffer.h" |
22 | #include "LogTimes.h" | ||
23 | #include "LogReader.h" | 22 | #include "LogReader.h" |
23 | #include "LogTimes.h" | ||
24 | 24 | ||
25 | pthread_mutex_t LogTimeEntry::timesLock = PTHREAD_MUTEX_INITIALIZER; | 25 | pthread_mutex_t LogTimeEntry::timesLock = PTHREAD_MUTEX_INITIALIZER; |
26 | 26 | ||
27 | LogTimeEntry::LogTimeEntry(LogReader &reader, SocketClient *client, | 27 | LogTimeEntry::LogTimeEntry(LogReader& reader, SocketClient* client, |
28 | bool nonBlock, unsigned long tail, | 28 | bool nonBlock, unsigned long tail, |
29 | unsigned int logMask, pid_t pid, | 29 | unsigned int logMask, pid_t pid, uint64_t start, |
30 | uint64_t start, uint64_t timeout) : | 30 | uint64_t timeout) |
31 | mRefCount(1), | 31 | : mRefCount(1), |
32 | mRelease(false), | 32 | mRelease(false), |
33 | mError(false), | 33 | mError(false), |
34 | threadRunning(false), | 34 | threadRunning(false), |
35 | leadingDropped(false), | 35 | leadingDropped(false), |
36 | mReader(reader), | 36 | mReader(reader), |
37 | mLogMask(logMask), | 37 | mLogMask(logMask), |
38 | mPid(pid), | 38 | mPid(pid), |
39 | mCount(0), | 39 | mCount(0), |
40 | mTail(tail), | 40 | mTail(tail), |
41 | mIndex(0), | 41 | mIndex(0), |
42 | mClient(client), | 42 | mClient(client), |
43 | mStart(start), | 43 | mStart(start), |
44 | mNonBlock(nonBlock), | 44 | mNonBlock(nonBlock), |
45 | mEnd(LogBufferElement::getCurrentSequence()) { | 45 | mEnd(LogBufferElement::getCurrentSequence()) { |
46 | mTimeout.tv_sec = timeout / NS_PER_SEC; | 46 | mTimeout.tv_sec = timeout / NS_PER_SEC; |
47 | mTimeout.tv_nsec = timeout % NS_PER_SEC; | 47 | mTimeout.tv_nsec = timeout % NS_PER_SEC; |
48 | pthread_cond_init(&threadTriggeredCondition, NULL); | 48 | pthread_cond_init(&threadTriggeredCondition, NULL); |
@@ -56,8 +56,8 @@ void LogTimeEntry::startReader_Locked(void) { | |||
56 | 56 | ||
57 | if (!pthread_attr_init(&attr)) { | 57 | if (!pthread_attr_init(&attr)) { |
58 | if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { | 58 | if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { |
59 | if (!pthread_create(&mThread, &attr, | 59 | if (!pthread_create(&mThread, &attr, LogTimeEntry::threadStart, |
60 | LogTimeEntry::threadStart, this)) { | 60 | this)) { |
61 | pthread_attr_destroy(&attr); | 61 | pthread_attr_destroy(&attr); |
62 | return; | 62 | return; |
63 | } | 63 | } |
@@ -71,8 +71,8 @@ void LogTimeEntry::startReader_Locked(void) { | |||
71 | decRef_Locked(); | 71 | decRef_Locked(); |
72 | } | 72 | } |
73 | 73 | ||
74 | void LogTimeEntry::threadStop(void *obj) { | 74 | void LogTimeEntry::threadStop(void* obj) { |
75 | LogTimeEntry *me = reinterpret_cast<LogTimeEntry *>(obj); | 75 | LogTimeEntry* me = reinterpret_cast<LogTimeEntry*>(obj); |
76 | 76 | ||
77 | lock(); | 77 | lock(); |
78 | 78 | ||
@@ -80,14 +80,14 @@ void LogTimeEntry::threadStop(void *obj) { | |||
80 | me->error_Locked(); | 80 | me->error_Locked(); |
81 | } | 81 | } |
82 | 82 | ||
83 | SocketClient *client = me->mClient; | 83 | SocketClient* client = me->mClient; |
84 | 84 | ||
85 | if (me->isError_Locked()) { | 85 | if (me->isError_Locked()) { |
86 | LogReader &reader = me->mReader; | 86 | LogReader& reader = me->mReader; |
87 | LastLogTimes × = reader.logbuf().mTimes; | 87 | LastLogTimes& times = reader.logbuf().mTimes; |
88 | 88 | ||
89 | LastLogTimes::iterator it = times.begin(); | 89 | LastLogTimes::iterator it = times.begin(); |
90 | while(it != times.end()) { | 90 | while (it != times.end()) { |
91 | if (*it == me) { | 91 | if (*it == me) { |
92 | times.erase(it); | 92 | times.erase(it); |
93 | me->release_nodelete_Locked(); | 93 | me->release_nodelete_Locked(); |
@@ -110,20 +110,20 @@ void LogTimeEntry::threadStop(void *obj) { | |||
110 | unlock(); | 110 | unlock(); |
111 | } | 111 | } |
112 | 112 | ||
113 | void *LogTimeEntry::threadStart(void *obj) { | 113 | void* LogTimeEntry::threadStart(void* obj) { |
114 | prctl(PR_SET_NAME, "logd.reader.per"); | 114 | prctl(PR_SET_NAME, "logd.reader.per"); |
115 | 115 | ||
116 | LogTimeEntry *me = reinterpret_cast<LogTimeEntry *>(obj); | 116 | LogTimeEntry* me = reinterpret_cast<LogTimeEntry*>(obj); |
117 | 117 | ||
118 | pthread_cleanup_push(threadStop, obj); | 118 | pthread_cleanup_push(threadStop, obj); |
119 | 119 | ||
120 | SocketClient *client = me->mClient; | 120 | SocketClient* client = me->mClient; |
121 | if (!client) { | 121 | if (!client) { |
122 | me->error(); | 122 | me->error(); |
123 | return NULL; | 123 | return NULL; |
124 | } | 124 | } |
125 | 125 | ||
126 | LogBuffer &logbuf = me->mReader.logbuf(); | 126 | LogBuffer& logbuf = me->mReader.logbuf(); |
127 | 127 | ||
128 | bool privileged = FlushCommand::hasReadLogs(client); | 128 | bool privileged = FlushCommand::hasReadLogs(client); |
129 | bool security = FlushCommand::hasSecurityLogs(client); | 129 | bool security = FlushCommand::hasSecurityLogs(client); |
@@ -135,11 +135,9 @@ void *LogTimeEntry::threadStart(void *obj) { | |||
135 | uint64_t start = me->mStart; | 135 | uint64_t start = me->mStart; |
136 | 136 | ||
137 | while (me->threadRunning && !me->isError_Locked()) { | 137 | while (me->threadRunning && !me->isError_Locked()) { |
138 | |||
139 | if (me->mTimeout.tv_sec || me->mTimeout.tv_nsec) { | 138 | if (me->mTimeout.tv_sec || me->mTimeout.tv_nsec) { |
140 | if (pthread_cond_timedwait(&me->threadTriggeredCondition, | 139 | if (pthread_cond_timedwait(&me->threadTriggeredCondition, |
141 | ×Lock, | 140 | ×Lock, &me->mTimeout) == ETIMEDOUT) { |
142 | &me->mTimeout) == ETIMEDOUT) { | ||
143 | me->mTimeout.tv_sec = 0; | 141 | me->mTimeout.tv_sec = 0; |
144 | me->mTimeout.tv_nsec = 0; | 142 | me->mTimeout.tv_nsec = 0; |
145 | } | 143 | } |
@@ -151,10 +149,12 @@ void *LogTimeEntry::threadStart(void *obj) { | |||
151 | unlock(); | 149 | unlock(); |
152 | 150 | ||
153 | if (me->mTail) { | 151 | if (me->mTail) { |
154 | logbuf.flushTo(client, start, privileged, security, FilterFirstPass, me); | 152 | logbuf.flushTo(client, start, privileged, security, FilterFirstPass, |
153 | me); | ||
155 | me->leadingDropped = true; | 154 | me->leadingDropped = true; |
156 | } | 155 | } |
157 | start = logbuf.flushTo(client, start, privileged, security, FilterSecondPass, me); | 156 | start = logbuf.flushTo(client, start, privileged, security, |
157 | FilterSecondPass, me); | ||
158 | 158 | ||
159 | lock(); | 159 | lock(); |
160 | 160 | ||
@@ -184,8 +184,8 @@ void *LogTimeEntry::threadStart(void *obj) { | |||
184 | } | 184 | } |
185 | 185 | ||
186 | // A first pass to count the number of elements | 186 | // A first pass to count the number of elements |
187 | int LogTimeEntry::FilterFirstPass(const LogBufferElement *element, void *obj) { | 187 | int LogTimeEntry::FilterFirstPass(const LogBufferElement* element, void* obj) { |
188 | LogTimeEntry *me = reinterpret_cast<LogTimeEntry *>(obj); | 188 | LogTimeEntry* me = reinterpret_cast<LogTimeEntry*>(obj); |
189 | 189 | ||
190 | LogTimeEntry::lock(); | 190 | LogTimeEntry::lock(); |
191 | 191 | ||
@@ -201,8 +201,8 @@ int LogTimeEntry::FilterFirstPass(const LogBufferElement *element, void *obj) { | |||
201 | me->mStart = element->getSequence(); | 201 | me->mStart = element->getSequence(); |
202 | } | 202 | } |
203 | 203 | ||
204 | if ((!me->mPid || (me->mPid == element->getPid())) | 204 | if ((!me->mPid || (me->mPid == element->getPid())) && |
205 | && (me->isWatching(element->getLogId()))) { | 205 | (me->isWatching(element->getLogId()))) { |
206 | ++me->mCount; | 206 | ++me->mCount; |
207 | } | 207 | } |
208 | 208 | ||
@@ -212,8 +212,8 @@ int LogTimeEntry::FilterFirstPass(const LogBufferElement *element, void *obj) { | |||
212 | } | 212 | } |
213 | 213 | ||
214 | // A second pass to send the selected elements | 214 | // A second pass to send the selected elements |
215 | int LogTimeEntry::FilterSecondPass(const LogBufferElement *element, void *obj) { | 215 | int LogTimeEntry::FilterSecondPass(const LogBufferElement* element, void* obj) { |
216 | LogTimeEntry *me = reinterpret_cast<LogTimeEntry *>(obj); | 216 | LogTimeEntry* me = reinterpret_cast<LogTimeEntry*>(obj); |
217 | 217 | ||
218 | LogTimeEntry::lock(); | 218 | LogTimeEntry::lock(); |
219 | 219 | ||
@@ -267,7 +267,7 @@ ok: | |||
267 | LogTimeEntry::unlock(); | 267 | LogTimeEntry::unlock(); |
268 | return true; | 268 | return true; |
269 | } | 269 | } |
270 | // FALLTHRU | 270 | // FALLTHRU |
271 | 271 | ||
272 | skip: | 272 | skip: |
273 | LogTimeEntry::unlock(); | 273 | LogTimeEntry::unlock(); |
@@ -279,7 +279,7 @@ stop: | |||
279 | } | 279 | } |
280 | 280 | ||
281 | void LogTimeEntry::cleanSkip_Locked(void) { | 281 | void LogTimeEntry::cleanSkip_Locked(void) { |
282 | for (log_id_t i = LOG_ID_MIN; i < LOG_ID_MAX; i = (log_id_t) (i + 1)) { | 282 | for (log_id_t i = LOG_ID_MIN; i < LOG_ID_MAX; i = (log_id_t)(i + 1)) { |
283 | skipAhead[i] = 0; | 283 | skipAhead[i] = 0; |
284 | } | 284 | } |
285 | } | 285 | } |
diff --git a/logd/LogTimes.h b/logd/LogTimes.h index 12df994af..23fdf4eea 100644 --- a/logd/LogTimes.h +++ b/logd/LogTimes.h | |||
@@ -18,8 +18,8 @@ | |||
18 | #define _LOGD_LOG_TIMES_H__ | 18 | #define _LOGD_LOG_TIMES_H__ |
19 | 19 | ||
20 | #include <pthread.h> | 20 | #include <pthread.h> |
21 | #include <time.h> | ||
22 | #include <sys/types.h> | 21 | #include <sys/types.h> |
22 | #include <time.h> | ||
23 | 23 | ||
24 | #include <list> | 24 | #include <list> |
25 | 25 | ||
@@ -38,9 +38,9 @@ class LogTimeEntry { | |||
38 | bool leadingDropped; | 38 | bool leadingDropped; |
39 | pthread_cond_t threadTriggeredCondition; | 39 | pthread_cond_t threadTriggeredCondition; |
40 | pthread_t mThread; | 40 | pthread_t mThread; |
41 | LogReader &mReader; | 41 | LogReader& mReader; |
42 | static void *threadStart(void *me); | 42 | static void* threadStart(void* me); |
43 | static void threadStop(void *me); | 43 | static void threadStop(void* me); |
44 | const unsigned int mLogMask; | 44 | const unsigned int mLogMask; |
45 | const pid_t mPid; | 45 | const pid_t mPid; |
46 | unsigned int skipAhead[LOG_ID_MAX]; | 46 | unsigned int skipAhead[LOG_ID_MAX]; |
@@ -48,20 +48,24 @@ class LogTimeEntry { | |||
48 | unsigned long mTail; | 48 | unsigned long mTail; |
49 | unsigned long mIndex; | 49 | unsigned long mIndex; |
50 | 50 | ||
51 | public: | 51 | public: |
52 | LogTimeEntry(LogReader &reader, SocketClient *client, bool nonBlock, | 52 | LogTimeEntry(LogReader& reader, SocketClient* client, bool nonBlock, |
53 | unsigned long tail, unsigned int logMask, pid_t pid, | 53 | unsigned long tail, unsigned int logMask, pid_t pid, |
54 | uint64_t start, uint64_t timeout); | 54 | uint64_t start, uint64_t timeout); |
55 | 55 | ||
56 | SocketClient *mClient; | 56 | SocketClient* mClient; |
57 | uint64_t mStart; | 57 | uint64_t mStart; |
58 | struct timespec mTimeout; | 58 | struct timespec mTimeout; |
59 | const bool mNonBlock; | 59 | const bool mNonBlock; |
60 | const uint64_t mEnd; // only relevant if mNonBlock | 60 | const uint64_t mEnd; // only relevant if mNonBlock |
61 | 61 | ||
62 | // Protect List manipulations | 62 | // Protect List manipulations |
63 | static void lock(void) { pthread_mutex_lock(×Lock); } | 63 | static void lock(void) { |
64 | static void unlock(void) { pthread_mutex_unlock(×Lock); } | 64 | pthread_mutex_lock(×Lock); |
65 | } | ||
66 | static void unlock(void) { | ||
67 | pthread_mutex_unlock(×Lock); | ||
68 | } | ||
65 | 69 | ||
66 | void startReader_Locked(void); | 70 | void startReader_Locked(void); |
67 | 71 | ||
@@ -72,7 +76,9 @@ public: | |||
72 | pthread_cond_signal(&threadTriggeredCondition); | 76 | pthread_cond_signal(&threadTriggeredCondition); |
73 | } | 77 | } |
74 | 78 | ||
75 | void triggerSkip_Locked(log_id_t id, unsigned int skip) { skipAhead[id] = skip; } | 79 | void triggerSkip_Locked(log_id_t id, unsigned int skip) { |
80 | skipAhead[id] = skip; | ||
81 | } | ||
76 | void cleanSkip_Locked(void); | 82 | void cleanSkip_Locked(void); |
77 | 83 | ||
78 | // These called after LogTimeEntry removed from list, lock implicitly held | 84 | // These called after LogTimeEntry removed from list, lock implicitly held |
@@ -93,16 +99,28 @@ public: | |||
93 | } | 99 | } |
94 | 100 | ||
95 | // Called to mark socket in jeopardy | 101 | // Called to mark socket in jeopardy |
96 | void error_Locked(void) { mError = true; } | 102 | void error_Locked(void) { |
97 | void error(void) { lock(); error_Locked(); unlock(); } | 103 | mError = true; |
104 | } | ||
105 | void error(void) { | ||
106 | lock(); | ||
107 | error_Locked(); | ||
108 | unlock(); | ||
109 | } | ||
98 | 110 | ||
99 | bool isError_Locked(void) const { return mRelease || mError; } | 111 | bool isError_Locked(void) const { |
112 | return mRelease || mError; | ||
113 | } | ||
100 | 114 | ||
101 | // Mark Used | 115 | // Mark Used |
102 | // Locking implied, grabbed when protection around loop iteration | 116 | // Locking implied, grabbed when protection around loop iteration |
103 | void incRef_Locked(void) { ++mRefCount; } | 117 | void incRef_Locked(void) { |
118 | ++mRefCount; | ||
119 | } | ||
104 | 120 | ||
105 | bool owned_Locked(void) const { return mRefCount != 0; } | 121 | bool owned_Locked(void) const { |
122 | return mRefCount != 0; | ||
123 | } | ||
106 | 124 | ||
107 | void decRef_Locked(void) { | 125 | void decRef_Locked(void) { |
108 | if ((mRefCount && --mRefCount) || !mRelease || threadRunning) { | 126 | if ((mRefCount && --mRefCount) || !mRelease || threadRunning) { |
@@ -111,12 +129,14 @@ public: | |||
111 | // No one else is holding a reference to this | 129 | // No one else is holding a reference to this |
112 | delete this; | 130 | delete this; |
113 | } | 131 | } |
114 | bool isWatching(log_id_t id) { return (mLogMask & (1<<id)) != 0; } | 132 | bool isWatching(log_id_t id) { |
133 | return (mLogMask & (1 << id)) != 0; | ||
134 | } | ||
115 | // flushTo filter callbacks | 135 | // flushTo filter callbacks |
116 | static int FilterFirstPass(const LogBufferElement *element, void *me); | 136 | static int FilterFirstPass(const LogBufferElement* element, void* me); |
117 | static int FilterSecondPass(const LogBufferElement *element, void *me); | 137 | static int FilterSecondPass(const LogBufferElement* element, void* me); |
118 | }; | 138 | }; |
119 | 139 | ||
120 | typedef std::list<LogTimeEntry *> LastLogTimes; | 140 | typedef std::list<LogTimeEntry*> LastLogTimes; |
121 | 141 | ||
122 | #endif // _LOGD_LOG_TIMES_H__ | 142 | #endif // _LOGD_LOG_TIMES_H__ |
diff --git a/logd/LogUtils.h b/logd/LogUtils.h index f044b2744..93d2a7927 100644 --- a/logd/LogUtils.h +++ b/logd/LogUtils.h | |||
@@ -20,9 +20,9 @@ | |||
20 | #include <sys/cdefs.h> | 20 | #include <sys/cdefs.h> |
21 | #include <sys/types.h> | 21 | #include <sys/types.h> |
22 | 22 | ||
23 | #include <utils/FastStrcmp.h> | ||
24 | #include <private/android_logger.h> | 23 | #include <private/android_logger.h> |
25 | #include <sysutils/SocketClient.h> | 24 | #include <sysutils/SocketClient.h> |
25 | #include <utils/FastStrcmp.h> | ||
26 | 26 | ||
27 | // Hijack this header as a common include file used by most all sources | 27 | // Hijack this header as a common include file used by most all sources |
28 | // to report some utilities defined here and there. | 28 | // to report some utilities defined here and there. |
@@ -30,31 +30,30 @@ | |||
30 | namespace android { | 30 | namespace android { |
31 | 31 | ||
32 | // Furnished in main.cpp. Caller must own and free returned value | 32 | // Furnished in main.cpp. Caller must own and free returned value |
33 | char *uidToName(uid_t uid); | 33 | char* uidToName(uid_t uid); |
34 | void prdebug(const char *fmt, ...) __printflike(1, 2); | 34 | void prdebug(const char* fmt, ...) __printflike(1, 2); |
35 | 35 | ||
36 | // Furnished in LogStatistics.cpp. | 36 | // Furnished in LogStatistics.cpp. |
37 | size_t sizesTotal(); | 37 | size_t sizesTotal(); |
38 | // Caller must own and free returned value | 38 | // Caller must own and free returned value |
39 | char *pidToName(pid_t pid); | 39 | char* pidToName(pid_t pid); |
40 | char *tidToName(pid_t tid); | 40 | char* tidToName(pid_t tid); |
41 | 41 | ||
42 | // Furnished in LogTags.cpp. Thread safe. | 42 | // Furnished in LogTags.cpp. Thread safe. |
43 | const char *tagToName(uint32_t tag); | 43 | const char* tagToName(uint32_t tag); |
44 | void ReReadEventLogTags(); | 44 | void ReReadEventLogTags(); |
45 | 45 | ||
46 | // Furnished by LogKlog.cpp. | 46 | // Furnished by LogKlog.cpp. |
47 | const char* strnstr(const char* s, size_t len, const char* needle); | 47 | const char* strnstr(const char* s, size_t len, const char* needle); |
48 | |||
49 | } | 48 | } |
50 | 49 | ||
51 | // Furnished in LogCommand.cpp | 50 | // Furnished in LogCommand.cpp |
52 | bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid); | 51 | bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid); |
53 | bool clientHasLogCredentials(SocketClient *cli); | 52 | bool clientHasLogCredentials(SocketClient* cli); |
54 | 53 | ||
55 | static inline bool worstUidEnabledForLogid(log_id_t id) { | 54 | static inline bool worstUidEnabledForLogid(log_id_t id) { |
56 | return (id == LOG_ID_MAIN) || (id == LOG_ID_SYSTEM) || | 55 | return (id == LOG_ID_MAIN) || (id == LOG_ID_SYSTEM) || |
57 | (id == LOG_ID_RADIO) || (id == LOG_ID_EVENTS); | 56 | (id == LOG_ID_RADIO) || (id == LOG_ID_EVENTS); |
58 | } | 57 | } |
59 | 58 | ||
60 | #endif // _LOGD_LOG_UTILS_H__ | 59 | #endif // _LOGD_LOG_UTILS_H__ |
diff --git a/logd/LogWhiteBlackList.cpp b/logd/LogWhiteBlackList.cpp index ae933b548..4b8b08042 100644 --- a/logd/LogWhiteBlackList.cpp +++ b/logd/LogWhiteBlackList.cpp | |||
@@ -64,7 +64,7 @@ PruneList::~PruneList() { | |||
64 | } | 64 | } |
65 | } | 65 | } |
66 | 66 | ||
67 | int PruneList::init(const char *str) { | 67 | int PruneList::init(const char* str) { |
68 | mWorstUidEnabled = true; | 68 | mWorstUidEnabled = true; |
69 | mWorstPidOfSystemEnabled = true; | 69 | mWorstPidOfSystemEnabled = true; |
70 | PruneCollection::iterator it; | 70 | PruneCollection::iterator it; |
@@ -113,13 +113,13 @@ int PruneList::init(const char *str) { | |||
113 | mWorstUidEnabled = false; | 113 | mWorstUidEnabled = false; |
114 | mWorstPidOfSystemEnabled = false; | 114 | mWorstPidOfSystemEnabled = false; |
115 | 115 | ||
116 | for(str = filter.c_str(); *str; ++str) { | 116 | for (str = filter.c_str(); *str; ++str) { |
117 | if (isspace(*str)) { | 117 | if (isspace(*str)) { |
118 | continue; | 118 | continue; |
119 | } | 119 | } |
120 | 120 | ||
121 | PruneCollection *list; | 121 | PruneCollection* list; |
122 | if ((*str == '~') || (*str == '!')) { // ~ supported, ! undocumented | 122 | if ((*str == '~') || (*str == '!')) { // ~ supported, ! undocumented |
123 | ++str; | 123 | ++str; |
124 | // special case, translates to worst UID at priority in blacklist | 124 | // special case, translates to worst UID at priority in blacklist |
125 | if (*str == '!') { | 125 | if (*str == '!') { |
@@ -184,7 +184,7 @@ int PruneList::init(const char *str) { | |||
184 | // insert sequentially into list | 184 | // insert sequentially into list |
185 | PruneCollection::iterator it = list->begin(); | 185 | PruneCollection::iterator it = list->begin(); |
186 | while (it != list->end()) { | 186 | while (it != list->end()) { |
187 | Prune &p = *it; | 187 | Prune& p = *it; |
188 | int m = uid - p.mUid; | 188 | int m = uid - p.mUid; |
189 | if (m == 0) { | 189 | if (m == 0) { |
190 | if (p.mPid == p.pid_all) { | 190 | if (p.mPid == p.pid_all) { |
@@ -198,14 +198,14 @@ int PruneList::init(const char *str) { | |||
198 | } | 198 | } |
199 | if (m <= 0) { | 199 | if (m <= 0) { |
200 | if (m < 0) { | 200 | if (m < 0) { |
201 | list->insert(it, Prune(uid,pid)); | 201 | list->insert(it, Prune(uid, pid)); |
202 | } | 202 | } |
203 | break; | 203 | break; |
204 | } | 204 | } |
205 | ++it; | 205 | ++it; |
206 | } | 206 | } |
207 | if (it == list->end()) { | 207 | if (it == list->end()) { |
208 | list->push_back(Prune(uid,pid)); | 208 | list->push_back(Prune(uid, pid)); |
209 | } | 209 | } |
210 | if (!*str) { | 210 | if (!*str) { |
211 | break; | 211 | break; |
@@ -217,7 +217,7 @@ int PruneList::init(const char *str) { | |||
217 | 217 | ||
218 | std::string PruneList::format() { | 218 | std::string PruneList::format() { |
219 | static const char nice_format[] = " %s"; | 219 | static const char nice_format[] = " %s"; |
220 | const char *fmt = nice_format + 1; | 220 | const char* fmt = nice_format + 1; |
221 | 221 | ||
222 | std::string string; | 222 | std::string string; |
223 | 223 | ||
@@ -250,7 +250,7 @@ std::string PruneList::format() { | |||
250 | // If there is scaling issues, resort to a better algorithm than linear | 250 | // If there is scaling issues, resort to a better algorithm than linear |
251 | // based on these assumptions. | 251 | // based on these assumptions. |
252 | 252 | ||
253 | bool PruneList::naughty(LogBufferElement *element) { | 253 | bool PruneList::naughty(LogBufferElement* element) { |
254 | PruneCollection::iterator it; | 254 | PruneCollection::iterator it; |
255 | for (it = mNaughty.begin(); it != mNaughty.end(); ++it) { | 255 | for (it = mNaughty.begin(); it != mNaughty.end(); ++it) { |
256 | if (!(*it).cmp(element)) { | 256 | if (!(*it).cmp(element)) { |
@@ -260,7 +260,7 @@ bool PruneList::naughty(LogBufferElement *element) { | |||
260 | return false; | 260 | return false; |
261 | } | 261 | } |
262 | 262 | ||
263 | bool PruneList::nice(LogBufferElement *element) { | 263 | bool PruneList::nice(LogBufferElement* element) { |
264 | PruneCollection::iterator it; | 264 | PruneCollection::iterator it; |
265 | for (it = mNice.begin(); it != mNice.end(); ++it) { | 265 | for (it = mNice.begin(); it != mNice.end(); ++it) { |
266 | if (!(*it).cmp(element)) { | 266 | if (!(*it).cmp(element)) { |
diff --git a/logd/LogWhiteBlackList.h b/logd/LogWhiteBlackList.h index 8b8e02f7d..6e9893b6d 100644 --- a/logd/LogWhiteBlackList.h +++ b/logd/LogWhiteBlackList.h | |||
@@ -19,8 +19,8 @@ | |||
19 | 19 | ||
20 | #include <sys/types.h> | 20 | #include <sys/types.h> |
21 | 21 | ||
22 | #include <list> | ||
23 | #include <string.h> | 22 | #include <string.h> |
23 | #include <list> | ||
24 | 24 | ||
25 | #include "LogBufferElement.h" | 25 | #include "LogBufferElement.h" |
26 | 26 | ||
@@ -33,16 +33,22 @@ class Prune { | |||
33 | const pid_t mPid; | 33 | const pid_t mPid; |
34 | int cmp(uid_t uid, pid_t pid) const; | 34 | int cmp(uid_t uid, pid_t pid) const; |
35 | 35 | ||
36 | public: | 36 | public: |
37 | static const uid_t uid_all = (uid_t) -1; | 37 | static const uid_t uid_all = (uid_t)-1; |
38 | static const pid_t pid_all = (pid_t) -1; | 38 | static const pid_t pid_all = (pid_t)-1; |
39 | 39 | ||
40 | Prune(uid_t uid, pid_t pid); | 40 | Prune(uid_t uid, pid_t pid); |
41 | 41 | ||
42 | uid_t getUid() const { return mUid; } | 42 | uid_t getUid() const { |
43 | pid_t getPid() const { return mPid; } | 43 | return mUid; |
44 | } | ||
45 | pid_t getPid() const { | ||
46 | return mPid; | ||
47 | } | ||
44 | 48 | ||
45 | int cmp(LogBufferElement *e) const { return cmp(e->getUid(), e->getPid()); } | 49 | int cmp(LogBufferElement* e) const { |
50 | return cmp(e->getUid(), e->getPid()); | ||
51 | } | ||
46 | 52 | ||
47 | std::string format(); | 53 | std::string format(); |
48 | }; | 54 | }; |
@@ -55,20 +61,28 @@ class PruneList { | |||
55 | bool mWorstUidEnabled; | 61 | bool mWorstUidEnabled; |
56 | bool mWorstPidOfSystemEnabled; | 62 | bool mWorstPidOfSystemEnabled; |
57 | 63 | ||
58 | public: | 64 | public: |
59 | PruneList(); | 65 | PruneList(); |
60 | ~PruneList(); | 66 | ~PruneList(); |
61 | 67 | ||
62 | int init(const char *str); | 68 | int init(const char* str); |
63 | 69 | ||
64 | bool naughty(LogBufferElement *element); | 70 | bool naughty(LogBufferElement* element); |
65 | bool naughty(void) { return !mNaughty.empty(); } | 71 | bool naughty(void) { |
66 | bool nice(LogBufferElement *element); | 72 | return !mNaughty.empty(); |
67 | bool nice(void) { return !mNice.empty(); } | 73 | } |
68 | bool worstUidEnabled() const { return mWorstUidEnabled; } | 74 | bool nice(LogBufferElement* element); |
69 | bool worstPidOfSystemEnabled() const { return mWorstPidOfSystemEnabled; } | 75 | bool nice(void) { |
76 | return !mNice.empty(); | ||
77 | } | ||
78 | bool worstUidEnabled() const { | ||
79 | return mWorstUidEnabled; | ||
80 | } | ||
81 | bool worstPidOfSystemEnabled() const { | ||
82 | return mWorstPidOfSystemEnabled; | ||
83 | } | ||
70 | 84 | ||
71 | std::string format(); | 85 | std::string format(); |
72 | }; | 86 | }; |
73 | 87 | ||
74 | #endif // _LOGD_LOG_WHITE_BLACK_LIST_H__ | 88 | #endif // _LOGD_LOG_WHITE_BLACK_LIST_H__ |
diff --git a/logd/libaudit.c b/logd/libaudit.c index 216f1a18c..dfd56f23a 100644 --- a/logd/libaudit.c +++ b/logd/libaudit.c | |||
@@ -31,8 +31,7 @@ | |||
31 | * @return | 31 | * @return |
32 | * This function returns 0 on success, else -errno. | 32 | * This function returns 0 on success, else -errno. |
33 | */ | 33 | */ |
34 | static int get_ack(int fd) | 34 | static int get_ack(int fd) { |
35 | { | ||
36 | int rc; | 35 | int rc; |
37 | struct audit_message rep; | 36 | struct audit_message rep; |
38 | 37 | ||
@@ -48,7 +47,7 @@ static int get_ack(int fd) | |||
48 | 47 | ||
49 | if (rep.nlh.nlmsg_type == NLMSG_ERROR) { | 48 | if (rep.nlh.nlmsg_type == NLMSG_ERROR) { |
50 | audit_get_reply(fd, &rep, GET_REPLY_BLOCKING, 0); | 49 | audit_get_reply(fd, &rep, GET_REPLY_BLOCKING, 0); |
51 | rc = ((struct nlmsgerr *)rep.data)->error; | 50 | rc = ((struct nlmsgerr*)rep.data)->error; |
52 | if (rc) { | 51 | if (rc) { |
53 | return -rc; | 52 | return -rc; |
54 | } | 53 | } |
@@ -70,8 +69,7 @@ static int get_ack(int fd) | |||
70 | * @return | 69 | * @return |
71 | * This function returns a positive sequence number on success, else -errno. | 70 | * This function returns a positive sequence number on success, else -errno. |
72 | */ | 71 | */ |
73 | static int audit_send(int fd, int type, const void *data, size_t size) | 72 | static int audit_send(int fd, int type, const void* data, size_t size) { |
74 | { | ||
75 | int rc; | 73 | int rc; |
76 | static int16_t sequence = 0; | 74 | static int16_t sequence = 0; |
77 | struct audit_message req; | 75 | struct audit_message req; |
@@ -123,13 +121,13 @@ static int audit_send(int fd, int type, const void *data, size_t size) | |||
123 | /* While failing and its due to interrupts */ | 121 | /* While failing and its due to interrupts */ |
124 | 122 | ||
125 | rc = TEMP_FAILURE_RETRY(sendto(fd, &req, req.nlh.nlmsg_len, 0, | 123 | rc = TEMP_FAILURE_RETRY(sendto(fd, &req, req.nlh.nlmsg_len, 0, |
126 | (struct sockaddr*) &addr, sizeof(addr))); | 124 | (struct sockaddr*)&addr, sizeof(addr))); |
127 | 125 | ||
128 | /* Not all the bytes were sent */ | 126 | /* Not all the bytes were sent */ |
129 | if (rc < 0) { | 127 | if (rc < 0) { |
130 | rc = -errno; | 128 | rc = -errno; |
131 | goto out; | 129 | goto out; |
132 | } else if ((uint32_t) rc != req.nlh.nlmsg_len) { | 130 | } else if ((uint32_t)rc != req.nlh.nlmsg_len) { |
133 | rc = -EPROTO; | 131 | rc = -EPROTO; |
134 | goto out; | 132 | goto out; |
135 | } | 133 | } |
@@ -138,7 +136,7 @@ static int audit_send(int fd, int type, const void *data, size_t size) | |||
138 | rc = get_ack(fd); | 136 | rc = get_ack(fd); |
139 | 137 | ||
140 | /* If the ack failed, return the error, else return the sequence number */ | 138 | /* If the ack failed, return the error, else return the sequence number */ |
141 | rc = (rc == 0) ? (int) sequence : rc; | 139 | rc = (rc == 0) ? (int)sequence : rc; |
142 | 140 | ||
143 | out: | 141 | out: |
144 | /* Don't let sequence roll to negative */ | 142 | /* Don't let sequence roll to negative */ |
@@ -149,8 +147,7 @@ out: | |||
149 | return rc; | 147 | return rc; |
150 | } | 148 | } |
151 | 149 | ||
152 | int audit_setup(int fd, pid_t pid) | 150 | int audit_setup(int fd, pid_t pid) { |
153 | { | ||
154 | int rc; | 151 | int rc; |
155 | struct audit_message rep; | 152 | struct audit_message rep; |
156 | struct audit_status status; | 153 | struct audit_status status; |
@@ -186,8 +183,7 @@ int audit_setup(int fd, pid_t pid) | |||
186 | return 0; | 183 | return 0; |
187 | } | 184 | } |
188 | 185 | ||
189 | int audit_rate_limit(int fd, unsigned rate_limit) | 186 | int audit_rate_limit(int fd, unsigned rate_limit) { |
190 | { | ||
191 | int rc; | 187 | int rc; |
192 | struct audit_message rep; | 188 | struct audit_message rep; |
193 | struct audit_status status; | 189 | struct audit_status status; |
@@ -207,13 +203,11 @@ int audit_rate_limit(int fd, unsigned rate_limit) | |||
207 | return 0; | 203 | return 0; |
208 | } | 204 | } |
209 | 205 | ||
210 | int audit_open() | 206 | int audit_open() { |
211 | { | ||
212 | return socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_AUDIT); | 207 | return socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_AUDIT); |
213 | } | 208 | } |
214 | 209 | ||
215 | int audit_get_reply(int fd, struct audit_message *rep, reply_t block, int peek) | 210 | int audit_get_reply(int fd, struct audit_message* rep, reply_t block, int peek) { |
216 | { | ||
217 | ssize_t len; | 211 | ssize_t len; |
218 | int flags; | 212 | int flags; |
219 | int rc = 0; | 213 | int rc = 0; |
@@ -235,7 +229,7 @@ int audit_get_reply(int fd, struct audit_message *rep, reply_t block, int peek) | |||
235 | * however, can be returned. | 229 | * however, can be returned. |
236 | */ | 230 | */ |
237 | len = TEMP_FAILURE_RETRY(recvfrom(fd, rep, sizeof(*rep), flags, | 231 | len = TEMP_FAILURE_RETRY(recvfrom(fd, rep, sizeof(*rep), flags, |
238 | (struct sockaddr*) &nladdr, &nladdrlen)); | 232 | (struct sockaddr*)&nladdr, &nladdrlen)); |
239 | 233 | ||
240 | /* | 234 | /* |
241 | * EAGAIN should be re-tried until success or another error manifests. | 235 | * EAGAIN should be re-tried until success or another error manifests. |
@@ -266,7 +260,6 @@ int audit_get_reply(int fd, struct audit_message *rep, reply_t block, int peek) | |||
266 | return rc; | 260 | return rc; |
267 | } | 261 | } |
268 | 262 | ||
269 | void audit_close(int fd) | 263 | void audit_close(int fd) { |
270 | { | ||
271 | close(fd); | 264 | close(fd); |
272 | } | 265 | } |
diff --git a/logd/libaudit.h b/logd/libaudit.h index 9865d4304..a2afe47b4 100644 --- a/logd/libaudit.h +++ b/logd/libaudit.h | |||
@@ -25,17 +25,14 @@ | |||
25 | #include <sys/socket.h> | 25 | #include <sys/socket.h> |
26 | #include <sys/types.h> | 26 | #include <sys/types.h> |
27 | 27 | ||
28 | #include <linux/netlink.h> | ||
29 | #include <linux/audit.h> | 28 | #include <linux/audit.h> |
29 | #include <linux/netlink.h> | ||
30 | 30 | ||
31 | __BEGIN_DECLS | 31 | __BEGIN_DECLS |
32 | 32 | ||
33 | #define MAX_AUDIT_MESSAGE_LENGTH 8970 | 33 | #define MAX_AUDIT_MESSAGE_LENGTH 8970 |
34 | 34 | ||
35 | typedef enum { | 35 | typedef enum { GET_REPLY_BLOCKING = 0, GET_REPLY_NONBLOCKING } reply_t; |
36 | GET_REPLY_BLOCKING = 0, | ||
37 | GET_REPLY_NONBLOCKING | ||
38 | } reply_t; | ||
39 | 36 | ||
40 | /* type == AUDIT_SIGNAL_INFO */ | 37 | /* type == AUDIT_SIGNAL_INFO */ |
41 | struct audit_sig_info { | 38 | struct audit_sig_info { |
@@ -46,7 +43,7 @@ struct audit_sig_info { | |||
46 | 43 | ||
47 | struct audit_message { | 44 | struct audit_message { |
48 | struct nlmsghdr nlh; | 45 | struct nlmsghdr nlh; |
49 | char data[MAX_AUDIT_MESSAGE_LENGTH]; | 46 | char data[MAX_AUDIT_MESSAGE_LENGTH]; |
50 | }; | 47 | }; |
51 | 48 | ||
52 | /** | 49 | /** |
@@ -78,7 +75,7 @@ extern void audit_close(int fd); | |||
78 | * @return | 75 | * @return |
79 | * This function returns 0 on success, else -errno. | 76 | * This function returns 0 on success, else -errno. |
80 | */ | 77 | */ |
81 | extern int audit_get_reply(int fd, struct audit_message *rep, reply_t block, | 78 | extern int audit_get_reply(int fd, struct audit_message* rep, reply_t block, |
82 | int peek); | 79 | int peek); |
83 | 80 | ||
84 | /** | 81 | /** |
@@ -105,7 +102,7 @@ extern int audit_setup(int fd, pid_t pid); | |||
105 | /* Guidelines to follow for dynamic rate_limit */ | 102 | /* Guidelines to follow for dynamic rate_limit */ |
106 | #define AUDIT_RATE_LIMIT_DEFAULT 20 /* acceptable burst rate */ | 103 | #define AUDIT_RATE_LIMIT_DEFAULT 20 /* acceptable burst rate */ |
107 | #define AUDIT_RATE_LIMIT_BURST_DURATION 10 /* number of seconds of burst */ | 104 | #define AUDIT_RATE_LIMIT_BURST_DURATION 10 /* number of seconds of burst */ |
108 | #define AUDIT_RATE_LIMIT_MAX 5 /* acceptable sustained rate */ | 105 | #define AUDIT_RATE_LIMIT_MAX 5 /* acceptable sustained rate */ |
109 | 106 | ||
110 | extern int audit_rate_limit(int fd, unsigned rate_limit); | 107 | extern int audit_rate_limit(int fd, unsigned rate_limit); |
111 | 108 | ||
diff --git a/logd/main.cpp b/logd/main.cpp index 2551f2e9b..33345067c 100644 --- a/logd/main.cpp +++ b/logd/main.cpp | |||
@@ -48,17 +48,15 @@ | |||
48 | #include <utils/threads.h> | 48 | #include <utils/threads.h> |
49 | 49 | ||
50 | #include "CommandListener.h" | 50 | #include "CommandListener.h" |
51 | #include "LogBuffer.h" | ||
52 | #include "LogListener.h" | ||
53 | #include "LogAudit.h" | 51 | #include "LogAudit.h" |
52 | #include "LogBuffer.h" | ||
54 | #include "LogKlog.h" | 53 | #include "LogKlog.h" |
54 | #include "LogListener.h" | ||
55 | #include "LogUtils.h" | 55 | #include "LogUtils.h" |
56 | 56 | ||
57 | #define KMSG_PRIORITY(PRI) \ | 57 | #define KMSG_PRIORITY(PRI) \ |
58 | '<', \ | 58 | '<', '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) / 10, \ |
59 | '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) / 10, \ | 59 | '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) % 10, '>' |
60 | '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) % 10, \ | ||
61 | '>' | ||
62 | 60 | ||
63 | // | 61 | // |
64 | // The service is designed to be run by init, it does not respond well | 62 | // The service is designed to be run by init, it does not respond well |
@@ -92,7 +90,8 @@ | |||
92 | static int drop_privs(bool klogd, bool auditd) { | 90 | static int drop_privs(bool klogd, bool auditd) { |
93 | // Tricky, if ro.build.type is "eng" then this is true because of the | 91 | // Tricky, if ro.build.type is "eng" then this is true because of the |
94 | // side effect that ro.debuggable == 1 as well, else it is false. | 92 | // side effect that ro.debuggable == 1 as well, else it is false. |
95 | bool eng = __android_logger_property_get_bool("ro.build.type", BOOL_DEFAULT_FALSE); | 93 | bool eng = |
94 | __android_logger_property_get_bool("ro.build.type", BOOL_DEFAULT_FALSE); | ||
96 | 95 | ||
97 | struct sched_param param; | 96 | struct sched_param param; |
98 | memset(¶m, 0, sizeof(param)); | 97 | memset(¶m, 0, sizeof(param)); |
@@ -102,7 +101,7 @@ static int drop_privs(bool klogd, bool auditd) { | |||
102 | if (!eng) return -1; | 101 | if (!eng) return -1; |
103 | } | 102 | } |
104 | 103 | ||
105 | if (sched_setscheduler((pid_t) 0, SCHED_BATCH, ¶m) < 0) { | 104 | if (sched_setscheduler((pid_t)0, SCHED_BATCH, ¶m) < 0) { |
106 | android::prdebug("failed to set batch scheduler"); | 105 | android::prdebug("failed to set batch scheduler"); |
107 | if (!eng) return -1; | 106 | if (!eng) return -1; |
108 | } | 107 | } |
@@ -122,21 +121,24 @@ static int drop_privs(bool klogd, bool auditd) { | |||
122 | if (!eng) return -1; | 121 | if (!eng) return -1; |
123 | } | 122 | } |
124 | 123 | ||
125 | std::unique_ptr<struct _cap_struct, int(*)(void *)> caps(cap_init(), cap_free); | 124 | std::unique_ptr<struct _cap_struct, int (*)(void*)> caps(cap_init(), |
125 | cap_free); | ||
126 | if (cap_clear(caps.get()) < 0) return -1; | 126 | if (cap_clear(caps.get()) < 0) return -1; |
127 | cap_value_t cap_value[] = { | 127 | cap_value_t cap_value[] = { CAP_SETGID, // must be first for below |
128 | CAP_SETGID, // must be first for below | 128 | klogd ? CAP_SYSLOG : CAP_SETGID, |
129 | klogd ? CAP_SYSLOG : CAP_SETGID, | 129 | auditd ? CAP_AUDIT_CONTROL : CAP_SETGID }; |
130 | auditd ? CAP_AUDIT_CONTROL : CAP_SETGID | 130 | if (cap_set_flag(caps.get(), CAP_PERMITTED, arraysize(cap_value), cap_value, |
131 | }; | 131 | CAP_SET) < 0) { |
132 | if (cap_set_flag(caps.get(), CAP_PERMITTED, | 132 | return -1; |
133 | arraysize(cap_value), cap_value, | 133 | } |
134 | CAP_SET) < 0) return -1; | 134 | if (cap_set_flag(caps.get(), CAP_EFFECTIVE, arraysize(cap_value), cap_value, |
135 | if (cap_set_flag(caps.get(), CAP_EFFECTIVE, | 135 | CAP_SET) < 0) { |
136 | arraysize(cap_value), cap_value, | 136 | return -1; |
137 | CAP_SET) < 0) return -1; | 137 | } |
138 | if (cap_set_proc(caps.get()) < 0) { | 138 | if (cap_set_proc(caps.get()) < 0) { |
139 | android::prdebug("failed to set CAP_SETGID, CAP_SYSLOG or CAP_AUDIT_CONTROL (%d)", errno); | 139 | android::prdebug( |
140 | "failed to set CAP_SETGID, CAP_SYSLOG or CAP_AUDIT_CONTROL (%d)", | ||
141 | errno); | ||
140 | if (!eng) return -1; | 142 | if (!eng) return -1; |
141 | } | 143 | } |
142 | 144 | ||
@@ -157,8 +159,12 @@ static int drop_privs(bool klogd, bool auditd) { | |||
157 | if (!eng) return -1; | 159 | if (!eng) return -1; |
158 | } | 160 | } |
159 | 161 | ||
160 | if (cap_set_flag(caps.get(), CAP_PERMITTED, 1, cap_value, CAP_CLEAR) < 0) return -1; | 162 | if (cap_set_flag(caps.get(), CAP_PERMITTED, 1, cap_value, CAP_CLEAR) < 0) { |
161 | if (cap_set_flag(caps.get(), CAP_EFFECTIVE, 1, cap_value, CAP_CLEAR) < 0) return -1; | 163 | return -1; |
164 | } | ||
165 | if (cap_set_flag(caps.get(), CAP_EFFECTIVE, 1, cap_value, CAP_CLEAR) < 0) { | ||
166 | return -1; | ||
167 | } | ||
162 | if (cap_set_proc(caps.get()) < 0) { | 168 | if (cap_set_proc(caps.get()) < 0) { |
163 | android::prdebug("failed to clear CAP_SETGID (%d)", errno); | 169 | android::prdebug("failed to clear CAP_SETGID (%d)", errno); |
164 | if (!eng) return -1; | 170 | if (!eng) return -1; |
@@ -168,8 +174,8 @@ static int drop_privs(bool klogd, bool auditd) { | |||
168 | } | 174 | } |
169 | 175 | ||
170 | // Property helper | 176 | // Property helper |
171 | static bool check_flag(const char *prop, const char *flag) { | 177 | static bool check_flag(const char* prop, const char* flag) { |
172 | const char *cp = strcasestr(prop, flag); | 178 | const char* cp = strcasestr(prop, flag); |
173 | if (!cp) { | 179 | if (!cp) { |
174 | return false; | 180 | return false; |
175 | } | 181 | } |
@@ -183,7 +189,7 @@ static bool check_flag(const char *prop, const char *flag) { | |||
183 | } | 189 | } |
184 | 190 | ||
185 | static int fdDmesg = -1; | 191 | static int fdDmesg = -1; |
186 | void android::prdebug(const char *fmt, ...) { | 192 | void android::prdebug(const char* fmt, ...) { |
187 | if (fdDmesg < 0) { | 193 | if (fdDmesg < 0) { |
188 | return; | 194 | return; |
189 | } | 195 | } |
@@ -211,14 +217,13 @@ void android::prdebug(const char *fmt, ...) { | |||
211 | 217 | ||
212 | static sem_t uidName; | 218 | static sem_t uidName; |
213 | static uid_t uid; | 219 | static uid_t uid; |
214 | static char *name; | 220 | static char* name; |
215 | 221 | ||
216 | static sem_t reinit; | 222 | static sem_t reinit; |
217 | static bool reinit_running = false; | 223 | static bool reinit_running = false; |
218 | static LogBuffer *logBuf = NULL; | 224 | static LogBuffer* logBuf = NULL; |
219 | |||
220 | static bool package_list_parser_cb(pkg_info *info, void * /* userdata */) { | ||
221 | 225 | ||
226 | static bool package_list_parser_cb(pkg_info* info, void* /* userdata */) { | ||
222 | bool rc = true; | 227 | bool rc = true; |
223 | if (info->uid == uid) { | 228 | if (info->uid == uid) { |
224 | name = strdup(info->name); | 229 | name = strdup(info->name); |
@@ -230,7 +235,7 @@ static bool package_list_parser_cb(pkg_info *info, void * /* userdata */) { | |||
230 | return rc; | 235 | return rc; |
231 | } | 236 | } |
232 | 237 | ||
233 | static void *reinit_thread_start(void * /*obj*/) { | 238 | static void* reinit_thread_start(void* /*obj*/) { |
234 | prctl(PR_SET_NAME, "logd.daemon"); | 239 | prctl(PR_SET_NAME, "logd.daemon"); |
235 | set_sched_policy(0, SP_BACKGROUND); | 240 | set_sched_policy(0, SP_BACKGROUND); |
236 | setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND); | 241 | setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND); |
@@ -243,11 +248,10 @@ static void *reinit_thread_start(void * /*obj*/) { | |||
243 | // If we are AID_ROOT, we should drop to AID_LOGD+AID_SYSTEM, if we are | 248 | // If we are AID_ROOT, we should drop to AID_LOGD+AID_SYSTEM, if we are |
244 | // anything else, we have even lesser privileges and accept our fate. Not | 249 | // anything else, we have even lesser privileges and accept our fate. Not |
245 | // worth checking for error returns setting this thread's privileges. | 250 | // worth checking for error returns setting this thread's privileges. |
246 | (void)setgid(AID_SYSTEM); // readonly access to /data/system/packages.list | 251 | (void)setgid(AID_SYSTEM); // readonly access to /data/system/packages.list |
247 | (void)setuid(AID_LOGD); // access to everything logd, eg /data/misc/logd | 252 | (void)setuid(AID_LOGD); // access to everything logd, eg /data/misc/logd |
248 | 253 | ||
249 | while (reinit_running && !sem_wait(&reinit) && reinit_running) { | 254 | while (reinit_running && !sem_wait(&reinit) && reinit_running) { |
250 | |||
251 | // uidToName Privileged Worker | 255 | // uidToName Privileged Worker |
252 | if (uid) { | 256 | if (uid) { |
253 | name = NULL; | 257 | name = NULL; |
@@ -261,8 +265,26 @@ static void *reinit_thread_start(void * /*obj*/) { | |||
261 | 265 | ||
262 | if (fdDmesg >= 0) { | 266 | if (fdDmesg >= 0) { |
263 | static const char reinit_message[] = { KMSG_PRIORITY(LOG_INFO), | 267 | static const char reinit_message[] = { KMSG_PRIORITY(LOG_INFO), |
264 | 'l', 'o', 'g', 'd', '.', 'd', 'a', 'e', 'm', 'o', 'n', ':', | 268 | 'l', |
265 | ' ', 'r', 'e', 'i', 'n', 'i', 't', '\n' }; | 269 | 'o', |
270 | 'g', | ||
271 | 'd', | ||
272 | '.', | ||
273 | 'd', | ||
274 | 'a', | ||
275 | 'e', | ||
276 | 'm', | ||
277 | 'o', | ||
278 | 'n', | ||
279 | ':', | ||
280 | ' ', | ||
281 | 'r', | ||
282 | 'e', | ||
283 | 'i', | ||
284 | 'n', | ||
285 | 'i', | ||
286 | 't', | ||
287 | '\n' }; | ||
266 | write(fdDmesg, reinit_message, sizeof(reinit_message)); | 288 | write(fdDmesg, reinit_message, sizeof(reinit_message)); |
267 | } | 289 | } |
268 | 290 | ||
@@ -279,7 +301,7 @@ static void *reinit_thread_start(void * /*obj*/) { | |||
279 | 301 | ||
280 | static sem_t sem_name; | 302 | static sem_t sem_name; |
281 | 303 | ||
282 | char *android::uidToName(uid_t u) { | 304 | char* android::uidToName(uid_t u) { |
283 | if (!u || !reinit_running) { | 305 | if (!u || !reinit_running) { |
284 | return NULL; | 306 | return NULL; |
285 | } | 307 | } |
@@ -292,7 +314,7 @@ char *android::uidToName(uid_t u) { | |||
292 | name = NULL; | 314 | name = NULL; |
293 | sem_post(&reinit); | 315 | sem_post(&reinit); |
294 | sem_wait(&uidName); | 316 | sem_wait(&uidName); |
295 | char *ret = name; | 317 | char* ret = name; |
296 | 318 | ||
297 | sem_post(&sem_name); | 319 | sem_post(&sem_name); |
298 | 320 | ||
@@ -305,7 +327,7 @@ void reinit_signal_handler(int /*signal*/) { | |||
305 | sem_post(&reinit); | 327 | sem_post(&reinit); |
306 | } | 328 | } |
307 | 329 | ||
308 | static void readDmesg(LogAudit *al, LogKlog *kl) { | 330 | static void readDmesg(LogAudit* al, LogKlog* kl) { |
309 | if (!al && !kl) { | 331 | if (!al && !kl) { |
310 | return; | 332 | return; |
311 | } | 333 | } |
@@ -315,8 +337,8 @@ static void readDmesg(LogAudit *al, LogKlog *kl) { | |||
315 | return; | 337 | return; |
316 | } | 338 | } |
317 | 339 | ||
318 | size_t len = rc + 1024; // Margin for additional input race or trailing nul | 340 | size_t len = rc + 1024; // Margin for additional input race or trailing nul |
319 | std::unique_ptr<char []> buf(new char[len]); | 341 | std::unique_ptr<char[]> buf(new char[len]); |
320 | 342 | ||
321 | rc = klogctl(KLOG_READ_ALL, buf.get(), len); | 343 | rc = klogctl(KLOG_READ_ALL, buf.get(), len); |
322 | if (rc <= 0) { | 344 | if (rc <= 0) { |
@@ -351,10 +373,8 @@ static int issueReinit() { | |||
351 | (void)cap_set_proc(caps); | 373 | (void)cap_set_proc(caps); |
352 | (void)cap_free(caps); | 374 | (void)cap_free(caps); |
353 | 375 | ||
354 | int sock = TEMP_FAILURE_RETRY( | 376 | int sock = TEMP_FAILURE_RETRY(socket_local_client( |
355 | socket_local_client("logd", | 377 | "logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM)); |
356 | ANDROID_SOCKET_NAMESPACE_RESERVED, | ||
357 | SOCK_STREAM)); | ||
358 | if (sock < 0) return -errno; | 378 | if (sock < 0) return -errno; |
359 | 379 | ||
360 | static const char reinitStr[] = "reinit"; | 380 | static const char reinitStr[] = "reinit"; |
@@ -384,7 +404,7 @@ static int issueReinit() { | |||
384 | // controlling the user space logger, and for any additional | 404 | // controlling the user space logger, and for any additional |
385 | // logging plugins like auditd and restart control. Additional | 405 | // logging plugins like auditd and restart control. Additional |
386 | // transitory per-client threads are created for each reader. | 406 | // transitory per-client threads are created for each reader. |
387 | int main(int argc, char *argv[]) { | 407 | int main(int argc, char* argv[]) { |
388 | // issue reinit command. KISS argument parsing. | 408 | // issue reinit command. KISS argument parsing. |
389 | if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) { | 409 | if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) { |
390 | return issueReinit(); | 410 | return issueReinit(); |
@@ -397,17 +417,15 @@ int main(int argc, char *argv[]) { | |||
397 | } | 417 | } |
398 | 418 | ||
399 | int fdPmesg = -1; | 419 | int fdPmesg = -1; |
400 | bool klogd = __android_logger_property_get_bool("logd.kernel", | 420 | bool klogd = __android_logger_property_get_bool( |
401 | BOOL_DEFAULT_TRUE | | 421 | "logd.kernel", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST | |
402 | BOOL_DEFAULT_FLAG_PERSIST | | 422 | BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE); |
403 | BOOL_DEFAULT_FLAG_ENG | | ||
404 | BOOL_DEFAULT_FLAG_SVELTE); | ||
405 | if (klogd) { | 423 | if (klogd) { |
406 | static const char proc_kmsg[] = "/proc/kmsg"; | 424 | static const char proc_kmsg[] = "/proc/kmsg"; |
407 | fdPmesg = android_get_control_file(proc_kmsg); | 425 | fdPmesg = android_get_control_file(proc_kmsg); |
408 | if (fdPmesg < 0) { | 426 | if (fdPmesg < 0) { |
409 | fdPmesg = TEMP_FAILURE_RETRY(open(proc_kmsg, | 427 | fdPmesg = TEMP_FAILURE_RETRY( |
410 | O_RDONLY | O_NDELAY | O_CLOEXEC)); | 428 | open(proc_kmsg, O_RDONLY | O_NDELAY | O_CLOEXEC)); |
411 | } | 429 | } |
412 | if (fdPmesg < 0) android::prdebug("Failed to open %s\n", proc_kmsg); | 430 | if (fdPmesg < 0) android::prdebug("Failed to open %s\n", proc_kmsg); |
413 | } | 431 | } |
@@ -423,8 +441,7 @@ int main(int argc, char *argv[]) { | |||
423 | memset(¶m, 0, sizeof(param)); | 441 | memset(¶m, 0, sizeof(param)); |
424 | pthread_attr_setschedparam(&attr, ¶m); | 442 | pthread_attr_setschedparam(&attr, ¶m); |
425 | pthread_attr_setschedpolicy(&attr, SCHED_BATCH); | 443 | pthread_attr_setschedpolicy(&attr, SCHED_BATCH); |
426 | if (!pthread_attr_setdetachstate(&attr, | 444 | if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { |
427 | PTHREAD_CREATE_DETACHED)) { | ||
428 | pthread_t thread; | 445 | pthread_t thread; |
429 | reinit_running = true; | 446 | reinit_running = true; |
430 | if (pthread_create(&thread, &attr, reinit_thread_start, NULL)) { | 447 | if (pthread_create(&thread, &attr, reinit_thread_start, NULL)) { |
@@ -434,8 +451,8 @@ int main(int argc, char *argv[]) { | |||
434 | pthread_attr_destroy(&attr); | 451 | pthread_attr_destroy(&attr); |
435 | } | 452 | } |
436 | 453 | ||
437 | bool auditd = __android_logger_property_get_bool("ro.logd.auditd", | 454 | bool auditd = |
438 | BOOL_DEFAULT_TRUE); | 455 | __android_logger_property_get_bool("ro.logd.auditd", BOOL_DEFAULT_TRUE); |
439 | if (drop_privs(klogd, auditd) != 0) { | 456 | if (drop_privs(klogd, auditd) != 0) { |
440 | return -1; | 457 | return -1; |
441 | } | 458 | } |
@@ -444,7 +461,7 @@ int main(int argc, char *argv[]) { | |||
444 | // socket connection, and as a reader lock on a range of log | 461 | // socket connection, and as a reader lock on a range of log |
445 | // entries. | 462 | // entries. |
446 | 463 | ||
447 | LastLogTimes *times = new LastLogTimes(); | 464 | LastLogTimes* times = new LastLogTimes(); |
448 | 465 | ||
449 | // LogBuffer is the object which is responsible for holding all | 466 | // LogBuffer is the object which is responsible for holding all |
450 | // log entries. | 467 | // log entries. |
@@ -453,18 +470,17 @@ int main(int argc, char *argv[]) { | |||
453 | 470 | ||
454 | signal(SIGHUP, reinit_signal_handler); | 471 | signal(SIGHUP, reinit_signal_handler); |
455 | 472 | ||
456 | if (__android_logger_property_get_bool("logd.statistics", | 473 | if (__android_logger_property_get_bool( |
457 | BOOL_DEFAULT_TRUE | | 474 | "logd.statistics", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST | |
458 | BOOL_DEFAULT_FLAG_PERSIST | | 475 | BOOL_DEFAULT_FLAG_ENG | |
459 | BOOL_DEFAULT_FLAG_ENG | | 476 | BOOL_DEFAULT_FLAG_SVELTE)) { |
460 | BOOL_DEFAULT_FLAG_SVELTE)) { | ||
461 | logBuf->enableStatistics(); | 477 | logBuf->enableStatistics(); |
462 | } | 478 | } |
463 | 479 | ||
464 | // LogReader listens on /dev/socket/logdr. When a client | 480 | // LogReader listens on /dev/socket/logdr. When a client |
465 | // connects, log entries in the LogBuffer are written to the client. | 481 | // connects, log entries in the LogBuffer are written to the client. |
466 | 482 | ||
467 | LogReader *reader = new LogReader(logBuf); | 483 | LogReader* reader = new LogReader(logBuf); |
468 | if (reader->startListener()) { | 484 | if (reader->startListener()) { |
469 | exit(1); | 485 | exit(1); |
470 | } | 486 | } |
@@ -473,7 +489,7 @@ int main(int argc, char *argv[]) { | |||
473 | // initiated log messages. New log entries are added to LogBuffer | 489 | // initiated log messages. New log entries are added to LogBuffer |
474 | // and LogReader is notified to send updates to connected clients. | 490 | // and LogReader is notified to send updates to connected clients. |
475 | 491 | ||
476 | LogListener *swl = new LogListener(logBuf, reader); | 492 | LogListener* swl = new LogListener(logBuf, reader); |
477 | // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value | 493 | // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value |
478 | if (swl->startListener(600)) { | 494 | if (swl->startListener(600)) { |
479 | exit(1); | 495 | exit(1); |
@@ -482,7 +498,7 @@ int main(int argc, char *argv[]) { | |||
482 | // Command listener listens on /dev/socket/logd for incoming logd | 498 | // Command listener listens on /dev/socket/logd for incoming logd |
483 | // administrative commands. | 499 | // administrative commands. |
484 | 500 | ||
485 | CommandListener *cl = new CommandListener(logBuf, reader, swl); | 501 | CommandListener* cl = new CommandListener(logBuf, reader, swl); |
486 | if (cl->startListener()) { | 502 | if (cl->startListener()) { |
487 | exit(1); | 503 | exit(1); |
488 | } | 504 | } |
@@ -491,17 +507,16 @@ int main(int argc, char *argv[]) { | |||
491 | // initiated log messages. New log entries are added to LogBuffer | 507 | // initiated log messages. New log entries are added to LogBuffer |
492 | // and LogReader is notified to send updates to connected clients. | 508 | // and LogReader is notified to send updates to connected clients. |
493 | 509 | ||
494 | LogAudit *al = NULL; | 510 | LogAudit* al = NULL; |
495 | if (auditd) { | 511 | if (auditd) { |
496 | al = new LogAudit(logBuf, reader, | 512 | al = new LogAudit(logBuf, reader, |
497 | __android_logger_property_get_bool( | 513 | __android_logger_property_get_bool( |
498 | "ro.logd.auditd.dmesg", | 514 | "ro.logd.auditd.dmesg", BOOL_DEFAULT_TRUE) |
499 | BOOL_DEFAULT_TRUE) | 515 | ? fdDmesg |
500 | ? fdDmesg | 516 | : -1); |
501 | : -1); | ||
502 | } | 517 | } |
503 | 518 | ||
504 | LogKlog *kl = NULL; | 519 | LogKlog* kl = NULL; |
505 | if (klogd) { | 520 | if (klogd) { |
506 | kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, al != NULL); | 521 | kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, al != NULL); |
507 | } | 522 | } |
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp index 8a35059c2..ddff39350 100644 --- a/logd/tests/logd_test.cpp +++ b/logd/tests/logd_test.cpp | |||
@@ -20,8 +20,8 @@ | |||
20 | #include <signal.h> | 20 | #include <signal.h> |
21 | #include <stdio.h> | 21 | #include <stdio.h> |
22 | #include <string.h> | 22 | #include <string.h> |
23 | #include <sys/types.h> | ||
24 | #include <sys/stat.h> | 23 | #include <sys/stat.h> |
24 | #include <sys/types.h> | ||
25 | #include <unistd.h> | 25 | #include <unistd.h> |
26 | 26 | ||
27 | #include <string> | 27 | #include <string> |
@@ -36,13 +36,11 @@ | |||
36 | #include <selinux/selinux.h> | 36 | #include <selinux/selinux.h> |
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | #include "../libaudit.h" // pickup AUDIT_RATE_LIMIT_* | 39 | #include "../LogReader.h" // pickup LOGD_SNDTIMEO |
40 | #include "../LogReader.h" // pickup LOGD_SNDTIMEO | 40 | #include "../libaudit.h" // pickup AUDIT_RATE_LIMIT_* |
41 | 41 | ||
42 | static void send_to_control(char* buf, size_t len) | 42 | static void send_to_control(char* buf, size_t len) { |
43 | { | 43 | int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, |
44 | int sock = socket_local_client("logd", | ||
45 | ANDROID_SOCKET_NAMESPACE_RESERVED, | ||
46 | SOCK_STREAM); | 44 | SOCK_STREAM); |
47 | if (sock >= 0) { | 45 | if (sock >= 0) { |
48 | if (write(sock, buf, strlen(buf) + 1) > 0) { | 46 | if (write(sock, buf, strlen(buf) + 1) > 0) { |
@@ -54,11 +52,7 @@ static void send_to_control(char* buf, size_t len) | |||
54 | len -= ret; | 52 | len -= ret; |
55 | buf += ret; | 53 | buf += ret; |
56 | 54 | ||
57 | struct pollfd p = { | 55 | struct pollfd p = {.fd = sock, .events = POLLIN, .revents = 0 }; |
58 | .fd = sock, | ||
59 | .events = POLLIN, | ||
60 | .revents = 0 | ||
61 | }; | ||
62 | 56 | ||
63 | ret = poll(&p, 1, 20); | 57 | ret = poll(&p, 1, 20); |
64 | if ((ret <= 0) || !(p.revents & POLLIN)) { | 58 | if ((ret <= 0) || !(p.revents & POLLIN)) { |
@@ -73,25 +67,23 @@ static void send_to_control(char* buf, size_t len) | |||
73 | /* | 67 | /* |
74 | * returns statistics | 68 | * returns statistics |
75 | */ | 69 | */ |
76 | static void my_android_logger_get_statistics(char *buf, size_t len) | 70 | static void my_android_logger_get_statistics(char* buf, size_t len) { |
77 | { | ||
78 | snprintf(buf, len, "getStatistics 0 1 2 3 4"); | 71 | snprintf(buf, len, "getStatistics 0 1 2 3 4"); |
79 | send_to_control(buf, len); | 72 | send_to_control(buf, len); |
80 | } | 73 | } |
81 | 74 | ||
82 | static void alloc_statistics(char **buffer, size_t *length) | 75 | static void alloc_statistics(char** buffer, size_t* length) { |
83 | { | ||
84 | size_t len = 8192; | 76 | size_t len = 8192; |
85 | char *buf; | 77 | char* buf; |
86 | 78 | ||
87 | for(int retry = 32; (retry >= 0); delete [] buf, --retry) { | 79 | for (int retry = 32; (retry >= 0); delete[] buf, --retry) { |
88 | buf = new char [len]; | 80 | buf = new char[len]; |
89 | my_android_logger_get_statistics(buf, len); | 81 | my_android_logger_get_statistics(buf, len); |
90 | 82 | ||
91 | buf[len-1] = '\0'; | 83 | buf[len - 1] = '\0'; |
92 | size_t ret = atol(buf) + 1; | 84 | size_t ret = atol(buf) + 1; |
93 | if (ret < 4) { | 85 | if (ret < 4) { |
94 | delete [] buf; | 86 | delete[] buf; |
95 | buf = NULL; | 87 | buf = NULL; |
96 | break; | 88 | break; |
97 | } | 89 | } |
@@ -100,14 +92,13 @@ static void alloc_statistics(char **buffer, size_t *length) | |||
100 | if (check) { | 92 | if (check) { |
101 | break; | 93 | break; |
102 | } | 94 | } |
103 | len += len / 8; // allow for some slop | 95 | len += len / 8; // allow for some slop |
104 | } | 96 | } |
105 | *buffer = buf; | 97 | *buffer = buf; |
106 | *length = len; | 98 | *length = len; |
107 | } | 99 | } |
108 | 100 | ||
109 | static char *find_benchmark_spam(char *cp) | 101 | static char* find_benchmark_spam(char* cp) { |
110 | { | ||
111 | // liblog_benchmarks has been run designed to SPAM. The signature of | 102 | // liblog_benchmarks has been run designed to SPAM. The signature of |
112 | // a noisiest UID statistics is: | 103 | // a noisiest UID statistics is: |
113 | // | 104 | // |
@@ -115,7 +106,7 @@ static char *find_benchmark_spam(char *cp) | |||
115 | // UID PACKAGE BYTES LINES | 106 | // UID PACKAGE BYTES LINES |
116 | // 0 root 54164 147569 | 107 | // 0 root 54164 147569 |
117 | // | 108 | // |
118 | char *benchmark = NULL; | 109 | char* benchmark = NULL; |
119 | do { | 110 | do { |
120 | static const char signature[] = "\n0 root "; | 111 | static const char signature[] = "\n0 root "; |
121 | 112 | ||
@@ -129,7 +120,7 @@ static char *find_benchmark_spam(char *cp) | |||
129 | } | 120 | } |
130 | benchmark = cp; | 121 | benchmark = cp; |
131 | #ifdef DEBUG | 122 | #ifdef DEBUG |
132 | char *end = strstr(benchmark, "\n"); | 123 | char* end = strstr(benchmark, "\n"); |
133 | if (end == NULL) { | 124 | if (end == NULL) { |
134 | end = benchmark + strlen(benchmark); | 125 | end = benchmark + strlen(benchmark); |
135 | } | 126 | } |
@@ -145,8 +136,8 @@ static char *find_benchmark_spam(char *cp) | |||
145 | } | 136 | } |
146 | // optional +/- field? | 137 | // optional +/- field? |
147 | if ((*cp == '-') || (*cp == '+')) { | 138 | if ((*cp == '-') || (*cp == '+')) { |
148 | while (isdigit(*++cp) || | 139 | while (isdigit(*++cp) || (*cp == '.') || (*cp == '%') || |
149 | (*cp == '.') || (*cp == '%') || (*cp == 'X')) { | 140 | (*cp == 'X')) { |
150 | ; | 141 | ; |
151 | } | 142 | } |
152 | while (isspace(*cp)) { | 143 | while (isspace(*cp)) { |
@@ -169,14 +160,14 @@ static char *find_benchmark_spam(char *cp) | |||
169 | 160 | ||
170 | TEST(logd, statistics) { | 161 | TEST(logd, statistics) { |
171 | size_t len; | 162 | size_t len; |
172 | char *buf; | 163 | char* buf; |
173 | 164 | ||
174 | alloc_statistics(&buf, &len); | 165 | alloc_statistics(&buf, &len); |
175 | 166 | ||
176 | ASSERT_TRUE(NULL != buf); | 167 | ASSERT_TRUE(NULL != buf); |
177 | 168 | ||
178 | // remove trailing FF | 169 | // remove trailing FF |
179 | char *cp = buf + len - 1; | 170 | char* cp = buf + len - 1; |
180 | *cp = '\0'; | 171 | *cp = '\0'; |
181 | bool truncated = *--cp != '\f'; | 172 | bool truncated = *--cp != '\f'; |
182 | if (!truncated) { | 173 | if (!truncated) { |
@@ -197,105 +188,107 @@ TEST(logd, statistics) { | |||
197 | 188 | ||
198 | EXPECT_EQ(0, truncated); | 189 | EXPECT_EQ(0, truncated); |
199 | 190 | ||
200 | char *main_logs = strstr(cp, "\nChattiest UIDs in main "); | 191 | char* main_logs = strstr(cp, "\nChattiest UIDs in main "); |
201 | EXPECT_TRUE(NULL != main_logs); | 192 | EXPECT_TRUE(NULL != main_logs); |
202 | 193 | ||
203 | char *radio_logs = strstr(cp, "\nChattiest UIDs in radio "); | 194 | char* radio_logs = strstr(cp, "\nChattiest UIDs in radio "); |
204 | if (!radio_logs) GTEST_LOG_(INFO) << "Value of: NULL != radio_logs\n" | 195 | if (!radio_logs) |
205 | "Actual: false\n" | 196 | GTEST_LOG_(INFO) << "Value of: NULL != radio_logs\n" |
206 | "Expected: false\n"; | 197 | "Actual: false\n" |
198 | "Expected: false\n"; | ||
207 | 199 | ||
208 | char *system_logs = strstr(cp, "\nChattiest UIDs in system "); | 200 | char* system_logs = strstr(cp, "\nChattiest UIDs in system "); |
209 | EXPECT_TRUE(NULL != system_logs); | 201 | EXPECT_TRUE(NULL != system_logs); |
210 | 202 | ||
211 | char *events_logs = strstr(cp, "\nChattiest UIDs in events "); | 203 | char* events_logs = strstr(cp, "\nChattiest UIDs in events "); |
212 | EXPECT_TRUE(NULL != events_logs); | 204 | EXPECT_TRUE(NULL != events_logs); |
213 | 205 | ||
214 | delete [] buf; | 206 | delete[] buf; |
215 | } | 207 | } |
216 | 208 | ||
217 | static void caught_signal(int /* signum */) { } | 209 | static void caught_signal(int /* signum */) { |
210 | } | ||
218 | 211 | ||
219 | static void dump_log_msg(const char *prefix, | 212 | static void dump_log_msg(const char* prefix, log_msg* msg, unsigned int version, |
220 | log_msg *msg, unsigned int version, int lid) { | 213 | int lid) { |
221 | std::cout << std::flush; | 214 | std::cout << std::flush; |
222 | std::cerr << std::flush; | 215 | std::cerr << std::flush; |
223 | fflush(stdout); | 216 | fflush(stdout); |
224 | fflush(stderr); | 217 | fflush(stderr); |
225 | switch(msg->entry.hdr_size) { | 218 | switch (msg->entry.hdr_size) { |
226 | case 0: | 219 | case 0: |
227 | version = 1; | 220 | version = 1; |
228 | break; | 221 | break; |
229 | |||
230 | case sizeof(msg->entry_v2): /* PLUS case sizeof(msg->entry_v3): */ | ||
231 | if (version == 0) { | ||
232 | version = (msg->entry_v3.lid < LOG_ID_MAX) ? 3 : 2; | ||
233 | } | ||
234 | break; | ||
235 | 222 | ||
236 | case sizeof(msg->entry_v4): | 223 | case sizeof(msg->entry_v2): /* PLUS case sizeof(msg->entry_v3): */ |
237 | if (version == 0) { | 224 | if (version == 0) { |
238 | version = 4; | 225 | version = (msg->entry_v3.lid < LOG_ID_MAX) ? 3 : 2; |
239 | } | 226 | } |
240 | break; | 227 | break; |
228 | |||
229 | case sizeof(msg->entry_v4): | ||
230 | if (version == 0) { | ||
231 | version = 4; | ||
232 | } | ||
233 | break; | ||
241 | } | 234 | } |
242 | 235 | ||
243 | fprintf(stderr, "%s: v%u[%u] ", prefix, version, msg->len()); | 236 | fprintf(stderr, "%s: v%u[%u] ", prefix, version, msg->len()); |
244 | if (version != 1) { | 237 | if (version != 1) { |
245 | fprintf(stderr, "hdr_size=%u ", msg->entry.hdr_size); | 238 | fprintf(stderr, "hdr_size=%u ", msg->entry.hdr_size); |
246 | } | 239 | } |
247 | fprintf(stderr, "pid=%u tid=%u %u.%09u ", | 240 | fprintf(stderr, "pid=%u tid=%u %u.%09u ", msg->entry.pid, msg->entry.tid, |
248 | msg->entry.pid, msg->entry.tid, msg->entry.sec, msg->entry.nsec); | 241 | msg->entry.sec, msg->entry.nsec); |
249 | switch(version) { | 242 | switch (version) { |
250 | case 1: | 243 | case 1: |
251 | break; | 244 | break; |
252 | case 2: | 245 | case 2: |
253 | fprintf(stderr, "euid=%u ", msg->entry_v2.euid); | 246 | fprintf(stderr, "euid=%u ", msg->entry_v2.euid); |
254 | break; | 247 | break; |
255 | case 3: | 248 | case 3: |
256 | default: | 249 | default: |
257 | lid = msg->entry.lid; | 250 | lid = msg->entry.lid; |
258 | break; | 251 | break; |
259 | } | 252 | } |
260 | 253 | ||
261 | switch(lid) { | 254 | switch (lid) { |
262 | case 0: | 255 | case 0: |
263 | fprintf(stderr, "lid=main "); | 256 | fprintf(stderr, "lid=main "); |
264 | break; | 257 | break; |
265 | case 1: | 258 | case 1: |
266 | fprintf(stderr, "lid=radio "); | 259 | fprintf(stderr, "lid=radio "); |
267 | break; | 260 | break; |
268 | case 2: | 261 | case 2: |
269 | fprintf(stderr, "lid=events "); | 262 | fprintf(stderr, "lid=events "); |
270 | break; | 263 | break; |
271 | case 3: | 264 | case 3: |
272 | fprintf(stderr, "lid=system "); | 265 | fprintf(stderr, "lid=system "); |
273 | break; | 266 | break; |
274 | case 4: | 267 | case 4: |
275 | fprintf(stderr, "lid=crash "); | 268 | fprintf(stderr, "lid=crash "); |
276 | break; | 269 | break; |
277 | case 5: | 270 | case 5: |
278 | fprintf(stderr, "lid=security "); | 271 | fprintf(stderr, "lid=security "); |
279 | break; | 272 | break; |
280 | case 6: | 273 | case 6: |
281 | fprintf(stderr, "lid=kernel "); | 274 | fprintf(stderr, "lid=kernel "); |
282 | break; | 275 | break; |
283 | default: | 276 | default: |
284 | if (lid >= 0) { | 277 | if (lid >= 0) { |
285 | fprintf(stderr, "lid=%d ", lid); | 278 | fprintf(stderr, "lid=%d ", lid); |
286 | } | 279 | } |
287 | } | 280 | } |
288 | 281 | ||
289 | unsigned int len = msg->entry.len; | 282 | unsigned int len = msg->entry.len; |
290 | fprintf(stderr, "msg[%u]={", len); | 283 | fprintf(stderr, "msg[%u]={", len); |
291 | unsigned char *cp = reinterpret_cast<unsigned char *>(msg->msg()); | 284 | unsigned char* cp = reinterpret_cast<unsigned char*>(msg->msg()); |
292 | if (!cp) { | 285 | if (!cp) { |
293 | static const unsigned char garbage[] = "<INVALID>"; | 286 | static const unsigned char garbage[] = "<INVALID>"; |
294 | cp = const_cast<unsigned char *>(garbage); | 287 | cp = const_cast<unsigned char*>(garbage); |
295 | len = strlen(reinterpret_cast<const char *>(garbage)); | 288 | len = strlen(reinterpret_cast<const char*>(garbage)); |
296 | } | 289 | } |
297 | while(len) { | 290 | while (len) { |
298 | unsigned char *p = cp; | 291 | unsigned char* p = cp; |
299 | while (*p && (((' ' <= *p) && (*p < 0x7F)) || (*p == '\n'))) { | 292 | while (*p && (((' ' <= *p) && (*p < 0x7F)) || (*p == '\n'))) { |
300 | ++p; | 293 | ++p; |
301 | } | 294 | } |
@@ -330,8 +323,7 @@ TEST(logd, both) { | |||
330 | bool user_logger_available = false; | 323 | bool user_logger_available = false; |
331 | bool user_logger_content = false; | 324 | bool user_logger_content = false; |
332 | 325 | ||
333 | int fd = socket_local_client("logdr", | 326 | int fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, |
334 | ANDROID_SOCKET_NAMESPACE_RESERVED, | ||
335 | SOCK_SEQPACKET); | 327 | SOCK_SEQPACKET); |
336 | if (fd >= 0) { | 328 | if (fd >= 0) { |
337 | struct sigaction ignore, old_sigaction; | 329 | struct sigaction ignore, old_sigaction; |
@@ -360,10 +352,9 @@ TEST(logd, both) { | |||
360 | bool kernel_logger_available = false; | 352 | bool kernel_logger_available = false; |
361 | bool kernel_logger_content = false; | 353 | bool kernel_logger_content = false; |
362 | 354 | ||
363 | static const char *loggers[] = { | 355 | static const char* loggers[] = { |
364 | "/dev/log/main", "/dev/log_main", | 356 | "/dev/log/main", "/dev/log_main", "/dev/log/radio", |
365 | "/dev/log/radio", "/dev/log_radio", | 357 | "/dev/log_radio", "/dev/log/events", "/dev/log_events", |
366 | "/dev/log/events", "/dev/log_events", | ||
367 | "/dev/log/system", "/dev/log_system", | 358 | "/dev/log/system", "/dev/log_system", |
368 | }; | 359 | }; |
369 | 360 | ||
@@ -389,10 +380,9 @@ TEST(logd, both) { | |||
389 | "user %-13s%s\n" | 380 | "user %-13s%s\n" |
390 | "kernel %-13s%s\n" | 381 | "kernel %-13s%s\n" |
391 | " status %-11s%s\n", | 382 | " status %-11s%s\n", |
392 | (user_logger_available) ? yes : no, | 383 | (user_logger_available) ? yes : no, (user_logger_content) ? yes : no, |
393 | (user_logger_content) ? yes : no, | ||
394 | (kernel_logger_available) ? yes : no, | 384 | (kernel_logger_available) ? yes : no, |
395 | (kernel_logger_content) ? yes : no, | 385 | (kernel_logger_content) ? yes : no, |
396 | (user_logger_available && kernel_logger_available) ? "ERROR" : "ok", | 386 | (user_logger_available && kernel_logger_available) ? "ERROR" : "ok", |
397 | (user_logger_content && kernel_logger_content) ? "ERROR" : "ok"); | 387 | (user_logger_content && kernel_logger_content) ? "ERROR" : "ok"); |
398 | 388 | ||
@@ -415,39 +405,37 @@ TEST(logd, both) { | |||
415 | // | 405 | // |
416 | TEST(logd, benchmark) { | 406 | TEST(logd, benchmark) { |
417 | size_t len; | 407 | size_t len; |
418 | char *buf; | 408 | char* buf; |
419 | 409 | ||
420 | alloc_statistics(&buf, &len); | 410 | alloc_statistics(&buf, &len); |
421 | bool benchmark_already_run = buf && find_benchmark_spam(buf); | 411 | bool benchmark_already_run = buf && find_benchmark_spam(buf); |
422 | delete [] buf; | 412 | delete[] buf; |
423 | 413 | ||
424 | if (benchmark_already_run) { | 414 | if (benchmark_already_run) { |
425 | fprintf(stderr, "WARNING: spam already present and too much history\n" | 415 | fprintf(stderr, |
426 | " false OK for prune by worst UID check\n"); | 416 | "WARNING: spam already present and too much history\n" |
417 | " false OK for prune by worst UID check\n"); | ||
427 | } | 418 | } |
428 | 419 | ||
429 | FILE *fp; | 420 | FILE* fp; |
430 | 421 | ||
431 | // Introduce some extreme spam for the worst UID filter | 422 | // Introduce some extreme spam for the worst UID filter |
432 | ASSERT_TRUE(NULL != (fp = popen( | 423 | ASSERT_TRUE( |
433 | "/data/nativetest/liblog-benchmarks/liblog-benchmarks" | 424 | NULL != |
434 | " BM_log_maximum_retry" | 425 | (fp = popen("/data/nativetest/liblog-benchmarks/liblog-benchmarks" |
435 | " BM_log_maximum" | 426 | " BM_log_maximum_retry" |
436 | " BM_clock_overhead" | 427 | " BM_log_maximum" |
437 | " BM_log_overhead" | 428 | " BM_clock_overhead" |
438 | " BM_log_latency" | 429 | " BM_log_overhead" |
439 | " BM_log_delay", | 430 | " BM_log_latency" |
440 | "r"))); | 431 | " BM_log_delay", |
432 | "r"))); | ||
441 | 433 | ||
442 | char buffer[5120]; | 434 | char buffer[5120]; |
443 | 435 | ||
444 | static const char *benchmarks[] = { | 436 | static const char* benchmarks[] = { |
445 | "BM_log_maximum_retry ", | 437 | "BM_log_maximum_retry ", "BM_log_maximum ", "BM_clock_overhead ", |
446 | "BM_log_maximum ", | 438 | "BM_log_overhead ", "BM_log_latency ", "BM_log_delay " |
447 | "BM_clock_overhead ", | ||
448 | "BM_log_overhead ", | ||
449 | "BM_log_latency ", | ||
450 | "BM_log_delay " | ||
451 | }; | 439 | }; |
452 | static const unsigned int log_maximum_retry = 0; | 440 | static const unsigned int log_maximum_retry = 0; |
453 | static const unsigned int log_maximum = 1; | 441 | static const unsigned int log_maximum = 1; |
@@ -462,7 +450,7 @@ TEST(logd, benchmark) { | |||
462 | 450 | ||
463 | while (fgets(buffer, sizeof(buffer), fp)) { | 451 | while (fgets(buffer, sizeof(buffer), fp)) { |
464 | for (unsigned i = 0; i < arraysize(ns); ++i) { | 452 | for (unsigned i = 0; i < arraysize(ns); ++i) { |
465 | char *cp = strstr(buffer, benchmarks[i]); | 453 | char* cp = strstr(buffer, benchmarks[i]); |
466 | if (!cp) { | 454 | if (!cp) { |
467 | continue; | 455 | continue; |
468 | } | 456 | } |
@@ -480,17 +468,18 @@ TEST(logd, benchmark) { | |||
480 | return; | 468 | return; |
481 | } | 469 | } |
482 | 470 | ||
483 | EXPECT_GE(200000UL, ns[log_maximum_retry]); // 104734 user | 471 | EXPECT_GE(200000UL, ns[log_maximum_retry]); // 104734 user |
484 | 472 | ||
485 | EXPECT_GE(90000UL, ns[log_maximum]); // 46913 user | 473 | EXPECT_GE(90000UL, ns[log_maximum]); // 46913 user |
486 | 474 | ||
487 | EXPECT_GE(4096UL, ns[clock_overhead]); // 4095 | 475 | EXPECT_GE(4096UL, ns[clock_overhead]); // 4095 |
488 | 476 | ||
489 | EXPECT_GE(250000UL, ns[log_overhead]); // 126886 user | 477 | EXPECT_GE(250000UL, ns[log_overhead]); // 126886 user |
490 | 478 | ||
491 | EXPECT_GE(10000000UL, ns[log_latency]); // 1453559 user space (background cgroup) | 479 | EXPECT_GE(10000000UL, |
480 | ns[log_latency]); // 1453559 user space (background cgroup) | ||
492 | 481 | ||
493 | EXPECT_GE(20000000UL, ns[log_delay]); // 10500289 user | 482 | EXPECT_GE(20000000UL, ns[log_delay]); // 10500289 user |
494 | 483 | ||
495 | for (unsigned i = 0; i < arraysize(ns); ++i) { | 484 | for (unsigned i = 0; i < arraysize(ns); ++i) { |
496 | EXPECT_NE(0UL, ns[i]); | 485 | EXPECT_NE(0UL, ns[i]); |
@@ -503,7 +492,7 @@ TEST(logd, benchmark) { | |||
503 | 492 | ||
504 | ASSERT_TRUE(NULL != buf); | 493 | ASSERT_TRUE(NULL != buf); |
505 | 494 | ||
506 | char *benchmark_statistics_found = find_benchmark_spam(buf); | 495 | char* benchmark_statistics_found = find_benchmark_spam(buf); |
507 | ASSERT_TRUE(benchmark_statistics_found != NULL); | 496 | ASSERT_TRUE(benchmark_statistics_found != NULL); |
508 | 497 | ||
509 | // Check how effective the SPAM filter is, parse out Now size. | 498 | // Check how effective the SPAM filter is, parse out Now size. |
@@ -512,13 +501,12 @@ TEST(logd, benchmark) { | |||
512 | 501 | ||
513 | unsigned long nowSpamSize = atol(benchmark_statistics_found); | 502 | unsigned long nowSpamSize = atol(benchmark_statistics_found); |
514 | 503 | ||
515 | delete [] buf; | 504 | delete[] buf; |
516 | 505 | ||
517 | ASSERT_NE(0UL, nowSpamSize); | 506 | ASSERT_NE(0UL, nowSpamSize); |
518 | 507 | ||
519 | // Determine if we have the spam filter enabled | 508 | // Determine if we have the spam filter enabled |
520 | int sock = socket_local_client("logd", | 509 | int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, |
521 | ANDROID_SOCKET_NAMESPACE_RESERVED, | ||
522 | SOCK_STREAM); | 510 | SOCK_STREAM); |
523 | 511 | ||
524 | ASSERT_TRUE(sock >= 0); | 512 | ASSERT_TRUE(sock >= 0); |
@@ -528,26 +516,27 @@ TEST(logd, benchmark) { | |||
528 | char buffer[80]; | 516 | char buffer[80]; |
529 | memset(buffer, 0, sizeof(buffer)); | 517 | memset(buffer, 0, sizeof(buffer)); |
530 | read(sock, buffer, sizeof(buffer)); | 518 | read(sock, buffer, sizeof(buffer)); |
531 | char *cp = strchr(buffer, '\n'); | 519 | char* cp = strchr(buffer, '\n'); |
532 | if (!cp || (cp[1] != '~') || (cp[2] != '!')) { | 520 | if (!cp || (cp[1] != '~') || (cp[2] != '!')) { |
533 | close(sock); | 521 | close(sock); |
534 | fprintf(stderr, | 522 | fprintf(stderr, |
535 | "WARNING: " | 523 | "WARNING: " |
536 | "Logger has SPAM filtration turned off \"%s\"\n", buffer); | 524 | "Logger has SPAM filtration turned off \"%s\"\n", |
525 | buffer); | ||
537 | return; | 526 | return; |
538 | } | 527 | } |
539 | } else { | 528 | } else { |
540 | int save_errno = errno; | 529 | int save_errno = errno; |
541 | close(sock); | 530 | close(sock); |
542 | FAIL() << "Can not send " << getPruneList << " to logger -- " << strerror(save_errno); | 531 | FAIL() << "Can not send " << getPruneList << " to logger -- " |
532 | << strerror(save_errno); | ||
543 | } | 533 | } |
544 | 534 | ||
545 | static const unsigned long expected_absolute_minimum_log_size = 65536UL; | 535 | static const unsigned long expected_absolute_minimum_log_size = 65536UL; |
546 | unsigned long totalSize = expected_absolute_minimum_log_size; | 536 | unsigned long totalSize = expected_absolute_minimum_log_size; |
547 | static const char getSize[] = { | 537 | static const char getSize[] = { 'g', 'e', 't', 'L', 'o', 'g', |
548 | 'g', 'e', 't', 'L', 'o', 'g', 'S', 'i', 'z', 'e', ' ', | 538 | 'S', 'i', 'z', 'e', ' ', LOG_ID_MAIN + '0', |
549 | LOG_ID_MAIN + '0', '\0' | 539 | '\0' }; |
550 | }; | ||
551 | if (write(sock, getSize, sizeof(getSize)) > 0) { | 540 | if (write(sock, getSize, sizeof(getSize)) > 0) { |
552 | char buffer[80]; | 541 | char buffer[80]; |
553 | memset(buffer, 0, sizeof(buffer)); | 542 | memset(buffer, 0, sizeof(buffer)); |
@@ -556,21 +545,22 @@ TEST(logd, benchmark) { | |||
556 | if (totalSize < expected_absolute_minimum_log_size) { | 545 | if (totalSize < expected_absolute_minimum_log_size) { |
557 | fprintf(stderr, | 546 | fprintf(stderr, |
558 | "WARNING: " | 547 | "WARNING: " |
559 | "Logger had unexpected referenced size \"%s\"\n", buffer); | 548 | "Logger had unexpected referenced size \"%s\"\n", |
549 | buffer); | ||
560 | totalSize = expected_absolute_minimum_log_size; | 550 | totalSize = expected_absolute_minimum_log_size; |
561 | } | 551 | } |
562 | } | 552 | } |
563 | close(sock); | 553 | close(sock); |
564 | 554 | ||
565 | // logd allows excursions to 110% of total size | 555 | // logd allows excursions to 110% of total size |
566 | totalSize = (totalSize * 11 ) / 10; | 556 | totalSize = (totalSize * 11) / 10; |
567 | 557 | ||
568 | // 50% threshold for SPAM filter (<20% typical, lots of engineering margin) | 558 | // 50% threshold for SPAM filter (<20% typical, lots of engineering margin) |
569 | ASSERT_GT(totalSize, nowSpamSize * 2); | 559 | ASSERT_GT(totalSize, nowSpamSize * 2); |
570 | } | 560 | } |
571 | 561 | ||
572 | // b/26447386 confirm fixed | 562 | // b/26447386 confirm fixed |
573 | void timeout_negative(const char *command) { | 563 | void timeout_negative(const char* command) { |
574 | log_msg msg_wrap, msg_timeout; | 564 | log_msg msg_wrap, msg_timeout; |
575 | bool content_wrap = false, content_timeout = false, written = false; | 565 | bool content_wrap = false, content_timeout = false, written = false; |
576 | unsigned int alarm_wrap = 0, alarm_timeout = 0; | 566 | unsigned int alarm_wrap = 0, alarm_timeout = 0; |
@@ -579,8 +569,7 @@ void timeout_negative(const char *command) { | |||
579 | int i = 3; | 569 | int i = 3; |
580 | 570 | ||
581 | while (--i) { | 571 | while (--i) { |
582 | int fd = socket_local_client("logdr", | 572 | int fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, |
583 | ANDROID_SOCKET_NAMESPACE_RESERVED, | ||
584 | SOCK_SEQPACKET); | 573 | SOCK_SEQPACKET); |
585 | ASSERT_LT(0, fd); | 574 | ASSERT_LT(0, fd); |
586 | 575 | ||
@@ -609,15 +598,16 @@ void timeout_negative(const char *command) { | |||
609 | 598 | ||
610 | // alarm triggers at 133% of the --wrap time out | 599 | // alarm triggers at 133% of the --wrap time out |
611 | content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0; | 600 | content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0; |
612 | if (!content_timeout) { // make sure we hit dumpAndClose | 601 | if (!content_timeout) { // make sure we hit dumpAndClose |
613 | content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0; | 602 | content_timeout = |
603 | recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0; | ||
614 | } | 604 | } |
615 | 605 | ||
616 | alarm_timeout = alarm((old_alarm <= 0) | 606 | alarm_timeout = |
617 | ? old_alarm | 607 | alarm((old_alarm <= 0) ? old_alarm |
618 | : (old_alarm > (1 + 3 - alarm_wrap)) | 608 | : (old_alarm > (1 + 3 - alarm_wrap)) |
619 | ? old_alarm - 3 + alarm_wrap | 609 | ? old_alarm - 3 + alarm_wrap |
620 | : 2); | 610 | : 2); |
621 | sigaction(SIGALRM, &old_sigaction, NULL); | 611 | sigaction(SIGALRM, &old_sigaction, NULL); |
622 | 612 | ||
623 | close(fd); | 613 | close(fd); |
@@ -647,7 +637,8 @@ TEST(logd, timeout_no_start) { | |||
647 | } | 637 | } |
648 | 638 | ||
649 | TEST(logd, timeout_start_epoch) { | 639 | TEST(logd, timeout_start_epoch) { |
650 | timeout_negative("dumpAndClose lids=0,1,2,3,4,5 timeout=6 start=0.000000000"); | 640 | timeout_negative( |
641 | "dumpAndClose lids=0,1,2,3,4,5 timeout=6 start=0.000000000"); | ||
651 | } | 642 | } |
652 | 643 | ||
653 | // b/26447386 refined behavior | 644 | // b/26447386 refined behavior |
@@ -672,18 +663,17 @@ TEST(logd, timeout) { | |||
672 | // content providers being active during the test. | 663 | // content providers being active during the test. |
673 | int i = 5; | 664 | int i = 5; |
674 | log_time now(android_log_clockid()); | 665 | log_time now(android_log_clockid()); |
675 | now.tv_sec -= 30; // reach back a moderate period of time | 666 | now.tv_sec -= 30; // reach back a moderate period of time |
676 | 667 | ||
677 | while (--i) { | 668 | while (--i) { |
678 | int fd = socket_local_client("logdr", | 669 | int fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, |
679 | ANDROID_SOCKET_NAMESPACE_RESERVED, | ||
680 | SOCK_SEQPACKET); | 670 | SOCK_SEQPACKET); |
681 | EXPECT_LT(0, fd); | 671 | EXPECT_LT(0, fd); |
682 | if (fd < 0) _exit(fd); | 672 | if (fd < 0) _exit(fd); |
683 | 673 | ||
684 | std::string ask = android::base::StringPrintf( | 674 | std::string ask = android::base::StringPrintf( |
685 | "dumpAndClose lids=0,1,2,3,4,5 timeout=6 start=%" | 675 | "dumpAndClose lids=0,1,2,3,4,5 timeout=6 start=%" PRIu32 |
686 | PRIu32 ".%09" PRIu32, | 676 | ".%09" PRIu32, |
687 | now.tv_sec, now.tv_nsec); | 677 | now.tv_sec, now.tv_nsec); |
688 | 678 | ||
689 | struct sigaction ignore, old_sigaction; | 679 | struct sigaction ignore, old_sigaction; |
@@ -709,15 +699,16 @@ TEST(logd, timeout) { | |||
709 | 699 | ||
710 | // alarm triggers at 133% of the --wrap time out | 700 | // alarm triggers at 133% of the --wrap time out |
711 | content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0; | 701 | content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0; |
712 | if (!content_timeout) { // make sure we hit dumpAndClose | 702 | if (!content_timeout) { // make sure we hit dumpAndClose |
713 | content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0; | 703 | content_timeout = |
704 | recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0; | ||
714 | } | 705 | } |
715 | 706 | ||
716 | alarm_timeout = alarm((old_alarm <= 0) | 707 | alarm_timeout = |
717 | ? old_alarm | 708 | alarm((old_alarm <= 0) ? old_alarm |
718 | : (old_alarm > (1 + 3 - alarm_wrap)) | 709 | : (old_alarm > (1 + 3 - alarm_wrap)) |
719 | ? old_alarm - 3 + alarm_wrap | 710 | ? old_alarm - 3 + alarm_wrap |
720 | : 2); | 711 | : 2); |
721 | sigaction(SIGALRM, &old_sigaction, NULL); | 712 | sigaction(SIGALRM, &old_sigaction, NULL); |
722 | 713 | ||
723 | close(fd); | 714 | close(fd); |
@@ -742,7 +733,7 @@ TEST(logd, timeout) { | |||
742 | } | 733 | } |
743 | } | 734 | } |
744 | } else { | 735 | } else { |
745 | now.tv_sec -= 120; // inactive, reach further back! | 736 | now.tv_sec -= 120; // inactive, reach further back! |
746 | } | 737 | } |
747 | } | 738 | } |
748 | 739 | ||
@@ -755,8 +746,8 @@ TEST(logd, timeout) { | |||
755 | } | 746 | } |
756 | 747 | ||
757 | if (content_wrap || !content_timeout) { | 748 | if (content_wrap || !content_timeout) { |
758 | fprintf(stderr, "now=%" PRIu32 ".%09" PRIu32 "\n", | 749 | fprintf(stderr, "now=%" PRIu32 ".%09" PRIu32 "\n", now.tv_sec, |
759 | now.tv_sec, now.tv_nsec); | 750 | now.tv_nsec); |
760 | } | 751 | } |
761 | 752 | ||
762 | EXPECT_TRUE(written); | 753 | EXPECT_TRUE(written); |
@@ -765,20 +756,22 @@ TEST(logd, timeout) { | |||
765 | EXPECT_TRUE(content_timeout); | 756 | EXPECT_TRUE(content_timeout); |
766 | EXPECT_NE(0U, alarm_timeout); | 757 | EXPECT_NE(0U, alarm_timeout); |
767 | 758 | ||
768 | _exit(!written + content_wrap + alarm_wrap + !content_timeout + !alarm_timeout); | 759 | _exit(!written + content_wrap + alarm_wrap + !content_timeout + |
760 | !alarm_timeout); | ||
769 | } | 761 | } |
770 | 762 | ||
771 | // b/27242723 confirmed fixed | 763 | // b/27242723 confirmed fixed |
772 | TEST(logd, SNDTIMEO) { | 764 | TEST(logd, SNDTIMEO) { |
773 | static const unsigned sndtimeo = LOGD_SNDTIMEO; // <sigh> it has to be done! | 765 | static const unsigned sndtimeo = |
766 | LOGD_SNDTIMEO; // <sigh> it has to be done! | ||
774 | static const unsigned sleep_time = sndtimeo + 3; | 767 | static const unsigned sleep_time = sndtimeo + 3; |
775 | static const unsigned alarm_time = sleep_time + 5; | 768 | static const unsigned alarm_time = sleep_time + 5; |
776 | 769 | ||
777 | int fd; | 770 | int fd; |
778 | 771 | ||
779 | ASSERT_TRUE((fd = socket_local_client("logdr", | 772 | ASSERT_TRUE( |
780 | ANDROID_SOCKET_NAMESPACE_RESERVED, | 773 | (fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, |
781 | SOCK_SEQPACKET)) > 0); | 774 | SOCK_SEQPACKET)) > 0); |
782 | 775 | ||
783 | struct sigaction ignore, old_sigaction; | 776 | struct sigaction ignore, old_sigaction; |
784 | memset(&ignore, 0, sizeof(ignore)); | 777 | memset(&ignore, 0, sizeof(ignore)); |
@@ -787,7 +780,7 @@ TEST(logd, SNDTIMEO) { | |||
787 | sigaction(SIGALRM, &ignore, &old_sigaction); | 780 | sigaction(SIGALRM, &ignore, &old_sigaction); |
788 | unsigned int old_alarm = alarm(alarm_time); | 781 | unsigned int old_alarm = alarm(alarm_time); |
789 | 782 | ||
790 | static const char ask[] = "stream lids=0,1,2,3,4,5,6"; // all sources | 783 | static const char ask[] = "stream lids=0,1,2,3,4,5,6"; // all sources |
791 | bool reader_requested = write(fd, ask, sizeof(ask)) == sizeof(ask); | 784 | bool reader_requested = write(fd, ask, sizeof(ask)) == sizeof(ask); |
792 | EXPECT_TRUE(reader_requested); | 785 | EXPECT_TRUE(reader_requested); |
793 | 786 | ||
@@ -799,7 +792,7 @@ TEST(logd, SNDTIMEO) { | |||
799 | dump_log_msg("user", &msg, 3, -1); | 792 | dump_log_msg("user", &msg, 3, -1); |
800 | } | 793 | } |
801 | 794 | ||
802 | fprintf (stderr, "Sleep for >%d seconds logd SO_SNDTIMEO ...\n", sndtimeo); | 795 | fprintf(stderr, "Sleep for >%d seconds logd SO_SNDTIMEO ...\n", sndtimeo); |
803 | sleep(sleep_time); | 796 | sleep(sleep_time); |
804 | 797 | ||
805 | // flush will block if we did not trigger. if it did, last entry returns 0 | 798 | // flush will block if we did not trigger. if it did, last entry returns 0 |
@@ -828,7 +821,7 @@ TEST(logd, getEventTag_list) { | |||
828 | snprintf(buffer, sizeof(buffer), "getEventTag name=*"); | 821 | snprintf(buffer, sizeof(buffer), "getEventTag name=*"); |
829 | send_to_control(buffer, sizeof(buffer)); | 822 | send_to_control(buffer, sizeof(buffer)); |
830 | buffer[sizeof(buffer) - 1] = '\0'; | 823 | buffer[sizeof(buffer) - 1] = '\0'; |
831 | char *cp; | 824 | char* cp; |
832 | long ret = strtol(buffer, &cp, 10); | 825 | long ret = strtol(buffer, &cp, 10); |
833 | EXPECT_GT(ret, 4096); | 826 | EXPECT_GT(ret, 4096); |
834 | #else | 827 | #else |
@@ -843,7 +836,7 @@ TEST(logd, getEventTag_42) { | |||
843 | snprintf(buffer, sizeof(buffer), "getEventTag id=42"); | 836 | snprintf(buffer, sizeof(buffer), "getEventTag id=42"); |
844 | send_to_control(buffer, sizeof(buffer)); | 837 | send_to_control(buffer, sizeof(buffer)); |
845 | buffer[sizeof(buffer) - 1] = '\0'; | 838 | buffer[sizeof(buffer) - 1] = '\0'; |
846 | char *cp; | 839 | char* cp; |
847 | long ret = strtol(buffer, &cp, 10); | 840 | long ret = strtol(buffer, &cp, 10); |
848 | EXPECT_GT(ret, 16); | 841 | EXPECT_GT(ret, 16); |
849 | EXPECT_TRUE(strstr(buffer, "\t(to life the universe etc|3)") != NULL); | 842 | EXPECT_TRUE(strstr(buffer, "\t(to life the universe etc|3)") != NULL); |
@@ -860,24 +853,23 @@ TEST(logd, getEventTag_newentry) { | |||
860 | log_time now(CLOCK_MONOTONIC); | 853 | log_time now(CLOCK_MONOTONIC); |
861 | char name[64]; | 854 | char name[64]; |
862 | snprintf(name, sizeof(name), "a%" PRIu64, now.nsec()); | 855 | snprintf(name, sizeof(name), "a%" PRIu64, now.nsec()); |
863 | snprintf(buffer, sizeof(buffer), | 856 | snprintf(buffer, sizeof(buffer), "getEventTag name=%s format=\"(new|1)\"", |
864 | "getEventTag name=%s format=\"(new|1)\"", name); | 857 | name); |
865 | send_to_control(buffer, sizeof(buffer)); | 858 | send_to_control(buffer, sizeof(buffer)); |
866 | buffer[sizeof(buffer) - 1] = '\0'; | 859 | buffer[sizeof(buffer) - 1] = '\0'; |
867 | char *cp; | 860 | char* cp; |
868 | long ret = strtol(buffer, &cp, 10); | 861 | long ret = strtol(buffer, &cp, 10); |
869 | EXPECT_GT(ret, 16); | 862 | EXPECT_GT(ret, 16); |
870 | EXPECT_TRUE(strstr(buffer, "\t(new|1)") != NULL); | 863 | EXPECT_TRUE(strstr(buffer, "\t(new|1)") != NULL); |
871 | EXPECT_TRUE(strstr(buffer, name) != NULL); | 864 | EXPECT_TRUE(strstr(buffer, name) != NULL); |
872 | // ToDo: also look for this in /data/misc/logd/event-log-tags and | 865 | // ToDo: also look for this in /data/misc/logd/event-log-tags and |
873 | // /dev/event-log-tags. | 866 | // /dev/event-log-tags. |
874 | #else | 867 | #else |
875 | GTEST_LOG_(INFO) << "This test does nothing.\n"; | 868 | GTEST_LOG_(INFO) << "This test does nothing.\n"; |
876 | #endif | 869 | #endif |
877 | } | 870 | } |
878 | 871 | ||
879 | static inline int32_t get4LE(const char* src) | 872 | static inline int32_t get4LE(const char* src) { |
880 | { | ||
881 | return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); | 873 | return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); |
882 | } | 874 | } |
883 | 875 | ||
@@ -894,10 +886,12 @@ void __android_log_btwrite_multiple__helper(int count) { | |||
894 | if (pid == 0) { | 886 | if (pid == 0) { |
895 | // child | 887 | // child |
896 | for (int i = count; i; --i) { | 888 | for (int i = count; i; --i) { |
897 | ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); | 889 | ASSERT_LT( |
890 | 0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); | ||
898 | usleep(100); | 891 | usleep(100); |
899 | } | 892 | } |
900 | ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1))); | 893 | ASSERT_LT(0, |
894 | __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1))); | ||
901 | usleep(1000000); | 895 | usleep(1000000); |
902 | 896 | ||
903 | _exit(0); | 897 | _exit(0); |
@@ -907,9 +901,11 @@ void __android_log_btwrite_multiple__helper(int count) { | |||
907 | ASSERT_EQ(0, TEMP_FAILURE_RETRY(waitid(P_PID, pid, &info, WEXITED))); | 901 | ASSERT_EQ(0, TEMP_FAILURE_RETRY(waitid(P_PID, pid, &info, WEXITED))); |
908 | ASSERT_EQ(0, info.si_status); | 902 | ASSERT_EQ(0, info.si_status); |
909 | 903 | ||
910 | struct logger_list *logger_list; | 904 | struct logger_list* logger_list; |
911 | ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( | 905 | ASSERT_TRUE(NULL != |
912 | LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, pid))); | 906 | (logger_list = android_logger_list_open( |
907 | LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, | ||
908 | 0, pid))); | ||
913 | 909 | ||
914 | int expected_count = (count < 2) ? count : 2; | 910 | int expected_count = (count < 2) ? count : 2; |
915 | int expected_chatty_count = (count <= 2) ? 0 : 1; | 911 | int expected_chatty_count = (count <= 2) ? 0 : 1; |
@@ -926,16 +922,17 @@ void __android_log_btwrite_multiple__helper(int count) { | |||
926 | log_msg log_msg; | 922 | log_msg log_msg; |
927 | if (android_logger_list_read(logger_list, &log_msg) <= 0) break; | 923 | if (android_logger_list_read(logger_list, &log_msg) <= 0) break; |
928 | 924 | ||
929 | if ((log_msg.entry.pid != pid) || | 925 | if ((log_msg.entry.pid != pid) || (log_msg.entry.len < (4 + 1 + 8)) || |
930 | (log_msg.entry.len < (4 + 1 + 8)) || | 926 | (log_msg.id() != LOG_ID_EVENTS)) |
931 | (log_msg.id() != LOG_ID_EVENTS)) continue; | 927 | continue; |
932 | 928 | ||
933 | char *eventData = log_msg.msg(); | 929 | char* eventData = log_msg.msg(); |
934 | if (!eventData) continue; | 930 | if (!eventData) continue; |
935 | 931 | ||
936 | uint32_t tag = get4LE(eventData); | 932 | uint32_t tag = get4LE(eventData); |
937 | 933 | ||
938 | if ((eventData[4] == EVENT_TYPE_LONG) && (log_msg.entry.len == (4 + 1 + 8))) { | 934 | if ((eventData[4] == EVENT_TYPE_LONG) && |
935 | (log_msg.entry.len == (4 + 1 + 8))) { | ||
939 | if (tag != 0) continue; | 936 | if (tag != 0) continue; |
940 | 937 | ||
941 | log_time tx(eventData + 4 + 1); | 938 | log_time tx(eventData + 4 + 1); |
@@ -949,7 +946,7 @@ void __android_log_btwrite_multiple__helper(int count) { | |||
949 | ++chatty_count; | 946 | ++chatty_count; |
950 | // int len = get4LE(eventData + 4 + 1); | 947 | // int len = get4LE(eventData + 4 + 1); |
951 | log_msg.buf[LOGGER_ENTRY_MAX_LEN] = '\0'; | 948 | log_msg.buf[LOGGER_ENTRY_MAX_LEN] = '\0'; |
952 | const char *cp; | 949 | const char* cp; |
953 | if ((cp = strstr(eventData + 4 + 1 + 4, " identical "))) { | 950 | if ((cp = strstr(eventData + 4 + 1 + 4, " identical "))) { |
954 | unsigned val = 0; | 951 | unsigned val = 0; |
955 | sscanf(cp, " identical %u lines", &val); | 952 | sscanf(cp, " identical %u lines", &val); |
@@ -1004,8 +1001,8 @@ static pid_t sepolicy_rate(unsigned rate, unsigned num) { | |||
1004 | int save_errno = errno; | 1001 | int save_errno = errno; |
1005 | security_context_t context; | 1002 | security_context_t context; |
1006 | getcon(&context); | 1003 | getcon(&context); |
1007 | fprintf(stderr, "setcon(\"u:r:shell:s0\") failed @\"%s\" %s\n", | 1004 | fprintf(stderr, "setcon(\"u:r:shell:s0\") failed @\"%s\" %s\n", context, |
1008 | context, strerror(save_errno)); | 1005 | strerror(save_errno)); |
1009 | freecon(context); | 1006 | freecon(context); |
1010 | _exit(-1); | 1007 | _exit(-1); |
1011 | // NOTREACHED | 1008 | // NOTREACHED |
@@ -1052,22 +1049,20 @@ static int count_avc(pid_t pid) { | |||
1052 | 1049 | ||
1053 | if (pid == 0) return count; | 1050 | if (pid == 0) return count; |
1054 | 1051 | ||
1055 | struct logger_list *logger_list; | 1052 | struct logger_list* logger_list; |
1056 | if (!(logger_list = android_logger_list_open(LOG_ID_EVENTS, | 1053 | if (!(logger_list = android_logger_list_open( |
1057 | ANDROID_LOG_RDONLY | | 1054 | LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, pid))) |
1058 | ANDROID_LOG_NONBLOCK, | 1055 | return count; |
1059 | 0, | ||
1060 | pid))) return count; | ||
1061 | for (;;) { | 1056 | for (;;) { |
1062 | log_msg log_msg; | 1057 | log_msg log_msg; |
1063 | 1058 | ||
1064 | if (android_logger_list_read(logger_list, &log_msg) <= 0) break; | 1059 | if (android_logger_list_read(logger_list, &log_msg) <= 0) break; |
1065 | 1060 | ||
1066 | if ((log_msg.entry.pid != pid) || | 1061 | if ((log_msg.entry.pid != pid) || (log_msg.entry.len < (4 + 1 + 8)) || |
1067 | (log_msg.entry.len < (4 + 1 + 8)) || | 1062 | (log_msg.id() != LOG_ID_EVENTS)) |
1068 | (log_msg.id() != LOG_ID_EVENTS)) continue; | 1063 | continue; |
1069 | 1064 | ||
1070 | char *eventData = log_msg.msg(); | 1065 | char* eventData = log_msg.msg(); |
1071 | if (!eventData) continue; | 1066 | if (!eventData) continue; |
1072 | 1067 | ||
1073 | uint32_t tag = get4LE(eventData); | 1068 | uint32_t tag = get4LE(eventData); |
@@ -1077,7 +1072,7 @@ static int count_avc(pid_t pid) { | |||
1077 | 1072 | ||
1078 | // int len = get4LE(eventData + 4 + 1); | 1073 | // int len = get4LE(eventData + 4 + 1); |
1079 | log_msg.buf[LOGGER_ENTRY_MAX_LEN] = '\0'; | 1074 | log_msg.buf[LOGGER_ENTRY_MAX_LEN] = '\0'; |
1080 | const char *cp = strstr(eventData + 4 + 1 + 4, "): avc: denied"); | 1075 | const char* cp = strstr(eventData + 4 + 1 + 4, "): avc: denied"); |
1081 | if (!cp) continue; | 1076 | if (!cp) continue; |
1082 | 1077 | ||
1083 | ++count; | 1078 | ++count; |
@@ -1103,10 +1098,11 @@ TEST(logd, sepolicy_rate_limiter_maximum) { | |||
1103 | TEST(logd, sepolicy_rate_limiter_sub_burst) { | 1098 | TEST(logd, sepolicy_rate_limiter_sub_burst) { |
1104 | #ifdef __ANDROID__ | 1099 | #ifdef __ANDROID__ |
1105 | // maximum period below half way between sustainable and burst rate. | 1100 | // maximum period below half way between sustainable and burst rate. |
1106 | static const int threshold = ((AUDIT_RATE_LIMIT_BURST_DURATION * | 1101 | static const int threshold = |
1107 | (AUDIT_RATE_LIMIT_DEFAULT + | 1102 | ((AUDIT_RATE_LIMIT_BURST_DURATION * |
1108 | AUDIT_RATE_LIMIT_MAX)) + | 1103 | (AUDIT_RATE_LIMIT_DEFAULT + AUDIT_RATE_LIMIT_MAX)) + |
1109 | 1) / 2; | 1104 | 1) / |
1105 | 2; | ||
1110 | static const int rate = (threshold / AUDIT_RATE_LIMIT_BURST_DURATION) - 1; | 1106 | static const int rate = (threshold / AUDIT_RATE_LIMIT_BURST_DURATION) - 1; |
1111 | static const int duration = AUDIT_RATE_LIMIT_BURST_DURATION; | 1107 | static const int duration = AUDIT_RATE_LIMIT_BURST_DURATION; |
1112 | EXPECT_EQ(rate * duration, count_avc(sepolicy_rate(rate, rate * duration))); | 1108 | EXPECT_EQ(rate * duration, count_avc(sepolicy_rate(rate, rate * duration))); |
@@ -1118,24 +1114,25 @@ TEST(logd, sepolicy_rate_limiter_sub_burst) { | |||
1118 | TEST(logd, sepolicy_rate_limiter_spam) { | 1114 | TEST(logd, sepolicy_rate_limiter_spam) { |
1119 | #ifdef __ANDROID__ | 1115 | #ifdef __ANDROID__ |
1120 | // maximum period of double the maximum burst rate | 1116 | // maximum period of double the maximum burst rate |
1121 | static const int threshold = ((AUDIT_RATE_LIMIT_BURST_DURATION * | 1117 | static const int threshold = |
1122 | (AUDIT_RATE_LIMIT_DEFAULT + | 1118 | ((AUDIT_RATE_LIMIT_BURST_DURATION * |
1123 | AUDIT_RATE_LIMIT_MAX)) + | 1119 | (AUDIT_RATE_LIMIT_DEFAULT + AUDIT_RATE_LIMIT_MAX)) + |
1124 | 1) / 2; | 1120 | 1) / |
1121 | 2; | ||
1125 | static const int rate = AUDIT_RATE_LIMIT_DEFAULT * 2; | 1122 | static const int rate = AUDIT_RATE_LIMIT_DEFAULT * 2; |
1126 | static const int duration = threshold / AUDIT_RATE_LIMIT_DEFAULT; | 1123 | static const int duration = threshold / AUDIT_RATE_LIMIT_DEFAULT; |
1127 | EXPECT_GE(((AUDIT_RATE_LIMIT_DEFAULT * duration) * 115) / | 1124 | EXPECT_GE( |
1128 | 100, // +15% margin | 1125 | ((AUDIT_RATE_LIMIT_DEFAULT * duration) * 115) / 100, // +15% margin |
1129 | count_avc(sepolicy_rate(rate, rate * duration))); | 1126 | count_avc(sepolicy_rate(rate, rate * duration))); |
1130 | // give logd another 3 seconds to react to the burst before checking | 1127 | // give logd another 3 seconds to react to the burst before checking |
1131 | sepolicy_rate(rate, rate * 3); | 1128 | sepolicy_rate(rate, rate * 3); |
1132 | // maximum period at double the maximum burst rate (spam filter kicked in) | 1129 | // maximum period at double the maximum burst rate (spam filter kicked in) |
1133 | EXPECT_GE(threshold * 2, | 1130 | EXPECT_GE( |
1134 | count_avc(sepolicy_rate(rate, | 1131 | threshold * 2, |
1135 | rate * AUDIT_RATE_LIMIT_BURST_DURATION))); | 1132 | count_avc(sepolicy_rate(rate, rate * AUDIT_RATE_LIMIT_BURST_DURATION))); |
1136 | // cool down, and check unspammy rate still works | 1133 | // cool down, and check unspammy rate still works |
1137 | sleep(2); | 1134 | sleep(2); |
1138 | EXPECT_LE(AUDIT_RATE_LIMIT_BURST_DURATION - 1, // allow _one_ to be lost | 1135 | EXPECT_LE(AUDIT_RATE_LIMIT_BURST_DURATION - 1, // allow _one_ to be lost |
1139 | count_avc(sepolicy_rate(1, AUDIT_RATE_LIMIT_BURST_DURATION))); | 1136 | count_avc(sepolicy_rate(1, AUDIT_RATE_LIMIT_BURST_DURATION))); |
1140 | #else | 1137 | #else |
1141 | GTEST_LOG_(INFO) << "This test does nothing.\n"; | 1138 | GTEST_LOG_(INFO) << "This test does nothing.\n"; |