Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 20db51d70e6b59a061db97ce9b89c771 > files > 12

net-snmp-5.3.2.2-14.el5.src.rpm

431439: CRM #1765368 HOST-RESOURCES-MIB::hrProcessorLoad

Author: cpu_linux.c: upstream, svn diff -r 15025:15026 + 17191
        hr_proc.c: Jan Safranek <jsafrane@redhat.com> (inspired by svn ver. 15026)
                   - just move the computation to the 'old' place

This patch fixes reading of CPU stats on multi-CPU machines + computes the load
in proper way (was: based on load average, now: based on real tick counts).

diff -ur --exclude '*.o' --exclude .libs --exclude '*.lo' --exclude man --exclude perl --exclude apps --exclude local --exclude '*.la' --exclude snmpd --exclude net-snmp-config-x --exclude net-snmp-config.h --exclude Makefile --exclude config.log --exclude config.sub --exclude config.status --exclude config.guess --exclude '*.orig' orig/agent/mibgroup/hardware/cpu/cpu_linux.c net-snmp-5.3.1/agent/mibgroup/hardware/cpu/cpu_linux.c
--- orig/agent/mibgroup/hardware/cpu/cpu_linux.c	2005-07-21 00:07:41.000000000 +0200
+++ net-snmp-5.3.1/agent/mibgroup/hardware/cpu/cpu_linux.c	2008-02-07 12:56:16.000000000 +0100
@@ -46,7 +46,7 @@
 #endif
         }
 
