From: Krisztian Mizser
Subject: UCD-SNMP/SystemStats: add cpusteal, cpuguest, cpuguestnice
References: bnc#604297
Patch-upstream: r20368

Signed-off-by: Leonardo Chiquitto <lchiquitto@suse.de>

---
 agent/mibgroup/hardware/cpu/cpu.c       |    8 ++++
 agent/mibgroup/hardware/cpu/cpu_linux.c |   30 ++++++++++++------
 agent/mibgroup/ucd-snmp/vmstat.c        |   14 ++++++++
 agent/mibgroup/ucd-snmp/vmstat.h        |    3 +
 include/net-snmp/agent/hardware/cpu.h   |    3 +
 mibs/UCD-SNMP-MIB.txt                   |   52 ++++++++++++++++++++++++++++++++
 6 files changed, 99 insertions(+), 11 deletions(-)

Index: agent/mibgroup/hardware/cpu/cpu.c
===================================================================
--- agent/mibgroup/hardware/cpu/cpu.c.orig
+++ agent/mibgroup/hardware/cpu/cpu.c
@@ -213,7 +213,10 @@ _cpu_update_stats( unsigned int reg, voi
                            cpu->wait_ticks +
                            cpu->kern_ticks +
                            cpu->intrpt_ticks +
-                           cpu->sirq_ticks;
+                           cpu->sirq_ticks +
+                           cpu->steal_ticks +
+                           cpu->guest_ticks +
+                           cpu->guestnice_ticks;
     }
 }
 
@@ -236,6 +239,9 @@ void _cpu_copy_stats( netsnmp_cpu_info *
     cpu2->kern_ticks = cpu->kern_ticks;
     cpu2->intrpt_ticks = cpu->intrpt_ticks;
     cpu2->sirq_ticks = cpu->sirq_ticks;
+    cpu2->steal_ticks = cpu->steal_ticks;
+    cpu2->guest_ticks = cpu->guest_ticks;
+    cpu2->guestnice_ticks = cpu->guestnice_ticks;
 
     cpu2->nInterrupts  = cpu->nInterrupts;
     cpu2->nCtxSwitches = cpu->nCtxSwitches;
Index: agent/mibgroup/hardware/cpu/cpu_linux.c
===================================================================
--- agent/mibgroup/hardware/cpu/cpu_linux.c.orig
+++ agent/mibgroup/hardware/cpu/cpu_linux.c
@@ -99,11 +99,12 @@ int netsnmp_cpu_arch_load( netsnmp_cache
     static char *buff  = NULL;
     static int   bsize = 0;
     static int   first = 1;
-    static int   has_cpu_26 = 1;
+    static int   num_cpuline_elem = 0;
     int          statfd, i;
     char        *b1, *b2;
     unsigned long long cusell = 0, cicell = 0, csysll = 0, cidell = 0,
-                       ciowll = 0, cirqll = 0, csoftll = 0;
+                       ciowll = 0, cirqll = 0, csoftll = 0, cstealll = 0,
+                       cguestll = 0, cguest_nicell = 0;
     netsnmp_cpu_info* cpu;
 
     if ((statfd = open(STAT_FILE, O_RDONLY, 0)) == -1) {
@@ -146,14 +147,25 @@ int netsnmp_cpu_arch_load( netsnmp_cache
             b1 = b2+5; /* Skip "cpuN " */
         }
 
-	if (!has_cpu_26 ||
-            sscanf(b1, "%llu %llu %llu %llu %llu %llu %llu", &cusell,
-                   &cicell, &csysll, &cidell, &ciowll, &cirqll, &csoftll) != 7) {
-	    has_cpu_26 = 0;
-	    sscanf(b1, "%llu %llu %llu %llu", &cusell, &cicell, &csysll,
-                   &cidell);
+        num_cpuline_elem = sscanf(b1, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
+            &cusell, &cicell, &csysll, &cidell, &ciowll, &cirqll, &csoftll,
+            &cstealll, &cguestll, &cguest_nicell);
+        DEBUGMSGTL(("cpu", "/proc/stat cpu line number of elements: %i\n", num_cpuline_elem));
 
-	} else {
+        // kernel 2.6.33 and above
+        if (num_cpuline_elem == 10) {
+            cpu->guestnice_ticks = (unsigned long)cguest_nicell;
+        }
+        // kernel 2.6.24 and above
+        if (num_cpuline_elem >= 9) {
+            cpu->guest_ticks = (unsigned long)cguestll;
+        }
+        // kernel 2.6.11 and above
+        if (num_cpuline_elem >= 8) {
+            cpu->steal_ticks = (unsigned long)cstealll;
+        }
+        // kernel 2.6
+        if (num_cpuline_elem >= 5) {
             cpu->wait_ticks   = (unsigned long)ciowll;
             cpu->intrpt_ticks = (unsigned long)cirqll;
             cpu->sirq_ticks   = (unsigned long)csoftll;
Index: agent/mibgroup/ucd-snmp/vmstat.c
===================================================================
--- agent/mibgroup/ucd-snmp/vmstat.c.orig
+++ agent/mibgroup/ucd-snmp/vmstat.c
@@ -20,7 +20,7 @@ init_vmstat(void)
         netsnmp_create_handler_registration("vmstat", vmstat_handler,
                              vmstat_oid, OID_LENGTH(vmstat_oid),
                              HANDLER_CAN_RONLY),
-        MIBINDEX, RAWSWAPOUT);
+        MIBINDEX, CPURAWGUESTNICE);
 }
 
 
@@ -112,6 +112,18 @@ vmstat_handler(netsnmp_mib_handler
              snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
                                         info->sirq_ticks & 0xffffffff);
              break;
+        case CPURAWSTEAL:
+             snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+                                        info->steal_ticks & 0xffffffff);
+             break;
+        case CPURAWGUEST:
+             snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+                                        info->guest_ticks & 0xffffffff);
+             break;
+        case CPURAWGUESTNICE:
+             snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+                                        info->guestnice_ticks & 0xffffffff);
+             break;
 
         /*
          *  'Cooked' CPU statistics
Index: agent/mibgroup/ucd-snmp/vmstat.h
===================================================================
--- agent/mibgroup/ucd-snmp/vmstat.h.orig
+++ agent/mibgroup/ucd-snmp/vmstat.h
@@ -36,5 +36,8 @@ void              init_vmstat(void);
 #define CPURAWSOFTIRQ 61
 #define RAWSWAPIN 62
 #define RAWSWAPOUT 63
+#define CPURAWSTEAL 64
+#define CPURAWGUEST 65
+#define CPURAWGUESTNICE 66
 
 #endif                          /* _MIBGROUP_VMSTAT_H */
