Date: Sat, 22 Apr 2017 00:22:27 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Bruce Evans <brde@optusnet.com.au> Cc: Jung-uk Kim <jkim@freebsd.org>, src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r317231 - head/usr.bin/systat Message-ID: <20170421232411.H2704@besplex.bde.org> In-Reply-To: <20170421131652.P966@besplex.bde.org> References: <201704202230.v3KMUdAm030762@repo.freebsd.org> <20170421131652.P966@besplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 21 Apr 2017, Bruce Evans wrote: > On Thu, 20 Apr 2017, Jung-uk Kim wrote: > >> Log: >> Fix systat(1) regression. It was broken by r317061. > > It is more broken than before. Now it fails when the kernel is older > than the utility instead of vice versa. When it fails, the failures > are more serious than before. systat -v actually does complete > checking for errors (some are only errors in itself), but mishandles > them. It reports the errors on the status line and continues. The > error message overwrites the previous one. Continuing is more broken > than before: The follow patch reduces the ABI breakage as much as possible. On a lightly loaded system, the maximum value in any counter used by top, vmstat or systat -v is growing at a rate of 1M per hour, so the 32-bit variables in the application are enough for about 166 days. I only applied the fix to some counter sysctls with broken ABIs, but wrote it for general use. It doesn't handle SYSCTL_IN(), and assumes unsigned counters. X Index: subr_counter.c X =================================================================== X --- subr_counter.c (revision 317243) X +++ subr_counter.c (working copy) X @@ -74,6 +75,95 @@ X uma_zfree(pcpu_zone_64, c); X } X X +/* Output a signed integer with the caller's size as well as possible. */ X +__unused X +static int X +sysctl_out_i(struct sysctl_req *req, intmax_t val) X +{ X + intmax_t valtrunc; X + int64_t val64; X + int32_t val32; X + int16_t val16; X + int8_t val8; X + int error; X + X + switch (req->oldlen) { X + case 1: X + valtrunc = val8 = val; X + error = SYSCTL_OUT(req, &val8, 1); X + break; X + case 2: X + valtrunc = val16 = val; X + error = SYSCTL_OUT(req, &val16, 2); X + break; X + case 4: X + valtrunc = val32 = val; X + error = SYSCTL_OUT(req, &val32, 4); X + break; X + case 8: X + valtrunc = val64 = val; X + error = SYSCTL_OUT(req, &val64, 8); X + break; X + default: X + valtrunc = val; X + error = SYSCTL_OUT(req, &val, sizeof(val)); X + break; X + } X + if (valtrunc != val && error == 0) X + error = EOVERFLOW; X + return (error); X +} X + X +uintmax_t sysoui_max; X + X +/* Output an unsigned integer with the caller's size as well as possible. */ X +static int X +sysctl_out_ui(struct sysctl_req *req, uintmax_t val) X +{ X + uintmax_t valtrunc; X + uint64_t val64; X + uint32_t val32; X + uint16_t val16; X + uint8_t val8; X + int error; X + X + if (sysoui_max < val) { X + sysoui_max = val; X + if ((val & 0xffff) == 0) X + printf("new sysoui_max %#jx\n", val); X + } X + val64 = val32 = val16 = val8 = 0; X + switch (req->oldlen) { X + case 1: X + valtrunc = val8 = val; X + error = SYSCTL_OUT(req, &val8, 1); X + break; X + case 2: X + valtrunc = val16 = val; X + error = SYSCTL_OUT(req, &val16, 2); X + break; X + case 4: X + valtrunc = val32 = val; X + error = SYSCTL_OUT(req, &val32, 4); X + break; X + case 8: X + valtrunc = val64 = val; X + error = SYSCTL_OUT(req, &val64, 8); X + break; X + default: X + valtrunc = val; X + error = SYSCTL_OUT(req, &val, sizeof(val)); X + break; X + } X + if (valtrunc != val && error == 0) { X + printf( X + "val %#jx, valtrunc %#jx, val64 %#jx, val32 %#x, val16 %#x, val8 %#x\n", X + val, valtrunc, val64, val32, val16, val8); X + error = EOVERFLOW; X + } X + return (error); X +} X + X int X sysctl_handle_counter_u64(SYSCTL_HANDLER_ARGS) X { X @@ -82,7 +172,7 @@ X X out = counter_u64_fetch(*(counter_u64_t *)arg1); X X - error = SYSCTL_OUT(req, &out, sizeof(uint64_t)); X + error = sysctl_out_ui(req, out); X X if (error || !req->newptr) X return (error); Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20170421232411.H2704>