Merge branch 'V5-4-patches' into V5-5-patches

* V5-4-patches:
  BUG #a2551: fix non-sequential cpu numbers on HP-UX. Thanks to Dave Olker.
diff --git a/agent/mibgroup/hardware/cpu/cpu_pstat.c b/agent/mibgroup/hardware/cpu/cpu_pstat.c
index 066fd65..8da916f 100644
--- a/agent/mibgroup/hardware/cpu/cpu_pstat.c
+++ b/agent/mibgroup/hardware/cpu/cpu_pstat.c
@@ -22,6 +22,7 @@
 void init_cpu_pstat( void ) {
     int                   i, cpuversion;
     struct pst_dynamic    psd;
+    struct pst_processor  *psp;
     char                  descr[ SNMP_MAXBUF ];
     netsnmp_cpu_info     *cpu = netsnmp_cpu_get_byIdx( -1, 1 );
     strcpy(cpu->name, "Overall CPU statistics");
@@ -58,13 +59,23 @@
     snprintf(descr, SNMP_MAXBUF, "An electronic chip without(?) an HP label");
 #endif
 
+    (void)memset(&psd, 0, sizeof(struct pst_dynamic));
     if (pstat_getdynamic(&psd, sizeof(psd), 1, 0) > 0) {
-        for ( i = 0; i < psd.psd_proc_cnt; i++ ) {
-            cpu = netsnmp_cpu_get_byIdx( i, 1 );
-            sprintf( cpu->name, "cpu%d", i );
-            sprintf( cpu->descr, descr );
+        size_t nspu = psd.psd_max_proc_cnt;
+        psp = (struct pst_processor *)
+                malloc(nspu * sizeof(struct pst_processor));
+        (void)memset(psp, 0, nspu * sizeof(struct pst_processor));
+        if (pstat_getprocessor(psp, sizeof(struct pst_processor), nspu, 0) != -1) {
+            for (i = 0; i < nspu; i++) {
+                if (psp[i].psp_processor_state == PSP_SPU_ENABLED) {
+                    cpu = netsnmp_cpu_get_byIdx( i, 1 );
+                    sprintf( cpu->name, "cpu%d", i );
+                    sprintf( cpu->descr, descr );
+                }
+            }
         }
     }
+    free(psp);
     cpu_num = psd.psd_proc_cnt;
 }
 
@@ -72,45 +83,56 @@
     /*
      * Load the latest CPU usage statistics
      */
-int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) 
+{
     int                   i;
     struct pst_dynamic    psd;
+    struct pst_processor  *psp;
     struct pst_vminfo     psv;
     netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 0 );
 
