am 91581f19: Merge "liblog: add pstore write"

* commit '91581f19906ade01eabc6e10a7dac209e710117a':
  liblog: add pstore write
This commit is contained in:
Mark Salyzyn 2015-01-23 23:59:45 +00:00 committed by Android Git Automerger
commit 982421df45
2 changed files with 59 additions and 20 deletions

View file

@ -24,7 +24,17 @@
#include <log/log.h> #include <log/log.h>
#include <log/log_read.h> #include <log/log_read.h>
/* Header Structure to logd */ #define LOGGER_MAGIC 'l'
/* Header Structure to pstore */
typedef struct __attribute__((__packed__)) {
uint8_t magic;
uint16_t len;
uint16_t uid;
uint16_t pid;
} android_pmsg_log_header_t;
/* Header Structure to logd, and second header for pstore */
typedef struct __attribute__((__packed__)) { typedef struct __attribute__((__packed__)) {
typeof_log_id_t id; typeof_log_id_t id;
uint16_t tid; uint16_t tid;

View file

@ -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 }; static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1, -1 };
#else #else
static int logd_fd = -1; static int logd_fd = -1;
static int pstore_fd = -1;
#endif #endif
/* /*
@ -110,6 +111,12 @@ static int __write_to_log_initialize()
logd_fd = -1; logd_fd = -1;
close(i); 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); i = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (i < 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); } while (ret == -EINTR);
#else #else
static const unsigned header_length = 1; static const unsigned header_length = 2;
struct iovec newVec[nr + header_length]; 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; struct timespec ts;
size_t i, payload_size; size_t i, payload_size;
static uid_t last_uid = AID_ROOT; /* logd *always* starts up as AID_ROOT */ 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? */ if (last_uid == AID_ROOT) { /* have we called to get the UID yet? */
last_uid = getuid(); last_uid = getuid();
} }
if (last_uid == AID_LOGD) { /* logd, after initialization and priv drop */ if (last_pid == (pid_t) -1) {
/* last_pid = getpid();
* 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;
}
/* /*
* struct { * 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; * android_log_header_t header;
* // caller provides * // caller provides
* union { * 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); 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.id = log_id;
header.tid = gettid(); header.tid = gettid();
header.realtime.tv_sec = ts.tv_sec; header.realtime.tv_sec = ts.tv_sec;
header.realtime.tv_nsec = ts.tv_nsec; header.realtime.tv_nsec = ts.tv_nsec;
newVec[0].iov_base = (unsigned char *) &header; newVec[0].iov_base = (unsigned char *) &pmsg_header;
newVec[0].iov_len = sizeof(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++) { for (payload_size = 0, i = header_length; i < nr + header_length; i++) {
newVec[i].iov_base = vec[i - header_length].iov_base; 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) { if (newVec[i].iov_len) {
++i; ++i;
} }
payload_size = LOGGER_ENTRY_MAX_PAYLOAD;
break; 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. * The write below could be lost, but will never block.
* *
* To logd, we drop the pmsg_header
*
* ENOTCONN occurs if logd dies. * ENOTCONN occurs if logd dies.
* EAGAIN occurs if logd is overloaded. * 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) { if (ret < 0) {
ret = -errno; ret = -errno;
if (ret == -ENOTCONN) { 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; return ret;
} }
ret = writev(logd_fd, newVec, i); ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, i - 1));
if (ret < 0) { if (ret < 0) {
ret = -errno; ret = -errno;
} }