Subject: bug#23539: tail -f file name headings displayed too many times after suspend

From: Janne Snabb <[email-masked]>
Date: Sat, 14 May 2016 23:36:03 +0300

Hi,

I have a habit of running "tail -F /some/log/file /other/log/file" in my
shell window. Whenever I need that shell window for something else, I
hit ctrl-Z to suspend the tail. Then I do whatever I need to do.

After I am done I do "fg" to get back to displaying the tail of the log
files. I get the log output that I missed while tail was suspended.

However that is followed by several extra file name headings with no log
output following the headings. Like this:

==> /var/log/nginx/access.log <==

==> /var/log/nginx/error.log <==

==> /var/log/nginx/access.log <==

==> /var/log/nginx/error.log <==

==> /var/log/nginx/access.log <==

This happens at least on Ubuntu 16.04 (4.4.0 kernel) and CentOS 7 (3.1.0
kernel) on x86_64 architecture. It happens with distro provided tail
(coreutils 8.25 on Ubuntu and coreutils 8.22 on CentOS) as well as with
coreutils 8.25 compiled from sources.

I also tried this on FreeBSD 8.4 (which does not have inotify) with
coreutils 8.25 but I was unable to reproduce it there. So it seems to be
Linux and inotify dependent.

I have been seeing this for long time, but I am unsure how long. I
finally took the effort to report this.

I wrote a shell script (#1) which demonstrates the problem:

#!/bin/sh

echo start > file1
echo start > file2

tail -f file1 file2 &
pid=$!

sleep 1
kill -STOP $pid
sleep 1
echo line >> file1
sleep 1
echo line >> file2
sleep 1
echo line >> file1
sleep 1
echo line >> file2
sleep 1
kill -CONT $pid
sleep 1
kill -TERM $pid
# end

The output of the above script ends with extra file name headings.

However the following script (#2) does not exhibit this behaviour:

#!/bin/sh

echo start > file1
echo start > file2

tail -f file1 file2 &
pid=$!

sleep 1
kill -STOP $pid
sleep 1
echo line >> file1
sleep 1
echo line >> file1
sleep 1
echo line >> file2
sleep 1
echo line >> file2
sleep 1
kill -CONT $pid
sleep 1
kill -TERM $pid
# end

The only difference between these two scripts is the ordering of the
writes to the files which are being tail'ed. If the writes are
interleaved, tail displays extra file name headings.

If I add the ---disable-inotify option to the tail commend line there is
no extra file name headings. Thus this is clearly inotify related.

I believe the extra file name headings are not displayed in case #2
because the following check in check_fspec() function suppresses them:

  if (fspec != *prev_fspec)

This only suppresses the headings if the inotify events are not
interleaved (case #2).

I am unsure how to fix this.

Best Regards,
-- 
Janne Snabb
[email-masked]