Index: include/net-snmp/agent/hardware/cpu.h
===================================================================
--- include/net-snmp/agent/hardware/cpu.h.orig
+++ include/net-snmp/agent/hardware/cpu.h
@@ -33,6 +33,9 @@ struct netsnmp_cpu_info_s {
      long kern_ticks;
      long intrpt_ticks;
      long sirq_ticks;
+     long steal_ticks;
+     long guest_ticks;
+     long guestnice_ticks;
 
      long total_ticks;
      long sys2_ticks;  /* For non-atomic system counts */
Index: mibs/UCD-SNMP-MIB.txt
===================================================================
--- mibs/UCD-SNMP-MIB.txt.orig
+++ mibs/UCD-SNMP-MIB.txt
@@ -1348,6 +1348,58 @@ ssRawSwapOut OBJECT-TYPE
         "Number of blocks swapped out"
     ::= { systemStats 63 }
 
+ssCpuRawSteal OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "The number of 'ticks' (typically 1/100s) spent
+         by the hypervisor code to run other VMs even
+         though the CPU in the current VM had something runnable.
+
+         This object will not be implemented on hosts where
+         the underlying operating system does not measure
+         this particular CPU metric.
+
+         On a multi-processor system, the 'ssCpuRaw*'
+         counters are cumulative over all CPUs, so their
+         sum will typically be N*100 (for N processors)."
+    ::= { systemStats 64 }
+
+ssCpuRawGuest OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "The number of 'ticks' (typically 1/100s) spent
+         by the CPU to run a virtual CPU (guest).
+
+         This object will not be implemented on hosts where
+         the underlying operating system does not measure
+         this particular CPU metric.
+
+         On a multi-processor system, the 'ssCpuRaw*'
+         counters are cumulative over all CPUs, so their
+         sum will typically be N*100 (for N processors)."
+    ::= { systemStats 65 }
+
+ssCpuRawGuestNice OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "The number of 'ticks' (typically 1/100s) spent
+         by the CPU to run a niced virtual CPU (guest).
+
+         This object will not be implemented on hosts where
+         the underlying operating system does not measure
+         this particular CPU metric.
+
+         On a multi-processor system, the 'ssCpuRaw*'
+         counters are cumulative over all CPUs, so their
+         sum will typically be N*100 (for N processors)."
+    ::= { systemStats 66 }
+
 -- possibly used in the future:
 --
 -- ssErrorFlag OBJECT-TYPE
