blob: 5e10adafe1e8e32634b7ebb59abf3492f03ee40a [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 Cherry828db1a2019-11-14 10:39:40 -080038 if (!logger) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080039 return;
40 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -080041
Tom Cherry828db1a2019-11-14 10:39:40 -080042 list_remove(&logger->node);
Mark Salyzyn018a96d2016-03-01 13:45:42 -080043
Tom Cherry828db1a2019-11-14 10:39:40 -080044 free(logger);
Mark Salyzyn018a96d2016-03-01 13:45:42 -080045}
46
47/* android_logger_alloc unimplemented, no use case */
48
49/* method for getting the associated sublog id */
Tom Cherry2d9779e2019-02-08 11:46:19 -080050log_id_t android_logger_get_id(struct logger* logger) {
Tom Cherry828db1a2019-11-14 10:39:40 -080051 return ((struct logger*)logger)->logId;
Mark Salyzyn018a96d2016-03-01 13:45:42 -080052}
53
Tom Cherry828db1a2019-11-14 10:39:40 -080054static int init_transport_context(struct logger_list* logger_list) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080055 if (!logger_list) {
56 return -EINVAL;
57 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -080058
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080059 if (list_empty(&logger_list->logger)) {
60 return -EINVAL;
61 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -080062
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070063 if (logger_list->transport_initialized) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -080064 return 0;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080065 }
66
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070067#if (FAKE_LOG_DEVICE == 0)
68 extern struct android_log_transport_read logdLoggerRead;
69 extern struct android_log_transport_read pmsgLoggerRead;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080070
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070071 struct android_log_transport_read* transport;
72 transport = (logger_list->mode & ANDROID_LOG_PSTORE) ? &pmsgLoggerRead : &logdLoggerRead;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080073
Tom Cherry828db1a2019-11-14 10:39:40 -080074 struct logger* logger;
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070075 unsigned logMask = 0;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080076
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070077 logger_for_each(logger, logger_list) {
78 log_id_t logId = logger->logId;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080079
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070080 if (logId == LOG_ID_SECURITY && __android_log_uid() != AID_SYSTEM) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080081 continue;
82 }
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070083 if (transport->read && (!transport->available || transport->available(logId) >= 0)) {
84 logMask |= 1 << logId;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080085 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080086 }
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070087 if (!logMask) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080088 return -ENODEV;
89 }
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070090
91 logger_list->transport_context.transport = transport;
92 logger_list->transport_context.logMask = logMask;
Tom Cherryf7e1b1e2019-08-23 14:04:12 -070093#endif
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080094 return 0;
Mark Salyzyn018a96d2016-03-01 13:45:42 -080095}
96
Tom Cherry828db1a2019-11-14 10:39:40 -080097#define LOGGER_FUNCTION(logger, def, func, args...) \
98 ssize_t ret = -EINVAL; \
99 \
100 if (!logger) { \
101 return ret; \
102 } \
103 ret = init_transport_context(logger->parent); \
104 if (ret < 0) { \
105 return ret; \
106 } \
107 \
108 ret = (def); \
109 android_log_transport_context* transport_context = &logger->parent->transport_context; \
110 if (transport_context->logMask & (1 << logger->logId) && transport_context->transport && \
111 transport_context->transport->func) { \
112 ssize_t retval = (transport_context->transport->func)(logger, transport_context, ##args); \
113 if (ret >= 0 || ret == (def)) { \
114 ret = retval; \
115 } \
116 } \
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800117 return ret
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800118
Tom Cherry2d9779e2019-02-08 11:46:19 -0800119int android_logger_clear(struct logger* logger) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800120 LOGGER_FUNCTION(logger, -ENODEV, clear);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800121}
122
123/* returns the total size of the log's ring buffer */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800124long android_logger_get_log_size(struct logger* logger) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800125 LOGGER_FUNCTION(logger, -ENODEV, getSize);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800126}
127
Tom Cherry2d9779e2019-02-08 11:46:19 -0800128int android_logger_set_log_size(struct logger* logger, unsigned long size) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800129 LOGGER_FUNCTION(logger, -ENODEV, setSize, size);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800130}
131
132/*
133 * returns the readable size of the log's ring buffer (that is, amount of the
134 * log consumed)
135 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800136long android_logger_get_log_readable_size(struct logger* logger) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800137 LOGGER_FUNCTION(logger, -ENODEV, getReadableSize);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800138}
139
140/*
141 * returns the logger version
142 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800143int android_logger_get_log_version(struct logger* logger) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800144 LOGGER_FUNCTION(logger, 4, version);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800145}
146
Tom Cherry828db1a2019-11-14 10:39:40 -0800147#define LOGGER_LIST_FUNCTION(logger_list, def, func, args...) \
148 ssize_t ret = init_transport_context(logger_list); \
149 if (ret < 0) { \
150 return ret; \
151 } \
152 \
153 ret = (def); \
154 android_log_transport_context* transport_context = &logger_list->transport_context; \
155 if (transport_context->transport && transport_context->transport->func) { \
156 ssize_t retval = (transport_context->transport->func)(logger_list, transport_context, ##args); \
157 if (ret >= 0 || ret == (def)) { \
158 ret = retval; \
159 } \
160 } \
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800161 return ret
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800162
163/*
164 * returns statistics
165 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800166ssize_t android_logger_get_statistics(struct logger_list* logger_list, char* buf, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800167 LOGGER_LIST_FUNCTION(logger_list, -ENODEV, getStats, buf, len);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800168}
169
Tom Cherry2d9779e2019-02-08 11:46:19 -0800170ssize_t android_logger_get_prune_list(struct logger_list* logger_list, char* buf, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800171 LOGGER_LIST_FUNCTION(logger_list, -ENODEV, getPrune, buf, len);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800172}
173
Tom Cherry2d9779e2019-02-08 11:46:19 -0800174int android_logger_set_prune_list(struct logger_list* logger_list, char* buf, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800175 LOGGER_LIST_FUNCTION(logger_list, -ENODEV, setPrune, buf, len);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800176}
177
Tom Cherry2d9779e2019-02-08 11:46:19 -0800178struct logger_list* android_logger_list_alloc(int mode, unsigned int tail, pid_t pid) {
Tom Cherry828db1a2019-11-14 10:39:40 -0800179 struct logger_list* logger_list;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800180
Tom Cherry828db1a2019-11-14 10:39:40 -0800181 logger_list = static_cast<struct logger_list*>(calloc(1, sizeof(*logger_list)));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800182 if (!logger_list) {
183 return NULL;
184 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800185
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800186 list_init(&logger_list->logger);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800187 logger_list->mode = mode;
188 logger_list->tail = tail;
189 logger_list->pid = pid;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800190
Tom Cherry828db1a2019-11-14 10:39:40 -0800191 return logger_list;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800192}
193
Tom Cherry2d9779e2019-02-08 11:46:19 -0800194struct logger_list* android_logger_list_alloc_time(int mode, log_time start, pid_t pid) {
Tom Cherry828db1a2019-11-14 10:39:40 -0800195 struct logger_list* logger_list;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800196
Tom Cherry828db1a2019-11-14 10:39:40 -0800197 logger_list = static_cast<struct logger_list*>(calloc(1, sizeof(*logger_list)));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800198 if (!logger_list) {
199 return NULL;
200 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800201
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800202 list_init(&logger_list->logger);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800203 logger_list->mode = mode;
204 logger_list->start = start;
205 logger_list->pid = pid;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800206
Tom Cherry828db1a2019-11-14 10:39:40 -0800207 return logger_list;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800208}
209
210/* android_logger_list_register unimplemented, no use case */
211/* android_logger_list_unregister unimplemented, no use case */
212
213/* Open the named log and add it to the logger list */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800214struct logger* android_logger_open(struct logger_list* logger_list, log_id_t logId) {
Tom Cherry828db1a2019-11-14 10:39:40 -0800215 struct logger* logger;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800216
Tom Cherry828db1a2019-11-14 10:39:40 -0800217 if (!logger_list || (logId >= LOG_ID_MAX)) {
Tom Cherryf7e1b1e2019-08-23 14:04:12 -0700218 return nullptr;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800219 }
220
Tom Cherry828db1a2019-11-14 10:39:40 -0800221 logger_for_each(logger, logger_list) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800222 if (logger->logId == logId) {
Tom Cherryf7e1b1e2019-08-23 14:04:12 -0700223 return reinterpret_cast<struct logger*>(logger);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800224 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800225 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800226
Tom Cherry828db1a2019-11-14 10:39:40 -0800227 logger = static_cast<struct logger*>(calloc(1, sizeof(*logger)));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800228 if (!logger) {
Tom Cherryf7e1b1e2019-08-23 14:04:12 -0700229 return nullptr;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800230 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800231
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800232 logger->logId = logId;
Tom Cherry828db1a2019-11-14 10:39:40 -0800233 list_add_tail(&logger_list->logger, &logger->node);
234 logger->parent = logger_list;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800235
Tom Cherryf7e1b1e2019-08-23 14:04:12 -0700236 // Reset known transport to re-evaluate, since we added a new logger.
Tom Cherry828db1a2019-11-14 10:39:40 -0800237 logger_list->transport_initialized = false;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800238
Tom Cherry828db1a2019-11-14 10:39:40 -0800239 return logger;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800240}
241
242/* Open the single named log and make it part of a new logger list */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800243struct logger_list* android_logger_list_open(log_id_t logId, int mode, unsigned int tail,
244 pid_t pid) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800245 struct logger_list* logger_list = android_logger_list_alloc(mode, tail, pid);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800246
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800247 if (!logger_list) {
248 return NULL;
249 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800250
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800251 if (!android_logger_open(logger_list, logId)) {
252 android_logger_list_free(logger_list);
253 return NULL;
254 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800255
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800256 return logger_list;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800257}
258
Mark Salyzyn8fd1faa2016-05-13 12:25:55 -0700259/* Validate log_msg packet, read function has already been null checked */
Tom Cherry828db1a2019-11-14 10:39:40 -0800260static int android_transport_read(struct logger_list* logger_list,
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800261 struct android_log_transport_context* transp,
262 struct log_msg* log_msg) {
263 int ret = (*transp->transport->read)(logger_list, transp, log_msg);
Mark Salyzyn8fd1faa2016-05-13 12:25:55 -0700264
Tom Cherry441054a2019-10-15 16:53:11 -0700265 if (ret < 0) {
266 return ret;
267 }
268
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800269 if (ret > (int)sizeof(*log_msg)) {
270 ret = sizeof(*log_msg);
271 }
272
Tom Cherry441054a2019-10-15 16:53:11 -0700273 if (ret < static_cast<int>(sizeof(log_msg->entry))) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800274 return -EINVAL;
275 }
276
Tom Cherry441054a2019-10-15 16:53:11 -0700277 if (log_msg->entry.hdr_size != sizeof(log_msg->entry)) {
278 return -EINVAL;
279 }
280
281 if (log_msg->entry.len > ret - log_msg->entry.hdr_size) {
282 return -EINVAL;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800283 }
284
285 return ret;
Mark Salyzyn8fd1faa2016-05-13 12:25:55 -0700286}
287
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800288/* Read from the selected logs */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800289int android_logger_list_read(struct logger_list* logger_list, struct log_msg* log_msg) {
Tom Cherry828db1a2019-11-14 10:39:40 -0800290 int ret = init_transport_context(logger_list);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800291 if (ret < 0) {
292 return ret;
293 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800294
Tom Cherry828db1a2019-11-14 10:39:40 -0800295 android_log_transport_context* transport_context = &logger_list->transport_context;
296 return android_transport_read(logger_list, transport_context, log_msg);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800297}
298
299/* Close all the logs */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800300void android_logger_list_free(struct logger_list* logger_list) {
Tom Cherry828db1a2019-11-14 10:39:40 -0800301 if (logger_list == NULL) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800302 return;
303 }
304
Tom Cherry828db1a2019-11-14 10:39:40 -0800305 android_log_transport_context* transport_context = &logger_list->transport_context;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800306
Tom Cherryf7e1b1e2019-08-23 14:04:12 -0700307 if (transport_context->transport && transport_context->transport->close) {
Tom Cherry828db1a2019-11-14 10:39:40 -0800308 (*transport_context->transport->close)(logger_list, transport_context);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800309 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800310
Tom Cherry828db1a2019-11-14 10:39:40 -0800311 while (!list_empty(&logger_list->logger)) {
312 struct listnode* node = list_head(&logger_list->logger);
313 struct logger* logger = node_to_item(node, struct logger, node);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800314 android_logger_free((struct logger*)logger);
315 }
Mark Salyzyncf983bc2016-03-08 16:18:26 -0800316
Tom Cherry828db1a2019-11-14 10:39:40 -0800317 free(logger_list);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800318}