Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d91ab581 authored by Mark Salyzyn's avatar Mark Salyzyn
Browse files

liblog: add pstore write

Used to push the Android log messages into pstore
(when available, and no propagation of error).

Change-Id: I9def8cf796d35d347f502d9745d5f42ec1200253
parent 69bdba21
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -24,7 +24,17 @@
#include <log/log.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__)) {
    typeof_log_id_t id;
    uint16_t tid;
+48 −19
Original line number Diff line number Diff line
@@ -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;
            }