1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
/*
* perfstat() interface
* e.g. AIX
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-features.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/hardware/cpu.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/protosw.h>
#include <libperfstat.h>
netsnmp_feature_require(hardware_cpu_copy_stats)
void _cpu_copy_stats( netsnmp_cpu_info *cpu );
/*
* Initialise the list of CPUs on the system
* (including descriptions)
*/
void init_cpu_perfstat( void ) {
int i;
perfstat_id_t name;
perfstat_cpu_t *cs2;
netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 1 );
strcpy(cpu->name, "Overall CPU statistics");
cpu_num = perfstat_cpu( NULL, NULL, sizeof(perfstat_cpu_t), 0 );
cs2 = (perfstat_cpu_t*)malloc( cpu_num*sizeof(perfstat_cpu_t));
strcpy( name.name, "");
if (perfstat_cpu(&name, cs2, sizeof(perfstat_cpu_t), cpu_num) > 0) {
for ( i = 0; i < cpu_num; i++ ) {
cpu = netsnmp_cpu_get_byIdx( i, 1 );
sprintf( cpu->name, cs2[i].name);
}
}
free(cs2);
}
/*
* Load the latest CPU usage statistics
*/
int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
int i,n;
perfstat_id_t name;
perfstat_cpu_total_t cs;
perfstat_cpu_t *cs2;
perfstat_memory_total_t ms;
netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 0 );
if (perfstat_cpu_total((perfstat_id_t *)NULL, &cs,
sizeof(perfstat_cpu_total_t), 1) > 0) {
/* Returns 'u_longlong_t' statistics */
cpu->user_ticks = (unsigned long long)cs.user / cs.ncpus;
cpu->sys_ticks = ((unsigned long long)cs.sys + (unsigned long long)cs.wait) / cs.ncpus;
cpu->kern_ticks = (unsigned long long)cs.sys / cs.ncpus;
cpu->wait_ticks = (unsigned long long)cs.wait / cs.ncpus;
cpu->idle_ticks = (unsigned long long)cs.idle / cs.ncpus;
/* intrpt_ticks, sirq_ticks, nice_ticks unused */
/*
* Interrupt/Context Switch statistics
* XXX - Do these really belong here ?
*/
cpu->pageIn = (unsigned long long)cs.sysread;
cpu->pageOut = (unsigned long long)cs.syswrite;
cpu->nInterrupts = (unsigned long long)cs.devintrs + cs.softintrs;
cpu->nCtxSwitches = (unsigned long long)cs.pswitch;
}
if (perfstat_memory_total((perfstat_id_t *)NULL, &ms,
sizeof(perfstat_memory_total_t), 1) > 0) {
cpu->swapIn = (unsigned long long)ms.pgspins;
cpu->swapOut = (unsigned long long)ms.pgspouts;
}
/*
* Per-CPU statistics
*/
n = cs.ncpus; /* XXX - Compare against cpu_num */
cs2 = (perfstat_cpu_t*)malloc( n*sizeof(perfstat_cpu_t));
strcpy( name.name, "");
if (perfstat_cpu(&name, cs2, sizeof(perfstat_cpu_t), n) > 0) {
for ( i = 0; i < n; i++ ) {
cpu = netsnmp_cpu_get_byIdx( i, 0 );
cpu->user_ticks = (unsigned long long)cs2[i].user;
cpu->sys_ticks = (unsigned long long)cs2[i].sys + (unsigned long long)cs2[i].wait;
cpu->kern_ticks = (unsigned long long)cs2[i].sys;
cpu->wait_ticks = (unsigned long long)cs2[i].wait;
cpu->idle_ticks = (unsigned long long)cs2[i].idle;
cpu->pageIn = (unsigned long long)cs2[i].sysread;
cpu->pageOut = (unsigned long long)cs2[i].syswrite;
cpu->nCtxSwitches = (unsigned long long)cs2[i].pswitch;
/* Interrupt stats only apply overall, not per-CPU */
}
} else {
_cpu_copy_stats( cpu );
}
free(cs2);
return 0;
}
|