blob: 1d8d5fc45dbc4d9f44d36bbedc372b5c0c1037a6 [file] [log] [blame]
Mark Salyzyn0175b072014-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 Salyzynb75cce02015-11-30 11:35:56 -080017#include <errno.h>
Mark Salyzynae2abf12017-03-31 10:48:39 -070018#include <string.h>
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070019#include <sys/prctl.h>
20
Mark Salyzyn0175b072014-02-26 09:50:16 -080021#include "FlushCommand.h"
22#include "LogBuffer.h"
Mark Salyzyn0175b072014-02-26 09:50:16 -080023#include "LogReader.h"
Mark Salyzyn501c3732017-03-10 14:31:54 -080024#include "LogTimes.h"
Mark Salyzyn0175b072014-02-26 09:50:16 -080025
26pthread_mutex_t LogTimeEntry::timesLock = PTHREAD_MUTEX_INITIALIZER;
27
Tom Cherryc9fa42c2020-04-08 10:37:09 -070028LogTimeEntry::LogTimeEntry(LogReader& reader, SocketClient* client, bool nonBlock,
Tom Cherry10d086e2019-08-21 14:16:34 -070029 unsigned long tail, log_mask_t logMask, pid_t pid, uint64_t start,
Tom Cherryc9fa42c2020-04-08 10:37:09 -070030 uint64_t timeout)
Tom Cherry4f227862018-10-08 17:33:50 -070031 : leadingDropped(false),
Mark Salyzyn501c3732017-03-10 14:31:54 -080032 mReader(reader),
33 mLogMask(logMask),
34 mPid(pid),
35 mCount(0),
36 mTail(tail),
37 mIndex(0),
38 mClient(client),
39 mStart(start),
Tom Cherryc9fa42c2020-04-08 10:37:09 -070040 mNonBlock(nonBlock) {
Mark Salyzynb75cce02015-11-30 11:35:56 -080041 mTimeout.tv_sec = timeout / NS_PER_SEC;
42 mTimeout.tv_nsec = timeout % NS_PER_SEC;
Mark Salyzynae2abf12017-03-31 10:48:39 -070043 memset(mLastTid, 0, sizeof(mLastTid));
44 pthread_cond_init(&threadTriggeredCondition, nullptr);
Mark Salyzyn77187782015-05-12 15:21:31 -070045 cleanSkip_Locked();
Mark Salyzyna16f7612014-08-07 08:16:52 -070046}
Mark Salyzyn0175b072014-02-26 09:50:16 -080047
Tom Cherry4f227862018-10-08 17:33:50 -070048bool LogTimeEntry::startReader_Locked() {
Mark Salyzyn765f7822014-04-04 12:47:44 -070049 pthread_attr_t attr;
50
Mark Salyzyn765f7822014-04-04 12:47:44 -070051 if (!pthread_attr_init(&attr)) {
52 if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) {
Mark Salyzyn501c3732017-03-10 14:31:54 -080053 if (!pthread_create(&mThread, &attr, LogTimeEntry::threadStart,
54 this)) {
Mark Salyzyn765f7822014-04-04 12:47:44 -070055 pthread_attr_destroy(&attr);
Tom Cherry4f227862018-10-08 17:33:50 -070056 return true;
Mark Salyzyn765f7822014-04-04 12:47:44 -070057 }
Mark Salyzyn0175b072014-02-26 09:50:16 -080058 }
Mark Salyzyn765f7822014-04-04 12:47:44 -070059 pthread_attr_destroy(&attr);
Mark Salyzyn0175b072014-02-26 09:50:16 -080060 }
Mark Salyzyn0175b072014-02-26 09:50:16 -080061
Tom Cherry4f227862018-10-08 17:33:50 -070062 return false;
Mark Salyzyn0175b072014-02-26 09:50:16 -080063}
64
Mark Salyzyn501c3732017-03-10 14:31:54 -080065void* LogTimeEntry::threadStart(void* obj) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070066 prctl(PR_SET_NAME, "logd.reader.per");
67
Mark Salyzyn501c3732017-03-10 14:31:54 -080068 LogTimeEntry* me = reinterpret_cast<LogTimeEntry*>(obj);
Mark Salyzyn0175b072014-02-26 09:50:16 -080069
Mark Salyzyn501c3732017-03-10 14:31:54 -080070 SocketClient* client = me->mClient;
Mark Salyzyn0175b072014-02-26 09:50:16 -080071
Mark Salyzyn501c3732017-03-10 14:31:54 -080072 LogBuffer& logbuf = me->mReader.logbuf();
Mark Salyzyn0175b072014-02-26 09:50:16 -080073
74 bool privileged = FlushCommand::hasReadLogs(client);
Mark Salyzyn8fa88962016-01-26 14:32:35 -080075 bool security = FlushCommand::hasSecurityLogs(client);
Mark Salyzyn0175b072014-02-26 09:50:16 -080076
Mark Salyzyn047cc072015-06-04 13:35:30 -070077 me->leadingDropped = true;
78
Mark Salyzyn3c501b52017-04-18 14:09:45 -070079 wrlock();
Mark Salyzyn0175b072014-02-26 09:50:16 -080080
Tom Cherry10d086e2019-08-21 14:16:34 -070081 uint64_t start = me->mStart;
Mark Salyzyn0175b072014-02-26 09:50:16 -080082
Tom Cherry4f227862018-10-08 17:33:50 -070083 while (!me->mRelease) {
Mark Salyzynb75cce02015-11-30 11:35:56 -080084 if (me->mTimeout.tv_sec || me->mTimeout.tv_nsec) {
Tom Cherryc9fa42c2020-04-08 10:37:09 -070085 if (pthread_cond_clockwait(&me->threadTriggeredCondition, &timesLock, CLOCK_MONOTONIC,
86 &me->mTimeout) == ETIMEDOUT) {
Mark Salyzynb75cce02015-11-30 11:35:56 -080087 me->mTimeout.tv_sec = 0;
88 me->mTimeout.tv_nsec = 0;
89 }
Tom Cherry4f227862018-10-08 17:33:50 -070090 if (me->mRelease) {
Mark Salyzynb75cce02015-11-30 11:35:56 -080091 break;
92 }
93 }
94
Mark Salyzyn0175b072014-02-26 09:50:16 -080095 unlock();
96
97 if (me->mTail) {
Mark Salyzynae2abf12017-03-31 10:48:39 -070098 logbuf.flushTo(client, start, nullptr, privileged, security,
99 FilterFirstPass, me);
Mark Salyzyn047cc072015-06-04 13:35:30 -0700100 me->leadingDropped = true;
Mark Salyzyn0175b072014-02-26 09:50:16 -0800101 }
Mark Salyzynae2abf12017-03-31 10:48:39 -0700102 start = logbuf.flushTo(client, start, me->mLastTid, privileged,
103 security, FilterSecondPass, me);
Mark Salyzyn0175b072014-02-26 09:50:16 -0800104
Mark Salyzyn3c501b52017-04-18 14:09:45 -0700105 wrlock();
Mark Salyzyna16f7612014-08-07 08:16:52 -0700106
Mark Salyzyn0175b072014-02-26 09:50:16 -0800107 if (start == LogBufferElement::FLUSH_ERROR) {
Mark Salyzynde4bb9c2015-09-16 15:34:00 -0700108 break;
Mark Salyzyn0175b072014-02-26 09:50:16 -0800109 }
110
Tom Cherry10d086e2019-08-21 14:16:34 -0700111 me->mStart = start + 1;
Mark Salyzynde4bb9c2015-09-16 15:34:00 -0700112
Tom Cherry4f227862018-10-08 17:33:50 -0700113 if (me->mNonBlock || me->mRelease) {
Mark Salyzyn0175b072014-02-26 09:50:16 -0800114 break;
115 }
116
TraianX Schiauda6495d2014-12-17 10:53:41 +0200117 me->cleanSkip_Locked();
118
Mark Salyzynb75cce02015-11-30 11:35:56 -0800119 if (!me->mTimeout.tv_sec && !me->mTimeout.tv_nsec) {
120 pthread_cond_wait(&me->threadTriggeredCondition, &timesLock);
121 }
Mark Salyzyn0175b072014-02-26 09:50:16 -0800122 }
123
Tom Cherry4f227862018-10-08 17:33:50 -0700124 LogReader& reader = me->mReader;
125 reader.release(client);
Mark Salyzyn0175b072014-02-26 09:50:16 -0800126
Tom Cherry4f227862018-10-08 17:33:50 -0700127 client->decRef();
128
129 LastLogTimes& times = reader.logbuf().mTimes;
130 auto it =
131 std::find_if(times.begin(), times.end(),
132 [&me](const auto& other) { return other.get() == me; });
133
134 if (it != times.end()) {
135 times.erase(it);
136 }
137
138 unlock();
Mark Salyzyn0175b072014-02-26 09:50:16 -0800139
Mark Salyzynae2abf12017-03-31 10:48:39 -0700140 return nullptr;
Mark Salyzyn0175b072014-02-26 09:50:16 -0800141}
142
143// A first pass to count the number of elements
Mark Salyzyn501c3732017-03-10 14:31:54 -0800144int LogTimeEntry::FilterFirstPass(const LogBufferElement* element, void* obj) {
145 LogTimeEntry* me = reinterpret_cast<LogTimeEntry*>(obj);
Mark Salyzyn0175b072014-02-26 09:50:16 -0800146
Mark Salyzyn3c501b52017-04-18 14:09:45 -0700147 LogTimeEntry::wrlock();
Mark Salyzyn0175b072014-02-26 09:50:16 -0800148
Mark Salyzyn047cc072015-06-04 13:35:30 -0700149 if (me->leadingDropped) {
150 if (element->getDropped()) {
151 LogTimeEntry::unlock();
152 return false;
153 }
154 me->leadingDropped = false;
155 }
156
Mark Salyzyn0175b072014-02-26 09:50:16 -0800157 if (me->mCount == 0) {
Tom Cherry10d086e2019-08-21 14:16:34 -0700158 me->mStart = element->getSequence();
Mark Salyzyn0175b072014-02-26 09:50:16 -0800159 }
160
Mark Salyzyn501c3732017-03-10 14:31:54 -0800161 if ((!me->mPid || (me->mPid == element->getPid())) &&
162 (me->isWatching(element->getLogId()))) {
Mark Salyzyn0175b072014-02-26 09:50:16 -0800163 ++me->mCount;
164 }
165
166 LogTimeEntry::unlock();
167
168 return false;
169}
170
171// A second pass to send the selected elements
Mark Salyzyn501c3732017-03-10 14:31:54 -0800172int LogTimeEntry::FilterSecondPass(const LogBufferElement* element, void* obj) {
173 LogTimeEntry* me = reinterpret_cast<LogTimeEntry*>(obj);
Mark Salyzyn0175b072014-02-26 09:50:16 -0800174
Mark Salyzyn3c501b52017-04-18 14:09:45 -0700175 LogTimeEntry::wrlock();
Mark Salyzyn0175b072014-02-26 09:50:16 -0800176
Tom Cherry10d086e2019-08-21 14:16:34 -0700177 me->mStart = element->getSequence();
TraianX Schiauda6495d2014-12-17 10:53:41 +0200178
179 if (me->skipAhead[element->getLogId()]) {
180 me->skipAhead[element->getLogId()]--;
Mark Salyzyn8d7656b2014-06-05 15:58:43 -0700181 goto skip;
Mark Salyzyn0175b072014-02-26 09:50:16 -0800182 }
183
Mark Salyzyn047cc072015-06-04 13:35:30 -0700184 if (me->leadingDropped) {
185 if (element->getDropped()) {
186 goto skip;
187 }
188 me->leadingDropped = false;
189 }
190
Mark Salyzyn0175b072014-02-26 09:50:16 -0800191 // Truncate to close race between first and second pass
192 if (me->mNonBlock && me->mTail && (me->mIndex >= me->mCount)) {
Mark Salyzynf7c0f752015-03-03 13:39:37 -0800193 goto stop;
Mark Salyzyn0175b072014-02-26 09:50:16 -0800194 }
195
TraianX Schiauda6495d2014-12-17 10:53:41 +0200196 if (!me->isWatching(element->getLogId())) {
Mark Salyzyn0175b072014-02-26 09:50:16 -0800197 goto skip;
198 }
199
200 if (me->mPid && (me->mPid != element->getPid())) {
201 goto skip;
202 }
203
Jintao_Zhu5f930722018-11-11 03:13:24 -0800204 if (me->mRelease) {
205 goto stop;
206 }
207
Mark Salyzyn0175b072014-02-26 09:50:16 -0800208 if (!me->mTail) {
209 goto ok;
210 }
211
212 ++me->mIndex;
213
214 if ((me->mCount > me->mTail) && (me->mIndex <= (me->mCount - me->mTail))) {
215 goto skip;
216 }
217
218 if (!me->mNonBlock) {
219 me->mTail = 0;
220 }
221
222ok:
TraianX Schiauda6495d2014-12-17 10:53:41 +0200223 if (!me->skipAhead[element->getLogId()]) {
Mark Salyzyn0175b072014-02-26 09:50:16 -0800224 LogTimeEntry::unlock();
225 return true;
226 }
Mark Salyzyn501c3732017-03-10 14:31:54 -0800227// FALLTHRU
Mark Salyzyn0175b072014-02-26 09:50:16 -0800228
229skip:
230 LogTimeEntry::unlock();
231 return false;
Mark Salyzynf7c0f752015-03-03 13:39:37 -0800232
233stop:
234 LogTimeEntry::unlock();
235 return -1;
Mark Salyzyn0175b072014-02-26 09:50:16 -0800236}
TraianX Schiauda6495d2014-12-17 10:53:41 +0200237
238void LogTimeEntry::cleanSkip_Locked(void) {
Mark Salyzynae2abf12017-03-31 10:48:39 -0700239 memset(skipAhead, 0, sizeof(skipAhead));
TraianX Schiauda6495d2014-12-17 10:53:41 +0200240}