Merge "liblog: remove LOGGER_LOCAL"
This commit is contained in:
commit
37b5edf61b
13 changed files with 15 additions and 662 deletions
|
@ -17,7 +17,6 @@
|
|||
liblog_sources = [
|
||||
"config_read.c",
|
||||
"config_write.c",
|
||||
"local_logger.c",
|
||||
"log_event_list.c",
|
||||
"log_event_write.c",
|
||||
"log_ratelimit.cpp",
|
||||
|
|
|
@ -145,10 +145,9 @@ that was used when opening the sub-log. It is recommended to open the log `ANDR
|
|||
these cases.
|
||||
|
||||
`android_set_log_transport()` selects transport filters. Argument is either `LOGGER_DEFAULT`,
|
||||
`LOGGER_LOGD`, `LOGGER_NULL` or `LOGGER_LOCAL`. Log to logger daemon for default or logd, drop
|
||||
contents on floor, or log into local memory respectively. `Both android_set_log_transport()` and
|
||||
`android_get_log_transport()` return the current transport mask, or a negative errno for any
|
||||
problems.
|
||||
`LOGGER_LOGD`, or `LOGGER_NULL`. Log to logger daemon for default or logd, or drop contents on floor
|
||||
respectively. `Both android_set_log_transport()` and `android_get_log_transport()` return the
|
||||
current transport mask, or a negative errno for any problems.
|
||||
|
||||
Errors
|
||||
------
|
||||
|
|
|
@ -55,12 +55,6 @@ static void __android_log_add_transport(
|
|||
}
|
||||
|
||||
LIBLOG_HIDDEN void __android_log_config_read() {
|
||||
if (__android_log_transport & LOGGER_LOCAL) {
|
||||
extern struct android_log_transport_read localLoggerRead;
|
||||
|
||||
__android_log_add_transport(&__android_log_transport_read, &localLoggerRead);
|
||||
}
|
||||
|
||||
#if (FAKE_LOG_DEVICE == 0)
|
||||
if ((__android_log_transport == LOGGER_DEFAULT) ||
|
||||
(__android_log_transport & LOGGER_LOGD)) {
|
||||
|
|
|
@ -55,13 +55,6 @@ static void __android_log_add_transport(
|
|||
}
|
||||
|
||||
LIBLOG_HIDDEN void __android_log_config_write() {
|
||||
if (__android_log_transport & LOGGER_LOCAL) {
|
||||
extern struct android_log_transport_write localLoggerWrite;
|
||||
|
||||
__android_log_add_transport(&__android_log_transport_write,
|
||||
&localLoggerWrite);
|
||||
}
|
||||
|
||||
if ((__android_log_transport == LOGGER_DEFAULT) ||
|
||||
(__android_log_transport & LOGGER_LOGD)) {
|
||||
#if (FAKE_LOG_DEVICE == 0)
|
||||
|
|
|
@ -22,7 +22,7 @@ extern "C" {
|
|||
#define LOGGER_LOGD 0x01
|
||||
#define LOGGER_KERNEL 0x02 /* Reserved/Deprecated */
|
||||
#define LOGGER_NULL 0x04 /* Does not release resources of other selections */
|
||||
#define LOGGER_LOCAL 0x08 /* logs sent to local memory */
|
||||
#define LOGGER_RESERVED 0x08 /* Reserved, previously for logging to local memory */
|
||||
#define LOGGER_STDERR 0x10 /* logs sent to stderr */
|
||||
/* clang-format on */
|
||||
|
||||
|
|
|
@ -1,550 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#if !defined(__MINGW32__)
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#include <log/uio.h>
|
||||
#include <sched.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <cutils/list.h> /* template, no library dependency */
|
||||
#include <log/log_transport.h>
|
||||
#include <private/android_filesystem_config.h>
|
||||
#include <private/android_logger.h>
|
||||
#include <system/thread_defs.h>
|
||||
|
||||
#include "config_read.h"
|
||||
#include "config_write.h"
|
||||
#include "log_portability.h"
|
||||
#include "logger.h"
|
||||
|
||||
static const char baseServiceName[] = "android.logd";
|
||||
|
||||
static int writeToLocalInit();
|
||||
static int writeToLocalAvailable(log_id_t logId);
|
||||
static void writeToLocalReset();
|
||||
static int writeToLocalWrite(log_id_t logId, struct timespec* ts,
|
||||
struct iovec* vec, size_t nr);
|
||||
|
||||
LIBLOG_HIDDEN struct android_log_transport_write localLoggerWrite = {
|
||||
.node = { &localLoggerWrite.node, &localLoggerWrite.node },
|
||||
.context.priv = NULL,
|
||||
.name = "local",
|
||||
.available = writeToLocalAvailable,
|
||||
.open = writeToLocalInit,
|
||||
.close = writeToLocalReset,
|
||||
.write = writeToLocalWrite,
|
||||
};
|
||||
|
||||
static int writeToLocalVersion(struct android_log_logger* logger,
|
||||
struct android_log_transport_context* transp);
|
||||
static int writeToLocalRead(struct android_log_logger_list* logger_list,
|
||||
struct android_log_transport_context* transp,
|
||||
struct log_msg* log_msg);
|
||||
static int writeToLocalPoll(struct android_log_logger_list* logger_list,
|
||||
struct android_log_transport_context* transp);
|
||||
static void writeToLocalClose(struct android_log_logger_list* logger_list,
|
||||
struct android_log_transport_context* transp);
|
||||
static int writeToLocalClear(struct android_log_logger* logger,
|
||||
struct android_log_transport_context* transp);
|
||||
static ssize_t writeToLocalGetSize(struct android_log_logger* logger,
|
||||
struct android_log_transport_context* transp);
|
||||
static ssize_t writeToLocalSetSize(
|
||||
struct android_log_logger* logger,
|
||||
struct android_log_transport_context* transp __unused, size_t size);
|
||||
static ssize_t writeToLocalGetReadbleSize(
|
||||
struct android_log_logger* logger,
|
||||
struct android_log_transport_context* transp);
|
||||
|
||||
struct android_log_transport_read localLoggerRead = {
|
||||
.node = { &localLoggerRead.node, &localLoggerRead.node },
|
||||
.name = "local",
|
||||
.available = writeToLocalAvailable,
|
||||
.version = writeToLocalVersion,
|
||||
.read = writeToLocalRead,
|
||||
.poll = writeToLocalPoll,
|
||||
.close = writeToLocalClose,
|
||||
.clear = writeToLocalClear,
|
||||
.getSize = writeToLocalGetSize,
|
||||
.setSize = writeToLocalSetSize,
|
||||
.getReadableSize = writeToLocalGetReadbleSize,
|
||||
.getPrune = NULL,
|
||||
.setPrune = NULL,
|
||||
.getStats = NULL,
|
||||
};
|
||||
|
||||
struct LogBufferElement {
|
||||
struct listnode node;
|
||||
log_id_t logId;
|
||||
pid_t tid;
|
||||
log_time timestamp;
|
||||
unsigned short len;
|
||||
char msg[];
|
||||
};
|
||||
|
||||
static const size_t MAX_SIZE_DEFAULT = 32768;
|
||||
|
||||
/*
|
||||
* Number of log buffers we support with the following assumption:
|
||||
* . . .
|
||||
* LOG_ID_SECURITY = 5, // security logs go to the system logs only
|
||||
* LOG_ID_KERNEL = 6, // place last, third-parties can not use it
|
||||
* LOG_ID_MAX
|
||||
* } log_id_t;
|
||||
*
|
||||
* Confirm the following should <log/log_id.h> be adjusted in the future.
|
||||
*/
|
||||
#define NUMBER_OF_LOG_BUFFERS \
|
||||
((LOG_ID_SECURITY == (LOG_ID_MAX - 2)) ? LOG_ID_SECURITY : LOG_ID_KERNEL)
|
||||
#define BLOCK_LOG_BUFFERS(id) \
|
||||
(((id) == LOG_ID_SECURITY) || ((id) == LOG_ID_KERNEL))
|
||||
|
||||
static struct LogBuffer {
|
||||
struct listnode head;
|
||||
pthread_rwlock_t listLock;
|
||||
char* serviceName; /* Also indicates ready by having a value */
|
||||
/* Order and proximity important for memset */
|
||||
size_t number[NUMBER_OF_LOG_BUFFERS]; /* clear memset */
|
||||
size_t size[NUMBER_OF_LOG_BUFFERS]; /* clear memset */
|
||||
size_t totalSize[NUMBER_OF_LOG_BUFFERS]; /* init memset */
|
||||
size_t maxSize[NUMBER_OF_LOG_BUFFERS]; /* init MAX_SIZE_DEFAULT */
|
||||
struct listnode* last[NUMBER_OF_LOG_BUFFERS]; /* init &head */
|
||||
} logbuf = {
|
||||
.head = { &logbuf.head, &logbuf.head }, .listLock = PTHREAD_RWLOCK_INITIALIZER,
|
||||
};
|
||||
|
||||
static void LogBufferInit(struct LogBuffer* log) {
|
||||
size_t i;
|
||||
|
||||
pthread_rwlock_wrlock(&log->listLock);
|
||||
list_init(&log->head);
|
||||
memset(log->number, 0,
|
||||
sizeof(log->number) + sizeof(log->size) + sizeof(log->totalSize));
|
||||
for (i = 0; i < NUMBER_OF_LOG_BUFFERS; ++i) {
|
||||
log->maxSize[i] = MAX_SIZE_DEFAULT;
|
||||
log->last[i] = &log->head;
|
||||
}
|
||||
#ifdef __BIONIC__
|
||||
asprintf(&log->serviceName, "%s@%d:%d", baseServiceName, __android_log_uid(),
|
||||
getpid());
|
||||
#else
|
||||
char buffer[sizeof(baseServiceName) + 1 + 5 + 1 + 5 + 8];
|
||||
snprintf(buffer, sizeof(buffer), "%s@%d:%d", baseServiceName,
|
||||
__android_log_uid(), getpid());
|
||||
log->serviceName = strdup(buffer);
|
||||
#endif
|
||||
pthread_rwlock_unlock(&log->listLock);
|
||||
}
|
||||
|
||||
static void LogBufferClear(struct LogBuffer* log) {
|
||||
size_t i;
|
||||
struct listnode* node;
|
||||
|
||||
pthread_rwlock_wrlock(&log->listLock);
|
||||
memset(log->number, 0, sizeof(log->number) + sizeof(log->size));
|
||||
for (i = 0; i < NUMBER_OF_LOG_BUFFERS; ++i) {
|
||||
log->last[i] = &log->head;
|
||||
}
|
||||
while ((node = list_head(&log->head)) != &log->head) {
|
||||
struct LogBufferElement* element;
|
||||
|
||||
element = node_to_item(node, struct LogBufferElement, node);
|
||||
list_remove(node);
|
||||
free(element);
|
||||
}
|
||||
pthread_rwlock_unlock(&log->listLock);
|
||||
}
|
||||
|
||||
static inline void LogBufferFree(struct LogBuffer* log) {
|
||||
pthread_rwlock_wrlock(&log->listLock);
|
||||
free(log->serviceName);
|
||||
log->serviceName = NULL;
|
||||
pthread_rwlock_unlock(&log->listLock);
|
||||
LogBufferClear(log);
|
||||
}
|
||||
|
||||
static int LogBufferLog(struct LogBuffer* log,
|
||||
struct LogBufferElement* element) {
|
||||
log_id_t logId = element->logId;
|
||||
|
||||
pthread_rwlock_wrlock(&log->listLock);
|
||||
log->number[logId]++;
|
||||
log->size[logId] += element->len;
|
||||
log->totalSize[logId] += element->len;
|
||||
/* prune entry(s) until enough space is available */
|
||||
if (log->last[logId] == &log->head) {
|
||||
log->last[logId] = list_tail(&log->head);
|
||||
}
|
||||
while (log->size[logId] > log->maxSize[logId]) {
|
||||
struct listnode* node = log->last[logId];
|
||||
struct LogBufferElement* e;
|
||||
struct android_log_logger_list* logger_list;
|
||||
|
||||
e = node_to_item(node, struct LogBufferElement, node);
|
||||
log->number[logId]--;
|
||||
log->size[logId] -= e->len;
|
||||
logger_list_rdlock();
|
||||
logger_list_for_each(logger_list) {
|
||||
struct android_log_transport_context* transp;
|
||||
|
||||
transport_context_for_each(transp, logger_list) {
|
||||
if ((transp->transport == &localLoggerRead) &&
|
||||
(transp->context.node == node)) {
|
||||
if (node == &log->head) {
|
||||
transp->context.node = &log->head;
|
||||
} else {
|
||||
transp->context.node = node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
logger_list_unlock();
|
||||
if (node != &log->head) {
|
||||
log->last[logId] = node->prev;
|
||||
}
|
||||
list_remove(node);
|
||||
LOG_ALWAYS_FATAL_IF(node == log->last[logId], "corrupted list");
|
||||
free(e);
|
||||
}
|
||||
/* add entry to list */
|
||||
list_add_head(&log->head, &element->node);
|
||||
/* ToDo: wake up all readers */
|
||||
pthread_rwlock_unlock(&log->listLock);
|
||||
|
||||
return element->len;
|
||||
}
|
||||
|
||||
/*
|
||||
* return zero if permitted to log directly to logd,
|
||||
* return 1 if binder server started and
|
||||
* return negative error number if failed to start binder server.
|
||||
*/
|
||||
static int writeToLocalInit() {
|
||||
pthread_attr_t attr;
|
||||
struct LogBuffer* log;
|
||||
|
||||
if (writeToLocalAvailable(LOG_ID_MAIN) < 0) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
log = &logbuf;
|
||||
if (!log->serviceName) {
|
||||
LogBufferInit(log);
|
||||
}
|
||||
|
||||
if (!log->serviceName) {
|
||||
LogBufferFree(log);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return EPERM; /* successful local-only logging */
|
||||
}
|
||||
|
||||
static void writeToLocalReset() {
|
||||
LogBufferFree(&logbuf);
|
||||
}
|
||||
|
||||
static int writeToLocalAvailable(log_id_t logId) {
|
||||
#if !defined(__MINGW32__)
|
||||
uid_t uid;
|
||||
#endif
|
||||
|
||||
if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Android hard coded permitted, system goes to logd */
|
||||
#if !defined(__MINGW32__)
|
||||
if (__android_log_transport == LOGGER_DEFAULT) {
|
||||
uid = __android_log_uid();
|
||||
if ((uid < AID_APP) && (getpwuid(uid) != NULL)) {
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ToDo: Ask package manager for LOGD permissions */
|
||||
/* Assume we do _not_ have permissions to go to LOGD, so must go local */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeToLocalWrite(log_id_t logId, struct timespec* ts,
|
||||
struct iovec* vec, size_t nr) {
|
||||
size_t len, i;
|
||||
struct LogBufferElement* element;
|
||||
|
||||
if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
for (i = 0; i < nr; ++i) {
|
||||
len += vec[i].iov_len;
|
||||
}
|
||||
|
||||
if (len > LOGGER_ENTRY_MAX_PAYLOAD) {
|
||||
len = LOGGER_ENTRY_MAX_PAYLOAD;
|
||||
}
|
||||
element = (struct LogBufferElement*)calloc(
|
||||
1, sizeof(struct LogBufferElement) + len + 1);
|
||||
if (!element) {
|
||||
return errno ? -errno : -ENOMEM;
|
||||
}
|
||||
element->timestamp.tv_sec = ts->tv_sec;
|
||||
element->timestamp.tv_nsec = ts->tv_nsec;
|
||||
#ifdef __BIONIC__
|
||||
element->tid = gettid();
|
||||
#else
|
||||
element->tid = getpid();
|
||||
#endif
|
||||
element->logId = logId;
|
||||
element->len = len;
|
||||
|
||||
char* cp = element->msg;
|
||||
for (i = 0; i < nr; ++i) {
|
||||
size_t iov_len = vec[i].iov_len;
|
||||
if (iov_len > len) {
|
||||
iov_len = len;
|
||||
}
|
||||
memcpy(cp, vec[i].iov_base, iov_len);
|
||||
len -= iov_len;
|
||||
if (len == 0) {
|
||||
break;
|
||||
}
|
||||
cp += iov_len;
|
||||
}
|
||||
|
||||
return LogBufferLog(&logbuf, element);
|
||||
}
|
||||
|
||||
static int writeToLocalVersion(struct android_log_logger* logger __unused,
|
||||
struct android_log_transport_context* transp
|
||||
__unused) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* within reader lock, serviceName already validated */
|
||||
static struct listnode* writeToLocalNode(
|
||||
struct android_log_logger_list* logger_list,
|
||||
struct android_log_transport_context* transp) {
|
||||
struct listnode* node;
|
||||
unsigned logMask;
|
||||
unsigned int tail;
|
||||
|
||||
node = transp->context.node;
|
||||
if (node) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (!logger_list->tail) {
|
||||
return transp->context.node = &logbuf.head;
|
||||
}
|
||||
|
||||
logMask = transp->logMask;
|
||||
tail = logger_list->tail;
|
||||
|
||||
for (node = list_head(&logbuf.head); node != &logbuf.head; node = node->next) {
|
||||
struct LogBufferElement* element;
|
||||
log_id_t logId;
|
||||
|
||||
element = node_to_item(node, struct LogBufferElement, node);
|
||||
logId = element->logId;
|
||||
|
||||
if ((logMask & (1 << logId)) && !--tail) {
|
||||
node = node->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return transp->context.node = node;
|
||||
}
|
||||
|
||||
static int writeToLocalRead(struct android_log_logger_list* logger_list,
|
||||
struct android_log_transport_context* transp,
|
||||
struct log_msg* log_msg) {
|
||||
int ret;
|
||||
struct listnode* node;
|
||||
unsigned logMask;
|
||||
|
||||
pthread_rwlock_rdlock(&logbuf.listLock);
|
||||
if (!logbuf.serviceName) {
|
||||
pthread_rwlock_unlock(&logbuf.listLock);
|
||||
return (logger_list->mode & ANDROID_LOG_NONBLOCK) ? -ENODEV : 0;
|
||||
}
|
||||
|
||||
logMask = transp->logMask;
|
||||
|
||||
node = writeToLocalNode(logger_list, transp);
|
||||
|
||||
ret = 0;
|
||||
|
||||
while (node != list_head(&logbuf.head)) {
|
||||
struct LogBufferElement* element;
|
||||
log_id_t logId;
|
||||
|
||||
node = node->prev;
|
||||
element = node_to_item(node, struct LogBufferElement, node);
|
||||
logId = element->logId;
|
||||
|
||||
if (logMask & (1 << logId)) {
|
||||
ret = log_msg->entry_v3.len = element->len;
|
||||
log_msg->entry_v3.hdr_size = sizeof(log_msg->entry_v3);
|
||||
log_msg->entry_v3.pid = getpid();
|
||||
log_msg->entry_v3.tid = element->tid;
|
||||
log_msg->entry_v3.sec = element->timestamp.tv_sec;
|
||||
log_msg->entry_v3.nsec = element->timestamp.tv_nsec;
|
||||
log_msg->entry_v3.lid = logId;
|
||||
memcpy(log_msg->entry_v3.msg, element->msg, ret);
|
||||
ret += log_msg->entry_v3.hdr_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
transp->context.node = node;
|
||||
|
||||
/* ToDo: if blocking, and no entry, put reader to sleep */
|
||||
pthread_rwlock_unlock(&logbuf.listLock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int writeToLocalPoll(struct android_log_logger_list* logger_list,
|
||||
struct android_log_transport_context* transp) {
|
||||
int ret = (logger_list->mode & ANDROID_LOG_NONBLOCK) ? -ENODEV : 0;
|
||||
|
||||
pthread_rwlock_rdlock(&logbuf.listLock);
|
||||
|
||||
if (logbuf.serviceName) {
|
||||
unsigned logMask = transp->logMask;
|
||||
struct listnode* node = writeToLocalNode(logger_list, transp);
|
||||
|
||||
ret = (node != list_head(&logbuf.head));
|
||||
if (ret) {
|
||||
do {
|
||||
ret = !!(logMask &
|
||||
(1 << (node_to_item(node->prev, struct LogBufferElement, node))
|
||||
->logId));
|
||||
} while (!ret && ((node = node->prev) != list_head(&logbuf.head)));
|
||||
}
|
||||
|
||||
transp->context.node = node;
|
||||
}
|
||||
|
||||
pthread_rwlock_unlock(&logbuf.listLock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void writeToLocalClose(struct android_log_logger_list* logger_list
|
||||
__unused,
|
||||
struct android_log_transport_context* transp) {
|
||||
pthread_rwlock_wrlock(&logbuf.listLock);
|
||||
transp->context.node = list_head(&logbuf.head);
|
||||
pthread_rwlock_unlock(&logbuf.listLock);
|
||||
}
|
||||
|
||||
static int writeToLocalClear(struct android_log_logger* logger,
|
||||
struct android_log_transport_context* unused
|
||||
__unused) {
|
||||
log_id_t logId = logger->logId;
|
||||
struct listnode *node, *n;
|
||||
|
||||
if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pthread_rwlock_wrlock(&logbuf.listLock);
|
||||
logbuf.number[logId] = 0;
|
||||
logbuf.last[logId] = &logbuf.head;
|
||||
list_for_each_safe(node, n, &logbuf.head) {
|
||||
struct LogBufferElement* element;
|
||||
element = node_to_item(node, struct LogBufferElement, node);
|
||||
|
||||
if (logId == element->logId) {
|
||||
struct android_log_logger_list* logger_list;
|
||||
|
||||
logger_list_rdlock();
|
||||
logger_list_for_each(logger_list) {
|
||||
struct android_log_transport_context* transp;
|
||||
|
||||
transport_context_for_each(transp, logger_list) {
|
||||
if ((transp->transport == &localLoggerRead) &&
|
||||
(transp->context.node == node)) {
|
||||
transp->context.node = node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
logger_list_unlock();
|
||||
list_remove(node);
|
||||
free(element);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_rwlock_unlock(&logbuf.listLock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t writeToLocalGetSize(struct android_log_logger* logger,
|
||||
struct android_log_transport_context* transp
|
||||
__unused) {
|
||||
ssize_t ret = -EINVAL;
|
||||
log_id_t logId = logger->logId;
|
||||
|
||||
if ((logId < NUMBER_OF_LOG_BUFFERS) && !BLOCK_LOG_BUFFERS(logId)) {
|
||||
pthread_rwlock_rdlock(&logbuf.listLock);
|
||||
ret = logbuf.maxSize[logId];
|
||||
pthread_rwlock_unlock(&logbuf.listLock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t writeToLocalSetSize(
|
||||
struct android_log_logger* logger,
|
||||
struct android_log_transport_context* transp __unused, size_t size) {
|
||||
ssize_t ret = -EINVAL;
|
||||
|
||||
if ((size > LOGGER_ENTRY_MAX_LEN) || (size < (4 * 1024 * 1024))) {
|
||||
log_id_t logId = logger->logId;
|
||||
if ((logId < NUMBER_OF_LOG_BUFFERS) || !BLOCK_LOG_BUFFERS(logId)) {
|
||||
pthread_rwlock_wrlock(&logbuf.listLock);
|
||||
ret = logbuf.maxSize[logId] = size;
|
||||
pthread_rwlock_unlock(&logbuf.listLock);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t writeToLocalGetReadbleSize(
|
||||
struct android_log_logger* logger,
|
||||
struct android_log_transport_context* transp __unused) {
|
||||
ssize_t ret = -EINVAL;
|
||||
log_id_t logId = logger->logId;
|
||||
|
||||
if ((logId < NUMBER_OF_LOG_BUFFERS) && !BLOCK_LOG_BUFFERS(logId)) {
|
||||
pthread_rwlock_rdlock(&logbuf.listLock);
|
||||
ret = logbuf.serviceName ? (ssize_t)logbuf.size[logId] : -EBADF;
|
||||
pthread_rwlock_unlock(&logbuf.listLock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -98,7 +98,6 @@ struct android_log_transport_read {
|
|||
};
|
||||
|
||||
struct android_log_logger_list {
|
||||
struct listnode node;
|
||||
struct listnode logger;
|
||||
struct listnode transport;
|
||||
int mode;
|
||||
|
@ -144,37 +143,6 @@ struct android_log_transport_context {
|
|||
(logp) = \
|
||||
node_to_item((logp)->node.next, struct android_log_logger, node))
|
||||
|
||||
/*
|
||||
* Global list of log readers.
|
||||
*
|
||||
* Usage case: search out transport contexts for all readers
|
||||
*/
|
||||
|
||||
LIBLOG_HIDDEN struct listnode __android_log_readers;
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define logger_list_rdlock()
|
||||
#define logger_list_wrlock()
|
||||
#define logger_list_unlock()
|
||||
#else
|
||||
LIBLOG_HIDDEN pthread_rwlock_t __android_log_readers_lock;
|
||||
|
||||
#define logger_list_rdlock() pthread_rwlock_rdlock(&__android_log_readers_lock)
|
||||
#define logger_list_wrlock() pthread_rwlock_wrlock(&__android_log_readers_lock)
|
||||
#define logger_list_unlock() pthread_rwlock_unlock(&__android_log_readers_lock)
|
||||
#endif
|
||||
|
||||
/* Must be called with logger_list_rdlock() or logger_list_wrlock() held */
|
||||
#define logger_list_for_each(logger_list) \
|
||||
for ((logger_list) = node_to_item(&__android_log_readers, \
|
||||
struct android_log_logger_list, node); \
|
||||
(logger_list) != node_to_item(&__android_log_readers, \
|
||||
struct android_log_logger_list, node) && \
|
||||
(logger_list) != node_to_item((logger_list)->node.next, \
|
||||
struct android_log_logger_list, node); \
|
||||
(logger_list) = node_to_item((logger_list)->node.next, \
|
||||
struct android_log_logger_list, node))
|
||||
|
||||
/* OS specific dribs and drabs */
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
|
|
@ -213,13 +213,6 @@ LIBLOG_ABI_PUBLIC int android_logger_set_prune_list(
|
|||
LOGGER_LIST_FUNCTION(logger_list, -ENODEV, setPrune, buf, len);
|
||||
}
|
||||
|
||||
LIBLOG_HIDDEN struct listnode __android_log_readers = { &__android_log_readers,
|
||||
&__android_log_readers };
|
||||
#if !defined(_WIN32)
|
||||
LIBLOG_HIDDEN pthread_rwlock_t __android_log_readers_lock =
|
||||
PTHREAD_RWLOCK_INITIALIZER;
|
||||
#endif
|
||||
|
||||
LIBLOG_ABI_PUBLIC struct logger_list* android_logger_list_alloc(
|
||||
int mode, unsigned int tail, pid_t pid) {
|
||||
struct android_log_logger_list* logger_list;
|
||||
|
@ -235,10 +228,6 @@ LIBLOG_ABI_PUBLIC struct logger_list* android_logger_list_alloc(
|
|||
logger_list->tail = tail;
|
||||
logger_list->pid = pid;
|
||||
|
||||
logger_list_wrlock();
|
||||
list_add_tail(&__android_log_readers, &logger_list->node);
|
||||
logger_list_unlock();
|
||||
|
||||
return (struct logger_list*)logger_list;
|
||||
}
|
||||
|
||||
|
@ -257,10 +246,6 @@ LIBLOG_ABI_PUBLIC struct logger_list* android_logger_list_alloc_time(
|
|||
logger_list->start = start;
|
||||
logger_list->pid = pid;
|
||||
|
||||
logger_list_wrlock();
|
||||
list_add_tail(&__android_log_readers, &logger_list->node);
|
||||
logger_list_unlock();
|
||||
|
||||
return (struct logger_list*)logger_list;
|
||||
}
|
||||
|
||||
|
@ -472,10 +457,6 @@ LIBLOG_ABI_PUBLIC void android_logger_list_free(struct logger_list* logger_list)
|
|||
return;
|
||||
}
|
||||
|
||||
logger_list_wrlock();
|
||||
list_remove(&logger_list_internal->node);
|
||||
logger_list_unlock();
|
||||
|
||||
while (!list_empty(&logger_list_internal->transport)) {
|
||||
struct listnode* node = list_head(&logger_list_internal->transport);
|
||||
struct android_log_transport_context* transp =
|
||||
|
|
|
@ -684,9 +684,9 @@ LIBLOG_ABI_PUBLIC int android_set_log_transport(int transport_flag) {
|
|||
return retval;
|
||||
}
|
||||
|
||||
__android_log_transport &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR;
|
||||
__android_log_transport &= LOGGER_LOGD | LOGGER_STDERR;
|
||||
|
||||
transport_flag &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR;
|
||||
transport_flag &= LOGGER_LOGD | LOGGER_STDERR;
|
||||
|
||||
if (__android_log_transport != transport_flag) {
|
||||
__android_log_transport = transport_flag;
|
||||
|
@ -714,7 +714,7 @@ LIBLOG_ABI_PUBLIC int android_get_log_transport() {
|
|||
if (write_to_log == __write_to_log_null) {
|
||||
ret = LOGGER_NULL;
|
||||
} else {
|
||||
__android_log_transport &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR;
|
||||
__android_log_transport &= LOGGER_LOGD | LOGGER_STDERR;
|
||||
ret = __android_log_transport;
|
||||
if ((write_to_log != __write_to_log_init) &&
|
||||
(write_to_log != __write_to_log_daemon)) {
|
||||
|
|
|
@ -54,9 +54,7 @@ cc_defaults {
|
|||
srcs: [
|
||||
"libc_test.cpp",
|
||||
"liblog_test_default.cpp",
|
||||
"liblog_test_local.cpp",
|
||||
"liblog_test_stderr.cpp",
|
||||
"liblog_test_stderr_local.cpp",
|
||||
"log_id_test.cpp",
|
||||
"log_radio_test.cpp",
|
||||
"log_read_test.cpp",
|
||||
|
|
|
@ -52,22 +52,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if (!defined(USING_LOGGER_DEFAULT) || !defined(USING_LOGGER_LOCAL) || \
|
||||
!defined(USING_LOGGER_STDERR))
|
||||
#ifdef liblog // a binary clue that we are overriding the test names
|
||||
// Does not support log reading blocking feature yet
|
||||
// Does not support LOG_ID_SECURITY (unless we set LOGGER_LOCAL | LOGGER_LOGD)
|
||||
// Assume some common aspects are tested by USING_LOGGER_DEFAULT:
|
||||
// Does not need to _retest_ pmsg functionality
|
||||
// Does not need to _retest_ property handling as it is a higher function
|
||||
// Does not need to _retest_ event mapping functionality
|
||||
// Does not need to _retest_ ratelimit
|
||||
// Does not need to _retest_ logprint
|
||||
#define USING_LOGGER_LOCAL
|
||||
#else
|
||||
#define USING_LOGGER_DEFAULT
|
||||
#endif
|
||||
#endif
|
||||
#ifdef USING_LOGGER_STDERR
|
||||
#define SUPPORTS_END_TO_END 0
|
||||
#else
|
||||
|
@ -175,7 +159,7 @@ static bool tested__android_log_close;
|
|||
#endif
|
||||
|
||||
TEST(liblog, __android_log_btwrite__android_logger_list_read) {
|
||||
#if (defined(__ANDROID__) || defined(USING_LOGGER_LOCAL))
|
||||
#ifdef __ANDROID__
|
||||
#ifdef TEST_PREFIX
|
||||
TEST_PREFIX
|
||||
#endif
|
||||
|
@ -269,7 +253,7 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#if (defined(__ANDROID__) || defined(USING_LOGGER_LOCAL))
|
||||
#ifdef __ANDROID__
|
||||
static void print_transport(const char* prefix, int logger) {
|
||||
static const char orstr[] = " | ";
|
||||
|
||||
|
@ -297,16 +281,11 @@ static void print_transport(const char* prefix, int logger) {
|
|||
fprintf(stderr, "%sLOGGER_NULL", prefix);
|
||||
prefix = orstr;
|
||||
}
|
||||
if (logger & LOGGER_LOCAL) {
|
||||
fprintf(stderr, "%sLOGGER_LOCAL", prefix);
|
||||
prefix = orstr;
|
||||
}
|
||||
if (logger & LOGGER_STDERR) {
|
||||
fprintf(stderr, "%sLOGGER_STDERR", prefix);
|
||||
prefix = orstr;
|
||||
}
|
||||
logger &= ~(LOGGER_LOGD | LOGGER_KERNEL | LOGGER_NULL | LOGGER_LOCAL |
|
||||
LOGGER_STDERR);
|
||||
logger &= ~(LOGGER_LOGD | LOGGER_KERNEL | LOGGER_NULL | LOGGER_STDERR);
|
||||
if (logger) {
|
||||
fprintf(stderr, "%s0x%x", prefix, logger);
|
||||
prefix = orstr;
|
||||
|
@ -321,7 +300,7 @@ static void print_transport(const char* prefix, int logger) {
|
|||
// and behind us, to make us whole. We could incorporate a prefix and
|
||||
// suffix test to make this standalone, but opted to not complicate this.
|
||||
TEST(liblog, android_set_log_transport) {
|
||||
#if (defined(__ANDROID__) || defined(USING_LOGGER_LOCAL))
|
||||
#ifdef __ANDROID__
|
||||
#ifdef TEST_PREFIX
|
||||
TEST_PREFIX
|
||||
#endif
|
||||
|
@ -632,7 +611,7 @@ TEST(liblog, __android_log_buf_write_and_print__newline_space_prefix) {
|
|||
buf_write_test("\n Hello World \n");
|
||||
}
|
||||
|
||||
#ifndef USING_LOGGER_LOCAL // requires blocking reader functionality
|
||||
#ifdef USING_LOGGER_DEFAULT // requires blocking reader functionality
|
||||
#ifdef TEST_PREFIX
|
||||
static unsigned signaled;
|
||||
static log_time signal_time;
|
||||
|
@ -944,7 +923,7 @@ TEST(liblog, android_logger_list_read__cpu_thread) {
|
|||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
#endif
|
||||
}
|
||||
#endif // !USING_LOGGER_LOCAL
|
||||
#endif // USING_LOGGER_DEFAULT
|
||||
|
||||
#ifdef TEST_PREFIX
|
||||
static const char max_payload_tag[] = "TEST_max_payload_and_longish_tag_XXXX";
|
||||
|
@ -2417,7 +2396,7 @@ TEST(liblog, android_errorWriteLog__android_logger_list_read__null_subtag) {
|
|||
}
|
||||
|
||||
// Do not retest logger list handling
|
||||
#if (defined(TEST_PREFIX) || !defined(USING_LOGGER_LOCAL))
|
||||
#ifdef TEST_PREFIX
|
||||
static int is_real_element(int type) {
|
||||
return ((type == EVENT_TYPE_INT) || (type == EVENT_TYPE_LONG) ||
|
||||
(type == EVENT_TYPE_STRING) || (type == EVENT_TYPE_FLOAT));
|
||||
|
@ -2572,7 +2551,7 @@ static int android_log_buffer_to_string(const char* msg, size_t len,
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif // TEST_PREFIX || !USING_LOGGER_LOCAL
|
||||
#endif // TEST_PREFIX
|
||||
|
||||
#ifdef TEST_PREFIX
|
||||
static const char* event_test_int32(uint32_t tag, size_t& expected_len) {
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
#include <log/log_transport.h>
|
||||
#define liblog liblog_local
|
||||
#define TEST_LOGGER LOGGER_LOCAL
|
||||
#include "liblog_test.cpp"
|
|
@ -1,4 +0,0 @@
|
|||
#include <log/log_transport.h>
|
||||
#define liblog liblog_stderr_local
|
||||
#define TEST_LOGGER (LOGGER_LOCAL | LOGGER_STDERR)
|
||||
#include "liblog_test.cpp"
|
Loading…
Reference in a new issue