blob: 17231396328fdbef280c598003db57ea7a4ce28d [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
Tom Cherryb632d142020-04-08 10:37:09 -070030LogTimeEntry::LogTimeEntry(LogReader& reader, SocketClient* client, bool nonBlock,
31 unsigned long tail, log_mask_t logMask, pid_t pid, log_time start,
32 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),
Tom Cherryb632d142020-04-08 10:37:09 -070042 mNonBlock(nonBlock) {
Mark Salyzync959c642015-11-30 11:35:56 -080043 mTimeout.tv_sec = timeout / NS_PER_SEC;
44 mTimeout.tv_nsec = timeout % NS_PER_SEC;
Mark Salyzynbec7b2d2017-03-31 10:48:39 -070045 memset(mLastTid, 0, sizeof(mLastTid));
46 pthread_cond_init(&threadTriggeredCondition, nullptr);
Mark Salyzyncd766f92015-05-12 15:21:31 -070047 cleanSkip_Locked();
Mark Salyzyn740d7c22014-08-07 08:16:52 -070048}
Mark Salyzyn12bac902014-02-26 09:50:16 -080049
Tom Cherry06e478b2018-10-08 17:33:50 -070050bool LogTimeEntry::startReader_Locked() {
Mark Salyzynca38ae52014-04-04 12:47:44 -070051 pthread_attr_t attr;
52
Mark Salyzynca38ae52014-04-04 12:47:44 -070053 if (!pthread_attr_init(&attr)) {
54 if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) {
Mark Salyzyn65059532017-03-10 14:31:54 -080055 if (!pthread_create(&mThread, &attr, LogTimeEntry::threadStart,
56 this)) {
Mark Salyzynca38ae52014-04-04 12:47:44 -070057 pthread_attr_destroy(&attr);
Tom Cherry06e478b2018-10-08 17:33:50 -070058 return true;
Mark Salyzynca38ae52014-04-04 12:47:44 -070059 }
Mark Salyzyn12bac902014-02-26 09:50:16 -080060 }
Mark Salyzynca38ae52014-04-04 12:47:44 -070061 pthread_attr_destroy(&attr);
Mark Salyzyn12bac902014-02-26 09:50:16 -080062 }
Mark Salyzyn12bac902014-02-26 09:50:16 -080063
Tom Cherry06e478b2018-10-08 17:33:50 -070064 return false;
Mark Salyzyn12bac902014-02-26 09:50:16 -080065}
66
Mark Salyzyn65059532017-03-10 14:31:54 -080067void* LogTimeEntry::threadStart(void* obj) {
Mark Salyzyn4e5efdc2014-04-28 14:07:23 -070068 prctl(PR_SET_NAME, "logd.reader.per");
69
Mark Salyzyn65059532017-03-10 14:31:54 -080070 LogTimeEntry* me = reinterpret_cast<LogTimeEntry*>(obj);
Mark Salyzyn12bac902014-02-26 09:50:16 -080071
Mark Salyzyn65059532017-03-10 14:31:54 -080072 SocketClient* client = me->mClient;
Mark Salyzyn12bac902014-02-26 09:50:16 -080073
Mark Salyzyn65059532017-03-10 14:31:54 -080074 LogBuffer& logbuf = me->mReader.logbuf();
Mark Salyzyn12bac902014-02-26 09:50:16 -080075
76 bool privileged = FlushCommand::hasReadLogs(client);
Mark Salyzynb10f7372016-01-26 14:32:35 -080077 bool security = FlushCommand::hasSecurityLogs(client);
Mark Salyzyn12bac902014-02-26 09:50:16 -080078
Mark Salyzyn80c1fc62015-06-04 13:35:30 -070079 me->leadingDropped = true;
80
Mark Salyzynd2712b12017-04-18 14:09:45 -070081 wrlock();
Mark Salyzyn12bac902014-02-26 09:50:16 -080082
Mark Salyzynd18255f2017-03-10 08:44:14 -080083 log_time start = me->mStart;
Mark Salyzyn12bac902014-02-26 09:50:16 -080084
Tom Cherry06e478b2018-10-08 17:33:50 -070085 while (!me->mRelease) {
Mark Salyzync959c642015-11-30 11:35:56 -080086 if (me->mTimeout.tv_sec || me->mTimeout.tv_nsec) {
Tom Cherryb632d142020-04-08 10:37:09 -070087 if (pthread_cond_clockwait(&me->threadTriggeredCondition, &timesLock, CLOCK_MONOTONIC,
88 &me->mTimeout) == ETIMEDOUT) {
Mark Salyzync959c642015-11-30 11:35:56 -080089 me->mTimeout.tv_sec = 0;
90 me->mTimeout.tv_nsec = 0;
91 }
Tom Cherry06e478b2018-10-08 17:33:50 -070092 if (me->mRelease) {
Mark Salyzync959c642015-11-30 11:35:56 -080093 break;
94 }
95 }
96
Mark Salyzyn12bac902014-02-26 09:50:16 -080097 unlock();
98
99 if (me->mTail) {
Mark Salyzynbec7b2d2017-03-31 10:48:39 -0700100 logbuf.flushTo(client, start, nullptr, privileged, security,
101 FilterFirstPass, me);
Mark Salyzyn80c1fc62015-06-04 13:35:30 -0700102 me->leadingDropped = true;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800103 }
Mark Salyzynbec7b2d2017-03-31 10:48:39 -0700104 start = logbuf.flushTo(client, start, me->mLastTid, privileged,
105 security, FilterSecondPass, me);
Mark Salyzyn12bac902014-02-26 09:50:16 -0800106
Mark Salyzynd2712b12017-04-18 14:09:45 -0700107 wrlock();
Mark Salyzyn740d7c22014-08-07 08:16:52 -0700108
Mark Salyzyn12bac902014-02-26 09:50:16 -0800109 if (start == LogBufferElement::FLUSH_ERROR) {
Mark Salyzyn28cb69a2015-09-16 15:34:00 -0700110 break;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800111 }
112
Mark Salyzynd18255f2017-03-10 08:44:14 -0800113 me->mStart = start + log_time(0, 1);
Mark Salyzyn28cb69a2015-09-16 15:34:00 -0700114
Tom Cherry06e478b2018-10-08 17:33:50 -0700115 if (me->mNonBlock || me->mRelease) {
Mark Salyzyn12bac902014-02-26 09:50:16 -0800116 break;
117 }
118
TraianX Schiau6ba427e2014-12-17 10:53:41 +0200119 me->cleanSkip_Locked();
120
Mark Salyzync959c642015-11-30 11:35:56 -0800121 if (!me->mTimeout.tv_sec && !me->mTimeout.tv_nsec) {
122 pthread_cond_wait(&me->threadTriggeredCondition, &timesLock);
123 }
Mark Salyzyn12bac902014-02-26 09:50:16 -0800124 }
125
Tom Cherry06e478b2018-10-08 17:33:50 -0700126 LogReader& reader = me->mReader;
127 reader.release(client);
Mark Salyzyn12bac902014-02-26 09:50:16 -0800128
Tom Cherry06e478b2018-10-08 17:33:50 -0700129 client->decRef();
130
131 LastLogTimes& times = reader.logbuf().mTimes;
132 auto it =
133 std::find_if(times.begin(), times.end(),
134 [&me](const auto& other) { return other.get() == me; });
135
136 if (it != times.end()) {
137 times.erase(it);
138 }
139
140 unlock();
Mark Salyzyn12bac902014-02-26 09:50:16 -0800141
Mark Salyzynbec7b2d2017-03-31 10:48:39 -0700142 return nullptr;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800143}
144
145// A first pass to count the number of elements
Mark Salyzyn65059532017-03-10 14:31:54 -0800146int LogTimeEntry::FilterFirstPass(const LogBufferElement* element, void* obj) {
147 LogTimeEntry* me = reinterpret_cast<LogTimeEntry*>(obj);
Mark Salyzyn12bac902014-02-26 09:50:16 -0800148
Mark Salyzynd2712b12017-04-18 14:09:45 -0700149 LogTimeEntry::wrlock();
Mark Salyzyn12bac902014-02-26 09:50:16 -0800150
Mark Salyzyn80c1fc62015-06-04 13:35:30 -0700151 if (me->leadingDropped) {
152 if (element->getDropped()) {
153 LogTimeEntry::unlock();
154 return false;
155 }
156 me->leadingDropped = false;
157 }
158
Mark Salyzyn12bac902014-02-26 09:50:16 -0800159 if (me->mCount == 0) {
Mark Salyzynd18255f2017-03-10 08:44:14 -0800160 me->mStart = element->getRealTime();
Mark Salyzyn12bac902014-02-26 09:50:16 -0800161 }
162
Mark Salyzyn65059532017-03-10 14:31:54 -0800163 if ((!me->mPid || (me->mPid == element->getPid())) &&
164 (me->isWatching(element->getLogId()))) {
Mark Salyzyn12bac902014-02-26 09:50:16 -0800165 ++me->mCount;
166 }
167
168 LogTimeEntry::unlock();
169
170 return false;
171}
172
173// A second pass to send the selected elements
Mark Salyzyn65059532017-03-10 14:31:54 -0800174int LogTimeEntry::FilterSecondPass(const LogBufferElement* element, void* obj) {
175 LogTimeEntry* me = reinterpret_cast<LogTimeEntry*>(obj);
Mark Salyzyn12bac902014-02-26 09:50:16 -0800176
Mark Salyzynd2712b12017-04-18 14:09:45 -0700177 LogTimeEntry::wrlock();
Mark Salyzyn12bac902014-02-26 09:50:16 -0800178
Mark Salyzynd18255f2017-03-10 08:44:14 -0800179 me->mStart = element->getRealTime();
TraianX Schiau6ba427e2014-12-17 10:53:41 +0200180
181 if (me->skipAhead[element->getLogId()]) {
182 me->skipAhead[element->getLogId()]--;
Mark Salyzyn0b09a2e2014-06-05 15:58:43 -0700183 goto skip;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800184 }
185
Mark Salyzyn80c1fc62015-06-04 13:35:30 -0700186 if (me->leadingDropped) {
187 if (element->getDropped()) {
188 goto skip;
189 }
190 me->leadingDropped = false;
191 }
192
Mark Salyzyn12bac902014-02-26 09:50:16 -0800193 // Truncate to close race between first and second pass
194 if (me->mNonBlock && me->mTail && (me->mIndex >= me->mCount)) {
Mark Salyzyn0aaf6cd2015-03-03 13:39:37 -0800195 goto stop;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800196 }
197
TraianX Schiau6ba427e2014-12-17 10:53:41 +0200198 if (!me->isWatching(element->getLogId())) {
Mark Salyzyn12bac902014-02-26 09:50:16 -0800199 goto skip;
200 }
201
202 if (me->mPid && (me->mPid != element->getPid())) {
203 goto skip;
204 }
205
Jintao_Zhu3e6f9d82018-11-11 03:13:24 -0800206 if (me->mRelease) {
207 goto stop;
208 }
209
Mark Salyzyn12bac902014-02-26 09:50:16 -0800210 if (!me->mTail) {
211 goto ok;
212 }
213
214 ++me->mIndex;
215
216 if ((me->mCount > me->mTail) && (me->mIndex <= (me->mCount - me->mTail))) {
217 goto skip;
218 }
219
220 if (!me->mNonBlock) {
221 me->mTail = 0;
222 }
223
224ok:
TraianX Schiau6ba427e2014-12-17 10:53:41 +0200225 if (!me->skipAhead[element->getLogId()]) {
Mark Salyzyn12bac902014-02-26 09:50:16 -0800226 LogTimeEntry::unlock();
227 return true;
228 }
Mark Salyzyn65059532017-03-10 14:31:54 -0800229// FALLTHRU
Mark Salyzyn12bac902014-02-26 09:50:16 -0800230
231skip:
232 LogTimeEntry::unlock();
233 return false;
Mark Salyzyn0aaf6cd2015-03-03 13:39:37 -0800234
235stop:
236 LogTimeEntry::unlock();
237 return -1;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800238}
TraianX Schiau6ba427e2014-12-17 10:53:41 +0200239
240void LogTimeEntry::cleanSkip_Locked(void) {
Mark Salyzynbec7b2d2017-03-31 10:48:39 -0700241 memset(skipAhead, 0, sizeof(skipAhead));
TraianX Schiau6ba427e2014-12-17 10:53:41 +0200242}