[TS-2822] Crash in LogBufferIterator::next

(cherry picked from commit 13453d9ab8c975fd12da632a49868eeaf2eb1fd3)


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/a0f821eb
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/a0f821eb
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/a0f821eb

Branch: refs/heads/4.2.x
Commit: a0f821eb6aa3a4f04edbbe623ed4d85f4054c381
Parents: 0c8d513
Author: Brian Geffon <[email protected]>
Authored: Wed May 21 11:05:35 2014 -0700
Committer: Phil Sorber <[email protected]>
Committed: Thu May 29 21:02:04 2014 -0600

----------------------------------------------------------------------
 CHANGES           |  1 +
 proxy/logstats.cc | 31 +++++++++++++++++++++++++------
 2 files changed, 26 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a0f821eb/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 8df1343..013fe5c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,7 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache Traffic Server 4.2.2
 
+  *) [TS-2822] Crash in LogBufferIterator::next
 
   *) [TS-2784] Make header_rewrite plugins compile on FBSD.
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a0f821eb/proxy/logstats.cc
----------------------------------------------------------------------
diff --git a/proxy/logstats.cc b/proxy/logstats.cc
index f3249ef..3d50ec7 100644
--- a/proxy/logstats.cc
+++ b/proxy/logstats.cc
@@ -1730,7 +1730,7 @@ process_file(int in_fd, off_t offset, unsigned max_age)
     unsigned second_read_size = sizeof(LogBufferHeader) - first_read_size;
     nread = read(in_fd, &buffer[first_read_size], second_read_size);
     if (!nread || EOF == nread) {
-      Debug("logstats", "Second read of header failed (attemped %d bytes at 
offset %d, got nothing).", second_read_size, first_read_size);
+      Debug("logstats", "Second read of header failed (attemped %d bytes at 
offset %d, got nothing), errno=%d.", second_read_size, first_read_size, errno);
       return 1;
     }
 
@@ -1746,11 +1746,30 @@ process_file(int in_fd, off_t offset, unsigned max_age)
       return 1;
     }
 
-    nread = read(in_fd, &buffer[sizeof(LogBufferHeader)], buffer_bytes);
-    if (!nread || EOF == nread) {
-      Debug("logstats", "Failed to read buffer payload [%d bytes]", 
buffer_bytes);
-      return 1;
-    }
+    const int MAX_READ_TRIES = 5;
+    int total_read = 0;
+    int read_tries_remaining = MAX_READ_TRIES; // since the data will be old 
anyway, let's only try a few times.
+    nread = 0;
+    do {
+      nread = read(in_fd, &buffer[sizeof(LogBufferHeader) + total_read], 
buffer_bytes - total_read);
+      if (EOF == nread || !nread) { // just bail on error
+        Debug("logstats", "Read failed while reading log buffer, wanted %d 
bytes, nread=%d, errno=%d", buffer_bytes - total_read, nread, errno);
+        return 1;
+      } else {
+        total_read += nread;
+      }
+
+      if (total_read < buffer_bytes) {
+        if (--read_tries_remaining <= 0) {
+          Debug("logstats_failed_retries", "Unable to read after %d tries, 
total_read=%d, buffer_bytes=%d", MAX_READ_TRIES, total_read, buffer_bytes);
+          return 1;
+        }
+        // let's wait until we get more data on this file descriptor
+        Debug("logstats_partial_read", "Failed to read buffer payload [%d 
bytes], total_read=%d, buffer_bytes=%d, tries_remaining=%d",
+            buffer_bytes - total_read, total_read, buffer_bytes, 
read_tries_remaining);
+        usleep(50*1000); // wait 50ms
+      }
+    } while (total_read < buffer_bytes);
 
     // Possibly skip too old entries (the entire buffer is skipped)
     if (header->high_timestamp >= max_age) {

Reply via email to