-#ifdef DESCR2_FIELD
+#ifdef DESCR_FIELD
         if (!strncmp( buf, DESCR_FIELD, strlen(DESCR_FIELD))) {
             cp = strchr( buf, ':' );
             strcpy( cpu->descr, cp+2 );
@@ -76,18 +76,12 @@
     static int   bsize = 0;
     static int   first = 1;
     static int   has_cpu_26 = 1;
-    int          statfd;
-    char        *b;
+    int          statfd, i;
+    char        *b1, *b2;
     unsigned long long cusell = 0, cicell = 0, csysll = 0, cidell = 0,
                        ciowll = 0, cirqll = 0, csoftll = 0;
     netsnmp_cpu_info* cpu;
 
-    cpu = netsnmp_cpu_get_byIdx( -1, 0 );
-    if (!cpu) {
-        snmp_log_perror("No CPU info entry");
-        return -1;
-    }
-
     if ((statfd = open(STAT_FILE, O_RDONLY, 0)) == -1) {
         snmp_log_perror(STAT_FILE);
         return -1;
@@ -106,15 +100,32 @@
     close(statfd);
 
         /*
-         * Overall CPU statistics
+         * CPU statistics (overall and per-CPU)
          */
-    b = strstr(buff, "cpu ");
-    if (b) {
+    b1 = buff;
+    while ( b2 = strstr( b1, "cpu" )) {
+        if (b2[3] == ' ') {
+            cpu = netsnmp_cpu_get_byIdx( -1, 0 );
+            if (!cpu) {
+                snmp_log_perror("No (overall) CPU info entry");
+                return -1;
+            }
+            b1 = b2+4; /* Skip "cpu " */
+        } else {
+            sscanf( b2, "cpu%d", &i );
+            cpu = netsnmp_cpu_get_byIdx( i, 0 );
+            if (!cpu) {
+                snmp_log_perror("Missing CPU info entry");
+                break;
+            }
+            b1 = b2+5; /* Skip "cpuN " */
+        }
+
 	if (!has_cpu_26 ||
-            sscanf(b, "cpu  %llu %llu %llu %llu %llu %llu %llu", &cusell,
+            sscanf(b1, "%llu %llu %llu %llu %llu %llu %llu", &cusell,
                    &cicell, &csysll, &cidell, &ciowll, &cirqll, &csoftll) != 7) {
 	    has_cpu_26 = 0;
-	    sscanf(b, "cpu  %llu %llu %llu %llu", &cusell, &cicell, &csysll,
+	    sscanf(b1, "%llu %llu %llu %llu", &cusell, &cicell, &csysll,
                    &cidell);
 
 	} else {
@@ -126,7 +137,8 @@
         cpu->nice_ticks = (unsigned long)cicell;
         cpu->sys_ticks  = (unsigned long)csysll;
         cpu->idle_ticks = (unsigned long)cidell;
-    } else {
+    }
+    if ( b1 == buff ) {
 	if (first)
 	    snmp_log(LOG_ERR, "No cpu line in %s\n", STAT_FILE);
     }
@@ -135,6 +147,7 @@
          * Interrupt/Context Switch statistics
          *   XXX - Do these really belong here ?
          */
+    cpu = netsnmp_cpu_get_byIdx( -1, 0 );
     _cpu_load_swap_etc( buff, cpu );
 
     /*
@@ -181,7 +194,7 @@
 	b = strstr(vmbuff, "pgpgin ");
 	if (b) {
 	    sscanf(b, "pgpgin %llu", &pin);
-            cpu->pageIn  = (unsigned long)pin;
+            cpu->pageIn  = (unsigned long)pin*2;  /* ??? */
 	} else {
 	    if (first)
 		snmp_log(LOG_ERR, "No pgpgin line in %s\n", VMSTAT_FILE);
@@ -190,7 +203,7 @@
 	b = strstr(vmbuff, "pgpgout ");
 	if (b) {
 	    sscanf(b, "pgpgout %llu", &pout);
-            cpu->pageOut = (unsigned long)pout;
+            cpu->pageOut = (unsigned long)pout*2;  /* ??? */
 	} else {
 	    if (first)
 		snmp_log(LOG_ERR, "No pgpgout line in %s\n", VMSTAT_FILE);
diff -ur --exclude '*.o' --exclude .libs --exclude '*.lo' --exclude man --exclude perl --exclude apps --exclude local --exclude '*.la' --exclude snmpd --exclude net-snmp-config-x --exclude net-snmp-config.h --exclude Makefile --exclude config.log --exclude config.sub --exclude config.status --exclude config.guess --exclude '*.orig' orig/agent/mibgroup/host/hr_proc.c net-snmp-5.3.1/agent/mibgroup/host/hr_proc.c
--- orig/agent/mibgroup/host/hr_proc.c	2006-05-19 19:02:22.000000000 +0200
+++ net-snmp-5.3.1/agent/mibgroup/host/hr_proc.c	2008-02-07 12:56:35.000000000 +0100
@@ -199,26 +199,36 @@
 {
     int             proc_idx;
     double          avenrun[3];
+    netsnmp_cpu_info *cpu;
+    long            cpu_total_ticks;
 
     proc_idx =
         header_hrproc(vp, name, length, exact, var_len, write_method);
     if (proc_idx == MATCH_FAILED)
         return NULL;
-    if (try_getloadavg(&avenrun[0], sizeof(avenrun) / sizeof(avenrun[0]))
-        == -1)
-        return NULL;
 
     switch (vp->magic) {
     case HRPROC_ID:
         *var_len = nullOidLen;
         return (u_char *) nullOid;
     case HRPROC_LOAD:
-#if NO_DUMMY_VALUES
-        return NULL;
-#endif
-        long_return = avenrun[0] * 100; /* 1 minute average */
-        if (long_return > 100)
-            long_return = 100;
+        cpu = netsnmp_cpu_get_byIdx( proc_idx & HRDEV_TYPE_MASK, 0 );
+        if ( !cpu || !cpu->history[0].total_hist ) 
+            return NULL;
+        cpu_total_ticks = cpu->user_ticks +
+                            cpu->nice_ticks +
+                            cpu->sys_ticks +
+                            cpu->idle_ticks +
+                            cpu->wait_ticks +
+                            cpu->kern_ticks +
+                            cpu->intrpt_ticks +
+                            cpu->sirq_ticks;
+        *var_len = sizeof(long_return);
+        long_return  = (cpu->idle_ticks  - cpu->history[0].idle_hist)*100;
+        long_return /= (cpu_total_ticks - cpu->history[0].total_hist);
+        long_return  = 100 - long_return;
+        if (long_return < 0)
+            long_return = 0;
         return (u_char *) & long_return;
     default:
         DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrproc\n",
diff --git a/net-snmp/agent/mibgroup/hardware/cpu/cpu_linux.c b/net-snmp/agent/mibgroup/hardware/cpu/cpu_linux.c
--- orig/agent/mibgroup/hardware/cpu/cpu_linux.c
+++ net-snmp/agent/mibgroup/hardware/cpu/cpu_linux.c
@@ -56,6 +56,15 @@ void init_cpu_linux( void ) {
             strcat( cpu->descr, "An S/390 CPU" );
 #endif
         }
+#if defined(__s390__) || defined(__s390x__)
+        else { /* s390 has different format of CPU_FILE */
+            if (sscanf( buf, "processor %d:", &i ) == 1)  {
+                cpu = netsnmp_cpu_get_byIdx( i, 1 );
+                sprintf( cpu->name, "cpu%d", i );
+                strcat( cpu->descr, "An S/390 CPU" );
+            }
+        }
+#endif
 
 #ifdef DESCR_FIELD
         if (!strncmp( buf, DESCR_FIELD, strlen(DESCR_FIELD))) {