blob: 17155019474c7769550d35fea2138f1db52a1dbc [file] [log] [blame]
Mark Salyzyn12bac902014-02-26 09:50:16 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Mark Salyzync959c642015-11-30 11:35:56 -080017#include <errno.h>
Mark Salyzynbec7b2d2017-03-31 10:48:39 -070018#include <string.h>
Mark Salyzyn4e5efdc2014-04-28 14:07:23 -070019#include <sys/prctl.h>
20
Mark Salyzynd18255f2017-03-10 08:44:14 -080021#include <private/android_logger.h>
22
Mark Salyzyn12bac902014-02-26 09:50:16 -080023#include "FlushCommand.h"
24#include "LogBuffer.h"
Mark Salyzyn12bac902014-02-26 09:50:16 -080025#include "LogReader.h"
Mark Salyzyn65059532017-03-10 14:31:54 -080026#include "LogTimes.h"
Mark Salyzyn12bac902014-02-26 09:50:16 -080027
28pthread_mutex_t LogTimeEntry::timesLock = PTHREAD_MUTEX_INITIALIZER;
29
Mark Salyzyn65059532017-03-10 14:31:54 -080030LogTimeEntry::LogTimeEntry(LogReader& reader, SocketClient* client,
Hao Wang10d19f62017-12-04 14:10:40 +080031 bool nonBlock, unsigned long tail, log_mask_t logMask,
32 pid_t pid, log_time start, uint64_t timeout)
Tom Cherry06e478b2018-10-08 17:33:50 -070033 : leadingDropped(false),
Mark Salyzyn65059532017-03-10 14:31:54 -080034 mReader(reader),
35 mLogMask(logMask),
36 mPid(pid),
37 mCount(0),
38 mTail(tail),
39 mIndex(0),
40 mClient(client),
41 mStart(start),
42 mNonBlock(nonBlock),
Mark Salyzynd18255f2017-03-10 08:44:14 -080043 mEnd(log_time(android_log_clockid())) {
Mark Salyzync959c642015-11-30 11:35:56 -080044 mTimeout.tv_sec = timeout / NS_PER_SEC;
45 mTimeout.tv_nsec = timeout % NS_PER_SEC;
Mark Salyzynbec7b2d2017-03-31 10:48:39 -070046 memset(mLastTid, 0, sizeof(mLastTid));
47 pthread_cond_init(&threadTriggeredCondition, nullptr);
Mark Salyzyncd766f92015-05-12 15:21:31 -070048 cleanSkip_Locked();
Mark Salyzyn740d7c22014-08-07 08:16:52 -070049}
Mark Salyzyn12bac902014-02-26 09:50:16 -080050
Tom Cherry06e478b2018-10-08 17:33:50 -070051bool LogTimeEntry::startReader_Locked() {
Mark Salyzynca38ae52014-04-04 12:47:44 -070052 pthread_attr_t attr;
53
Mark Salyzynca38ae52014-04-04 12:47:44 -070054 if (!pthread_attr_init(&attr)) {
55 if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) {
Mark Salyzyn65059532017-03-10 14:31:54 -080056 if (!pthread_create(&mThread, &attr, LogTimeEntry::threadStart,
57 this)) {
Mark Salyzynca38ae52014-04-04 12:47:44 -070058 pthread_attr_destroy(&attr);
Tom Cherry06e478b2018-10-08 17:33:50 -070059 return true;
Mark Salyzynca38ae52014-04-04 12:47:44 -070060 }
Mark Salyzyn12bac902014-02-26 09:50:16 -080061 }
Mark Salyzynca38ae52014-04-04 12:47:44 -070062 pthread_attr_destroy(&attr);
Mark Salyzyn12bac902014-02-26 09:50:16 -080063 }
Mark Salyzyn12bac902014-02-26 09:50:16 -080064
Tom Cherry06e478b2018-10-08 17:33:50 -070065 return false;
Mark Salyzyn12bac902014-02-26 09:50:16 -080066}
67
Mark Salyzyn65059532017-03-10 14:31:54 -080068void* LogTimeEntry::threadStart(void* obj) {
Mark Salyzyn4e5efdc2014-04-28 14:07:23 -070069 prctl(PR_SET_NAME, "logd.reader.per");
70
Mark Salyzyn65059532017-03-10 14:31:54 -080071 LogTimeEntry* me = reinterpret_cast<LogTimeEntry*>(obj);
Mark Salyzyn12bac902014-02-26 09:50:16 -080072
Mark Salyzyn65059532017-03-10 14:31:54 -080073 SocketClient* client = me->mClient;
Mark Salyzyn12bac902014-02-26 09:50:16 -080074
Mark Salyzyn65059532017-03-10 14:31:54 -080075 LogBuffer& logbuf = me->mReader.logbuf();
Mark Salyzyn12bac902014-02-26 09:50:16 -080076
77 bool privileged = FlushCommand::hasReadLogs(client);
Mark Salyzynb10f7372016-01-26 14:32:35 -080078 bool security = FlushCommand::hasSecurityLogs(client);
Mark Salyzyn12bac902014-02-26 09:50:16 -080079
Mark Salyzyn80c1fc62015-06-04 13:35:30 -070080 me->leadingDropped = true;
81
Mark Salyzynd2712b12017-04-18 14:09:45 -070082 wrlock();
Mark Salyzyn12bac902014-02-26 09:50:16 -080083
Mark Salyzynd18255f2017-03-10 08:44:14 -080084 log_time start = me->mStart;
Mark Salyzyn12bac902014-02-26 09:50:16 -080085
Tom Cherry06e478b2018-10-08 17:33:50 -070086 while (!me->mRelease) {
Mark Salyzync959c642015-11-30 11:35:56 -080087 if (me->mTimeout.tv_sec || me->mTimeout.tv_nsec) {
88 if (pthread_cond_timedwait(&me->threadTriggeredCondition,
Mark Salyzyn65059532017-03-10 14:31:54 -080089 &timesLock, &me->mTimeout) == ETIMEDOUT) {
Mark Salyzync959c642015-11-30 11:35:56 -080090 me->mTimeout.tv_sec = 0;
91 me->mTimeout.tv_nsec = 0;
92 }
Tom Cherry06e478b2018-10-08 17:33:50 -070093 if (me->mRelease) {
Mark Salyzync959c642015-11-30 11:35:56 -080094 break;
95 }
96 }
97
Mark Salyzyn12bac902014-02-26 09:50:16 -080098 unlock();
99
100 if (me->mTail) {
Mark Salyzynbec7b2d2017-03-31 10:48:39 -0700101 logbuf.flushTo(client, start, nullptr, privileged, security,
102 FilterFirstPass, me);
Mark Salyzyn80c1fc62015-06-04 13:35:30 -0700103 me->leadingDropped = true;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800104 }
Mark Salyzynbec7b2d2017-03-31 10:48:39 -0700105 start = logbuf.flushTo(client, start, me->mLastTid, privileged,
106 security, FilterSecondPass, me);
Mark Salyzyn12bac902014-02-26 09:50:16 -0800107
Mark Salyzynd2712b12017-04-18 14:09:45 -0700108 wrlock();
Mark Salyzyn740d7c22014-08-07 08:16:52 -0700109
Mark Salyzyn12bac902014-02-26 09:50:16 -0800110 if (start == LogBufferElement::FLUSH_ERROR) {
Mark Salyzyn28cb69a2015-09-16 15:34:00 -0700111 break;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800112 }
113
Mark Salyzynd18255f2017-03-10 08:44:14 -0800114 me->mStart = start + log_time(0, 1);
Mark Salyzyn28cb69a2015-09-16 15:34:00 -0700115
Tom Cherry06e478b2018-10-08 17:33:50 -0700116 if (me->mNonBlock || me->mRelease) {
Mark Salyzyn12bac902014-02-26 09:50:16 -0800117 break;
118 }
119
TraianX Schiau6ba427e2014-12-17 10:53:41 +0200120 me->cleanSkip_Locked();
121
Mark Salyzync959c642015-11-30 11:35:56 -0800122 if (!me->mTimeout.tv_sec && !me->mTimeout.tv_nsec) {
123 pthread_cond_wait(&me->threadTriggeredCondition, &timesLock);
124 }
Mark Salyzyn12bac902014-02-26 09:50:16 -0800125 }
126
Tom Cherry06e478b2018-10-08 17:33:50 -0700127 LogReader& reader = me->mReader;
128 reader.release(client);
Mark Salyzyn12bac902014-02-26 09:50:16 -0800129
Tom Cherry06e478b2018-10-08 17:33:50 -0700130 client->decRef();
131
132 LastLogTimes& times = reader.logbuf().mTimes;
133 auto it =
134 std::find_if(times.begin(), times.end(),
135 [&me](const auto& other) { return other.get() == me; });
136
137 if (it != times.end()) {
138 times.erase(it);
139 }
140
141 unlock();
Mark Salyzyn12bac902014-02-26 09:50:16 -0800142
Mark Salyzynbec7b2d2017-03-31 10:48:39 -0700143 return nullptr;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800144}
145
146// A first pass to count the number of elements
Mark Salyzyn65059532017-03-10 14:31:54 -0800147int LogTimeEntry::FilterFirstPass(const LogBufferElement* element, void* obj) {
148 LogTimeEntry* me = reinterpret_cast<LogTimeEntry*>(obj);
Mark Salyzyn12bac902014-02-26 09:50:16 -0800149
Mark Salyzynd2712b12017-04-18 14:09:45 -0700150 LogTimeEntry::wrlock();
Mark Salyzyn12bac902014-02-26 09:50:16 -0800151
Mark Salyzyn80c1fc62015-06-04 13:35:30 -0700152 if (me->leadingDropped) {
153 if (element->getDropped()) {
154 LogTimeEntry::unlock();
155 return false;
156 }
157 me->leadingDropped = false;
158 }
159
Mark Salyzyn12bac902014-02-26 09:50:16 -0800160 if (me->mCount == 0) {
Mark Salyzynd18255f2017-03-10 08:44:14 -0800161 me->mStart = element->getRealTime();
Mark Salyzyn12bac902014-02-26 09:50:16 -0800162 }
163
Mark Salyzyn65059532017-03-10 14:31:54 -0800164 if ((!me->mPid || (me->mPid == element->getPid())) &&
165 (me->isWatching(element->getLogId()))) {
Mark Salyzyn12bac902014-02-26 09:50:16 -0800166 ++me->mCount;
167 }
168
169 LogTimeEntry::unlock();
170
171 return false;
172}
173
174// A second pass to send the selected elements
Mark Salyzyn65059532017-03-10 14:31:54 -0800175int LogTimeEntry::FilterSecondPass(const LogBufferElement* element, void* obj) {
176 LogTimeEntry* me = reinterpret_cast<LogTimeEntry*>(obj);
Mark Salyzyn12bac902014-02-26 09:50:16 -0800177
Mark Salyzynd2712b12017-04-18 14:09:45 -0700178 LogTimeEntry::wrlock();
Mark Salyzyn12bac902014-02-26 09:50:16 -0800179
Mark Salyzynd18255f2017-03-10 08:44:14 -0800180 me->mStart = element->getRealTime();
TraianX Schiau6ba427e2014-12-17 10:53:41 +0200181
182 if (me->skipAhead[element->getLogId()]) {
183 me->skipAhead[element->getLogId()]--;
Mark Salyzyn0b09a2e2014-06-05 15:58:43 -0700184 goto skip;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800185 }
186
Mark Salyzyn80c1fc62015-06-04 13:35:30 -0700187 if (me->leadingDropped) {
188 if (element->getDropped()) {
189 goto skip;
190 }
191 me->leadingDropped = false;
192 }
193
Mark Salyzyn12bac902014-02-26 09:50:16 -0800194 // Truncate to close race between first and second pass
195 if (me->mNonBlock && me->mTail && (me->mIndex >= me->mCount)) {
Mark Salyzyn0aaf6cd2015-03-03 13:39:37 -0800196 goto stop;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800197 }
198
TraianX Schiau6ba427e2014-12-17 10:53:41 +0200199 if (!me->isWatching(element->getLogId())) {
Mark Salyzyn12bac902014-02-26 09:50:16 -0800200 goto skip;
201 }
202
203 if (me->mPid && (me->mPid != element->getPid())) {
204 goto skip;
205 }
206
Mark Salyzyn12bac902014-02-26 09:50:16 -0800207 if (!me->mTail) {
208 goto ok;
209 }
210
211 ++me->mIndex;
212
213 if ((me->mCount > me->mTail) && (me->mIndex <= (me->mCount - me->mTail))) {
214 goto skip;
215 }
216
217 if (!me->mNonBlock) {
218 me->mTail = 0;
219 }
220
221ok:
TraianX Schiau6ba427e2014-12-17 10:53:41 +0200222 if (!me->skipAhead[element->getLogId()]) {
Mark Salyzyn12bac902014-02-26 09:50:16 -0800223 LogTimeEntry::unlock();
224 return true;
225 }
Mark Salyzyn65059532017-03-10 14:31:54 -0800226// FALLTHRU
Mark Salyzyn12bac902014-02-26 09:50:16 -0800227
228skip:
229 LogTimeEntry::unlock();
230 return false;
Mark Salyzyn0aaf6cd2015-03-03 13:39:37 -0800231
232stop:
233 LogTimeEntry::unlock();
234 return -1;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800235}
TraianX Schiau6ba427e2014-12-17 10:53:41 +0200236
237void LogTimeEntry::cleanSkip_Locked(void) {
Mark Salyzynbec7b2d2017-03-31 10:48:39 -0700238 memset(skipAhead, 0, sizeof(skipAhead));
TraianX Schiau6ba427e2014-12-17 10:53:41 +0200239}