diff options
author | Mark Salyzyn <salyzyn@google.com> | 2014-12-15 10:52:12 -0800 |
---|---|---|
committer | Mark Salyzyn <salyzyn@google.com> | 2015-01-23 23:33:31 +0000 |
commit | d91ab5815d21ac89019e5590ff206a41336cc67e (patch) | |
tree | c8924c30ce17573e7f616b1058616b506a575634 /liblog | |
parent | 69bdba21f6915735c15aa4ba9ad33b9048d7032d (diff) | |
download | system_core-d91ab5815d21ac89019e5590ff206a41336cc67e.zip system_core-d91ab5815d21ac89019e5590ff206a41336cc67e.tar.gz system_core-d91ab5815d21ac89019e5590ff206a41336cc67e.tar.bz2 |
liblog: add pstore write
Used to push the Android log messages into pstore
(when available, and no propagation of error).
Change-Id: I9def8cf796d35d347f502d9745d5f42ec1200253
Diffstat (limited to 'liblog')
-rw-r--r-- | liblog/logd_write.c | 67 |
1 files changed, 48 insertions, 19 deletions
diff --git a/liblog/logd_write.c b/liblog/logd_write.c index 3d847f1..1e9b591 100644 --- a/liblog/logd_write.c +++ b/liblog/logd_write.c @@ -62,6 +62,7 @@ static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER; static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1, -1 }; #else static int logd_fd = -1; +static int pstore_fd = -1; #endif /* @@ -110,6 +111,12 @@ static int __write_to_log_initialize() logd_fd = -1; close(i); } + if (pstore_fd >= 0) { + i = pstore_fd; + pstore_fd = -1; + close(i); + } + pstore_fd = open("/dev/pmsg0", O_WRONLY); i = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (i < 0) { @@ -156,32 +163,26 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr) } } while (ret == -EINTR); #else - static const unsigned header_length = 1; + static const unsigned header_length = 2; struct iovec newVec[nr + header_length]; - struct android_log_header_t header; + android_log_header_t header; + android_pmsg_log_header_t pmsg_header; struct timespec ts; size_t i, payload_size; static uid_t last_uid = AID_ROOT; /* logd *always* starts up as AID_ROOT */ + static pid_t last_pid = (pid_t) -1; if (last_uid == AID_ROOT) { /* have we called to get the UID yet? */ last_uid = getuid(); } - if (last_uid == AID_LOGD) { /* logd, after initialization and priv drop */ - /* - * ignore log messages we send to ourself (logd). - * Such log messages are often generated by libraries we depend on - * which use standard Android logging. - */ - return 0; - } - - if (logd_fd < 0) { - return -EBADF; + if (last_pid == (pid_t) -1) { + last_pid = getpid(); } - /* * struct { - * // what we provide + * // whate we provire to pstore + * android_pmsg_log_header_t pmsg_header; + * // what we provide to socket * android_log_header_t header; * // caller provides * union { @@ -199,13 +200,20 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr) clock_gettime(CLOCK_REALTIME, &ts); + pmsg_header.magic = LOGGER_MAGIC; + pmsg_header.len = sizeof(pmsg_header) + sizeof(header); + pmsg_header.uid = last_uid; + pmsg_header.pid = last_pid; + header.id = log_id; header.tid = gettid(); header.realtime.tv_sec = ts.tv_sec; header.realtime.tv_nsec = ts.tv_nsec; - newVec[0].iov_base = (unsigned char *) &header; - newVec[0].iov_len = sizeof(header); + newVec[0].iov_base = (unsigned char *) &pmsg_header; + newVec[0].iov_len = sizeof(pmsg_header); + newVec[1].iov_base = (unsigned char *) &header; + newVec[1].iov_len = sizeof(header); for (payload_size = 0, i = header_length; i < nr + header_length; i++) { newVec[i].iov_base = vec[i - header_length].iov_base; @@ -216,17 +224,38 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr) if (newVec[i].iov_len) { ++i; } + payload_size = LOGGER_ENTRY_MAX_PAYLOAD; break; } } + pmsg_header.len += payload_size; + + if (pstore_fd >= 0) { + TEMP_FAILURE_RETRY(writev(pstore_fd, newVec, i)); + } + + if (last_uid == AID_LOGD) { /* logd, after initialization and priv drop */ + /* + * ignore log messages we send to ourself (logd). + * Such log messages are often generated by libraries we depend on + * which use standard Android logging. + */ + return 0; + } + + if (logd_fd < 0) { + return -EBADF; + } /* * The write below could be lost, but will never block. * + * To logd, we drop the pmsg_header + * * ENOTCONN occurs if logd dies. * EAGAIN occurs if logd is overloaded. */ - ret = writev(logd_fd, newVec, i); + ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, i - 1)); if (ret < 0) { ret = -errno; if (ret == -ENOTCONN) { @@ -242,7 +271,7 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr) return ret; } - ret = writev(logd_fd, newVec, i); + ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, i - 1)); if (ret < 0) { ret = -errno; } |