xref: /aosp_15_r20/system/logging/logd/LogReader.cpp (revision 598139dc91b21518d67c408eaea2644226490971)
1*598139dcSAndroid Build Coastguard Worker /*
2*598139dcSAndroid Build Coastguard Worker  * Copyright (C) 2012-2013 The Android Open Source Project
3*598139dcSAndroid Build Coastguard Worker  *
4*598139dcSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*598139dcSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*598139dcSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*598139dcSAndroid Build Coastguard Worker  *
8*598139dcSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*598139dcSAndroid Build Coastguard Worker  *
10*598139dcSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*598139dcSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*598139dcSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*598139dcSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*598139dcSAndroid Build Coastguard Worker  * limitations under the License.
15*598139dcSAndroid Build Coastguard Worker  */
16*598139dcSAndroid Build Coastguard Worker 
17*598139dcSAndroid Build Coastguard Worker #include <ctype.h>
18*598139dcSAndroid Build Coastguard Worker #include <inttypes.h>
19*598139dcSAndroid Build Coastguard Worker #include <poll.h>
20*598139dcSAndroid Build Coastguard Worker #include <sched.h>
21*598139dcSAndroid Build Coastguard Worker #include <sys/prctl.h>
22*598139dcSAndroid Build Coastguard Worker #include <sys/socket.h>
23*598139dcSAndroid Build Coastguard Worker #include <sys/types.h>
24*598139dcSAndroid Build Coastguard Worker 
25*598139dcSAndroid Build Coastguard Worker #include <chrono>
26*598139dcSAndroid Build Coastguard Worker 
27*598139dcSAndroid Build Coastguard Worker #include <android-base/logging.h>
28*598139dcSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
29*598139dcSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
30*598139dcSAndroid Build Coastguard Worker #include <binder/ProcessState.h>
31*598139dcSAndroid Build Coastguard Worker #include <cutils/sockets.h>
32*598139dcSAndroid Build Coastguard Worker #include <private/android_filesystem_config.h>
33*598139dcSAndroid Build Coastguard Worker #include <private/android_logger.h>
34*598139dcSAndroid Build Coastguard Worker 
35*598139dcSAndroid Build Coastguard Worker #include "LogdNativeService.h"
36*598139dcSAndroid Build Coastguard Worker #include "LogBuffer.h"
37*598139dcSAndroid Build Coastguard Worker #include "LogBufferElement.h"
38*598139dcSAndroid Build Coastguard Worker #include "LogPermissions.h"
39*598139dcSAndroid Build Coastguard Worker #include "LogReader.h"
40*598139dcSAndroid Build Coastguard Worker #include "LogUtils.h"
41*598139dcSAndroid Build Coastguard Worker #include "LogWriter.h"
42*598139dcSAndroid Build Coastguard Worker 
43*598139dcSAndroid Build Coastguard Worker using android::defaultServiceManager;
44*598139dcSAndroid Build Coastguard Worker using android::ProcessState;
45*598139dcSAndroid Build Coastguard Worker using android::sp;
46*598139dcSAndroid Build Coastguard Worker using android::String16;
47*598139dcSAndroid Build Coastguard Worker 
CanReadSecurityLogs(SocketClient * client)48*598139dcSAndroid Build Coastguard Worker static bool CanReadSecurityLogs(SocketClient* client) {
49*598139dcSAndroid Build Coastguard Worker     return client->getUid() == AID_SYSTEM || client->getGid() == AID_SYSTEM;
50*598139dcSAndroid Build Coastguard Worker }
51*598139dcSAndroid Build Coastguard Worker 
SocketClientToName(SocketClient * client)52*598139dcSAndroid Build Coastguard Worker static std::string SocketClientToName(SocketClient* client) {
53*598139dcSAndroid Build Coastguard Worker     return android::base::StringPrintf("pid %d, fd %d", client->getPid(), client->getSocket());
54*598139dcSAndroid Build Coastguard Worker }
55*598139dcSAndroid Build Coastguard Worker 
InitLogdBinderServiceStatus(LogReaderList * reader_list)56*598139dcSAndroid Build Coastguard Worker static bool InitLogdBinderServiceStatus(LogReaderList* reader_list) {
57*598139dcSAndroid Build Coastguard Worker     sp<LogdNativeService> service = new LogdNativeService(reader_list);
58*598139dcSAndroid Build Coastguard Worker     auto service_status = defaultServiceManager()->addService(String16("logd"), service);
59*598139dcSAndroid Build Coastguard Worker     if (service_status != android::OK) {
60*598139dcSAndroid Build Coastguard Worker         LOG(ERROR) << "Failed to add logd binder service.";
61*598139dcSAndroid Build Coastguard Worker         return false;
62*598139dcSAndroid Build Coastguard Worker     }
63*598139dcSAndroid Build Coastguard Worker 
64*598139dcSAndroid Build Coastguard Worker     sp<ProcessState> proc(ProcessState::self());
65*598139dcSAndroid Build Coastguard Worker     proc->startThreadPool();
66*598139dcSAndroid Build Coastguard Worker     return true;
67*598139dcSAndroid Build Coastguard Worker }
68*598139dcSAndroid Build Coastguard Worker 
GetLogdBinderServiceStatus(LogReaderList * reader_list)69*598139dcSAndroid Build Coastguard Worker static bool GetLogdBinderServiceStatus(LogReaderList* reader_list) {
70*598139dcSAndroid Build Coastguard Worker     static bool service_status = InitLogdBinderServiceStatus(reader_list);
71*598139dcSAndroid Build Coastguard Worker     return service_status;
72*598139dcSAndroid Build Coastguard Worker }
73*598139dcSAndroid Build Coastguard Worker 
74*598139dcSAndroid Build Coastguard Worker class SocketLogWriter : public LogWriter {
75*598139dcSAndroid Build Coastguard Worker   public:
SocketLogWriter(LogReader * reader,SocketClient * client,bool privileged)76*598139dcSAndroid Build Coastguard Worker     SocketLogWriter(LogReader* reader, SocketClient* client, bool privileged)
77*598139dcSAndroid Build Coastguard Worker         : LogWriter(client->getUid(), privileged), reader_(reader), client_(client) {}
78*598139dcSAndroid Build Coastguard Worker 
Write(const logger_entry & entry,const char * msg)79*598139dcSAndroid Build Coastguard Worker     bool Write(const logger_entry& entry, const char* msg) override {
80*598139dcSAndroid Build Coastguard Worker         struct iovec iovec[2];
81*598139dcSAndroid Build Coastguard Worker         iovec[0].iov_base = const_cast<logger_entry*>(&entry);
82*598139dcSAndroid Build Coastguard Worker         iovec[0].iov_len = entry.hdr_size;
83*598139dcSAndroid Build Coastguard Worker         iovec[1].iov_base = const_cast<char*>(msg);
84*598139dcSAndroid Build Coastguard Worker         iovec[1].iov_len = entry.len;
85*598139dcSAndroid Build Coastguard Worker 
86*598139dcSAndroid Build Coastguard Worker         return client_->sendDatav(iovec, 1 + (entry.len != 0)) == 0;
87*598139dcSAndroid Build Coastguard Worker     }
88*598139dcSAndroid Build Coastguard Worker 
Release()89*598139dcSAndroid Build Coastguard Worker     void Release() override {
90*598139dcSAndroid Build Coastguard Worker         reader_->release(client_);
91*598139dcSAndroid Build Coastguard Worker         client_->decRef();
92*598139dcSAndroid Build Coastguard Worker     }
93*598139dcSAndroid Build Coastguard Worker 
Shutdown()94*598139dcSAndroid Build Coastguard Worker     void Shutdown() override { shutdown(client_->getSocket(), SHUT_RDWR); }
95*598139dcSAndroid Build Coastguard Worker 
name() const96*598139dcSAndroid Build Coastguard Worker     std::string name() const override { return SocketClientToName(client_); }
97*598139dcSAndroid Build Coastguard Worker 
98*598139dcSAndroid Build Coastguard Worker   private:
99*598139dcSAndroid Build Coastguard Worker     LogReader* reader_;
100*598139dcSAndroid Build Coastguard Worker     SocketClient* client_;
101*598139dcSAndroid Build Coastguard Worker };
102*598139dcSAndroid Build Coastguard Worker 
LogReader(LogBuffer * logbuf,LogReaderList * reader_list)103*598139dcSAndroid Build Coastguard Worker LogReader::LogReader(LogBuffer* logbuf, LogReaderList* reader_list)
104*598139dcSAndroid Build Coastguard Worker     : SocketListener(getLogSocket(), true), log_buffer_(logbuf), reader_list_(reader_list) {}
105*598139dcSAndroid Build Coastguard Worker 
106*598139dcSAndroid Build Coastguard Worker // Note returning false will release the SocketClient instance.
onDataAvailable(SocketClient * cli)107*598139dcSAndroid Build Coastguard Worker bool LogReader::onDataAvailable(SocketClient* cli) {
108*598139dcSAndroid Build Coastguard Worker     static bool name_set;
109*598139dcSAndroid Build Coastguard Worker     if (!name_set) {
110*598139dcSAndroid Build Coastguard Worker         prctl(PR_SET_NAME, "logd.reader");
111*598139dcSAndroid Build Coastguard Worker         name_set = true;
112*598139dcSAndroid Build Coastguard Worker     }
113*598139dcSAndroid Build Coastguard Worker 
114*598139dcSAndroid Build Coastguard Worker     char buffer[255];
115*598139dcSAndroid Build Coastguard Worker 
116*598139dcSAndroid Build Coastguard Worker     int len = read(cli->getSocket(), buffer, sizeof(buffer) - 1);
117*598139dcSAndroid Build Coastguard Worker     if (len <= 0) {
118*598139dcSAndroid Build Coastguard Worker         DoSocketDelete(cli);
119*598139dcSAndroid Build Coastguard Worker         return false;
120*598139dcSAndroid Build Coastguard Worker     }
121*598139dcSAndroid Build Coastguard Worker     buffer[len] = '\0';
122*598139dcSAndroid Build Coastguard Worker 
123*598139dcSAndroid Build Coastguard Worker     // Clients are only allowed to send one command, disconnect them if they send another.
124*598139dcSAndroid Build Coastguard Worker     if (DoSocketDelete(cli)) {
125*598139dcSAndroid Build Coastguard Worker         return false;
126*598139dcSAndroid Build Coastguard Worker     }
127*598139dcSAndroid Build Coastguard Worker 
128*598139dcSAndroid Build Coastguard Worker     unsigned long tail = 0;
129*598139dcSAndroid Build Coastguard Worker     static const char _tail[] = " tail=";
130*598139dcSAndroid Build Coastguard Worker     char* cp = strstr(buffer, _tail);
131*598139dcSAndroid Build Coastguard Worker     if (cp) {
132*598139dcSAndroid Build Coastguard Worker         tail = atol(cp + sizeof(_tail) - 1);
133*598139dcSAndroid Build Coastguard Worker     }
134*598139dcSAndroid Build Coastguard Worker 
135*598139dcSAndroid Build Coastguard Worker     log_time start(log_time::EPOCH);
136*598139dcSAndroid Build Coastguard Worker     static const char _start[] = " start=";
137*598139dcSAndroid Build Coastguard Worker     cp = strstr(buffer, _start);
138*598139dcSAndroid Build Coastguard Worker     if (cp) {
139*598139dcSAndroid Build Coastguard Worker         // Parse errors will result in current time
140*598139dcSAndroid Build Coastguard Worker         start.strptime(cp + sizeof(_start) - 1, "%s.%q");
141*598139dcSAndroid Build Coastguard Worker     }
142*598139dcSAndroid Build Coastguard Worker 
143*598139dcSAndroid Build Coastguard Worker     std::chrono::steady_clock::time_point deadline = {};
144*598139dcSAndroid Build Coastguard Worker     static const char _timeout[] = " timeout=";
145*598139dcSAndroid Build Coastguard Worker     cp = strstr(buffer, _timeout);
146*598139dcSAndroid Build Coastguard Worker     if (cp) {
147*598139dcSAndroid Build Coastguard Worker         long timeout_seconds = atol(cp + sizeof(_timeout) - 1);
148*598139dcSAndroid Build Coastguard Worker         deadline = std::chrono::steady_clock::now() + std::chrono::seconds(timeout_seconds);
149*598139dcSAndroid Build Coastguard Worker     }
150*598139dcSAndroid Build Coastguard Worker 
151*598139dcSAndroid Build Coastguard Worker     unsigned int logMask = -1;
152*598139dcSAndroid Build Coastguard Worker     static const char _logIds[] = " lids=";
153*598139dcSAndroid Build Coastguard Worker     cp = strstr(buffer, _logIds);
154*598139dcSAndroid Build Coastguard Worker     if (cp) {
155*598139dcSAndroid Build Coastguard Worker         logMask = 0;
156*598139dcSAndroid Build Coastguard Worker         cp += sizeof(_logIds) - 1;
157*598139dcSAndroid Build Coastguard Worker         while (*cp != '\0') {
158*598139dcSAndroid Build Coastguard Worker             int val = 0;
159*598139dcSAndroid Build Coastguard Worker             while (isdigit(*cp)) {
160*598139dcSAndroid Build Coastguard Worker                 val = val * 10 + *cp - '0';
161*598139dcSAndroid Build Coastguard Worker                 ++cp;
162*598139dcSAndroid Build Coastguard Worker             }
163*598139dcSAndroid Build Coastguard Worker             logMask |= 1 << val;
164*598139dcSAndroid Build Coastguard Worker             if (*cp != ',') {
165*598139dcSAndroid Build Coastguard Worker                 break;
166*598139dcSAndroid Build Coastguard Worker             }
167*598139dcSAndroid Build Coastguard Worker             ++cp;
168*598139dcSAndroid Build Coastguard Worker         }
169*598139dcSAndroid Build Coastguard Worker     }
170*598139dcSAndroid Build Coastguard Worker 
171*598139dcSAndroid Build Coastguard Worker     pid_t pid = 0;
172*598139dcSAndroid Build Coastguard Worker     static const char _pid[] = " pid=";
173*598139dcSAndroid Build Coastguard Worker     cp = strstr(buffer, _pid);
174*598139dcSAndroid Build Coastguard Worker     if (cp) {
175*598139dcSAndroid Build Coastguard Worker         pid = atol(cp + sizeof(_pid) - 1);
176*598139dcSAndroid Build Coastguard Worker     }
177*598139dcSAndroid Build Coastguard Worker 
178*598139dcSAndroid Build Coastguard Worker     bool nonBlock = false;
179*598139dcSAndroid Build Coastguard Worker     if (!fastcmp<strncmp>(buffer, "dumpAndClose", 12)) {
180*598139dcSAndroid Build Coastguard Worker         // Allow writer to get some cycles, and wait for pending notifications
181*598139dcSAndroid Build Coastguard Worker         sched_yield();
182*598139dcSAndroid Build Coastguard Worker         logd_lock.lock();
183*598139dcSAndroid Build Coastguard Worker         logd_lock.unlock();
184*598139dcSAndroid Build Coastguard Worker         sched_yield();
185*598139dcSAndroid Build Coastguard Worker         nonBlock = true;
186*598139dcSAndroid Build Coastguard Worker     }
187*598139dcSAndroid Build Coastguard Worker 
188*598139dcSAndroid Build Coastguard Worker     bool privileged = clientHasLogCredentials(cli);
189*598139dcSAndroid Build Coastguard Worker     bool can_read_security = CanReadSecurityLogs(cli);
190*598139dcSAndroid Build Coastguard Worker     if (!can_read_security) {
191*598139dcSAndroid Build Coastguard Worker         logMask &= ~(1 << LOG_ID_SECURITY);
192*598139dcSAndroid Build Coastguard Worker     }
193*598139dcSAndroid Build Coastguard Worker 
194*598139dcSAndroid Build Coastguard Worker     std::unique_ptr<LogWriter> socket_log_writer(new SocketLogWriter(this, cli, privileged));
195*598139dcSAndroid Build Coastguard Worker 
196*598139dcSAndroid Build Coastguard Worker     uint64_t sequence = 1;
197*598139dcSAndroid Build Coastguard Worker     // Convert realtime to sequence number
198*598139dcSAndroid Build Coastguard Worker     if (start != log_time::EPOCH) {
199*598139dcSAndroid Build Coastguard Worker         bool start_time_set = false;
200*598139dcSAndroid Build Coastguard Worker         uint64_t last = sequence;
201*598139dcSAndroid Build Coastguard Worker         auto log_find_start = [pid, start, &sequence, &start_time_set, &last](
202*598139dcSAndroid Build Coastguard Worker                                       log_id_t, pid_t element_pid, uint64_t element_sequence,
203*598139dcSAndroid Build Coastguard Worker                                       log_time element_realtime) -> FilterResult {
204*598139dcSAndroid Build Coastguard Worker             if (pid && pid != element_pid) {
205*598139dcSAndroid Build Coastguard Worker                 return FilterResult::kSkip;
206*598139dcSAndroid Build Coastguard Worker             }
207*598139dcSAndroid Build Coastguard Worker             if (start == element_realtime) {
208*598139dcSAndroid Build Coastguard Worker                 sequence = element_sequence;
209*598139dcSAndroid Build Coastguard Worker                 start_time_set = true;
210*598139dcSAndroid Build Coastguard Worker                 return FilterResult::kStop;
211*598139dcSAndroid Build Coastguard Worker             } else {
212*598139dcSAndroid Build Coastguard Worker                 if (start < element_realtime) {
213*598139dcSAndroid Build Coastguard Worker                     sequence = last;
214*598139dcSAndroid Build Coastguard Worker                     start_time_set = true;
215*598139dcSAndroid Build Coastguard Worker                     return FilterResult::kStop;
216*598139dcSAndroid Build Coastguard Worker                 }
217*598139dcSAndroid Build Coastguard Worker                 last = element_sequence;
218*598139dcSAndroid Build Coastguard Worker             }
219*598139dcSAndroid Build Coastguard Worker             return FilterResult::kSkip;
220*598139dcSAndroid Build Coastguard Worker         };
221*598139dcSAndroid Build Coastguard Worker         auto lock = std::lock_guard{logd_lock};
222*598139dcSAndroid Build Coastguard Worker         auto flush_to_state = log_buffer_->CreateFlushToState(sequence, logMask);
223*598139dcSAndroid Build Coastguard Worker         log_buffer_->FlushTo(socket_log_writer.get(), *flush_to_state, log_find_start);
224*598139dcSAndroid Build Coastguard Worker 
225*598139dcSAndroid Build Coastguard Worker         if (!start_time_set) {
226*598139dcSAndroid Build Coastguard Worker             if (nonBlock) {
227*598139dcSAndroid Build Coastguard Worker                 return false;
228*598139dcSAndroid Build Coastguard Worker             }
229*598139dcSAndroid Build Coastguard Worker             sequence = log_buffer_->sequence();
230*598139dcSAndroid Build Coastguard Worker         }
231*598139dcSAndroid Build Coastguard Worker     }
232*598139dcSAndroid Build Coastguard Worker 
233*598139dcSAndroid Build Coastguard Worker     LOG(INFO) << android::base::StringPrintf(
234*598139dcSAndroid Build Coastguard Worker             "logdr: UID=%d GID=%d PID=%d %c tail=%lu logMask=%x pid=%d "
235*598139dcSAndroid Build Coastguard Worker             "start=%" PRIu64 "ns deadline=%" PRIi64 "ns",
236*598139dcSAndroid Build Coastguard Worker             cli->getUid(), cli->getGid(), cli->getPid(), nonBlock ? 'n' : 'b', tail, logMask,
237*598139dcSAndroid Build Coastguard Worker             (int)pid, start.nsec(), static_cast<int64_t>(deadline.time_since_epoch().count()));
238*598139dcSAndroid Build Coastguard Worker 
239*598139dcSAndroid Build Coastguard Worker     if (start == log_time::EPOCH) {
240*598139dcSAndroid Build Coastguard Worker         deadline = {};
241*598139dcSAndroid Build Coastguard Worker     }
242*598139dcSAndroid Build Coastguard Worker 
243*598139dcSAndroid Build Coastguard Worker     auto lock = std::lock_guard{logd_lock};
244*598139dcSAndroid Build Coastguard Worker     auto entry = std::make_unique<LogReaderThread>(log_buffer_, reader_list_,
245*598139dcSAndroid Build Coastguard Worker                                                    std::move(socket_log_writer), nonBlock, tail,
246*598139dcSAndroid Build Coastguard Worker                                                    logMask, pid, start, sequence, deadline);
247*598139dcSAndroid Build Coastguard Worker     // release client and entry reference counts once done
248*598139dcSAndroid Build Coastguard Worker     cli->incRef();
249*598139dcSAndroid Build Coastguard Worker 
250*598139dcSAndroid Build Coastguard Worker     entry->set_pending_reader_thread_key(cli->getUid(), cli->getGid(), cli->getPid(),
251*598139dcSAndroid Build Coastguard Worker                                          cli->getSocket());
252*598139dcSAndroid Build Coastguard Worker 
253*598139dcSAndroid Build Coastguard Worker     bool only_read_event_logs = (logMask ^ (1 << LOG_ID_EVENTS)) == 0;
254*598139dcSAndroid Build Coastguard Worker 
255*598139dcSAndroid Build Coastguard Worker     // The logd access will be granted when any of the following three
256*598139dcSAndroid Build Coastguard Worker     // conditions is satisfied:
257*598139dcSAndroid Build Coastguard Worker     // 1. the client (native processes) is exempted from user consent check.
258*598139dcSAndroid Build Coastguard Worker     // 2. the client doesn't have log credentials and so can only access its own log data anyway
259*598139dcSAndroid Build Coastguard Worker     // 3. the client (for EventLog API) only wants to access the event log.
260*598139dcSAndroid Build Coastguard Worker     if (clientIsExemptedFromUserConsent(cli) || !clientHasLogCredentials(cli) ||
261*598139dcSAndroid Build Coastguard Worker         only_read_event_logs) {
262*598139dcSAndroid Build Coastguard Worker         reader_list_->AddAndRunThread(std::move(entry));
263*598139dcSAndroid Build Coastguard Worker     } else {
264*598139dcSAndroid Build Coastguard Worker         if (GetLogdBinderServiceStatus(reader_list_)) {
265*598139dcSAndroid Build Coastguard Worker             reader_list_->AddPendingThread(std::move(entry));
266*598139dcSAndroid Build Coastguard Worker         } else {
267*598139dcSAndroid Build Coastguard Worker             // The logd binder service is not available, we are not able to
268*598139dcSAndroid Build Coastguard Worker             // check user consent. So we revoke the privileges.
269*598139dcSAndroid Build Coastguard Worker             entry->Revoke();
270*598139dcSAndroid Build Coastguard Worker             reader_list_->AddAndRunThread(std::move(entry));
271*598139dcSAndroid Build Coastguard Worker         }
272*598139dcSAndroid Build Coastguard Worker     }
273*598139dcSAndroid Build Coastguard Worker 
274*598139dcSAndroid Build Coastguard Worker     // Set acceptable upper limit to wait for slow reader processing b/27242723
275*598139dcSAndroid Build Coastguard Worker     struct timeval t = { LOGD_SNDTIMEO, 0 };
276*598139dcSAndroid Build Coastguard Worker     setsockopt(cli->getSocket(), SOL_SOCKET, SO_SNDTIMEO, (const char*)&t,
277*598139dcSAndroid Build Coastguard Worker                sizeof(t));
278*598139dcSAndroid Build Coastguard Worker 
279*598139dcSAndroid Build Coastguard Worker     return true;
280*598139dcSAndroid Build Coastguard Worker }
281*598139dcSAndroid Build Coastguard Worker 
DoSocketDelete(SocketClient * cli)282*598139dcSAndroid Build Coastguard Worker bool LogReader::DoSocketDelete(SocketClient* cli) {
283*598139dcSAndroid Build Coastguard Worker     auto cli_name = SocketClientToName(cli);
284*598139dcSAndroid Build Coastguard Worker     auto lock = std::lock_guard{logd_lock};
285*598139dcSAndroid Build Coastguard Worker     return reader_list_->ReleaseThreadByName(cli_name);
286*598139dcSAndroid Build Coastguard Worker }
287*598139dcSAndroid Build Coastguard Worker 
getLogSocket()288*598139dcSAndroid Build Coastguard Worker int LogReader::getLogSocket() {
289*598139dcSAndroid Build Coastguard Worker     static const char socketName[] = "logdr";
290*598139dcSAndroid Build Coastguard Worker     int sock = android_get_control_socket(socketName);
291*598139dcSAndroid Build Coastguard Worker 
292*598139dcSAndroid Build Coastguard Worker     if (sock < 0) {
293*598139dcSAndroid Build Coastguard Worker         sock = socket_local_server(
294*598139dcSAndroid Build Coastguard Worker             socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET);
295*598139dcSAndroid Build Coastguard Worker     }
296*598139dcSAndroid Build Coastguard Worker 
297*598139dcSAndroid Build Coastguard Worker     return sock;
298*598139dcSAndroid Build Coastguard Worker }
299