-    pstat_getdynamic(&psd, sizeof(psd), 1, 0);
-    /* XXX - Compare cpu_num against psd.psd_proc_cnt */
-    cpu->user_ticks = (unsigned long long)psd.psd_cpu_time[CP_USER];
-    cpu->nice_ticks = (unsigned long long)psd.psd_cpu_time[CP_NICE];
-    cpu->sys2_ticks = (unsigned long long)psd.psd_cpu_time[CP_SYS]+
-                                     psd.psd_cpu_time[CP_WAIT];
-    cpu->idle_ticks = (unsigned long long)psd.psd_cpu_time[CP_IDLE];
-    cpu->wait_ticks = (unsigned long long)psd.psd_cpu_time[CP_WAIT];
-    cpu->kern_ticks = (unsigned long long)psd.psd_cpu_time[CP_SYS];
-        /* XXX - record (sum of) "all other ticks" */
-        /* intrpt_ticks, sirq_ticks unused */
+    if (pstat_getdynamic(&psd, sizeof(psd), 1, 0) > 0) {
+        size_t nspu = psd.psd_max_proc_cnt;
+        /* XXX - Compare cpu_num against psd.psd_proc_cnt */
+        cpu->user_ticks = (unsigned long long)psd.psd_cpu_time[CP_USER];
+        cpu->nice_ticks = (unsigned long long)psd.psd_cpu_time[CP_NICE];
+        cpu->sys2_ticks = (unsigned long long)psd.psd_cpu_time[CP_SYS]+
+                          (unsigned long long)psd.psd_cpu_time[CP_WAIT];
+        cpu->idle_ticks = (unsigned long long)psd.psd_cpu_time[CP_IDLE];
+        cpu->wait_ticks = (unsigned long long)psd.psd_cpu_time[CP_WAIT];
+        cpu->kern_ticks = (unsigned long long)psd.psd_cpu_time[CP_SYS];
+            /* XXX - record (sum of) "all other ticks" */
+            /* intrpt_ticks, sirq_ticks unused */
 
-        /*
-         * Interrupt/Context Switch statistics
-         *   XXX - Do these really belong here ?
-         */
-    pstat_getvminfo(&psv, sizeof(psv), 1, 0);
-    cpu->swapIn  = (unsigned long long)psv.psv_sswpin;
-    cpu->swapOut = (unsigned long long)psv.psv_sswpout;
-    cpu->nInterrupts  = (unsigned long long)psv.psv_sintr;
-    cpu->nCtxSwitches = (unsigned long long)psv.psv_sswtch;
+            /*
+             * Interrupt/Context Switch statistics
+             *   XXX - Do these really belong here ?
+             */
+        pstat_getvminfo(&psv, sizeof(psv), 1, 0);
+        cpu->swapIn  = (unsigned long long)psv.psv_sswpin;
+        cpu->swapOut = (unsigned long long)psv.psv_sswpout;
+        cpu->nInterrupts  = (unsigned long long)psv.psv_sintr;
+        cpu->nCtxSwitches = (unsigned long long)psv.psv_sswtch;
 
+        psp = (struct pst_processor *)
+                malloc(nspu * sizeof(struct pst_processor));
+        (void)memset(psp, 0, nspu * sizeof(struct pst_processor));
 
-    for ( i = 0; i < psd.psd_proc_cnt; i++ ) {
-        cpu = netsnmp_cpu_get_byIdx( i, 0 );
-        cpu->user_ticks = (unsigned long long)psd.psd_mp_cpu_time[i][CP_USER];
-        cpu->nice_ticks = (unsigned long long)psd.psd_mp_cpu_time[i][CP_NICE];
-        cpu->sys2_ticks = (unsigned long long)psd.psd_mp_cpu_time[i][CP_SYS]+
-                                         psd.psd_mp_cpu_time[i][CP_WAIT];
-        cpu->idle_ticks = (unsigned long long)psd.psd_mp_cpu_time[i][CP_IDLE];
-        cpu->wait_ticks = (unsigned long long)psd.psd_mp_cpu_time[i][CP_WAIT];
-        cpu->kern_ticks = (unsigned long long)psd.psd_mp_cpu_time[i][CP_SYS];
-        /* XXX - record (sum of) "all other ticks" */
+        if (pstat_getprocessor(psp, sizeof(struct pst_processor), nspu, 0) != -1) {
+            for (i = 0; i < nspu; i++) {
+                if (psp[i].psp_processor_state == PSP_SPU_ENABLED) {
+                    cpu = netsnmp_cpu_get_byIdx( i, 0 );
+                    cpu->user_ticks = (unsigned long long)psp[i].psp_cpu_time[CP_USER];
+                    cpu->nice_ticks = (unsigned long long)psp[i].psp_cpu_time[CP_NICE];
+                    cpu->sys2_ticks = (unsigned long long)psp[i].psp_cpu_time[CP_SYS]+
+                                      (unsigned long long)psp[i].psp_cpu_time[CP_WAIT];
+                    cpu->idle_ticks = (unsigned long long)psp[i].psp_cpu_time[CP_IDLE];
+                    cpu->wait_ticks = (unsigned long long)psp[i].psp_cpu_time[CP_WAIT];
+                    cpu->kern_ticks = (unsigned long long)psp[i].psp_cpu_time[CP_SYS];
+                }
+            }
+        }
+        free(psp);
     }
 
     return 0;