xref: /aosp_15_r20/system/logging/liblog/logger_read.cpp (revision 598139dc91b21518d67c408eaea2644226490971)
1*598139dcSAndroid Build Coastguard Worker /*
2*598139dcSAndroid Build Coastguard Worker ** Copyright 2013-2014, 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 "log/log_read.h"
18*598139dcSAndroid Build Coastguard Worker 
19*598139dcSAndroid Build Coastguard Worker #include <errno.h>
20*598139dcSAndroid Build Coastguard Worker #include <fcntl.h>
21*598139dcSAndroid Build Coastguard Worker #include <pthread.h>
22*598139dcSAndroid Build Coastguard Worker #include <sched.h>
23*598139dcSAndroid Build Coastguard Worker #include <stddef.h>
24*598139dcSAndroid Build Coastguard Worker #include <stdint.h>
25*598139dcSAndroid Build Coastguard Worker #include <stdlib.h>
26*598139dcSAndroid Build Coastguard Worker #include <string.h>
27*598139dcSAndroid Build Coastguard Worker #include <unistd.h>
28*598139dcSAndroid Build Coastguard Worker 
29*598139dcSAndroid Build Coastguard Worker #include <android/log.h>
30*598139dcSAndroid Build Coastguard Worker 
31*598139dcSAndroid Build Coastguard Worker #include "logd_reader.h"
32*598139dcSAndroid Build Coastguard Worker #include "logger.h"
33*598139dcSAndroid Build Coastguard Worker #include "pmsg_reader.h"
34*598139dcSAndroid Build Coastguard Worker 
35*598139dcSAndroid Build Coastguard Worker /* method for getting the associated sublog id */
android_logger_get_id(struct logger * logger)36*598139dcSAndroid Build Coastguard Worker log_id_t android_logger_get_id(struct logger* logger) {
37*598139dcSAndroid Build Coastguard Worker   return static_cast<log_id_t>(reinterpret_cast<uintptr_t>(logger) & LOGGER_LOG_ID_MASK);
38*598139dcSAndroid Build Coastguard Worker }
39*598139dcSAndroid Build Coastguard Worker 
android_logger_list_alloc_internal(int mode,unsigned int tail,log_time start,pid_t pid)40*598139dcSAndroid Build Coastguard Worker static struct logger_list* android_logger_list_alloc_internal(int mode, unsigned int tail,
41*598139dcSAndroid Build Coastguard Worker                                                               log_time start, pid_t pid) {
42*598139dcSAndroid Build Coastguard Worker   auto* logger_list = static_cast<struct logger_list*>(calloc(1, sizeof(struct logger_list)));
43*598139dcSAndroid Build Coastguard Worker   if (!logger_list) {
44*598139dcSAndroid Build Coastguard Worker     return nullptr;
45*598139dcSAndroid Build Coastguard Worker   }
46*598139dcSAndroid Build Coastguard Worker 
47*598139dcSAndroid Build Coastguard Worker   logger_list->mode = mode;
48*598139dcSAndroid Build Coastguard Worker   logger_list->start = start;
49*598139dcSAndroid Build Coastguard Worker   logger_list->tail = tail;
50*598139dcSAndroid Build Coastguard Worker   logger_list->pid = pid;
51*598139dcSAndroid Build Coastguard Worker 
52*598139dcSAndroid Build Coastguard Worker   return logger_list;
53*598139dcSAndroid Build Coastguard Worker }
54*598139dcSAndroid Build Coastguard Worker 
android_logger_list_alloc(int mode,unsigned int tail,pid_t pid)55*598139dcSAndroid Build Coastguard Worker struct logger_list* android_logger_list_alloc(int mode, unsigned int tail, pid_t pid) {
56*598139dcSAndroid Build Coastguard Worker   return android_logger_list_alloc_internal(mode, tail, log_time(0, 0), pid);
57*598139dcSAndroid Build Coastguard Worker }
58*598139dcSAndroid Build Coastguard Worker 
android_logger_list_alloc_time(int mode,log_time start,pid_t pid)59*598139dcSAndroid Build Coastguard Worker struct logger_list* android_logger_list_alloc_time(int mode, log_time start, pid_t pid) {
60*598139dcSAndroid Build Coastguard Worker   return android_logger_list_alloc_internal(mode, 0, start, pid);
61*598139dcSAndroid Build Coastguard Worker }
62*598139dcSAndroid Build Coastguard Worker 
63*598139dcSAndroid Build Coastguard Worker /* Open the named log and add it to the logger list */
android_logger_open(struct logger_list * logger_list,log_id_t log_id)64*598139dcSAndroid Build Coastguard Worker struct logger* android_logger_open(struct logger_list* logger_list, log_id_t log_id) {
65*598139dcSAndroid Build Coastguard Worker   if (!logger_list || !__android_log_id_is_valid(log_id)) {
66*598139dcSAndroid Build Coastguard Worker     return nullptr;
67*598139dcSAndroid Build Coastguard Worker   }
68*598139dcSAndroid Build Coastguard Worker 
69*598139dcSAndroid Build Coastguard Worker   logger_list->log_mask |= 1 << log_id;
70*598139dcSAndroid Build Coastguard Worker 
71*598139dcSAndroid Build Coastguard Worker   uintptr_t logger = log_id;
72*598139dcSAndroid Build Coastguard Worker   logger |= (logger_list->mode & ANDROID_LOG_PSTORE) ? LOGGER_PMSG : LOGGER_LOGD;
73*598139dcSAndroid Build Coastguard Worker   return reinterpret_cast<struct logger*>(logger);
74*598139dcSAndroid Build Coastguard Worker }
75*598139dcSAndroid Build Coastguard Worker 
76*598139dcSAndroid Build Coastguard Worker /* Open the single named log and make it part of a new logger list */
android_logger_list_open(log_id_t logId,int mode,unsigned int tail,pid_t pid)77*598139dcSAndroid Build Coastguard Worker struct logger_list* android_logger_list_open(log_id_t logId, int mode, unsigned int tail,
78*598139dcSAndroid Build Coastguard Worker                                              pid_t pid) {
79*598139dcSAndroid Build Coastguard Worker   struct logger_list* logger_list = android_logger_list_alloc(mode, tail, pid);
80*598139dcSAndroid Build Coastguard Worker 
81*598139dcSAndroid Build Coastguard Worker   if (!logger_list) {
82*598139dcSAndroid Build Coastguard Worker     return NULL;
83*598139dcSAndroid Build Coastguard Worker   }
84*598139dcSAndroid Build Coastguard Worker 
85*598139dcSAndroid Build Coastguard Worker   if (!android_logger_open(logger_list, logId)) {
86*598139dcSAndroid Build Coastguard Worker     android_logger_list_free(logger_list);
87*598139dcSAndroid Build Coastguard Worker     return NULL;
88*598139dcSAndroid Build Coastguard Worker   }
89*598139dcSAndroid Build Coastguard Worker 
90*598139dcSAndroid Build Coastguard Worker   return logger_list;
91*598139dcSAndroid Build Coastguard Worker }
92*598139dcSAndroid Build Coastguard Worker 
android_logger_list_read(struct logger_list * logger_list,struct log_msg * log_msg)93*598139dcSAndroid Build Coastguard Worker int android_logger_list_read(struct logger_list* logger_list, struct log_msg* log_msg) {
94*598139dcSAndroid Build Coastguard Worker   if (logger_list == nullptr || logger_list->log_mask == 0) {
95*598139dcSAndroid Build Coastguard Worker     return -EINVAL;
96*598139dcSAndroid Build Coastguard Worker   }
97*598139dcSAndroid Build Coastguard Worker 
98*598139dcSAndroid Build Coastguard Worker   int ret = 0;
99*598139dcSAndroid Build Coastguard Worker 
100*598139dcSAndroid Build Coastguard Worker #ifdef __ANDROID__
101*598139dcSAndroid Build Coastguard Worker   if (logger_list->mode & ANDROID_LOG_PSTORE) {
102*598139dcSAndroid Build Coastguard Worker     ret = PmsgRead(logger_list, log_msg);
103*598139dcSAndroid Build Coastguard Worker   } else {
104*598139dcSAndroid Build Coastguard Worker     ret = LogdRead(logger_list, log_msg);
105*598139dcSAndroid Build Coastguard Worker   }
106*598139dcSAndroid Build Coastguard Worker #endif
107*598139dcSAndroid Build Coastguard Worker 
108*598139dcSAndroid Build Coastguard Worker   if (ret <= 0) {
109*598139dcSAndroid Build Coastguard Worker     return ret;
110*598139dcSAndroid Build Coastguard Worker   }
111*598139dcSAndroid Build Coastguard Worker 
112*598139dcSAndroid Build Coastguard Worker   if (ret > LOGGER_ENTRY_MAX_LEN) {
113*598139dcSAndroid Build Coastguard Worker     ret = LOGGER_ENTRY_MAX_LEN;
114*598139dcSAndroid Build Coastguard Worker   }
115*598139dcSAndroid Build Coastguard Worker 
116*598139dcSAndroid Build Coastguard Worker   if (ret < static_cast<int>(sizeof(log_msg->entry))) {
117*598139dcSAndroid Build Coastguard Worker     return -EINVAL;
118*598139dcSAndroid Build Coastguard Worker   }
119*598139dcSAndroid Build Coastguard Worker 
120*598139dcSAndroid Build Coastguard Worker   if (log_msg->entry.hdr_size < sizeof(log_msg->entry) ||
121*598139dcSAndroid Build Coastguard Worker       log_msg->entry.hdr_size >= LOGGER_ENTRY_MAX_LEN - sizeof(log_msg->entry)) {
122*598139dcSAndroid Build Coastguard Worker     return -EINVAL;
123*598139dcSAndroid Build Coastguard Worker   }
124*598139dcSAndroid Build Coastguard Worker 
125*598139dcSAndroid Build Coastguard Worker   if (log_msg->entry.len > ret - log_msg->entry.hdr_size) {
126*598139dcSAndroid Build Coastguard Worker     return -EINVAL;
127*598139dcSAndroid Build Coastguard Worker   }
128*598139dcSAndroid Build Coastguard Worker 
129*598139dcSAndroid Build Coastguard Worker   log_msg->buf[log_msg->entry.len + log_msg->entry.hdr_size] = '\0';
130*598139dcSAndroid Build Coastguard Worker 
131*598139dcSAndroid Build Coastguard Worker   return ret;
132*598139dcSAndroid Build Coastguard Worker }
133*598139dcSAndroid Build Coastguard Worker 
134*598139dcSAndroid Build Coastguard Worker /* Close all the logs */
android_logger_list_free(struct logger_list * logger_list)135*598139dcSAndroid Build Coastguard Worker void android_logger_list_free(struct logger_list* logger_list) {
136*598139dcSAndroid Build Coastguard Worker   if (logger_list == NULL) {
137*598139dcSAndroid Build Coastguard Worker     return;
138*598139dcSAndroid Build Coastguard Worker   }
139*598139dcSAndroid Build Coastguard Worker 
140*598139dcSAndroid Build Coastguard Worker #ifdef __ANDROID__
141*598139dcSAndroid Build Coastguard Worker   if (logger_list->mode & ANDROID_LOG_PSTORE) {
142*598139dcSAndroid Build Coastguard Worker     PmsgClose(logger_list);
143*598139dcSAndroid Build Coastguard Worker   } else {
144*598139dcSAndroid Build Coastguard Worker     LogdClose(logger_list);
145*598139dcSAndroid Build Coastguard Worker   }
146*598139dcSAndroid Build Coastguard Worker #endif
147*598139dcSAndroid Build Coastguard Worker 
148*598139dcSAndroid Build Coastguard Worker   free(logger_list);
149*598139dcSAndroid Build Coastguard Worker }
150