blob: e8a89eb26cc9af64e929880a70027d3b5bfced1c [file] [log] [blame]
Mark Salyzyn018a96d2016-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 Cherry71ba1642019-01-10 10:37:36 -080017#include "log/log_read.h"
18
Mark Salyzyn018a96d2016-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 Salyzyn6584d0a2016-09-28 13:26:55 -070028#include <android/log.h>
Mark Salyzyn018a96d2016-03-01 13:45:42 -080029#include <cutils/list.h>
Mark Salyzync33103c2016-03-28 16:20:29 -070030#include <private/android_filesystem_config.h>
Mark Salyzyn018a96d2016-03-01 13:45:42 -080031
Mark Salyzyn018a96d2016-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 Salyzyn2ed51d72017-03-09 08:09:43 -080037static void android_logger_free(struct logger* logger) {
Tom Cherry71ba1642019-01-10 10:37:36 -080038 struct android_log_logger* logger_internal = (struct android_log_logger*)logger;
Mark Salyzyn018a96d2016-03-01 13:45:42 -080039
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080040 if (!logger_internal) {
41 return;
42 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -080043
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080044 list_remove(&logger_internal->node);
Mark Salyzyn018a96d2016-03-01 13:45:42 -080045
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080046 free(logger_internal);
Mark Salyzyn018a96d2016-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 Cherry2d9779e2019-02-08 11:46:19 -080052log_id_t android_logger_get_id(struct logger* logger) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080053 return ((struct android_log_logger*)logger)->logId;
Mark Salyzyn018a96d2016-03-01 13:45:42 -080054}
55
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080056static int init_transport_context(struct android_log_logger_list* logger_list) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080057 if (!logger_list) {
58 return -EINVAL;
59 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -080060
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080061 if (list_empty(&logger_list->logger)) {
62 return -EINVAL;
63 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -080064
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070065 if (logger_list->transport_initialized) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -080066 return 0;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080067 }
68
Tom Cherryf7e1b1e2019-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 Salyzyn2ed51d72017-03-09 08:09:43 -080072
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070073 struct android_log_transport_read* transport;
74 transport = (logger_list->mode & ANDROID_LOG_PSTORE) ? &pmsgLoggerRead : &logdLoggerRead;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080075
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070076 struct android_log_logger* logger;
77 unsigned logMask = 0;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080078
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070079 logger_for_each(logger, logger_list) {
80 log_id_t logId = logger->logId;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080081
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070082 if (logId == LOG_ID_SECURITY && __android_log_uid() != AID_SYSTEM) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080083 continue;
84 }
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070085 if (transport->read && (!transport->available || transport->available(logId) >= 0)) {
86 logMask |= 1 << logId;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080087 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080088 }
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070089 if (!logMask) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080090 return -ENODEV;
91 }
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070092
93 logger_list->transport_context.transport = transport;
94 logger_list->transport_context.logMask = logMask;
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070095#endif
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080096 return 0;
Mark Salyzyn018a96d2016-03-01 13:45:42 -080097}
98
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070099#define LOGGER_FUNCTION(logger, def, func, args...) \
100 ssize_t ret = -EINVAL; \
101 android_log_logger* logger_internal = reinterpret_cast<android_log_logger*>(logger); \
102 \
103 if (!logger_internal) { \
104 return ret; \
105 } \
106 ret = init_transport_context(logger_internal->parent); \
107 if (ret < 0) { \
108 return ret; \
109 } \
110 \
111 ret = (def); \
112 android_log_transport_context* transport_context = &logger_internal->parent->transport_context; \
113 if (transport_context->logMask & (1 << logger_internal->logId) && \
114 transport_context->transport && transport_context->transport->func) { \
115 ssize_t retval = \
116 (transport_context->transport->func)(logger_internal, transport_context, ##args); \
117 if (ret >= 0 || ret == (def)) { \
118 ret = retval; \
119 } \
120 } \
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800121 return ret
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800122
Tom Cherry2d9779e2019-02-08 11:46:19 -0800123int android_logger_clear(struct logger* logger) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800124 LOGGER_FUNCTION(logger, -ENODEV, clear);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800125}
126
127/* returns the total size of the log's ring buffer */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800128long android_logger_get_log_size(struct logger* logger) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800129 LOGGER_FUNCTION(logger, -ENODEV, getSize);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800130}
131
Tom Cherry2d9779e2019-02-08 11:46:19 -0800132int android_logger_set_log_size(struct logger* logger, unsigned long size) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800133 LOGGER_FUNCTION(logger, -ENODEV, setSize, size);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800134}
135
136/*
137 * returns the readable size of the log's ring buffer (that is, amount of the
138 * log consumed)
139 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800140long android_logger_get_log_readable_size(struct logger* logger) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800141 LOGGER_FUNCTION(logger, -ENODEV, getReadableSize);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800142}
143
144/*
145 * returns the logger version
146 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800147int android_logger_get_log_version(struct logger* logger) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800148 LOGGER_FUNCTION(logger, 4, version);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800149}
150
Tom Cherryf7e1b1e2019-08-23 14:04:12 -0700151#define LOGGER_LIST_FUNCTION(logger_list, def, func, args...) \
152 android_log_logger_list* logger_list_internal = \
153 reinterpret_cast<android_log_logger_list*>(logger_list); \
154 \
155 ssize_t ret = init_transport_context(logger_list_internal); \
156 if (ret < 0) { \
157 return ret; \
158 } \
159 \
160 ret = (def); \
161 android_log_transport_context* transport_context = &logger_list_internal->transport_context; \
162 if (transport_context->transport && transport_context->transport->func) { \
163 ssize_t retval = \
164 (transport_context->transport->func)(logger_list_internal, transport_context, ##args); \
165 if (ret >= 0 || ret == (def)) { \
166 ret = retval; \
167 } \
168 } \
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800169 return ret
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800170
171/*
172 * returns statistics
173 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800174ssize_t android_logger_get_statistics(struct logger_list* logger_list, char* buf, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800175 LOGGER_LIST_FUNCTION(logger_list, -ENODEV, getStats, buf, len);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800176}
177
Tom Cherry2d9779e2019-02-08 11:46:19 -0800178ssize_t android_logger_get_prune_list(struct logger_list* logger_list, char* buf, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800179 LOGGER_LIST_FUNCTION(logger_list, -ENODEV, getPrune, buf, len);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800180}
181
Tom Cherry2d9779e2019-02-08 11:46:19 -0800182int android_logger_set_prune_list(struct logger_list* logger_list, char* buf, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800183 LOGGER_LIST_FUNCTION(logger_list, -ENODEV, setPrune, buf, len);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800184}
185
Tom Cherry2d9779e2019-02-08 11:46:19 -0800186struct logger_list* android_logger_list_alloc(int mode, unsigned int tail, pid_t pid) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800187 struct android_log_logger_list* logger_list;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800188
Tom Cherry71ba1642019-01-10 10:37:36 -0800189 logger_list = static_cast<android_log_logger_list*>(calloc(1, sizeof(*logger_list)));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800190 if (!logger_list) {
191 return NULL;
192 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800193
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800194 list_init(&logger_list->logger);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800195 logger_list->mode = mode;
196 logger_list->tail = tail;
197 logger_list->pid = pid;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800198
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800199 return (struct logger_list*)logger_list;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800200}
201
Tom Cherry2d9779e2019-02-08 11:46:19 -0800202struct logger_list* android_logger_list_alloc_time(int mode, log_time start, pid_t pid) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800203 struct android_log_logger_list* logger_list;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800204
Tom Cherry71ba1642019-01-10 10:37:36 -0800205 logger_list = static_cast<android_log_logger_list*>(calloc(1, sizeof(*logger_list)));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800206 if (!logger_list) {
207 return NULL;
208 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800209
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800210 list_init(&logger_list->logger);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800211 logger_list->mode = mode;
212 logger_list->start = start;
213 logger_list->pid = pid;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800214
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800215 return (struct logger_list*)logger_list;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800216}
217
218/* android_logger_list_register unimplemented, no use case */
219/* android_logger_list_unregister unimplemented, no use case */
220
221/* Open the named log and add it to the logger list */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800222struct logger* android_logger_open(struct logger_list* logger_list, log_id_t logId) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800223 struct android_log_logger_list* logger_list_internal =
224 (struct android_log_logger_list*)logger_list;
225 struct android_log_logger* logger;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800226
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800227 if (!logger_list_internal || (logId >= LOG_ID_MAX)) {
Tom Cherryf7e1b1e2019-08-23 14:04:12 -0700228 return nullptr;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800229 }
230
231 logger_for_each(logger, logger_list_internal) {
232 if (logger->logId == logId) {
Tom Cherryf7e1b1e2019-08-23 14:04:12 -0700233 return reinterpret_cast<struct logger*>(logger);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800234 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800235 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800236
Tom Cherry71ba1642019-01-10 10:37:36 -0800237 logger = static_cast<android_log_logger*>(calloc(1, sizeof(*logger)));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800238 if (!logger) {
Tom Cherryf7e1b1e2019-08-23 14:04:12 -0700239 return nullptr;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800240 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800241
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800242 logger->logId = logId;
243 list_add_tail(&logger_list_internal->logger, &logger->node);
244 logger->parent = logger_list_internal;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800245
Tom Cherryf7e1b1e2019-08-23 14:04:12 -0700246 // Reset known transport to re-evaluate, since we added a new logger.
247 logger_list_internal->transport_initialized = false;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800248
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800249 return (struct logger*)logger;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800250}
251
252/* Open the single named log and make it part of a new logger list */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800253struct logger_list* android_logger_list_open(log_id_t logId, int mode, unsigned int tail,
254 pid_t pid) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800255 struct logger_list* logger_list = android_logger_list_alloc(mode, tail, pid);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800256
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800257 if (!logger_list) {
258 return NULL;
259 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800260
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800261 if (!android_logger_open(logger_list, logId)) {
262 android_logger_list_free(logger_list);
263 return NULL;
264 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800265
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800266 return logger_list;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800267}
268
Mark Salyzyn8fd1faa2016-05-13 12:25:55 -0700269/* Validate log_msg packet, read function has already been null checked */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800270static int android_transport_read(struct android_log_logger_list* logger_list,
271 struct android_log_transport_context* transp,
272 struct log_msg* log_msg) {
273 int ret = (*transp->transport->read)(logger_list, transp, log_msg);
Mark Salyzyn8fd1faa2016-05-13 12:25:55 -0700274
Tom Cherryb8bacea2019-11-15 16:41:36 -0800275 if (ret <= 0) {
Tom Cherry441054a2019-10-15 16:53:11 -0700276 return ret;
277 }
278
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800279 if (ret > (int)sizeof(*log_msg)) {
280 ret = sizeof(*log_msg);
281 }
282
Tom Cherry441054a2019-10-15 16:53:11 -0700283 if (ret < static_cast<int>(sizeof(log_msg->entry))) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800284 return -EINVAL;
285 }
286
Tom Cherry441054a2019-10-15 16:53:11 -0700287 if (log_msg->entry.hdr_size != sizeof(log_msg->entry)) {
288 return -EINVAL;
289 }
290
291 if (log_msg->entry.len > ret - log_msg->entry.hdr_size) {
292 return -EINVAL;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800293 }
294
295 return ret;
Mark Salyzyn8fd1faa2016-05-13 12:25:55 -0700296}
297
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800298/* Read from the selected logs */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800299int android_logger_list_read(struct logger_list* logger_list, struct log_msg* log_msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800300 struct android_log_logger_list* logger_list_internal =
301 (struct android_log_logger_list*)logger_list;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800302
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800303 int ret = init_transport_context(logger_list_internal);
304 if (ret < 0) {
305 return ret;
306 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800307
Tom Cherryf7e1b1e2019-08-23 14:04:12 -0700308 android_log_transport_context* transport_context = &logger_list_internal->transport_context;
309 return android_transport_read(logger_list_internal, transport_context, log_msg);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800310}
311
312/* Close all the logs */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800313void android_logger_list_free(struct logger_list* logger_list) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800314 struct android_log_logger_list* logger_list_internal =
315 (struct android_log_logger_list*)logger_list;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800316
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800317 if (logger_list_internal == NULL) {
318 return;
319 }
320
Tom Cherryf7e1b1e2019-08-23 14:04:12 -0700321 android_log_transport_context* transport_context = &logger_list_internal->transport_context;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800322
Tom Cherryf7e1b1e2019-08-23 14:04:12 -0700323 if (transport_context->transport && transport_context->transport->close) {
324 (*transport_context->transport->close)(logger_list_internal, transport_context);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800325 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800326
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800327 while (!list_empty(&logger_list_internal->logger)) {
328 struct listnode* node = list_head(&logger_list_internal->logger);
Tom Cherry71ba1642019-01-10 10:37:36 -0800329 struct android_log_logger* logger = node_to_item(node, struct android_log_logger, node);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800330 android_logger_free((struct logger*)logger);
331 }
Mark Salyzyncf983bc2016-03-08 16:18:26 -0800332
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800333 free(logger_list_internal);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800334}