From b95c58fc77bcf47123d522b1d8f6bc5f47b750f0 Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Fri, 6 Apr 2018 15:55:48 +0200 Subject: [PATCH] util: make log_len Android Logger backend specific Under the pipe backend, it is the daemon who decides when to stop sending more logs when dumping so util does not need to keep track. Change-Id: I53aea552e8fd4bda2857dc63cef40d9f91f1b4d7 Signed-off-by: Michal Bloch --- src/logutil/fd_info.c | 1 - src/logutil/fd_info.h | 3 +-- src/logutil/fdi_logger.c | 31 ++++++++++++++++++++++++------- src/logutil/logutil.c | 17 ++++++++++------- 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/logutil/fd_info.c b/src/logutil/fd_info.c index b7df402..cd449e0 100644 --- a/src/logutil/fd_info.c +++ b/src/logutil/fd_info.c @@ -41,7 +41,6 @@ struct fd_info *fdi_create(struct fd_ops *ops, const char *name) return NULL; fdi->fd = -1; - fdi->log_len = UNLIMITED_LOG_LEN; fdi->ops = ops; fdi->name = name; fdi->priv_data = NULL; diff --git a/src/logutil/fd_info.h b/src/logutil/fd_info.h index 7ac36ee..b269ab0 100644 --- a/src/logutil/fd_info.h +++ b/src/logutil/fd_info.h @@ -26,13 +26,11 @@ #include "sort_vector.h" #define RECEIVE_BUFFER_SIZE 16384 // How large (in bytes) pipe receiving buffer is. -#define UNLIMITED_LOG_LEN (-RECEIVE_BUFFER_SIZE - 1) // value not reachable through a single read() struct fd_ops; struct fd_info { int fd; - int log_len; struct fd_ops *ops; const char *name; void *priv_data; @@ -54,6 +52,7 @@ struct fd_ops { struct logger_entry *(*extract_entry)(struct fd_info *fdi); /// Transition into a state that allows reading and printing out logs + /// Return values > 0 mean everything went fine but we don't want to print int (*prepare_print)(struct fd_info *fdi, int dump, list_head filters, log_format *format); /// Clear the buffer diff --git a/src/logutil/fdi_logger.c b/src/logutil/fdi_logger.c index b28697f..0ae78f9 100644 --- a/src/logutil/fdi_logger.c +++ b/src/logutil/fdi_logger.c @@ -26,7 +26,10 @@ #include "fd_info.h" #include "fdi_logger.h" +#define UNLIMITED_LOG_LEN -1 + struct logger_priv_data { + int log_len; struct logger_entry *entry; }; @@ -124,19 +127,30 @@ static void logger_destroy(struct fd_info *fdi) static int logger_prepare_print(struct fd_info *fdi, int dump, list_head filters, log_format *format) { assert(fdi); + struct logger_priv_data *const lpd = (struct logger_priv_data *)fdi->priv_data; + assert(lpd); assert(format); for (list_head iter = filters; iter; list_next(&iter)) log_add_filter_string(format, (const char *)list_at(iter)); - if (!dump) + if (dump == DUMP_CONTINUOUS) { + lpd->log_len = UNLIMITED_LOG_LEN; return 0; + } - const int log_len = logger_get_log_len(fdi->fd); - if (log_len < 0) - return log_len; + lpd->log_len = logger_get_log_len(fdi->fd); + if (lpd->log_len < 0) + return lpd->log_len; + + if (lpd->log_len == 0) { + /* signify we don't want to get printed; + we can't rely on the regular removal + path because there won't be a read() + to trigger it */ + return 1; + } - fdi->log_len = log_len; return 0; } @@ -163,13 +177,16 @@ static int logger_read(struct fd_info *fdi) parse_androidlogger_message(ale, lpd->entry, r); add_recv_timestamp(lpd->entry); - if (fdi->log_len > 0) { + if (lpd->log_len != UNLIMITED_LOG_LEN) { /* extra 4 bytes to workaround AL driver bug: current size (ie. log_len) is reported as if the connection were using protocol version 2, even if the connection is actually using v1, whose header is 4 bytes smaller */ - fdi->log_len -= (r + 4); + lpd->log_len -= (r + 4); + + if (lpd->log_len <= 0) + return 0; // emulate EOF } return r; diff --git a/src/logutil/logutil.c b/src/logutil/logutil.c index 77116ac..1429dd5 100755 --- a/src/logutil/logutil.c +++ b/src/logutil/logutil.c @@ -117,16 +117,14 @@ static void do_print(struct fd_info **data_fds, int fd_count, struct sort_vector } for (nfds = 0; nfds < fd_count; ++nfds) { + if (!data_fds[nfds]) + continue; int fd = data_fds[nfds]->fd; ev.data.ptr = data_fds[nfds]; if (fd_set_flags(fd, O_NONBLOCK) < 0) goto cleanup; - if (data_fds[nfds]->log_len != 0) { - /* can't rely on the regular log_len-based removal path - as there would potentially be no read to trigger it */ - epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev); - ++epoll_cnt; - } + epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev); + ++epoll_cnt; } while (epoll_cnt > 0) { @@ -153,7 +151,7 @@ static void do_print(struct fd_info **data_fds, int fd_count, struct sort_vector if (fdi_push_log(fdi, logs, l_file)) break; - if (r == 0 || (logs->dump != DUMP_CONTINUOUS && fdi->log_len <= 0 && fdi->log_len != UNLIMITED_LOG_LEN)) { + if (r == 0) { epoll_ctl(epollfd, EPOLL_CTL_DEL, fdi->fd, NULL); --epoll_cnt; } @@ -403,6 +401,11 @@ int main(int argc, char **argv) break; case ACTION_PRINT: { r = fdi->ops->prepare_print(fdi, logs.dump, filters, l_file.format); + if (r > 0) { + // everything went fine, but we're not printing this one + fdi_free(fdi); + fdi_ptrs[i] = NULL; + } break; } case ACTION_GETSIZE: { uint32_t size; -- 2.7.4