Date: Mon, 27 Jun 2005 13:40:24 GMT From: Bruce Evans <bde@zeta.org.au> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/82682: "Accounting resumed" while disk fills up Message-ID: <200506271340.j5RDeOmX067316@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/82682; it has been noted by GNATS. From: Bruce Evans <bde@zeta.org.au> To: Wietse Venema <wietse@porcupine.org> Cc: freebsd-gnats-submit@freebsd.org, freebsd-bugs@freebsd.org Subject: Re: kern/82682: "Accounting resumed" while disk fills up Date: Mon, 27 Jun 2005 23:39:52 +1000 (EST) On Sun, 26 Jun 2005, Wietse Venema wrote: >> Description: > When the disk fills up, the kernel as expected disables process accounting, but it RESUMES process accounting while the disk fills up further. > > Perhaps the code gets confused when the free space becomes negative (see repeat-by example below). But that is pure speculation. > > I have been using FreeBSD for 10+ years and routinely use dd of /dev/zero to wipe the free space as root. I did not notice this accounting anomaly when I was still using FreeBSD 4. This is one one the many possible and actual sign extension/overflow bugs caused by the poorly chosen types in the 64-bit statfs. From kern_acct.c: %%% if (sb.f_bavail > acctresume * sb.f_blocks / 100) { acctp = savacctp; acctcred = savacctcred; acctflags = savacctflags; savacctp = NULLVP; savacctcred = NOCRED; log(LOG_NOTICE, "Accounting resumed\n"); } %%% In RELENG_4, everything in struct statfs has a non-foot-shooting type (plain long), but in -current after 2003/12/11 the types don't mesh properly; most types are 64 bits; f_bavail is still signed, as it needs to be to represent negative free space, but most of the other types are unsigned, as they need to be to cause sign extension bugs. In the above, `acctresume * sb.f_blocks / 100' has type uint64_t and is not very large, but sb.f_bavail has type int64_t and is not very large in absolute value, so as soon as sb.f_bavail becomes negative it is converted to a huge uint64_t as part of the comparison and the comparison always succeeds. Another bug in the above is that `acctresume * sb.f_blocks' overflows if sb.f_blocks exceeds 1/4 of the maximum for the data type. This overflow is hard to reach since (2^64)/4-1 blocks should be enough for anyone, and even overflow at (2^31)/4 blocks in RELENG_4 is hard to reach due to other limits (mainly the limit of 2^31-1 512-blocks). Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200506271340.j5RDeOmX067316>