There is an error in modules/dashboard/phpsysinfo/class.Linux.inc.php. To calculate CPU utilization, this PHP script reads /proc/stat. However, on a 32-bit multi-CPU system with lots of idle CPU, the idle time field can exceed PHP's maximum integer size of 214748364732 which leads to an incorrect CPU utilization calculation. Here is an example /proc/stat output for my FreePBX system:
# cat /proc/stat
cpu 8961443 2639176 43824894 2243474696 379954 33798 41429 0 0
cpu0 539265 57837 356500 1123950062 121860 17211 24984 0 0
cpu1 8422178 2581339 43468393 1119524633 258094 16586 16444 0 0
...
...
Suggested fix is to replace the long integer arithmetic which is required to support /proc/stat with a call to vmstat, as shown below.
Replace:
if ($bar) {
$buf = rfts( '/proc/stat', 1 );
if( $buf != "ERROR" ) {
sscanf($buf, "%*s %Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae);
// Find out the CPU load
// user + sys = load
// total = total
$load = $ab + $ac + $ad; // cpu.user + cpu.sys
$total = $ab + $ac + $ad + $ae; // cpu.total
// we need a second value, wait 1 second befor getting (< 1 second no good value will occour)
sleep(1);
$buf = rfts( '/proc/stat', 1 );
sscanf($buf, "%*s %Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae);
$load2 = $ab + $ac + $ad;
$total2 = $ab + $ac + $ad + $ae;
$results['cpupercent'] = ($total2 != $total)?((100*($load2 - $load)) / ($total2 - $total)):0;
}
}
with:
if ($bar) {
$results['cpupercent'] = 100 - exec("vmstat -n 1 2 | tail -1 | cut -c 73-74");
}