blob: ff816b768f30b618b0577463b270fb7e613eaeb7 [file] [log] [blame]
Mark Salyzyndd9094a2016-03-01 13:45:42 -08001/*
2** Copyright 2013-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
Tom Cherryf623f022019-01-10 10:37:36 -080017#include "log/log_read.h"
18
Mark Salyzyndd9094a2016-03-01 13:45:42 -080019#include <errno.h>
20#include <fcntl.h>
21#include <pthread.h>
22#include <sched.h>
23#include <stddef.h>
24#include <stdlib.h>
25#include <string.h>
26#include <unistd.h>
27
Mark Salyzyn5a79c7d2016-09-28 13:26:55 -070028#include <android/log.h>
Mark Salyzyndd9094a2016-03-01 13:45:42 -080029#include <cutils/list.h>
Mark Salyzynb3db3cf2016-03-28 16:20:29 -070030#include <private/android_filesystem_config.h>
Mark Salyzyndd9094a2016-03-01 13:45:42 -080031
Mark Salyzyndd9094a2016-03-01 13:45:42 -080032#include "log_portability.h"
33#include "logger.h"
34
35/* android_logger_alloc unimplemented, no use case */
36/* android_logger_free not exported */
Mark Salyzyn6e315682017-03-09 08:09:43 -080037static void android_logger_free(struct logger* logger) {
Tom Cherryf623f022019-01-10 10:37:36 -080038 struct android_log_logger* logger_internal = (struct android_log_logger*)logger;
Mark Salyzyndd9094a2016-03-01 13:45:42 -080039
Mark Salyzyn6e315682017-03-09 08:09:43 -080040 if (!logger_internal) {
41 return;
42 }
Mark Salyzyndd9094a2016-03-01 13:45:42 -080043
Mark Salyzyn6e315682017-03-09 08:09:43 -080044 list_remove(&logger_internal->node);
Mark Salyzyndd9094a2016-03-01 13:45:42 -080045
Mark Salyzyn6e315682017-03-09 08:09:43 -080046 free(logger_internal);
Mark Salyzyndd9094a2016-03-01 13:45:42 -080047}
48
49/* android_logger_alloc unimplemented, no use case */
50
51/* method for getting the associated sublog id */
Tom Cherry3d6a8782019-02-08 11:46:19 -080052log_id_t android_logger_get_id(struct logger* logger) {
Mark Salyzyn6e315682017-03-09 08:09:43 -080053 return ((struct android_log_logger*)logger)->logId;
Mark Salyzyndd9094a2016-03-01 13:45:42 -080054}
55
Mark Salyzyn6e315682017-03-09 08:09:43 -080056static int init_transport_context(struct android_log_logger_list* logger_list) {
Mark Salyzyn6e315682017-03-09 08:09:43 -080057 if (!logger_list) {
58 return -EINVAL;
59 }
Mark Salyzyndd9094a2016-03-01 13:45:42 -080060
Mark Salyzyn6e315682017-03-09 08:09:43 -080061 if (list_empty(&logger_list->logger)) {
62 return -EINVAL;
63 }
Mark Salyzyndd9094a2016-03-01 13:45:42 -080064
Tom Cherryed7c18c2019-08-23 14:04:12 -070065 if (logger_list->transport_initialized) {
Mark Salyzyndd9094a2016-03-01 13:45:42 -080066 return 0;
Mark Salyzyn6e315682017-03-09 08:09:43 -080067 }
68
Tom Cherryed7c18c2019-08-23 14:04:12 -070069#if (FAKE_LOG_DEVICE == 0)
70 extern struct android_log_transport_read logdLoggerRead;
71 extern struct android_log_transport_read pmsgLoggerRead;
Mark Salyzyn6e315682017-03-09 08:09:43 -080072
Tom Cherryed7c18c2019-08-23 14:04:12 -070073 struct android_log_transport_read* transport;
74 transport = (logger_list->mode & ANDROID_LOG_PSTORE) ? &pmsgLoggerRead : &logdLoggerRead;
Mark Salyzyn6e315682017-03-09 08:09:43 -080075
Tom Cherryed7c18c2019-08-23 14:04:12 -070076 struct android_log_logger* logger;
77 unsigned logMask = 0;
Mark Salyzyn6e315682017-03-09 08:09:43 -080078
Tom Cherryed7c18c2019-08-23 14:04:12 -070079 logger_for_each(logger, logger_list) {
80 log_id_t logId = logger->logId;
Mark Salyzyn6e315682017-03-09 08:09:43 -080081
Tom Cherryed7c18c2019-08-23 14:04:12 -070082 if (logId == LOG_ID_SECURITY && __android_log_uid() != AID_SYSTEM) {
Mark Salyzyn6e315682017-03-09 08:09:43 -080083 continue;
84 }
Tom Cherryed7c18c2019-08-23 14:04:12 -070085 if (transport->read && (!transport->available || transport->available(logId) >= 0)) {
86 logMask |= 1 << logId;
Mark Salyzyn6e315682017-03-09 08:09:43 -080087 }
Mark Salyzyn6e315682017-03-09 08:09:43 -080088 }
Tom Cherryed7c18c2019-08-23 14:04:12 -070089 if (!logMask) {
Mark Salyzyn6e315682017-03-09 08:09:43 -080090 return -ENODEV;
91 }
Tom Cherryed7c18c2019-08-23 14:04:12 -070092
93 logger_list->transport_context.transport = transport;
94 logger_list->transport_context.logMask = logMask;
95 logger_list->transport_context.ret = 1;
96#endif
Mark Salyzyn6e315682017-03-09 08:09:43 -080097 return 0;
Mark Salyzyndd9094a2016-03-01 13:45:42 -080098}
99
Tom Cherryed7c18c2019-08-23 14:04:12 -0700100#define LOGGER_FUNCTION(logger, def, func, args...) \
101 ssize_t ret = -EINVAL; \
102 android_log_logger* logger_internal = reinterpret_cast<android_log_logger*>(logger); \
103 \
104 if (!logger_internal) { \
105 return ret; \
106 } \
107 ret = init_transport_context(logger_internal->parent); \
108 if (ret < 0) { \
109 return ret; \
110 } \
111 \
112 ret = (def); \
113 android_log_transport_context* transport_context = &logger_internal->parent->transport_context; \
114 if (transport_context->logMask & (1 << logger_internal->logId) && \
115 transport_context->transport && transport_context->transport->func) { \
116 ssize_t retval = \
117 (transport_context->transport->func)(logger_internal, transport_context, ##args); \
118 if (ret >= 0 || ret == (def)) { \
119 ret = retval; \
120 } \
121 } \
Mark Salyzyn6e315682017-03-09 08:09:43 -0800122 return ret
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800123
Tom Cherry3d6a8782019-02-08 11:46:19 -0800124int android_logger_clear(struct logger* logger) {
Mark Salyzyn6e315682017-03-09 08:09:43 -0800125 LOGGER_FUNCTION(logger, -ENODEV, clear);
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800126}
127
128/* returns the total size of the log's ring buffer */
Tom Cherry3d6a8782019-02-08 11:46:19 -0800129long android_logger_get_log_size(struct logger* logger) {
Mark Salyzyn6e315682017-03-09 08:09:43 -0800130 LOGGER_FUNCTION(logger, -ENODEV, getSize);
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800131}
132
Tom Cherry3d6a8782019-02-08 11:46:19 -0800133int android_logger_set_log_size(struct logger* logger, unsigned long size) {
Mark Salyzyn6e315682017-03-09 08:09:43 -0800134 LOGGER_FUNCTION(logger, -ENODEV, setSize, size);
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800135}
136
137/*
138 * returns the readable size of the log's ring buffer (that is, amount of the
139 * log consumed)
140 */
Tom Cherry3d6a8782019-02-08 11:46:19 -0800141long android_logger_get_log_readable_size(struct logger* logger) {
Mark Salyzyn6e315682017-03-09 08:09:43 -0800142 LOGGER_FUNCTION(logger, -ENODEV, getReadableSize);
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800143}
144
145/*
146 * returns the logger version
147 */
Tom Cherry3d6a8782019-02-08 11:46:19 -0800148int android_logger_get_log_version(struct logger* logger) {
Mark Salyzyn6e315682017-03-09 08:09:43 -0800149 LOGGER_FUNCTION(logger, 4, version);
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800150}
151
Tom Cherryed7c18c2019-08-23 14:04:12 -0700152#define LOGGER_LIST_FUNCTION(logger_list, def, func, args...) \
153 android_log_logger_list* logger_list_internal = \
154 reinterpret_cast<android_log_logger_list*>(logger_list); \
155 \
156 ssize_t ret = init_transport_context(logger_list_internal); \
157 if (ret < 0) { \
158 return ret; \
159 } \
160 \
161 ret = (def); \
162 android_log_transport_context* transport_context = &logger_list_internal->transport_context; \
163 if (transport_context->transport && transport_context->transport->func) { \
164 ssize_t retval = \
165 (transport_context->transport->func)(logger_list_internal, transport_context, ##args); \
166 if (ret >= 0 || ret == (def)) { \
167 ret = retval; \
168 } \
169 } \
Mark Salyzyn6e315682017-03-09 08:09:43 -0800170 return ret
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800171
172/*
173 * returns statistics
174 */
Tom Cherry3d6a8782019-02-08 11:46:19 -0800175ssize_t android_logger_get_statistics(struct logger_list* logger_list, char* buf, size_t len) {
Mark Salyzyn6e315682017-03-09 08:09:43 -0800176 LOGGER_LIST_FUNCTION(logger_list, -ENODEV, getStats, buf, len);
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800177}
178
Tom Cherry3d6a8782019-02-08 11:46:19 -0800179ssize_t android_logger_get_prune_list(struct logger_list* logger_list, char* buf, size_t len) {
Mark Salyzyn6e315682017-03-09 08:09:43 -0800180 LOGGER_LIST_FUNCTION(logger_list, -ENODEV, getPrune, buf, len);
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800181}
182
Tom Cherry3d6a8782019-02-08 11:46:19 -0800183int android_logger_set_prune_list(struct logger_list* logger_list, char* buf, size_t len) {
Mark Salyzyn6e315682017-03-09 08:09:43 -0800184 LOGGER_LIST_FUNCTION(logger_list, -ENODEV, setPrune, buf, len);
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800185}
186
Tom Cherry3d6a8782019-02-08 11:46:19 -0800187struct logger_list* android_logger_list_alloc(int mode, unsigned int tail, pid_t pid) {
Mark Salyzyn6e315682017-03-09 08:09:43 -0800188 struct android_log_logger_list* logger_list;
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800189
Tom Cherryf623f022019-01-10 10:37:36 -0800190 logger_list = static_cast<android_log_logger_list*>(calloc(1, sizeof(*logger_list)));
Mark Salyzyn6e315682017-03-09 08:09:43 -0800191 if (!logger_list) {
192 return NULL;
193 }
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800194
Mark Salyzyn6e315682017-03-09 08:09:43 -0800195 list_init(&logger_list->logger);
Mark Salyzyn6e315682017-03-09 08:09:43 -0800196 logger_list->mode = mode;
197 logger_list->tail = tail;
198 logger_list->pid = pid;
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800199
Mark Salyzyn6e315682017-03-09 08:09:43 -0800200 return (struct logger_list*)logger_list;
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800201}
202
Tom Cherry3d6a8782019-02-08 11:46:19 -0800203struct logger_list* android_logger_list_alloc_time(int mode, log_time start, pid_t pid) {
Mark Salyzyn6e315682017-03-09 08:09:43 -0800204 struct android_log_logger_list* logger_list;
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800205
Tom Cherryf623f022019-01-10 10:37:36 -0800206 logger_list = static_cast<android_log_logger_list*>(calloc(1, sizeof(*logger_list)));
Mark Salyzyn6e315682017-03-09 08:09:43 -0800207 if (!logger_list) {
208 return NULL;
209 }
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800210
Mark Salyzyn6e315682017-03-09 08:09:43 -0800211 list_init(&logger_list->logger);
Mark Salyzyn6e315682017-03-09 08:09:43 -0800212 logger_list->mode = mode;
213 logger_list->start = start;
214 logger_list->pid = pid;
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800215
Mark Salyzyn6e315682017-03-09 08:09:43 -0800216 return (struct logger_list*)logger_list;
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800217}
218
219/* android_logger_list_register unimplemented, no use case */
220/* android_logger_list_unregister unimplemented, no use case */
221
222/* Open the named log and add it to the logger list */
Tom Cherry3d6a8782019-02-08 11:46:19 -0800223struct logger* android_logger_open(struct logger_list* logger_list, log_id_t logId) {
Mark Salyzyn6e315682017-03-09 08:09:43 -0800224 struct android_log_logger_list* logger_list_internal =
225 (struct android_log_logger_list*)logger_list;
226 struct android_log_logger* logger;
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800227
Mark Salyzyn6e315682017-03-09 08:09:43 -0800228 if (!logger_list_internal || (logId >= LOG_ID_MAX)) {
Tom Cherryed7c18c2019-08-23 14:04:12 -0700229 return nullptr;
Mark Salyzyn6e315682017-03-09 08:09:43 -0800230 }
231
232 logger_for_each(logger, logger_list_internal) {
233 if (logger->logId == logId) {
Tom Cherryed7c18c2019-08-23 14:04:12 -0700234 return reinterpret_cast<struct logger*>(logger);
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800235 }
Mark Salyzyn6e315682017-03-09 08:09:43 -0800236 }
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800237
Tom Cherryf623f022019-01-10 10:37:36 -0800238 logger = static_cast<android_log_logger*>(calloc(1, sizeof(*logger)));
Mark Salyzyn6e315682017-03-09 08:09:43 -0800239 if (!logger) {
Tom Cherryed7c18c2019-08-23 14:04:12 -0700240 return nullptr;
Mark Salyzyn6e315682017-03-09 08:09:43 -0800241 }
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800242
Mark Salyzyn6e315682017-03-09 08:09:43 -0800243 logger->logId = logId;
244 list_add_tail(&logger_list_internal->logger, &logger->node);
245 logger->parent = logger_list_internal;
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800246
Tom Cherryed7c18c2019-08-23 14:04:12 -0700247 // Reset known transport to re-evaluate, since we added a new logger.
248 logger_list_internal->transport_initialized = false;
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800249
Mark Salyzyn6e315682017-03-09 08:09:43 -0800250 return (struct logger*)logger;
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800251}
252
253/* Open the single named log and make it part of a new logger list */
Tom Cherry3d6a8782019-02-08 11:46:19 -0800254struct logger_list* android_logger_list_open(log_id_t logId, int mode, unsigned int tail,
255 pid_t pid) {
Mark Salyzyn6e315682017-03-09 08:09:43 -0800256 struct logger_list* logger_list = android_logger_list_alloc(mode, tail, pid);
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800257
Mark Salyzyn6e315682017-03-09 08:09:43 -0800258 if (!logger_list) {
259 return NULL;
260 }
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800261
Mark Salyzyn6e315682017-03-09 08:09:43 -0800262 if (!android_logger_open(logger_list, logId)) {
263 android_logger_list_free(logger_list);
264 return NULL;
265 }
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800266
Mark Salyzyn6e315682017-03-09 08:09:43 -0800267 return logger_list;
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800268}
269
Mark Salyzynbaff8aa2016-05-13 12:25:55 -0700270/* Validate log_msg packet, read function has already been null checked */
Mark Salyzyn6e315682017-03-09 08:09:43 -0800271static int android_transport_read(struct android_log_logger_list* logger_list,
272 struct android_log_transport_context* transp,
273 struct log_msg* log_msg) {
274 int ret = (*transp->transport->read)(logger_list, transp, log_msg);
Mark Salyzynbaff8aa2016-05-13 12:25:55 -0700275
Mark Salyzyn6e315682017-03-09 08:09:43 -0800276 if (ret > (int)sizeof(*log_msg)) {
277 ret = sizeof(*log_msg);
278 }
279
280 transp->ret = ret;
281
282 /* propagate errors, or make sure len & hdr_size members visible */
283 if (ret < (int)(sizeof(log_msg->entry.len) + sizeof(log_msg->entry.hdr_size))) {
284 if (ret >= (int)sizeof(log_msg->entry.len)) {
285 log_msg->entry.len = 0;
Mark Salyzynbaff8aa2016-05-13 12:25:55 -0700286 }
Mark Salyzynbaff8aa2016-05-13 12:25:55 -0700287 return ret;
Mark Salyzyn6e315682017-03-09 08:09:43 -0800288 }
289
290 /* hdr_size correction (logger_entry -> logger_entry_v2+ conversion) */
291 if (log_msg->entry_v2.hdr_size == 0) {
292 log_msg->entry_v2.hdr_size = sizeof(struct logger_entry);
293 }
294 if ((log_msg->entry_v2.hdr_size < sizeof(log_msg->entry_v1)) ||
295 (log_msg->entry_v2.hdr_size > sizeof(log_msg->entry))) {
296 return -EINVAL;
297 }
298
299 /* len validation */
300 if (ret <= log_msg->entry_v2.hdr_size) {
301 log_msg->entry.len = 0;
302 } else {
303 log_msg->entry.len = ret - log_msg->entry_v2.hdr_size;
304 }
305
306 return ret;
Mark Salyzynbaff8aa2016-05-13 12:25:55 -0700307}
308
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800309/* Read from the selected logs */
Tom Cherry3d6a8782019-02-08 11:46:19 -0800310int android_logger_list_read(struct logger_list* logger_list, struct log_msg* log_msg) {
Mark Salyzyn6e315682017-03-09 08:09:43 -0800311 struct android_log_logger_list* logger_list_internal =
312 (struct android_log_logger_list*)logger_list;
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800313
Mark Salyzyn6e315682017-03-09 08:09:43 -0800314 int ret = init_transport_context(logger_list_internal);
315 if (ret < 0) {
316 return ret;
317 }
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800318
Tom Cherryed7c18c2019-08-23 14:04:12 -0700319 android_log_transport_context* transport_context = &logger_list_internal->transport_context;
320 return android_transport_read(logger_list_internal, transport_context, log_msg);
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800321}
322
323/* Close all the logs */
Tom Cherry3d6a8782019-02-08 11:46:19 -0800324void android_logger_list_free(struct logger_list* logger_list) {
Mark Salyzyn6e315682017-03-09 08:09:43 -0800325 struct android_log_logger_list* logger_list_internal =
326 (struct android_log_logger_list*)logger_list;
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800327
Mark Salyzyn6e315682017-03-09 08:09:43 -0800328 if (logger_list_internal == NULL) {
329 return;
330 }
331
Tom Cherryed7c18c2019-08-23 14:04:12 -0700332 android_log_transport_context* transport_context = &logger_list_internal->transport_context;
Mark Salyzyn6e315682017-03-09 08:09:43 -0800333
Tom Cherryed7c18c2019-08-23 14:04:12 -0700334 if (transport_context->transport && transport_context->transport->close) {
335 (*transport_context->transport->close)(logger_list_internal, transport_context);
Mark Salyzyn6e315682017-03-09 08:09:43 -0800336 }
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800337
Mark Salyzyn6e315682017-03-09 08:09:43 -0800338 while (!list_empty(&logger_list_internal->logger)) {
339 struct listnode* node = list_head(&logger_list_internal->logger);
Tom Cherryf623f022019-01-10 10:37:36 -0800340 struct android_log_logger* logger = node_to_item(node, struct android_log_logger, node);
Mark Salyzyn6e315682017-03-09 08:09:43 -0800341 android_logger_free((struct logger*)logger);
342 }
Mark Salyzyn5d2670a2016-03-08 16:18:26 -0800343
Mark Salyzyn6e315682017-03-09 08:09:43 -0800344 free(logger_list_internal);
Mark Salyzyndd9094a2016-03-01 13:45:42 -0800345}