blob: ec86e6ba25dae0fc26b7b385e67c536419b14fc7 [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
Mark Salyzyne9c41962014-01-02 13:52:29 -08002 * Copyright (C) 2007-2014 The Android Open Source Project
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08003 *
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 */
Mark Salyzyn31dd00f2015-03-04 17:01:30 -080016#if (FAKE_LOG_DEVICE == 0)
Mark Salyzynd45d36e2015-02-12 15:14:26 -080017#include <endian.h>
Mark Salyzyn31dd00f2015-03-04 17:01:30 -080018#endif
Mark Salyzyn154f4602014-02-20 14:59:07 -080019#include <errno.h>
20#include <fcntl.h>
Yabin Cui4a6e5a32015-01-26 19:48:54 -080021#if !defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080022#include <pthread.h>
23#endif
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080024#include <stdarg.h>
Mark Salyzynd45d36e2015-02-12 15:14:26 -080025#include <stdatomic.h>
Mark Salyzyn154f4602014-02-20 14:59:07 -080026#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
Nick Kralevicha1703222013-03-15 09:45:12 -070029#include <sys/stat.h>
Mark Salyzyn154f4602014-02-20 14:59:07 -080030#include <sys/types.h>
31#if (FAKE_LOG_DEVICE == 0)
32#include <sys/socket.h>
33#include <sys/un.h>
34#endif
35#include <time.h>
36#include <unistd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080037
Dan Albertc68fedc2014-08-18 17:29:34 -070038#ifdef __BIONIC__
39#include <android/set_abort_message.h>
40#endif
41
Mark Salyzyna0140042015-03-13 06:50:32 -070042#include <log/event_tag_map.h>
Colin Cross9227bd32013-07-23 16:59:20 -070043#include <log/logd.h>
Mark Salyzyn154f4602014-02-20 14:59:07 -080044#include <log/logger.h>
45#include <log/log_read.h>
46#include <private/android_filesystem_config.h>
Mark Salyzyn7a809402015-01-16 13:38:07 -080047#include <private/android_logger.h>
Mark Salyzyne9c41962014-01-02 13:52:29 -080048
Mark Salyzyncf4aa032013-11-22 07:54:30 -080049#define LOG_BUF_SIZE 1024
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080050
51#if FAKE_LOG_DEVICE
Mark Salyzyn154f4602014-02-20 14:59:07 -080052/* This will be defined when building for the host. */
Kristian Monsenb5a98902014-01-28 11:26:56 -080053#include "fake_log_device.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080054#endif
55
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080056static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr);
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -080057static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080058
Mark Salyzyna04464a2014-04-30 08:50:53 -070059#ifndef __unused
60#define __unused __attribute__((__unused__))
61#endif
Kristian Monsenb5a98902014-01-28 11:26:56 -080062
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -080063#if !defined(_WIN32)
64static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
65
66static void lock()
67{
68 /*
69 * If we trigger a signal handler in the middle of locked activity and the
70 * signal handler logs a message, we could get into a deadlock state.
71 */
72 pthread_mutex_lock(&log_init_lock);
73}
74
Mark Salyzyna0140042015-03-13 06:50:32 -070075static int trylock()
76{
77 return pthread_mutex_trylock(&log_init_lock);
78}
79
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -080080static void unlock()
81{
82 pthread_mutex_unlock(&log_init_lock);
83}
84
85#else /* !defined(_WIN32) */
86
87#define lock() ((void)0)
Mark Salyzyna0140042015-03-13 06:50:32 -070088#define trylock() (0) /* success */
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -080089#define unlock() ((void)0)
90
91#endif /* !defined(_WIN32) */
92
Mark Salyzyn154f4602014-02-20 14:59:07 -080093#if FAKE_LOG_DEVICE
Mark Salyzyn083b0372015-12-04 10:59:45 -080094static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1, -1, -1 };
Mark Salyzyna04464a2014-04-30 08:50:53 -070095#else
96static int logd_fd = -1;
Mark Salyzynd91ab582014-12-15 10:52:12 -080097static int pstore_fd = -1;
Mark Salyzyn154f4602014-02-20 14:59:07 -080098#endif
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080099
100/*
101 * This is used by the C++ code to decide if it should write logs through
Mark Salyzyn154f4602014-02-20 14:59:07 -0800102 * the C code. Basically, if /dev/socket/logd is available, we're running in
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800103 * the simulator rather than a desktop tool and want to use the device.
104 */
105static enum {
Chris Pearson19299902010-06-02 16:25:35 -0700106 kLogUninitialized, kLogNotAvailable, kLogAvailable
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800107} g_log_status = kLogUninitialized;
Mark Salyzyn53016d82015-02-04 12:28:47 -0800108
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800109int __android_log_dev_available(void)
110{
111 if (g_log_status == kLogUninitialized) {
Mark Salyzyn154f4602014-02-20 14:59:07 -0800112 if (access("/dev/socket/logdw", W_OK) == 0)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800113 g_log_status = kLogAvailable;
114 else
115 g_log_status = kLogNotAvailable;
116 }
117
118 return (g_log_status == kLogAvailable);
119}
120
Mark Salyzyn8245af12014-03-25 13:45:33 -0700121/* log_init_lock assumed */
122static int __write_to_log_initialize()
123{
124 int i, ret = 0;
125
126#if FAKE_LOG_DEVICE
127 for (i = 0; i < LOG_ID_MAX; i++) {
128 char buf[sizeof("/dev/log_system")];
129 snprintf(buf, sizeof(buf), "/dev/log_%s", android_log_id_to_name(i));
130 log_fds[i] = fakeLogOpen(buf, O_WRONLY);
131 }
132#else
Mark Salyzyn0d00a442015-03-13 12:15:57 -0700133 if (pstore_fd < 0) {
134 pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY));
Mark Salyzyn8245af12014-03-25 13:45:33 -0700135 }
136
Mark Salyzyn0d00a442015-03-13 12:15:57 -0700137 if (logd_fd < 0) {
138 i = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0));
139 if (i < 0) {
140 ret = -errno;
141 } else if (TEMP_FAILURE_RETRY(fcntl(i, F_SETFL, O_NONBLOCK)) < 0) {
Mark Salyzyn8245af12014-03-25 13:45:33 -0700142 ret = -errno;
143 close(i);
Mark Salyzyn0d00a442015-03-13 12:15:57 -0700144 } else {
145 struct sockaddr_un un;
146 memset(&un, 0, sizeof(struct sockaddr_un));
147 un.sun_family = AF_UNIX;
148 strcpy(un.sun_path, "/dev/socket/logdw");
149
150 if (TEMP_FAILURE_RETRY(connect(i, (struct sockaddr *)&un,
151 sizeof(struct sockaddr_un))) < 0) {
152 ret = -errno;
153 close(i);
154 } else {
155 logd_fd = i;
156 }
Mark Salyzyn8245af12014-03-25 13:45:33 -0700157 }
158 }
Mark Salyzyn8245af12014-03-25 13:45:33 -0700159#endif
160
161 return ret;
162}
163
Mark Salyzyn53016d82015-02-04 12:28:47 -0800164static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800165{
166 ssize_t ret;
Mark Salyzyn8245af12014-03-25 13:45:33 -0700167#if FAKE_LOG_DEVICE
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800168 int log_fd;
169
170 if (/*(int)log_id >= 0 &&*/ (int)log_id < (int)LOG_ID_MAX) {
171 log_fd = log_fds[(int)log_id];
172 } else {
Mark Salyzyn8245af12014-03-25 13:45:33 -0700173 return -EBADF;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800174 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800175 do {
Mark Salyzyn154f4602014-02-20 14:59:07 -0800176 ret = fakeLogWritev(log_fd, vec, nr);
Mark Salyzyn8245af12014-03-25 13:45:33 -0700177 if (ret < 0) {
178 ret = -errno;
179 }
180 } while (ret == -EINTR);
Mark Salyzyn154f4602014-02-20 14:59:07 -0800181#else
Mark Salyzynd91ab582014-12-15 10:52:12 -0800182 static const unsigned header_length = 2;
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700183 struct iovec newVec[nr + header_length];
Mark Salyzynd91ab582014-12-15 10:52:12 -0800184 android_log_header_t header;
185 android_pmsg_log_header_t pmsg_header;
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700186 struct timespec ts;
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700187 size_t i, payload_size;
Mark Salyzyn076ba812014-05-29 17:53:41 -0700188 static uid_t last_uid = AID_ROOT; /* logd *always* starts up as AID_ROOT */
Mark Salyzynd91ab582014-12-15 10:52:12 -0800189 static pid_t last_pid = (pid_t) -1;
Mark Salyzynd45d36e2015-02-12 15:14:26 -0800190 static atomic_int_fast32_t dropped;
Mark Salyzyn083b0372015-12-04 10:59:45 -0800191 static atomic_int_fast32_t dropped_security;
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700192
Mark Salyzyn31f7df52015-03-13 15:57:11 -0700193 if (!nr) {
194 return -EINVAL;
195 }
196
Mark Salyzyn076ba812014-05-29 17:53:41 -0700197 if (last_uid == AID_ROOT) { /* have we called to get the UID yet? */
198 last_uid = getuid();
199 }
Mark Salyzynd91ab582014-12-15 10:52:12 -0800200 if (last_pid == (pid_t) -1) {
201 last_pid = getpid();
Mark Salyzyn154f4602014-02-20 14:59:07 -0800202 }
Mark Salyzyn083b0372015-12-04 10:59:45 -0800203 if (log_id == LOG_ID_SECURITY) {
Mark Salyzyna0140042015-03-13 06:50:32 -0700204 if (vec[0].iov_len < 4) {
205 return -EINVAL;
206 }
Mark Salyzyn083b0372015-12-04 10:59:45 -0800207 if ((last_uid != AID_SYSTEM) && (last_uid != AID_ROOT)) {
208 uid_t uid = geteuid();
209 if ((uid != AID_SYSTEM) && (uid != AID_ROOT)) {
210 gid_t gid = getgid();
211 if ((gid != AID_SYSTEM) && (gid != AID_ROOT)) {
212 gid = getegid();
213 if ((gid != AID_SYSTEM) && (gid != AID_ROOT)) {
214 return -EPERM;
215 }
216 }
217 }
218 }
219 if (!__android_log_security()) {
Mark Salyzyna0140042015-03-13 06:50:32 -0700220 atomic_store(&dropped_security, 0);
221 return -EPERM;
222 }
223 } else if (log_id == LOG_ID_EVENTS) {
Mark Salyzyna0140042015-03-13 06:50:32 -0700224 if (vec[0].iov_len < 4) {
225 return -EINVAL;
226 }
Mark Salyzyn6aa21b22015-12-22 15:50:14 -0800227 if (((uint32_t *)vec[0].iov_base)[0] != htole32(SNET_EVENT_LOG_TAG)) {
228 static atomic_uintptr_t map;
229 int ret;
230 const char *tag = NULL;
231 EventTagMap *m, *f = NULL;
Mark Salyzyna0140042015-03-13 06:50:32 -0700232
Mark Salyzyn6aa21b22015-12-22 15:50:14 -0800233 m = (EventTagMap *)atomic_load(&map);
Mark Salyzyna0140042015-03-13 06:50:32 -0700234 if (!m) {
Mark Salyzyn6aa21b22015-12-22 15:50:14 -0800235 ret = trylock();
236 m = (EventTagMap *)atomic_load(&map); /* trylock flush cache */
237 if (!m) {
238 m = android_openEventTagMap(EVENT_TAG_MAP_FILE);
239 if (ret) { /* trylock failed, local copy, mark for close */
240 f = m;
241 } else {
242 if (!m) { /* One chance to open map file */
243 m = (EventTagMap *)(uintptr_t)-1LL;
244 }
245 atomic_store(&map, (uintptr_t)m);
Mark Salyzyna0140042015-03-13 06:50:32 -0700246 }
Mark Salyzyn6aa21b22015-12-22 15:50:14 -0800247 }
248 if (!ret) { /* trylock succeeded, unlock */
249 unlock();
Mark Salyzyna0140042015-03-13 06:50:32 -0700250 }
251 }
Mark Salyzyn6aa21b22015-12-22 15:50:14 -0800252 if (m && (m != (EventTagMap *)(uintptr_t)-1LL)) {
253 tag = android_lookupEventTag(
Mark Salyzyna0140042015-03-13 06:50:32 -0700254 m,
255 htole32(((uint32_t *)vec[0].iov_base)[0]));
Mark Salyzyn6aa21b22015-12-22 15:50:14 -0800256 }
257 ret = __android_log_is_loggable(ANDROID_LOG_INFO,
258 tag,
259 ANDROID_LOG_VERBOSE);
260 if (f) { /* local copy marked for close */
261 android_closeEventTagMap(f);
262 }
263 if (!ret) {
264 return -EPERM;
265 }
Mark Salyzyna0140042015-03-13 06:50:32 -0700266 }
267 } else {
268 /* Validate the incoming tag, tag content can not split across iovec */
269 char prio = ANDROID_LOG_VERBOSE;
270 const char *tag = vec[0].iov_base;
271 size_t len = vec[0].iov_len;
272 if (!tag) {
273 len = 0;
274 }
275 if (len > 0) {
276 prio = *tag;
277 if (len > 1) {
278 --len;
279 ++tag;
280 } else {
281 len = vec[1].iov_len;
282 tag = ((const char *)vec[1].iov_base);
283 if (!tag) {
284 len = 0;
285 }
286 }
287 }
288 /* tag must be nul terminated */
289 if (strnlen(tag, len) >= len) {
290 tag = NULL;
291 }
292
293 if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
Mark Salyzyn083b0372015-12-04 10:59:45 -0800294 return -EPERM;
295 }
296 }
Mark Salyzyna0140042015-03-13 06:50:32 -0700297
Mark Salyzynb992d0d2014-03-20 16:09:38 -0700298 /*
299 * struct {
Mark Salyzyn53016d82015-02-04 12:28:47 -0800300 * // what we provide to pstore
Mark Salyzynd91ab582014-12-15 10:52:12 -0800301 * android_pmsg_log_header_t pmsg_header;
302 * // what we provide to socket
Mark Salyzyn7a809402015-01-16 13:38:07 -0800303 * android_log_header_t header;
Mark Salyzynb992d0d2014-03-20 16:09:38 -0700304 * // caller provides
305 * union {
306 * struct {
307 * char prio;
308 * char payload[];
309 * } string;
310 * struct {
311 * uint32_t tag
312 * char payload[];
313 * } binary;
314 * };
315 * };
316 */
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700317
Mark Salyzynba7a9a02015-12-01 15:57:25 -0800318 clock_gettime(android_log_clockid(), &ts);
Mark Salyzyn076ba812014-05-29 17:53:41 -0700319
Mark Salyzynd91ab582014-12-15 10:52:12 -0800320 pmsg_header.magic = LOGGER_MAGIC;
321 pmsg_header.len = sizeof(pmsg_header) + sizeof(header);
322 pmsg_header.uid = last_uid;
323 pmsg_header.pid = last_pid;
324
Mark Salyzyn7a809402015-01-16 13:38:07 -0800325 header.tid = gettid();
326 header.realtime.tv_sec = ts.tv_sec;
327 header.realtime.tv_nsec = ts.tv_nsec;
Mark Salyzyn154f4602014-02-20 14:59:07 -0800328
Mark Salyzynd91ab582014-12-15 10:52:12 -0800329 newVec[0].iov_base = (unsigned char *) &pmsg_header;
330 newVec[0].iov_len = sizeof(pmsg_header);
331 newVec[1].iov_base = (unsigned char *) &header;
332 newVec[1].iov_len = sizeof(header);
Mark Salyzyn154f4602014-02-20 14:59:07 -0800333
Mark Salyzynd45d36e2015-02-12 15:14:26 -0800334 if (logd_fd > 0) {
Mark Salyzyn083b0372015-12-04 10:59:45 -0800335 int32_t snapshot = atomic_exchange_explicit(&dropped_security, 0,
336 memory_order_relaxed);
337 if (snapshot) {
338 android_log_event_int_t buffer;
339
340 header.id = LOG_ID_SECURITY;
341 buffer.header.tag = htole32(LIBLOG_LOG_TAG);
342 buffer.payload.type = EVENT_TYPE_INT;
343 buffer.payload.data = htole32(snapshot);
344
345 newVec[2].iov_base = &buffer;
346 newVec[2].iov_len = sizeof(buffer);
347
348 ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, 2));
349 if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
350 atomic_fetch_add_explicit(&dropped_security, snapshot,
351 memory_order_relaxed);
352 }
353 }
354 snapshot = atomic_exchange_explicit(&dropped, 0, memory_order_relaxed);
Mark Salyzyna0140042015-03-13 06:50:32 -0700355 if (snapshot && __android_log_is_loggable(ANDROID_LOG_INFO,
356 "liblog",
357 ANDROID_LOG_VERBOSE)) {
Mark Salyzynd45d36e2015-02-12 15:14:26 -0800358 android_log_event_int_t buffer;
359
360 header.id = LOG_ID_EVENTS;
361 buffer.header.tag = htole32(LIBLOG_LOG_TAG);
362 buffer.payload.type = EVENT_TYPE_INT;
363 buffer.payload.data = htole32(snapshot);
364
365 newVec[2].iov_base = &buffer;
366 newVec[2].iov_len = sizeof(buffer);
367
368 ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, 2));
369 if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
Mark Salyzyn083b0372015-12-04 10:59:45 -0800370 atomic_fetch_add_explicit(&dropped, snapshot,
371 memory_order_relaxed);
Mark Salyzynd45d36e2015-02-12 15:14:26 -0800372 }
373 }
374 }
375
376 header.id = log_id;
377
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700378 for (payload_size = 0, i = header_length; i < nr + header_length; i++) {
379 newVec[i].iov_base = vec[i - header_length].iov_base;
380 payload_size += newVec[i].iov_len = vec[i - header_length].iov_len;
381
382 if (payload_size > LOGGER_ENTRY_MAX_PAYLOAD) {
383 newVec[i].iov_len -= payload_size - LOGGER_ENTRY_MAX_PAYLOAD;
384 if (newVec[i].iov_len) {
385 ++i;
386 }
Mark Salyzynd91ab582014-12-15 10:52:12 -0800387 payload_size = LOGGER_ENTRY_MAX_PAYLOAD;
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700388 break;
389 }
Mark Salyzyn154f4602014-02-20 14:59:07 -0800390 }
Mark Salyzynd91ab582014-12-15 10:52:12 -0800391 pmsg_header.len += payload_size;
392
393 if (pstore_fd >= 0) {
394 TEMP_FAILURE_RETRY(writev(pstore_fd, newVec, i));
395 }
396
397 if (last_uid == AID_LOGD) { /* logd, after initialization and priv drop */
398 /*
399 * ignore log messages we send to ourself (logd).
400 * Such log messages are often generated by libraries we depend on
401 * which use standard Android logging.
402 */
403 return 0;
404 }
405
406 if (logd_fd < 0) {
407 return -EBADF;
408 }
Mark Salyzyn154f4602014-02-20 14:59:07 -0800409
Mark Salyzyn8245af12014-03-25 13:45:33 -0700410 /*
411 * The write below could be lost, but will never block.
412 *
Mark Salyzynd91ab582014-12-15 10:52:12 -0800413 * To logd, we drop the pmsg_header
414 *
Mark Salyzyn8245af12014-03-25 13:45:33 -0700415 * ENOTCONN occurs if logd dies.
416 * EAGAIN occurs if logd is overloaded.
417 */
Mark Salyzynd91ab582014-12-15 10:52:12 -0800418 ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, i - 1));
Mark Salyzyn8245af12014-03-25 13:45:33 -0700419 if (ret < 0) {
420 ret = -errno;
421 if (ret == -ENOTCONN) {
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -0800422 lock();
Mark Salyzyn0d00a442015-03-13 12:15:57 -0700423 close(logd_fd);
424 logd_fd = -1;
Mark Salyzyn8245af12014-03-25 13:45:33 -0700425 ret = __write_to_log_initialize();
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -0800426 unlock();
Mark Salyzyn8245af12014-03-25 13:45:33 -0700427
428 if (ret < 0) {
429 return ret;
430 }
431
Mark Salyzynd91ab582014-12-15 10:52:12 -0800432 ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, i - 1));
Mark Salyzyn8245af12014-03-25 13:45:33 -0700433 if (ret < 0) {
434 ret = -errno;
435 }
436 }
437 }
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700438
Mark Salyzyn7a809402015-01-16 13:38:07 -0800439 if (ret > (ssize_t)sizeof(header)) {
440 ret -= sizeof(header);
Mark Salyzynd45d36e2015-02-12 15:14:26 -0800441 } else if (ret == -EAGAIN) {
442 atomic_fetch_add_explicit(&dropped, 1, memory_order_relaxed);
Mark Salyzyn083b0372015-12-04 10:59:45 -0800443 if (log_id == LOG_ID_SECURITY) {
444 atomic_fetch_add_explicit(&dropped_security, 1,
445 memory_order_relaxed);
446 }
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700447 }
Mark Salyzyn154f4602014-02-20 14:59:07 -0800448#endif
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700449
450 return ret;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800451}
452
Mark Salyzyn154f4602014-02-20 14:59:07 -0800453#if FAKE_LOG_DEVICE
454static const char *LOG_NAME[LOG_ID_MAX] = {
455 [LOG_ID_MAIN] = "main",
456 [LOG_ID_RADIO] = "radio",
457 [LOG_ID_EVENTS] = "events",
Mark Salyzyn99f47a92014-04-07 14:58:08 -0700458 [LOG_ID_SYSTEM] = "system",
Mark Salyzyn440e1092014-10-10 15:13:15 -0700459 [LOG_ID_CRASH] = "crash",
Mark Salyzyn083b0372015-12-04 10:59:45 -0800460 [LOG_ID_SECURITY] = "security",
Mark Salyzyn440e1092014-10-10 15:13:15 -0700461 [LOG_ID_KERNEL] = "kernel",
Mark Salyzyn154f4602014-02-20 14:59:07 -0800462};
463
Adam Lesinskia1ac84c2014-10-20 12:31:30 -0700464const char *android_log_id_to_name(log_id_t log_id)
Mark Salyzyn154f4602014-02-20 14:59:07 -0800465{
466 if (log_id >= LOG_ID_MAX) {
467 log_id = LOG_ID_MAIN;
468 }
469 return LOG_NAME[log_id];
470}
471#endif
472
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800473static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr)
474{
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -0800475 lock();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800476
477 if (write_to_log == __write_to_log_init) {
Mark Salyzyn8245af12014-03-25 13:45:33 -0700478 int ret;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800479
Mark Salyzyn8245af12014-03-25 13:45:33 -0700480 ret = __write_to_log_initialize();
481 if (ret < 0) {
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -0800482 unlock();
Mark Salyzyn0d00a442015-03-13 12:15:57 -0700483#if (FAKE_LOG_DEVICE == 0)
484 if (pstore_fd >= 0) {
485 __write_to_log_daemon(log_id, vec, nr);
486 }
487#endif
Mark Salyzyn8245af12014-03-25 13:45:33 -0700488 return ret;
489 }
490
Mark Salyzyn53016d82015-02-04 12:28:47 -0800491 write_to_log = __write_to_log_daemon;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800492 }
493
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -0800494 unlock();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800495
496 return write_to_log(log_id, vec, nr);
497}
498
499int __android_log_write(int prio, const char *tag, const char *msg)
500{
Dan Albertc7aadc42015-04-02 10:32:44 -0700501 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800502}
503
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800504int __android_log_buf_write(int bufID, int prio, const char *tag, const char *msg)
505{
506 struct iovec vec[3];
Wink Saville3761e962012-11-28 12:20:19 -0800507 char tmp_tag[32];
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800508
509 if (!tag)
510 tag = "";
511
512 /* XXX: This needs to go! */
Wink Saville3761e962012-11-28 12:20:19 -0800513 if ((bufID != LOG_ID_RADIO) &&
514 (!strcmp(tag, "HTC_RIL") ||
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800515 !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */
Jeff Sharkey84dcf092012-08-13 11:27:30 -0700516 !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800517 !strcmp(tag, "AT") ||
518 !strcmp(tag, "GSM") ||
519 !strcmp(tag, "STK") ||
520 !strcmp(tag, "CDMA") ||
521 !strcmp(tag, "PHONE") ||
Wink Saville3761e962012-11-28 12:20:19 -0800522 !strcmp(tag, "SMS"))) {
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800523 bufID = LOG_ID_RADIO;
Mark Salyzyn8245af12014-03-25 13:45:33 -0700524 /* Inform third party apps/ril/radio.. to use Rlog or RLOG */
Wink Saville3761e962012-11-28 12:20:19 -0800525 snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);
526 tag = tmp_tag;
527 }
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800528
Dan Albertc7aadc42015-04-02 10:32:44 -0700529#if __BIONIC__
530 if (prio == ANDROID_LOG_FATAL) {
531 android_set_abort_message(msg);
532 }
533#endif
534
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800535 vec[0].iov_base = (unsigned char *) &prio;
536 vec[0].iov_len = 1;
537 vec[1].iov_base = (void *) tag;
538 vec[1].iov_len = strlen(tag) + 1;
539 vec[2].iov_base = (void *) msg;
540 vec[2].iov_len = strlen(msg) + 1;
541
542 return write_to_log(bufID, vec, 3);
543}
544
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800545int __android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap)
546{
Chris Pearson19299902010-06-02 16:25:35 -0700547 char buf[LOG_BUF_SIZE];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800548
549 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
550
551 return __android_log_write(prio, tag, buf);
552}
553
554int __android_log_print(int prio, const char *tag, const char *fmt, ...)
555{
556 va_list ap;
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800557 char buf[LOG_BUF_SIZE];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800558
559 va_start(ap, fmt);
560 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
561 va_end(ap);
562
563 return __android_log_write(prio, tag, buf);
564}
565
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800566int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...)
567{
568 va_list ap;
569 char buf[LOG_BUF_SIZE];
570
571 va_start(ap, fmt);
572 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
573 va_end(ap);
574
575 return __android_log_buf_write(bufID, prio, tag, buf);
576}
577
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800578void __android_log_assert(const char *cond, const char *tag,
Mark Salyzyncf4aa032013-11-22 07:54:30 -0800579 const char *fmt, ...)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800580{
Chris Pearson19299902010-06-02 16:25:35 -0700581 char buf[LOG_BUF_SIZE];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800582
Chris Pearson19299902010-06-02 16:25:35 -0700583 if (fmt) {
584 va_list ap;
585 va_start(ap, fmt);
586 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
587 va_end(ap);
588 } else {
589 /* Msg not provided, log condition. N.B. Do not use cond directly as
590 * format string as it could contain spurious '%' syntax (e.g.
591 * "%d" in "blocks%devs == 0").
592 */
593 if (cond)
594 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
595 else
596 strcpy(buf, "Unspecified assertion failed");
597 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800598
599 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
Elliott Hughes02ff4b82015-03-07 11:21:37 -0800600 abort(); /* abort so we have a chance to debug the situation */
Elliott Hughesda6b2e22014-04-23 14:57:32 -0700601 /* NOTREACHED */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800602}
603
604int __android_log_bwrite(int32_t tag, const void *payload, size_t len)
605{
606 struct iovec vec[2];
607
608 vec[0].iov_base = &tag;
609 vec[0].iov_len = sizeof(tag);
610 vec[1].iov_base = (void*)payload;
611 vec[1].iov_len = len;
612
613 return write_to_log(LOG_ID_EVENTS, vec, 2);
614}
615
Mark Salyzyn083b0372015-12-04 10:59:45 -0800616int __android_log_security_bwrite(int32_t tag, const void *payload, size_t len)
617{
618 struct iovec vec[2];
619
620 vec[0].iov_base = &tag;
621 vec[0].iov_len = sizeof(tag);
622 vec[1].iov_base = (void*)payload;
623 vec[1].iov_len = len;
624
625 return write_to_log(LOG_ID_SECURITY, vec, 2);
626}
627
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800628/*
629 * Like __android_log_bwrite, but takes the type as well. Doesn't work
630 * for the general case where we're generating lists of stuff, but very
631 * handy if we just want to dump an integer into the log.
632 */
633int __android_log_btwrite(int32_t tag, char type, const void *payload,
Mark Salyzyn154f4602014-02-20 14:59:07 -0800634 size_t len)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800635{
636 struct iovec vec[3];
637
638 vec[0].iov_base = &tag;
639 vec[0].iov_len = sizeof(tag);
640 vec[1].iov_base = &type;
641 vec[1].iov_len = sizeof(type);
642 vec[2].iov_base = (void*)payload;
643 vec[2].iov_len = len;
644
645 return write_to_log(LOG_ID_EVENTS, vec, 3);
646}
Nick Kralevich2a4d05a2014-07-01 10:57:16 -0700647
648/*
649 * Like __android_log_bwrite, but used for writing strings to the
650 * event log.
651 */
652int __android_log_bswrite(int32_t tag, const char *payload)
653{
654 struct iovec vec[4];
655 char type = EVENT_TYPE_STRING;
656 uint32_t len = strlen(payload);
657
658 vec[0].iov_base = &tag;
659 vec[0].iov_len = sizeof(tag);
660 vec[1].iov_base = &type;
661 vec[1].iov_len = sizeof(type);
662 vec[2].iov_base = &len;
663 vec[2].iov_len = sizeof(len);
664 vec[3].iov_base = (void*)payload;
665 vec[3].iov_len = len;
666
667 return write_to_log(LOG_ID_EVENTS, vec, 4);
668}