summaryrefslogtreecommitdiffstats
path: root/liblog
diff options
context:
space:
mode:
authorMark Salyzyn <salyzyn@google.com>2014-12-15 10:52:12 -0800
committerMark Salyzyn <salyzyn@google.com>2015-01-23 23:33:31 +0000
commitd91ab5815d21ac89019e5590ff206a41336cc67e (patch)
treec8924c30ce17573e7f616b1058616b506a575634 /liblog
parent69bdba21f6915735c15aa4ba9ad33b9048d7032d (diff)
downloadsystem_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.c67
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;
}