util: make log_len Android Logger backend specific 89/175089/5
authorMichal Bloch <m.bloch@samsung.com>
Fri, 6 Apr 2018 13:55:48 +0000 (15:55 +0200)
committerMaciej Slodczyk <m.slodczyk2@partner.samsung.com>
Tue, 3 Jul 2018 15:27:53 +0000 (17:27 +0200)
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 <m.bloch@samsung.com>
src/logutil/fd_info.c
src/logutil/fd_info.h
src/logutil/fdi_logger.c
src/logutil/logutil.c

index b7df402..cd449e0 100644 (file)
@@ -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;
index 7ac36ee..b269ab0 100644 (file)
 #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
index b28697f..0ae78f9 100644 (file)
 #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;
index 77116ac..1429dd5 100755 (executable)
@@ -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;