Bug 12808

Summary: [PATCH] vmstat -i output wraps to negative values
Product: Base System Reporter: toasty <toasty>
Component: binAssignee: Nick Hibma <n_hibma>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.0-CURRENT   
Hardware: Any   
OS: Any   

Description toasty 1999-07-25 22:10:01 UTC
The output of vmstat -i will wrap around to negative numbers.

# vmstat -i
interrupt      total      rate
fxp0 irq11   1986997576      618
ata-pci0 irq14 43093267       13
ata-pci0 irq15 85069735       26
pn0 irq10    1083789644      337
ahc0 irq9      433666        0
clk irq0     321001949       99
rtc irq8     410878329      127
Total        -363703130     -113

The 'total' variable is only a signed long. Could this possibly be changed
to an unsigned long or even a long long?

Fix: 

In vmstat.c:
	
void
dointr()
{
        register long *intrcnt, inttotal, uptime;


inttotal should be changed to an unsigned long, if not a larger datatype.
Comment 1 nick.hibma 1999-07-26 08:32:15 UTC
 > # vmstat -i
 > interrupt      total      rate
 > fxp0 irq11   1986997576      618
 > ata-pci0 irq14 43093267       13
 > ata-pci0 irq15 85069735       26
 > pn0 irq10    1083789644      337
 > ahc0 irq9      433666        0
 > clk irq0     321001949       99
 > rtc irq8     410878329      127
 > Total        -363703130     -113

What's the uptime for this machine? :-)

 > The 'total' variable is only a signed long. Could this possibly be changed
 > to an unsigned long or even a long long?

It definitely should be unsigned, so overflows will make it count from 0
and up.

 > >Fix:

Reboot more often, for example through a crontab?

	2 2 1 1 *	/sbin/reboot


Or apply the following patch. This converts the values into unsigned
long. A better solution would be to convert the values in the kernel and
in vmstat.c to quads I guess. 

--- vmstat.c.old        Wed May 19 15:20:54 1999
+++ vmstat.c    Mon Jul 26 09:27:26 1999
@@ -765,7 +765,7 @@
 void
 dointr()
 {
-       register long *intrcnt, inttotal, uptime;
+       register unsigned long *intrcnt, inttotal, uptime;
        register int nintr, inamlen;
        register char *intrname;
 
@@ -784,12 +784,12 @@
        nintr /= sizeof(long);
        while (--nintr >= 0) {
                if (*intrcnt)
-                       (void)printf("%-12s %8ld %8ld\n", intrname,
+                       (void)printf("%-12s %8lu %8lu\n", intrname,
                            *intrcnt, *intrcnt / uptime);
                intrname += strlen(intrname) + 1;
                inttotal += *intrcnt++;
        }
-       (void)printf("Total        %8ld %8ld\n", inttotal, inttotal /
uptime);
+       (void)printf("Total        %8lu %8lu\n", inttotal, inttotal /
uptime);
 }
 
 #define        MAX_KMSTATS     200

(And the same patch uuencoded)

begin 644 vmstat.c.patch
M+2TM('9M<W1A="YC+F]L9`E7960@36%Y(#$Y(#$U.C(P.C4T(#$Y.3D**RLK
M('9M<W1A="YC"4UO;B!*=6P@,C8@,#DZ,C<Z,C8@,3DY.0I`0"`M-S8U+#<@
M*S<V-2PW($!`"B!V;VED"B!D;VEN='(H*0H@>PHM"7)E9VES=&5R(&QO;F<@
M*FEN=')C;G0L(&EN='1O=&%L+"!U<'1I;64["BL)<F5G:7-T97(@=6YS:6=N
M960@;&]N9R`J:6YT<F-N="P@:6YT=&]T86PL('5P=&EM93L*(`ER96=I<W1E
M<B!I;G0@;FEN='(L(&EN86UL96X["B`)<F5G:7-T97(@8VAA<B`J:6YT<FYA
M;64["B`*0$`@+3<X-"PQ,B`K-S@T+#$R($!`"B`);FEN='(@+ST@<VEZ96]F
M*&QO;F<I.PH@"7=H:6QE("@M+6YI;G1R(#X](#`I('L*(`D):68@*"II;G1R
M8VYT*0HM"0D)*'9O:60I<')I;G1F*"(E+3$R<R`E.&QD("4X;&1<;B(L(&EN
M=')N86UE+`HK"0D)*'9O:60I<')I;G1F*"(E+3$R<R`E.&QU("4X;'5<;B(L
M(&EN=')N86UE+`H@"0D)("`@("II;G1R8VYT+"`J:6YT<F-N="`O('5P=&EM
M92D["B`)"6EN=')N86UE("L]('-T<FQE;BAI;G1R;F%M92D@*R`Q.PH@"0EI
M;G1T;W1A;"`K/2`J:6YT<F-N="LK.PH@"7T*+0DH=F]I9"EP<FEN=&8H(E1O
M=&%L("`@("`@("`E.&QD("4X;&1<;B(L(&EN='1O=&%L+"!I;G1T;W1A;"`O
M('5P=&EM92D["BL)*'9O:60I<')I;G1F*")4;W1A;"`@("`@("`@)3AL=2`E
M.&QU7&XB+"!I;G1T;W1A;"P@:6YT=&]T86P@+R!U<'1I;64I.PH@?0H@"B`C
79&5F:6YE"4U!6%]+35-40513"3(P,`IT
`
end

Nick
-- 
ISIS/STA, T.P.270, Joint Research Centre, 21020 Ispra, Italy
Comment 2 Nick Hibma freebsd_committer freebsd_triage 1999-07-26 08:34:49 UTC
Responsible Changed
From-To: freebsd-bugs->n_hibma

remind me to commit the patch after review 

Comment 3 Nick Hibma freebsd_committer freebsd_triage 1999-07-26 10:18:29 UTC
State Changed
From-To: open->closed

Committed. Thanks!. 

Comment 4 toasty 1999-07-26 20:15:26 UTC
>  > # vmstat -i
>  > interrupt      total      rate
>  > fxp0 irq11   1986997576      618
>  > ata-pci0 irq14 43093267       13
>  > ata-pci0 irq15 85069735       26
>  > pn0 irq10    1083789644      337
>  > ahc0 irq9      433666        0
>  > clk irq0     321001949       99
>  > rtc irq8     410878329      127
>  > Total        -363703130     -113
> 
> What's the uptime for this machine? :-)
> 

su-2.03# uname -a
FreeBSD nfs.dragondata.com 4.0-CURRENT FreeBSD 4.0-CURRENT #2: Thu May  6
00:18:24 CDT 1999     toasty@nfs.dragondata.com:/usr/src/sys/compile/NFS i386
su-2.03# w
 2:11PM  up 38 days,  2:02, 2 users, load averages: 1.60, 1.64, 1.65

38 days isn't an reasonable time to wraparound. :)


Even worse, is another machine of mine:

# vmstat -i
interrupt      total      rate
clk0 irq0    -1099210494      -34
rtc0 irq8    -204812585       -6
fdc0 irq6           1        0
wdc0 irq14   184631379        5
sc0 irq1          254        0
ep0 irq10    -758217127      -23
Total        -1877608572      -58

# w
 2:12PM  up 369 days, 20:15, 1 user, load averages: 0.38, 0.37, 0.33


Everything else appears ok in vmstat though. :)

>  > >Fix:
> 
> Reboot more often, for example through a crontab?
> 
> 	2 2 1 1 *	/sbin/reboot
> 

Nah, 38 day uptimes aren't something to reboot out of. :)

> 
> Or apply the following patch. This converts the values into unsigned
> long. A better solution would be to convert the values in the kernel and
> in vmstat.c to quads I guess. 
> 

Quads would be nice, especially considering my 369 day uptime box. :)



Thanks,

Kevin