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)