summaryrefslogtreecommitdiff
path: root/src/tail.c
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2016-11-09 17:23:04 +0000
committerPádraig Brady <P@draigBrady.com>2016-11-09 19:36:42 +0000
commit7fc7206b03a7f54b23904373ad397f693a5fae2a (patch)
treef82dde5b62877b33a07859dc4538fb95f4b31b50 /src/tail.c
parent2a809125299261db9db9b97e93b5885223c6e9d3 (diff)
downloadcoreutils-7fc7206b03a7f54b23904373ad397f693a5fae2a.tar.xz
tail: avoid outputting repeated data with remote files
* src/tail.c (tail_forever): Only read up to st_size on network file systems to avoid the issue with a stale attribute cache returning a smaller st_size than we have already read(). The was seen with glusterfs at least and caused the complete file to be repeatedly output due to assuming the file was truncated in this case. * NEWS: Mention the fix.
Diffstat (limited to 'src/tail.c')
-rw-r--r--src/tail.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/tail.c b/src/tail.c
index 96982ed5b..b3018d526 100644
--- a/src/tail.c
+++ b/src/tail.c
@@ -1220,9 +1220,19 @@ tail_forever (struct File_spec *f, size_t n_files, double sleep_interval)
}
}
- bytes_read = dump_remainder (name, fd,
- (f[i].blocking
- ? COPY_A_BUFFER : COPY_TO_EOF));
+ /* Don't read more than st_size on networked file systems
+ because it was seen on glusterfs at least, that st_size
+ may be smaller than the data read on a _subsequent_ stat call. */
+ uintmax_t bytes_to_read;
+ if (f[i].blocking)
+ bytes_to_read = COPY_A_BUFFER;
+ else if (S_ISREG (mode) && f[i].remote)
+ bytes_to_read = stats.st_size - f[i].size;
+ else
+ bytes_to_read = COPY_TO_EOF;
+
+ bytes_read = dump_remainder (name, fd, bytes_to_read);
+
any_input |= (bytes_read != 0);
f[i].size += bytes_read;
}