From owner-freebsd-bugs Wed Jan 10 6:10:23 2001 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 451E337B698 for ; Wed, 10 Jan 2001 06:10:02 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.1/8.11.1) id f0AEA2x65736; Wed, 10 Jan 2001 06:10:02 -0800 (PST) (envelope-from gnats) Received: from goliath.siemens.de (goliath.siemens.de [194.138.37.131]) by hub.freebsd.org (Postfix) with ESMTP id E746637B402 for ; Wed, 10 Jan 2001 06:03:44 -0800 (PST) Received: from mail1.siemens.de (mail1.siemens.de [139.23.33.14]) by goliath.siemens.de (8.11.0/8.11.0) with ESMTP id f0AE3gC13265 for ; Wed, 10 Jan 2001 15:03:43 +0100 (MET) Received: from curry.mchp.siemens.de (curry.mchp.siemens.de [139.25.42.7]) by mail1.siemens.de (8.11.0/8.11.0) with ESMTP id f0AE3gG09831 for ; Wed, 10 Jan 2001 15:03:42 +0100 (MET) Received: (from localhost) by curry.mchp.siemens.de (8.11.1/8.11.1) id f0AE3g690371 for FreeBSD-gnats-submit@freebsd.org; Wed, 10 Jan 2001 15:03:42 +0100 (CET) Message-Id: <200101101403.f0AE3gc13210@curry.mchp.siemens.de> Date: Wed, 10 Jan 2001 15:03:42 +0100 (CET) From: Andre Albsmeier To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: kern/24223: "tail -f file" is a CPU hog when file is on an NFS volume Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 24223 >Category: kern >Synopsis: "tail -f file" is a CPU hog when file is on an NFS volume >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Jan 10 06:10:01 PST 2001 >Closed-Date: >Last-Modified: >Originator: Andre Albsmeier >Release: FreeBSD 4.2-STABLE i386 >Organization: >Environment: FreeBSD 4.2-STABLE with a nfs mounted volume from another FreeBSD 4.2-STABLE server. >Description: If "tail -f file" is executed for a file which resides on an NFS mounted volume it consumes all CPU time. >How-To-Repeat: mount some-server:/filesystem /mnt cat blah > /mnt/file tail -f /mnt/file run top in another window >Fix: unknown. tail spins around in the code segment below (forward.c). The switch statement is called repeatedly with action == USE_KQUEUE. for (;;) { while ((ch = getc(fp)) != EOF) if (putchar(ch) == EOF) oerr(); if (ferror(fp)) { ierr(); return; } (void)fflush(stdout); if (! fflag) break; clearerr(fp); switch (action) { case ADD_EVENTS: { int n = 0; struct timespec ts = { 0, 0 }; if (Fflag && fileno(fp) != STDIN_FILENO) { ev[n].ident = fileno(fp); ev[n].filter = EVFILT_VNODE; ev[n].flags = EV_ADD | EV_ENABLE | EV_CLEAR; ev[n].fflags = NOTE_DELETE | NOTE_RENAME; n++; } ev[n].ident = fileno(fp); ev[n].filter = EVFILT_READ; ev[n].flags = EV_ADD | EV_ENABLE; n++; if (kevent(kq, ev, n, NULL, 0, &ts) < 0) { close(kq); kq = -1; action = USE_SLEEP; } else { action = USE_KQUEUE; } break; } case USE_KQUEUE: if (kevent(kq, NULL, 0, ev, 1, NULL) < 0) err(1, "kevent"); if (ev->filter == EVFILT_VNODE) { /* file was rotated, wait until it reappears */ action = USE_SLEEP; } else if (ev->data < 0) { /* file shrank, reposition to end */ if (fseek(fp, 0L, SEEK_END) == -1) { ierr(); return; } } break; case USE_SLEEP: (void) usleep(250000); clearerr(fp); if (Fflag && fileno(fp) != STDIN_FILENO && stat(fname, &sb2) != -1) { if (sb2.st_ino != sbp->st_ino || sb2.st_dev != sbp->st_dev || sb2.st_rdev != sbp->st_rdev || sb2.st_nlink == 0) { fp = freopen(fname, "r", fp); if (fp == NULL) { ierr(); break; } *sbp = sb2; if (kq != -1) action = ADD_EVENTS; } } break; } } } /* * rlines -- display the last offset lines of the file. */ static void rlines(fp, off, sbp) FILE *fp; long off; struct stat *sbp; { register off_t size; register char *p; char *start; if (!(size = sbp->st_size)) return; if (size > SIZE_T_MAX) { errno = EFBIG; ierr(); return; } if ((start = mmap(NULL, (size_t)size, PROT_READ, MAP_SHARED, fileno(fp), (off_t)0)) == MAP_FAILED) { ierr(); return; } /* Last char is special, ignore whether newline or not. */ for (p = start + size - 1; --size;) if (*--p == '\n' && !--off) { ++p; break; } /* Set the file pointer to reflect the length displayed. */ size = sbp->st_size - size; WR(p, size); if (fseek(fp, (long)sbp->st_size, SEEK_SET) == -1) { ierr(); return; } if (munmap(start, (size_t)sbp->st_size)) { ierr(); return; } } >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message