|
1 --- a/include/net-snmp/agent/hardware/cpu.h 2014-06-09 04:44:56.766491669 -0700 |
|
2 +++ b/include/net-snmp/agent/hardware/cpu.h 2014-06-09 04:45:47.845551969 -0700 |
|
3 @@ -52,6 +52,11 @@ |
|
4 netsnmp_cpu_info *next; |
|
5 }; |
|
6 |
|
7 + /* Auxilary structure used for updating the new cpu list */ |
|
8 +struct cpu_idx { |
|
9 + int idx; |
|
10 + struct cpu_idx *next; |
|
11 +}; |
|
12 |
|
13 /* |
|
14 * Possibly not all needed ?? |
|
15 @@ -60,6 +65,7 @@ |
|
16 netsnmp_cpu_info *netsnmp_cpu_get_next( netsnmp_cpu_info* ); |
|
17 netsnmp_cpu_info *netsnmp_cpu_get_byIdx( int, int ); |
|
18 netsnmp_cpu_info *netsnmp_cpu_get_byName( char*, int ); |
|
19 +int netsnmp_update_cpu_list( struct cpu_idx * ); /* returns the number of deleted cpus */ |
|
20 |
|
21 netsnmp_cache *netsnmp_cpu_get_cache( void ); |
|
22 int netsnmp_cpu_load( void ); |
|
23 --- a/agent/mibgroup/hardware/cpu/cpu.c 2014-06-09 04:44:56.766855758 -0700 |
|
24 +++ b/agent/mibgroup/hardware/cpu/cpu.c 2014-06-19 05:07:54.648759853 -0700 |
|
25 @@ -244,3 +244,59 @@ |
|
26 cpu2->pageIn = cpu->pageIn; |
|
27 cpu2->pageOut = cpu->pageOut; |
|
28 } |
|
29 + |
|
30 + /* |
|
31 + * Updates the cpu list, keeping the cpus whose indices are passed |
|
32 + * assumes the passed linked list of indices is sorted in ascending order |
|
33 + * returns the number of deleted cpus |
|
34 + */ |
|
35 +int netsnmp_update_cpu_list( struct cpu_idx *new_cpu_list ) |
|
36 +{ |
|
37 + netsnmp_cpu_info *prev, *current, *temp1, *temp2; |
|
38 + int n=0; |
|
39 + netsnmp_cpu_info *cpu; |
|
40 + |
|
41 + for( prev=current=_cpu_head; current && new_cpu_list ; |
|
42 + current=current->next, new_cpu_list=new_cpu_list->next ) { |
|
43 + if ( current->idx == new_cpu_list->idx ) { |
|
44 + prev=current; |
|
45 + } else { |
|
46 + current=current->next; |
|
47 + while ( current && (current->idx != new_cpu_list->idx) ) |
|
48 + current = current->next; |
|
49 + if ( !current ) { |
|
50 + /*This shouldn't happen. Something went really wrong */ |
|
51 + return -1; |
|
52 + } |
|
53 + |
|
54 + temp1 = prev->next; |
|
55 + prev->next = current; |
|
56 + prev = current; |
|
57 + /* remove the unassigned cpus */ |
|
58 + while ( temp1 != current ) { |
|
59 + temp2 = temp1; |
|
60 + temp1 = temp1->next; |
|
61 + n++; |
|
62 + SNMP_FREE(temp2->history); |
|
63 + SNMP_FREE(temp2); |
|
64 + } |
|
65 + } |
|
66 + } /*end of for */ |
|
67 + |
|
68 + if ( !current && new_cpu_list ) { |
|
69 + /* This shouldn't happen. */ |
|
70 + return -1; |
|
71 + } |
|
72 + |
|
73 + /* Delete the unassigned trailing cpus from the list */ |
|
74 + while ( current ) { |
|
75 + temp2 = current; |
|
76 + current = current->next; |
|
77 + n++; |
|
78 + SNMP_FREE(temp2->history); |
|
79 + SNMP_FREE(temp2); |
|
80 + } |
|
81 + prev->next = NULL; |
|
82 + return n; |
|
83 +} |
|
84 + |
|
85 --- a/agent/mibgroup/hardware/cpu/cpu_kstat.c 2014-06-09 04:44:56.766680662 -0700 |
|
86 +++ b/agent/mibgroup/hardware/cpu/cpu_kstat.c 2014-06-19 04:53:47.176189429 -0700 |
|
87 @@ -17,16 +17,16 @@ |
|
88 extern kstat_ctl_t *kstat_fd; |
|
89 extern int cpu_num; |
|
90 int _cpu_status(char *state); |
|
91 +static void add_new_kstat_cpu_entry(kstat_t *ksp); |
|
92 +static struct cpu_idx * add_cpu_idx(struct cpu_idx * head, int idx); |
|
93 |
|
94 /* |
|
95 * Initialise the list of CPUs on the system |
|
96 * (including descriptions) |
|
97 */ |
|
98 void init_cpu_kstat( void ) { |
|
99 - int i, n=0, clock, state_begin; |
|
100 - char ctype[15], ftype[15], state[10]; |
|
101 + int n=0; |
|
102 kstat_t *ksp; |
|
103 - kstat_named_t *ks_data; |
|
104 netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 1 ); |
|
105 strcpy(cpu->name, "Overall CPU statistics"); |
|
106 |
|
107 @@ -41,36 +41,50 @@ |
|
108 if ((strcmp(ksp->ks_module, "cpu_info") == 0) && |
|
109 (strcmp(ksp->ks_class, "misc" ) == 0)) { |
|
110 kstat_read(kstat_fd, ksp, NULL ); |
|
111 + add_new_kstat_cpu_entry(ksp); |
|
112 n++; |
|
113 - clock = 999999; |
|
114 - memset(ctype, 0, sizeof(ctype)); |
|
115 - memset(ftype, 0, sizeof(ftype)); |
|
116 - memset(state, 0, sizeof(state)); |
|
117 - for (i=0, ks_data = ksp->ks_data; i < ksp->ks_ndata; i++, ks_data++) { |
|
118 - if ( strcmp( ks_data->name, "state" ) == 0 ) { |
|
119 - strncpy( state, ks_data->value.c, sizeof(state)); |
|
120 - state[sizeof(state)-1] = '\0'; |
|
121 - } else if ( strcmp( ks_data->name, "state_begin" ) == 0 ) { |
|
122 - state_begin = ks_data->value.i32; |
|
123 - } else if ( strcmp( ks_data->name, "cpu_type" ) == 0 ) { |
|
124 - strncpy( ctype, ks_data->value.c, sizeof(ctype)); |
|
125 - state[sizeof(ctype)-1] = '\0'; |
|
126 - } else if ( strcmp( ks_data->name, "fpu_type" ) == 0 ) { |
|
127 - strncpy( ftype, ks_data->value.c, sizeof(ftype)); |
|
128 - state[sizeof(ftype)-1] = '\0'; |
|
129 - } else if ( strcmp( ks_data->name, "clock_MHz" ) == 0 ) { |
|
130 - clock = ks_data->value.i32; |
|
131 - } |
|
132 - } |
|
133 - i = ksp->ks_instance; |
|
134 - cpu = netsnmp_cpu_get_byIdx( i, 1 ); |
|
135 - sprintf( cpu->name, "cpu%d", i ); |
|
136 - sprintf( cpu->descr, "CPU %d Sun %d MHz %s with %s FPU %s", |
|
137 - i, clock, ctype, ftype, state ); |
|
138 - cpu->status = _cpu_status(state); /* XXX - or in 'n_c_a_load' ? */ |
|
139 } |
|
140 } |
|
141 - cpu_num = i; |
|
142 + cpu_num = n; |
|
143 +} |
|
144 + |
|
145 + |
|
146 + /* |
|
147 + * adds the new cpu entry to the exisitng list |
|
148 + */ |
|
149 +static void |
|
150 +add_new_kstat_cpu_entry( kstat_t *ksp ) { |
|
151 + int i, clock, state_begin; |
|
152 + char ctype[15], ftype[15], state[10]; |
|
153 + kstat_named_t *ks_data; |
|
154 + netsnmp_cpu_info *cpu; |
|
155 + |
|
156 + clock = 999999; |
|
157 + memset(ctype, 0, sizeof(ctype)); |
|
158 + memset(ftype, 0, sizeof(ftype)); |
|
159 + memset(state, 0, sizeof(state)); |
|
160 + |
|
161 + for (i=0, ks_data = ksp->ks_data; i < ksp->ks_ndata; i++, ks_data++) { |
|
162 + if ( strcmp( ks_data->name, "state" ) == 0 ) { |
|
163 + strncpy( state, ks_data->value.c, sizeof(state)); |
|
164 + state[sizeof(state)-1] = '\0'; |
|
165 + } else if ( strcmp( ks_data->name, "state_begin" ) == 0 ) { |
|
166 + state_begin = ks_data->value.i32; |
|
167 + } else if ( strcmp( ks_data->name, "cpu_type" ) == 0 ) { |
|
168 + strncpy( ctype, ks_data->value.c, sizeof(ctype)); |
|
169 + ctype[sizeof(ctype)-1] = '\0'; |
|
170 + } else if ( strcmp( ks_data->name, "fpu_type" ) == 0 ) { |
|
171 + strncpy( ftype, ks_data->value.c, sizeof(ftype)); |
|
172 + ftype[sizeof(ftype)-1] = '\0'; |
|
173 + } else if ( strcmp( ks_data->name, "clock_MHz" ) == 0 ) { |
|
174 + clock = ks_data->value.i32; |
|
175 + } |
|
176 + } |
|
177 + i = ksp->ks_instance; |
|
178 + cpu = netsnmp_cpu_get_byIdx( i, 1 ); |
|
179 + sprintf( cpu->name, "cpu%d", i ); |
|
180 + sprintf( cpu->descr, "CPU %d Sun %d MHz %s with %s FPU %s", i, clock, ctype, ftype, state ); |
|
181 + cpu->status = _cpu_status(state); |
|
182 } |
|
183 |
|
184 |
|
185 @@ -78,11 +92,12 @@ |
|
186 * Load the latest CPU usage statistics |
|
187 */ |
|
188 int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) { |
|
189 - int i=1; |
|
190 + int i=1, n=0; |
|
191 kstat_t *ksp; |
|
192 cpu_stat_t cs; |
|
193 netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 0 ); |
|
194 netsnmp_cpu_info *cpu2; |
|
195 + struct cpu_idx *new_cpu_list = NULL, *temp_cpu_idx; |
|
196 |
|
197 /* Clear overall stats, ready for summing individual CPUs */ |
|
198 cpu->user_ticks = 0; |
|
199 @@ -97,6 +112,32 @@ |
|
200 |
|
201 kstat_chain_update( kstat_fd ); |
|
202 DEBUGMSGTL(("cpu", "cpu_kstat load\n ")); |
|
203 + |
|
204 + /* |
|
205 + * The stats update is three step. |
|
206 + * First - add in the new cpus' info to the linked list |
|
207 + */ |
|
208 + for (ksp = kstat_fd->kc_chain; ksp != NULL; ksp = ksp->ks_next) { |
|
209 + if (ksp->ks_flags & KSTAT_FLAG_INVALID) |
|
210 + continue; |
|
211 + if ((strcmp(ksp->ks_module, "cpu_info") == 0) && |
|
212 + (strcmp(ksp->ks_class, "misc" ) == 0)) { |
|
213 + kstat_read(kstat_fd, ksp, NULL ); |
|
214 + i = ksp->ks_instance; |
|
215 + new_cpu_list = add_cpu_idx( new_cpu_list, i); |
|
216 + cpu2 = netsnmp_cpu_get_byIdx( i, 0 ); |
|
217 + if ( !cpu2 ) { |
|
218 + add_new_kstat_cpu_entry(ksp); |
|
219 + n++; |
|
220 + } |
|
221 + } |
|
222 + } |
|
223 + |
|
224 + |
|
225 + /* Second - update the CPU list to reflect new kernel structures */ |
|
226 + n -= netsnmp_update_cpu_list( new_cpu_list ); |
|
227 + |
|
228 + /* Third - for updating stats for the new CPU set */ |
|
229 for (ksp = kstat_fd->kc_chain; ksp != NULL; ksp = ksp->ks_next) { |
|
230 if (ksp->ks_flags & KSTAT_FLAG_INVALID) |
|
231 continue; |
|
232 @@ -104,7 +145,7 @@ |
|
233 i = ksp->ks_instance; |
|
234 cpu2 = netsnmp_cpu_get_byIdx( i, 0 ); |
|
235 if ( !cpu2 ) |
|
236 - break; /* or continue ?*/ /*Skip new CPUs */ |
|
237 + continue; /* This shouldn't happen. Inconsistency in kstat CPU data */ |
|
238 if ((ksp->ks_type != KSTAT_TYPE_RAW) || |
|
239 (ksp->ks_data_size != sizeof(cs))|| |
|
240 (kstat_read(kstat_fd, ksp, &cs) == -1)) { |
|
241 @@ -138,9 +179,43 @@ |
|
242 cpu->nCtxSwitches += (unsigned long)cs.cpu_sysinfo.pswitch; |
|
243 } |
|
244 } |
|
245 + cpu_num += n; |
|
246 + /* Clean up the temporary CPU index list */ |
|
247 + while(new_cpu_list) { |
|
248 + temp_cpu_idx = new_cpu_list; |
|
249 + new_cpu_list = new_cpu_list->next; |
|
250 + SNMP_FREE(temp_cpu_idx); |
|
251 + } |
|
252 return 0; |
|
253 } |
|
254 |
|
255 + /* returns the new head */ |
|
256 +static struct cpu_idx * |
|
257 +add_cpu_idx(struct cpu_idx * head, int idx) |
|
258 +{ |
|
259 + struct cpu_idx *cpu_idx, *current; |
|
260 + cpu_idx = SNMP_MALLOC_TYPEDEF( struct cpu_idx ); |
|
261 + if ( !cpu_idx ) { |
|
262 + DEBUGMSG(("cpu", "(cpu_idx creation failed)\n")); |
|
263 + return head; |
|
264 + } |
|
265 + |
|
266 + cpu_idx->idx = idx; |
|
267 + if ( !head || head->idx > idx ) { |
|
268 + cpu_idx->next = head; |
|
269 + return cpu_idx; |
|
270 + } |
|
271 + |
|
272 + for ( current=head; current; current=current->next ) { |
|
273 + if ( !current->next || current->next->idx > idx ) { |
|
274 + cpu_idx->next = current->next; |
|
275 + current->next = cpu_idx; |
|
276 + return head; |
|
277 + } |
|
278 + } |
|
279 + |
|
280 +} |
|
281 + |
|
282 int |
|
283 _cpu_status( char *state) |
|
284 { |