summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Salyzyn2017-03-10 16:31:54 -0600
committerMark Salyzyn2017-03-13 12:31:09 -0500
commit501c373916e292764400dbae735f44b33378400f (patch)
tree56946d23a00461d2a462658f36689faa1d9d71a3
parent488525b47ba23b2548f3bf6aa2f4ce6267b2d9b5 (diff)
downloadplatform-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
-rw-r--r--logd/.clang-format11
-rw-r--r--logd/CommandListener.cpp137
-rw-r--r--logd/CommandListener.h81
-rw-r--r--logd/FlushCommand.cpp40
-rw-r--r--logd/FlushCommand.h23
-rw-r--r--logd/LogAudit.cpp146
-rw-r--r--logd/LogAudit.h26
-rw-r--r--logd/LogBuffer.cpp304
-rw-r--r--logd/LogBuffer.h80
-rw-r--r--logd/LogBufferElement.cpp112
-rw-r--r--logd/LogBufferElement.h82
-rw-r--r--logd/LogCommand.cpp41
-rw-r--r--logd/LogCommand.h9
-rw-r--r--logd/LogKlog.cpp362
-rw-r--r--logd/LogKlog.h40
-rw-r--r--logd/LogListener.cpp54
-rw-r--r--logd/LogListener.h14
-rw-r--r--logd/LogReader.cpp62
-rw-r--r--logd/LogReader.h19
-rw-r--r--logd/LogStatistics.cpp225
-rw-r--r--logd/LogStatistics.h406
-rw-r--r--logd/LogTags.cpp147
-rw-r--r--logd/LogTags.h49
-rw-r--r--logd/LogTimes.cpp88
-rw-r--r--logd/LogTimes.h62
-rw-r--r--logd/LogUtils.h19
-rw-r--r--logd/LogWhiteBlackList.cpp20
-rw-r--r--logd/LogWhiteBlackList.h48
-rw-r--r--logd/libaudit.c31
-rw-r--r--logd/libaudit.h15
-rw-r--r--logd/main.cpp161
-rw-r--r--logd/tests/logd_test.cpp457
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 @@
1BasedOnStyle: Google
2AllowShortFunctionsOnASingleLine: false
3
4CommentPragmas: NOLINT:.*
5DerivePointerAlignment: false
6IndentWidth: 4
7PointerAlignment: Left
8TabWidth: 4
9PenaltyExcessCharacter: 32
10
11Cpp11BracedListStyle: 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
40CommandListener::CommandListener(LogBuffer *buf, LogReader * /*reader*/, 40CommandListener::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
56CommandListener::ShutdownCmd::ShutdownCmd(LogReader *reader, 56CommandListener::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
63int CommandListener::ShutdownCmd::runCommand(SocketClient * /*cli*/, 60int 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
71CommandListener::ClearCmd::ClearCmd(LogBuffer *buf) : 67CommandListener::ClearCmd::ClearCmd(LogBuffer* buf)
72 LogCommand("clear"), 68 : LogCommand("clear"), mBuf(*buf) {
73 mBuf(*buf) {
74} 69}
75 70
76static void setname() { 71static void setname() {
@@ -81,8 +76,8 @@ static void setname() {
81 } 76 }
82} 77}
83 78
84int CommandListener::ClearCmd::runCommand(SocketClient *cli, 79int 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
107CommandListener::GetBufSizeCmd::GetBufSizeCmd(LogBuffer *buf) : 102CommandListener::GetBufSizeCmd::GetBufSizeCmd(LogBuffer* buf)
108 LogCommand("getLogSize"), 103 : LogCommand("getLogSize"), mBuf(*buf) {
109 mBuf(*buf) {
110} 104}
111 105
112int CommandListener::GetBufSizeCmd::runCommand(SocketClient *cli, 106int 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
133CommandListener::SetBufSizeCmd::SetBufSizeCmd(LogBuffer *buf) : 127CommandListener::SetBufSizeCmd::SetBufSizeCmd(LogBuffer* buf)
134 LogCommand("setLogSize"), 128 : LogCommand("setLogSize"), mBuf(*buf) {
135 mBuf(*buf) {
136} 129}
137 130
138int CommandListener::SetBufSizeCmd::runCommand(SocketClient *cli, 131int 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
167CommandListener::GetBufSizeUsedCmd::GetBufSizeUsedCmd(LogBuffer *buf) : 160CommandListener::GetBufSizeUsedCmd::GetBufSizeUsedCmd(LogBuffer* buf)
168 LogCommand("getLogSizeUsed"), 161 : LogCommand("getLogSizeUsed"), mBuf(*buf) {
169 mBuf(*buf) {
170} 162}
171 163
172int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient *cli, 164int 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
193CommandListener::GetStatisticsCmd::GetStatisticsCmd(LogBuffer *buf) : 185CommandListener::GetStatisticsCmd::GetStatisticsCmd(LogBuffer* buf)
194 LogCommand("getStatistics"), 186 : LogCommand("getStatistics"), mBuf(*buf) {
195 mBuf(*buf) {
196} 187}
197 188
198static std::string package_string(const std::string &str) { 189static 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
207int CommandListener::GetStatisticsCmd::runCommand(SocketClient *cli, 199int 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
244CommandListener::GetPruneListCmd::GetPruneListCmd(LogBuffer *buf) : 236CommandListener::GetPruneListCmd::GetPruneListCmd(LogBuffer* buf)
245 LogCommand("getPruneList"), 237 : LogCommand("getPruneList"), mBuf(*buf) {
246 mBuf(*buf) {
247} 238}
248 239
249int CommandListener::GetPruneListCmd::runCommand(SocketClient *cli, 240int 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
256CommandListener::SetPruneListCmd::SetPruneListCmd(LogBuffer *buf) : 247CommandListener::SetPruneListCmd::SetPruneListCmd(LogBuffer* buf)
257 LogCommand("setPruneList"), 248 : LogCommand("setPruneList"), mBuf(*buf) {
258 mBuf(*buf) {
259} 249}
260 250
261int CommandListener::SetPruneListCmd::runCommand(SocketClient *cli, 251int 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
289CommandListener::GetEventTagCmd::GetEventTagCmd(LogBuffer *buf) : 279CommandListener::GetEventTagCmd::GetEventTagCmd(LogBuffer* buf)
290 LogCommand("getEventTag"), 280 : LogCommand("getEventTag"), mBuf(*buf) {
291 mBuf(*buf) {
292} 281}
293 282
294int CommandListener::GetEventTagCmd::runCommand(SocketClient *cli, 283int 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,
340CommandListener::ReinitCmd::ReinitCmd() : LogCommand("reinit") { 329CommandListener::ReinitCmd::ReinitCmd() : LogCommand("reinit") {
341} 330}
342 331
343int CommandListener::ReinitCmd::runCommand(SocketClient *cli, 332int 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
354CommandListener::ExitCmd::ExitCmd(CommandListener *parent) : 343CommandListener::ExitCmd::ExitCmd(CommandListener* parent)
355 LogCommand("EXIT"), 344 : LogCommand("EXIT"), mParent(*parent) {
356 mParent(*parent) {
357} 345}
358 346
359int CommandListener::ExitCmd::runCommand(SocketClient * cli, 347int 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
27void reinit_signal_handler(int /*signal*/); 27void reinit_signal_handler(int /*signal*/);
28 28
29class CommandListener : public FrameworkListener { 29class CommandListener : public FrameworkListener {
30 public:
31 CommandListener(LogBuffer* buf, LogReader* reader, LogListener* swl);
32 virtual ~CommandListener() {
33 }
30 34
31public: 35 private:
32 CommandListener(LogBuffer *buf, LogReader *reader, LogListener *swl);
33 virtual ~CommandListener() {}
34
35private:
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
29FlushCommand::FlushCommand(LogReader &reader, 29FlushCommand::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.
54void FlushCommand::runSocketCommand(SocketClient *client) { 50void FlushCommand::runSocketCommand(SocketClient* client) {
55 LogTimeEntry *entry = NULL; 51 LogTimeEntry* entry = NULL;
56 LastLogTimes &times = 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
96bool FlushCommand::hasReadLogs(SocketClient *client) { 92bool FlushCommand::hasReadLogs(SocketClient* client) {
97 return clientHasLogCredentials(client); 93 return clientHasLogCredentials(client);
98} 94}
99 95
100static bool clientHasSecurityCredentials(SocketClient *client) { 96static 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
104bool FlushCommand::hasSecurityLogs(SocketClient *client) { 100bool 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;
26class LogReader; 26class LogReader;
27 27
28class FlushCommand : public SocketClientCommand { 28class 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
37public: 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 '>' 43LogAudit::LogAudit(LogBuffer* buf, LogReader* reader, int fdDmesg)
44 44 : SocketListener(mSock = getLogSocket(), false),
45LogAudit::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
62void LogAudit::checkRateLimit() { 77void 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
102bool LogAudit::onDataAvailable(SocketClient *cli) { 117bool 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
126int LogAudit::logPrint(const char *fmt, ...) { 141int 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
368int LogAudit::log(char *buf, size_t len) { 378int 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 @@
26class LogReader; 26class LogReader;
27 27
28class LogAudit : public SocketListener { 28class 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
41public: 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
46protected: 48 protected:
47 virtual bool onDataAvailable(SocketClient *cli); 49 virtual bool onDataAvailable(SocketClient* cli);
48 50
49private: 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
110LogBuffer::LogBuffer(LastLogTimes *times): 110LogBuffer::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
130enum match_type { 129enum match_type { DIFFERENT, SAME, SAME_LIBLOG };
131 DIFFERENT,
132 SAME,
133 SAME_LIBLOG
134};
135 130
136static enum match_type identical(LogBufferElement* elem, LogBufferElement* last) { 131static 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
190int LogBuffer::log(log_id_t log_id, log_time realtime, 188int 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
446LogBufferElementCollection::iterator LogBuffer::erase( 442LogBufferElementCollection::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
542public: 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
554class LogBufferElementLast { 552class 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
559public: 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//
653bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { 646bool 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
1075uint64_t LogBuffer::flushTo( 1069uint64_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//
42namespace android { 42namespace android {
43 43
44static bool isMonotonic(const log_time &mono) { 44static 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
76typedef std::list<LogBufferElement *> LogBufferElementCollection; 75typedef std::list<LogBufferElement*> LogBufferElementCollection;
77 76
78class LogBuffer { 77class 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
109public: 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 }
155private: 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
36LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime, 36LogBufferElement::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
53LogBufferElement::LogBufferElement(const LogBufferElement &elem) : 53LogBufferElement::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
66LogBufferElement::~LogBufferElement() { 66LogBufferElement::~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
71char *android::tidToName(pid_t tid) { 71char* 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
116size_t LogBufferElement::populateDroppedMessage(char*& buffer, 116size_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
27class LogBuffer; 27class 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
35class LogBufferElement { 35class 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);
59public: 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
27LogCommand::LogCommand(const char *cmd) : FrameworkCommand(cmd) { 27LogCommand::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
43static bool groupIsLog(char *buf) { 43static 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
148bool clientHasLogCredentials(SocketClient *cli) { 143bool 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
23class LogCommand : public FrameworkCommand { 23class LogCommand : public FrameworkCommand {
24public: 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
41static const char priority_message[] = { KMSG_PRIORITY(LOG_INFO), '\0' }; 38static 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 '>'
46static char *is_prio(char *s, size_t len) { 43static 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 ']'
63static char *is_timestamp(char *s, size_t len) { 60static 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
98char *log_strntok_r(char *s, size_t *len, char **last, size_t *sublen) { 96char* 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
218LogKlog::LogKlog(LogBuffer *buf, LogReader *reader, int fdWrite, int fdRead, bool auditd) : 216LogKlog::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
233bool LogKlog::onDataAvailable(SocketClient *cli) { 232bool 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 275void LogKlog::calculateCorrection(const log_time& monotonic,
277void 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
326void LogKlog::sniffTime(log_time &now, 323void 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
401pid_t LogKlog::sniffPid(const char **buf, size_t len) { 397pid_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
444static int parseKernelPrio(const char **buf, size_t len) { 437static 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
504static int convertKernelPrioToAndroidPrio(int pri) { 497static 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
533static const char *strnrchr(const char *s, size_t len, char c) { 526static 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
713twoWord: 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
23char *log_strntok_r(char *s, size_t *len, char **saveptr, size_t *sublen); 23char* log_strntok_r(char* s, size_t* len, char** saveptr, size_t* sublen);
24 24
25class LogBuffer; 25class LogBuffer;
26class LogReader; 26class LogReader;
27 27
28class LogKlog : public SocketListener { 28class 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
43public: 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) {
52protected: 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
33LogListener::LogListener(LogBuffer *buf, LogReader *reader) : 33LogListener::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
39bool LogListener::onDataAvailable(SocketClient *cli) { 37bool 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
23class LogListener : public SocketListener { 23class LogListener : public SocketListener {
24 LogBuffer *logbuf; 24 LogBuffer* logbuf;
25 LogReader *reader; 25 LogReader* reader;
26 26
27public: 27 public:
28 LogListener(LogBuffer *buf, LogReader *reader); 28 LogListener(LogBuffer* buf, LogReader* reader);
29 29
30protected: 30 protected:
31 virtual bool onDataAvailable(SocketClient *cli); 31 virtual bool onDataAvailable(SocketClient* cli);
32 32
33private: 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
32LogReader::LogReader(LogBuffer *logbuf) : 32LogReader::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
44bool LogReader::onDataAvailable(SocketClient *cli) { 43bool 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
193void LogReader::doSocketDelete(SocketClient *cli) { 196void LogReader::doSocketDelete(SocketClient* cli) {
194 LastLogTimes &times = 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 @@
24class LogBuffer; 24class LogBuffer;
25 25
26class LogReader : public SocketListener { 26class LogReader : public SocketListener {
27 LogBuffer &mLogbuf; 27 LogBuffer& mLogbuf;
28 28
29public: 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
35protected: 37 protected:
36 virtual bool onDataAvailable(SocketClient *cli); 38 virtual bool onDataAvailable(SocketClient* cli);
37 39
38private: 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
42namespace android { 42namespace android {
43 43
44size_t sizesTotal() { return LogStatistics::sizesTotal(); } 44size_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
47char *pidToName(pid_t pid) { 49char* 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
72void LogStatistics::add(LogBufferElement *element) { 73void 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
117void LogStatistics::subtract(LogBufferElement *element) { 118void 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.
154void LogStatistics::drop(LogBufferElement *element) { 155void 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
183const char *LogStatistics::uidToName(uid_t uid) const { 184const 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
239std::string UidEntry::formatHeader(const std::string &name, log_id_t id) const { 241std::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
250std::string UidEntry::format(const LogStatistics &stat, log_id_t id) const { 251std::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
358std::string PidEntry::formatHeader(const std::string &name, log_id_t /* id */) const { 357std::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
367std::string PidEntry::format(const LogStatistics &stat, log_id_t /* id */) const { 364std::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
395std::string TidEntry::formatHeader(const std::string &name, log_id_t /* id */) const { 390std::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
404std::string TidEntry::format(const LogStatistics &stat, log_id_t /* id */) const { 397std::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
435std::string TagEntry::formatHeader(const std::string &name, log_id_t id) const { 425std::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
445std::string TagEntry::format(const LogStatistics & /* stat */, log_id_t /* id */) const { 433std::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 {
611uid_t pidToUid(pid_t pid) { 599uid_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
630uid_t LogStatistics::pidToUid(pid_t pid) { 617uid_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
635const char *LogStatistics::pidToName(pid_t pid) const { 622const 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
39class LogStatistics; 39class LogStatistics;
40 40
41template <typename TKey, typename TEntry> 41template <typename TKey, typename TEntry>
42class LogHashtable { 42class 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
61public: 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
186namespace EntryBaseConstants { 191namespace EntryBaseConstants {
187 static constexpr size_t pruned_len = 14; 192static constexpr size_t pruned_len = 14;
188 static constexpr size_t total_len = 80; 193static constexpr size_t total_len = 80;
189} 194}
190 195
191struct EntryBase { 196struct 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 {
228struct EntryBaseDropped : public EntryBase { 237struct 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
278namespace android { 295namespace android {
@@ -282,32 +299,42 @@ uid_t pidToUid(pid_t pid);
282struct PidEntry : public EntryBaseDropped { 299struct 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
338struct TidEntry : public EntryBaseDropped { 365struct 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
401struct TagEntry : public EntryBaseDropped { 440struct 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
432template <typename TEntry> 479template <typename TEntry>
433class LogFindWorst { 480class LogFindWorst {
434 std::unique_ptr<const TEntry *[]> sorted; 481 std::unique_ptr<const TEntry* []> sorted;
435 482
436public: 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
526public: 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
129void LogTags::AddEventLogTags(uint32_t tag, uid_t uid, 129void 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.
276static inline uint32_t get4LE(const char* msg) 280static 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.
285void LogTags::ReadPersistEventLogTags() { 288void 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.
436uint32_t LogTags::nameToTag_locked(const std::string& name, 440uint32_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
592void LogTags::WriteDynamicEventLogTags(uint32_t tag, uid_t uid) { 593void 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
614void LogTags::WriteDebugEventLogTags(uint32_t tag, uid_t uid) { 615void 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
639void LogTags::WritePersistEventLogTags(uint32_t tag, 640void 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
794std::string LogTags::formatEntry(uint32_t tag, uid_t uid, 795std::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
810std::string LogTags::formatEntry_locked(uint32_t tag, uid_t uid, 809std::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
844std::string LogTags::formatGetEventTag(uid_t uid, 843std::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
94public: 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
25pthread_mutex_t LogTimeEntry::timesLock = PTHREAD_MUTEX_INITIALIZER; 25pthread_mutex_t LogTimeEntry::timesLock = PTHREAD_MUTEX_INITIALIZER;
26 26
27LogTimeEntry::LogTimeEntry(LogReader &reader, SocketClient *client, 27LogTimeEntry::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
74void LogTimeEntry::threadStop(void *obj) { 74void 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 &times = 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
113void *LogTimeEntry::threadStart(void *obj) { 113void* 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 &timesLock, 140 &timesLock, &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
187int LogTimeEntry::FilterFirstPass(const LogBufferElement *element, void *obj) { 187int 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
215int LogTimeEntry::FilterSecondPass(const LogBufferElement *element, void *obj) { 215int 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
272skip: 272skip:
273 LogTimeEntry::unlock(); 273 LogTimeEntry::unlock();
@@ -279,7 +279,7 @@ stop:
279} 279}
280 280
281void LogTimeEntry::cleanSkip_Locked(void) { 281void 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
51public: 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(&timesLock); } 63 static void lock(void) {
64 static void unlock(void) { pthread_mutex_unlock(&timesLock); } 64 pthread_mutex_lock(&timesLock);
65 }
66 static void unlock(void) {
67 pthread_mutex_unlock(&timesLock);
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
120typedef std::list<LogTimeEntry *> LastLogTimes; 140typedef 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 @@
30namespace android { 30namespace 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
33char *uidToName(uid_t uid); 33char* uidToName(uid_t uid);
34void prdebug(const char *fmt, ...) __printflike(1, 2); 34void prdebug(const char* fmt, ...) __printflike(1, 2);
35 35
36// Furnished in LogStatistics.cpp. 36// Furnished in LogStatistics.cpp.
37size_t sizesTotal(); 37size_t sizesTotal();
38// Caller must own and free returned value 38// Caller must own and free returned value
39char *pidToName(pid_t pid); 39char* pidToName(pid_t pid);
40char *tidToName(pid_t tid); 40char* tidToName(pid_t tid);
41 41
42// Furnished in LogTags.cpp. Thread safe. 42// Furnished in LogTags.cpp. Thread safe.
43const char *tagToName(uint32_t tag); 43const char* tagToName(uint32_t tag);
44void ReReadEventLogTags(); 44void ReReadEventLogTags();
45 45
46// Furnished by LogKlog.cpp. 46// Furnished by LogKlog.cpp.
47const char* strnstr(const char* s, size_t len, const char* needle); 47const 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
52bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid); 51bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid);
53bool clientHasLogCredentials(SocketClient *cli); 52bool clientHasLogCredentials(SocketClient* cli);
54 53
55static inline bool worstUidEnabledForLogid(log_id_t id) { 54static 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
67int PruneList::init(const char *str) { 67int 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
218std::string PruneList::format() { 218std::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
253bool PruneList::naughty(LogBufferElement *element) { 253bool 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
263bool PruneList::nice(LogBufferElement *element) { 263bool 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
36public: 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
58public: 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 */
34static int get_ack(int fd) 34static 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 */
73static int audit_send(int fd, int type, const void *data, size_t size) 72static 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
143out: 141out:
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
152int audit_setup(int fd, pid_t pid) 150int 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
189int audit_rate_limit(int fd, unsigned rate_limit) 186int 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
210int audit_open() 206int 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
215int audit_get_reply(int fd, struct audit_message *rep, reply_t block, int peek) 210int 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
269void audit_close(int fd) 263void 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
35typedef enum { 35typedef 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 */
41struct audit_sig_info { 38struct audit_sig_info {
@@ -46,7 +43,7 @@ struct audit_sig_info {
46 43
47struct audit_message { 44struct 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 */
81extern int audit_get_reply(int fd, struct audit_message *rep, reply_t block, 78extern 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
110extern int audit_rate_limit(int fd, unsigned rate_limit); 107extern 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 @@
92static int drop_privs(bool klogd, bool auditd) { 90static 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(&param, 0, sizeof(param)); 97 memset(&param, 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, &param) < 0) { 104 if (sched_setscheduler((pid_t)0, SCHED_BATCH, &param) < 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
171static bool check_flag(const char *prop, const char *flag) { 177static 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
185static int fdDmesg = -1; 191static int fdDmesg = -1;
186void android::prdebug(const char *fmt, ...) { 192void 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
212static sem_t uidName; 218static sem_t uidName;
213static uid_t uid; 219static uid_t uid;
214static char *name; 220static char* name;
215 221
216static sem_t reinit; 222static sem_t reinit;
217static bool reinit_running = false; 223static bool reinit_running = false;
218static LogBuffer *logBuf = NULL; 224static LogBuffer* logBuf = NULL;
219
220static bool package_list_parser_cb(pkg_info *info, void * /* userdata */) {
221 225
226static 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
233static void *reinit_thread_start(void * /*obj*/) { 238static 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
280static sem_t sem_name; 302static sem_t sem_name;
281 303
282char *android::uidToName(uid_t u) { 304char* 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
308static void readDmesg(LogAudit *al, LogKlog *kl) { 330static 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.
387int main(int argc, char *argv[]) { 407int 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(&param, 0, sizeof(param)); 441 memset(&param, 0, sizeof(param));
424 pthread_attr_setschedparam(&attr, &param); 442 pthread_attr_setschedparam(&attr, &param);
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
42static void send_to_control(char* buf, size_t len) 42static 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 */
76static void my_android_logger_get_statistics(char *buf, size_t len) 70static 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
82static void alloc_statistics(char **buffer, size_t *length) 75static 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
109static char *find_benchmark_spam(char *cp) 101static 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
170TEST(logd, statistics) { 161TEST(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
217static void caught_signal(int /* signum */) { } 209static void caught_signal(int /* signum */) {
210}
218 211
219static void dump_log_msg(const char *prefix, 212static 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//
416TEST(logd, benchmark) { 406TEST(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
573void timeout_negative(const char *command) { 563void 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
649TEST(logd, timeout_start_epoch) { 639TEST(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
772TEST(logd, SNDTIMEO) { 764TEST(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
879static inline int32_t get4LE(const char* src) 872static 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) {
1103TEST(logd, sepolicy_rate_limiter_sub_burst) { 1098TEST(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) {
1118TEST(logd, sepolicy_rate_limiter_spam) { 1114TEST(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";