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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
/*
* sysctl() interface
* e.g. BSD/OS, NetBSD, OpenBSD, later Darwin releases
*/
#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>
#if defined(__FreeBSD__)
#include <sys/resource.h>
#if !defined(CPUSTATES)
#include <sys/dkstat.h>
#endif
#else
#include <sys/sched.h>
#endif
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
#ifdef HAVE_VM_VM_PARAM_H
#include <vm/vm_param.h>
#endif
#ifdef HAVE_VM_VM_EXTERN_H
#include <vm/vm_extern.h>
#endif
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_sysctl( void ) {
int i, n;
size_t siz;
int ncpu_mib[] = { CTL_HW, HW_NCPU };
#if !(defined(__NetBSD__) && ( defined(__i386__) || defined(__x86_64__) ) )
int model_mib[] = { CTL_HW, HW_MODEL };
#endif
char descr[ SNMP_MAXBUF ];
netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 1 );
strcpy(cpu->name, "Overall CPU statistics");
siz = sizeof(n);
sysctl(ncpu_mib, 2, &n, &siz, NULL, 0);
if ( n <= 0 )
n = 1; /* Single CPU system */
siz = sizeof(descr);
#if defined(__NetBSD__) && ( defined(__i386__) || defined(__x86_64__) )
sysctlbyname("machdep.cpu_brand", descr, &siz, NULL, 0);
#else
sysctl(model_mib, 2, descr, &siz, NULL, 0);
#endif
for ( i = 0; i < n; i++ ) {
cpu = netsnmp_cpu_get_byIdx( i, 1 );
cpu->status = 2; /* running */
sprintf( cpu->name, "cpu%d", i );
sprintf( cpu->descr, "%s", descr );
}
cpu_num = n;
}
#if defined(__NetBSD__)
#define NETSNMP_CPU_STATS uint64_t
#else
#define NETSNMP_CPU_STATS long
#endif
#if defined(__NetBSD__)
#define NETSNMP_KERN_CPU KERN_CP_TIME
#elif defined(KERN_CPUSTATS) /* BSDi */
#define NETSNMP_KERN_CPU KERN_CPUSTATS
#elif defined(KERN_CPTIME) /* OpenBSD */
#define NETSNMP_KERN_CPU KERN_CPTIME
#elif defined(__FreeBSD__)
#define NETSNMP_KERN_CPU 0 /* dummy value - sysctlnametomib(2) should be used */
#else
#error "No CPU statistics sysctl token"
#endif
/*
Need to check details before enabling this!
#if defined(KERN_MPCPUSTATS)
#define NETSNMP_KERN_MCPU KERN_MPCPUSTATS
#define NETSNMP_KERN_MCPU_TYPE struct mpcpustats
#elif defined(KERN_MP_CPUSTATS)
#define NETSNMP_KERN_MCPU KERN_MP_CPUSTATS
#define NETSNMP_KERN_MCPU_TYPE struct cpustats
#endif
*/
#if defined(VM_UVMEXP2) || defined(VM_UVMEXP)
#define NS_VM_INTR intrs
#define NS_VM_SWTCH swtch
#define NS_VM_PAGEIN pageins
#define NS_VM_PAGEOUT pdpageouts
#define NS_VM_SWAPIN swapins
#define NS_VM_SWAPOUT swapouts
#if defined(VM_UVMEXP2) /* NetBSD 1.6+ */
#define NETSNMP_VM_STATS VM_UVMEXP2
#define NETSNMP_VM_STATS_TYPE struct uvmexp_sysctl
#else /* VM_UVMEXP */ /* OpenBSD 3+, NetBSD 1.6+ */
#define NETSNMP_VM_STATS VM_UVMEXP
#define NETSNMP_VM_STATS_TYPE struct uvmexp
#endif /* VM_UVMEXP2 || VM_UVMEXP */
#elif defined(__FreeBSD__) /* FreeBSD */
#define NETSNMP_VM_STATS VM_METER
#define NETSNMP_VM_STATS_TYPE struct vmmeter
#define NS_VM_INTR v_intr
#define NS_VM_SWTCH v_swtch
#define NS_VM_PAGEIN v_swappgsin
#define NS_VM_PAGEOUT v_swappgsout
#define NS_VM_SWAPIN v_swapin
#define NS_VM_SWAPOUT v_swapout
#elif defined(VM_METER) /* OpenBSD, NetBSD */
#define NETSNMP_VM_STATS VM_METER
#define NETSNMP_VM_STATS_TYPE struct vmtotal
#elif defined(VM_CNT) /* BSDi */
#define NETSNMP_VM_STATS VM_CNT
#define NETSNMP_VM_STATS_TYPE struct vmmeter
#define NS_VM_INTR v_intr
#define NS_VM_SWTCH v_swtch
#undef NS_VM_PAGEIN
#undef NS_VM_PAGEOUT
#define NS_VM_SWAPIN v_swpin
#define NS_VM_SWAPOUT v_swpout
#endif
/*
* Load the latest CPU usage statistics
*/
int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
#ifdef NETSNMP_KERN_MCPU
int i;
#endif
/*
* Strictly speaking, BSDi ought to use
* "struct cpustats cpu_stats"
* but this array was used in the previous code, and
* is correct for the {Open,Net}BSD versions too.
* Don't fight it, Dave - go with the flow....
*/
NETSNMP_CPU_STATS cpu_stats[CPUSTATES];
#if !defined(__FreeBSD__) && !defined(__NetBSD__)
int cpu_mib[] = { CTL_KERN, NETSNMP_KERN_CPU };
#endif
size_t cpu_size = sizeof(cpu_stats);
#ifdef NETSNMP_KERN_MCPU
NETSNMP_KERN_MCPU_TYPE *mcpu_stats;
int mcpu_mib[] = { CTL_KERN, NETSNMP_KERN_MCPU };
size_t mcpu_size;
#endif
NETSNMP_VM_STATS_TYPE mem_stats;
int mem_mib[] = { CTL_VM, NETSNMP_VM_STATS };
size_t mem_size = sizeof(NETSNMP_VM_STATS_TYPE);
netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 0 );
#if (defined(__FreeBSD__) || defined(__NetBSD__))
sysctlbyname("kern.cp_time", cpu_stats, &cpu_size, NULL, 0);
#else
sysctl(cpu_mib, 2, cpu_stats, &cpu_size, NULL, 0);
#endif
cpu->user_ticks = (unsigned long long)cpu_stats[CP_USER];
cpu->nice_ticks = (unsigned long long)cpu_stats[CP_NICE];
cpu->sys2_ticks = (unsigned long long)cpu_stats[CP_SYS]+cpu_stats[CP_INTR];
cpu->kern_ticks = (unsigned long long)cpu_stats[CP_SYS];
cpu->idle_ticks = (unsigned long long)cpu_stats[CP_IDLE];
cpu->intrpt_ticks = (unsigned long long)cpu_stats[CP_INTR];
/* wait_ticks, sirq_ticks unused */
/*
* Interrupt/Context Switch statistics
* XXX - Do these really belong here ?
*/
sysctl(mem_mib, 2, &mem_stats, &mem_size, NULL, 0);
cpu->nInterrupts = (unsigned long long)mem_stats.NS_VM_INTR;
cpu->nCtxSwitches = (unsigned long long)mem_stats.NS_VM_SWTCH;
cpu->swapIn = (unsigned long long)mem_stats.NS_VM_SWAPIN;
cpu->swapOut = (unsigned long long)mem_stats.NS_VM_SWAPOUT;
#ifdef NS_VM_PAGEIN
cpu->pageIn = (unsigned long long)mem_stats.NS_VM_PAGEIN;
#endif
#ifdef NS_VM_PAGEOUT
cpu->pageOut = (unsigned long long)mem_stats.NS_VM_PAGEOUT;
#endif
#ifdef NETSNMP_KERN_MCPU
mcpu_size = cpu_num*sizeof(NETSNMP_KERN_MCPU_TYPE);
mcpu_stats = malloc(mcpu_size);
sysctl(mcpu_mib, 2, mcpu_stats, &mcpu_size, NULL, 0);
for ( i = 0; i < cpu_num; i++ ) {
cpu = netsnmp_cpu_get_byIdx( i, 0 );
/* XXX - per-CPU statistics - mcpu_mib[i].??? */
}
free(mcpu_stats);
#else
/* Copy "overall" figures to cpu0 entry */
_cpu_copy_stats( cpu );
#endif
return 0;
}
|