Package: snmpd Version: 5.1.2-6.1 Severity: normal Tags: upstream, patch Hi!
In UCD-SNMP-MIB there are some ssRawCpu* objects defined under systemStats. I use these for RRD graphics and noticed on one machine after several months without reboot, that ssRawCpuIdle reached 4294967295 (=2^32-1) and stayed on this instead of rolling over and starting with 0 again like Counter32 (the type of ssRawCpuIdle) let me expect. I searched the code and found the problem in agent/mibgroup/ucd-snmp/vmstat.c function getstat(), where /proc/stat is read and the line beginning with "cpu " is read using sscanf(b, "cpu %lu %lu %lu %lu %lu %lu %lu", cuse, cice, csys, cide, ciow, cirq, csoft) This causes trouble if one of the numbers becomes larger than 2^32, which results in cide been set to 4294967295 instead of dividing it by 2^32 and showing only the rest. I created the attached patch, which uses sscanf with %llu instead of %lu and scanning into unsigned long long variables which are casted to unsigned long at the end, which realizes the 32bit roll over. My system is Debian sarge with net-snmp 5.1.2-6.1 on i386 Linux 2.6. For the records here an example of plain 5.1.2-6.1: $ snmpwalk -v2c -cxxxxx xxx.xxx.xx.xx 1.3.6.1.4.1.2021.11 [...] UCD-SNMP-MIB::ssCpuRawUser.0 = Counter32: 103338508 UCD-SNMP-MIB::ssCpuRawNice.0 = Counter32: 712456 UCD-SNMP-MIB::ssCpuRawSystem.0 = Counter32: 21972438 UCD-SNMP-MIB::ssCpuRawIdle.0 = Counter32: 4294967295 <--- UCD-SNMP-MIB::ssCpuRawWait.0 = Counter32: 1736944 UCD-SNMP-MIB::ssCpuRawKernel.0 = Counter32: 6566013 UCD-SNMP-MIB::ssCpuRawInterrupt.0 = Counter32: 4044025 [...] And after applying my patch: UCD-SNMP-MIB::ssCpuRawUser.0 = Counter32: 103339140 UCD-SNMP-MIB::ssCpuRawNice.0 = Counter32: 712456 UCD-SNMP-MIB::ssCpuRawSystem.0 = Counter32: 21973413 UCD-SNMP-MIB::ssCpuRawIdle.0 = Counter32: 30284027 <--- UCD-SNMP-MIB::ssCpuRawWait.0 = Counter32: 1737308 UCD-SNMP-MIB::ssCpuRawKernel.0 = Counter32: 6566223 UCD-SNMP-MIB::ssCpuRawInterrupt.0 = Counter32: 4044197 I just reported this to the upstream BTS at sorceforge.net as http://sourceforge.net/tracker/index.php?func=detail&aid=1197183&group_id=12694&atid=112694 Tschoeeee Roland -- System Information: Debian Release: 3.1 APT prefers testing APT policy: (300, 'testing'), (70, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Kernel: Linux 2.4.28 Locale: LANG=de_DE, LC_CTYPE=de_DE (charmap=ISO-8859-1) Versions of packages snmpd depends on: ii libc6 2.3.2.ds1-21 GNU C Library: Shared libraries an ii libsensors3 1:2.9.1-1 library to read temperature/voltag ii libsnmp5 5.1.2-6.1 NET SNMP (Simple Network Managemen ii libwrap0 7.6.dbs-8 Wietse Venema's TCP wrappers libra -- no debconf information -- * [EMAIL PROTECTED] * http://www.spinnaker.de/ *
--- agent/mibgroup/ucd-snmp/vmstat.c.org 2004-04-15 00:32:23.000000000 +0200 +++ agent/mibgroup/ucd-snmp/vmstat.c 2005-05-07 12:43:52.000000000 +0200 @@ -203,6 +203,8 @@ static int bsize = 0, vmbsize = 0; char *b; time_t now; + unsigned long long cusell = 0, cicell = 0, csysll = 0, cidell = 0, + ciowll = 0, cirqll = 0, csoftll = 0; time(&now); if (cache_time + CACHE_TIMEOUT < now) { @@ -245,12 +247,22 @@ b = strstr(buff, "cpu "); if (b) { if (!has_cpu_26 || - sscanf(b, "cpu %lu %lu %lu %lu %lu %lu %lu", cuse, cice, csys, - cide, ciow, cirq, csoft) != 7) { + sscanf(b, "cpu %llu %llu %llu %llu %llu %llu %llu", &cusell, + &cicell, &csysll, &cidell, &ciowll, &cirqll, &csoftll) + != 7) { has_cpu_26 = 0; - sscanf(b, "cpu %lu %lu %lu %lu", cuse, cice, csys, cide); + sscanf(b, "cpu %llu %llu %llu %llu", + &cusell, &cicell, &csysll, &cidell); *ciow = *cirq = *csoft = 0; + } else { + *ciow = (unsigned long)ciowll; + *cirq = (unsigned long)cirqll; + *csoft = (unsigned long)csoftll; } + *cuse = (unsigned long)cusell; + *cice = (unsigned long)cicell; + *csys = (unsigned long)csysll; + *cide = (unsigned long)cidell; } else { if (first)