Subject: bin/20644: tail -f soaks up CPU time if filesystem doesn't support kqueue
To: None <>
From: None <>
List: netbsd-bugs
Date: 03/10/2003 01:26:30
>Number:         20644
>Category:       bin
>Synopsis:       tail -f soaks up CPU time if filesystem doesn't support kqueue
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Mar 09 23:27:00 PST 2003
>Originator:     Dave Huang
>Release:        NetBSD 1.6
Name: Dave Huang         |  Mammal, mammal / their names are called /
INet: |  they raise a paw / the bat, the cat /
FurryMUCK: Dahan         |  dolphin and dog / koala bear and hog -- TMBG
Dahan: Hani G Y+C 27 Y++ L+++ W- C++ T++ A+ E+ S++ V++ F- Q+++ P+ B+ PA+ PL++
System: NetBSD 1.6 NetBSD 1.6 (YERFABLE) #196: Thu Sep 12 19:22:18 CDT 2002 alpha
Architecture: alpha
Machine: alpha
	If tail -f is run on a file residing on a filesystem that
doesn't support the kqueue EVFILT_VNODE event, such as unionfs
(apparently) it falls back to calling stat periodically to see if the
file has changed. However, it does a usleep(1000000) in an attempt to
sleep 1 second between calls to stat. Since usleep() only accepts
sleep times strictly less than 1,000,000 microseconds, it immediately
returns an error (which tail ignores), and tail ends up in a tight
loop attempting to read from the file.
	tail -f a file on a unionfs and note that tail is always
runnable, and uses a bunch of CPU time.
	Don't use usleep(1000000), just call sleep(1) if you want to
sleep for a second.

Index: forward.c
RCS file: /cvsroot/src/usr.bin/tail/forward.c,v
retrieving revision 1.23
diff -u -r1.23 forward.c
--- forward.c	2002/10/30 21:48:50	1.23
+++ forward.c	2003/03/10 07:18:44
@@ -248,7 +248,7 @@
 			 * We pause for one second after displaying any data
 			 * that has accumulated since we read the file.
-                	(void) usleep(1000000);
+                	(void) sleep(1);
 			if (fflag == 2 && fileno(fp) != STDIN_FILENO &&
 			    stat(fname, &statbuf) != -1) {