]>
Commit | Line | Data |
---|---|---|
4f99ac2f | 1 | 351991: Port net-snmp to lm_sensors-3.x.x |
2 | Source: upstream, svn diff -r 16736:16739 | |
3 | Reviewed-By: Jan Safranek <jsafrane@redhat.com> | |
4 | ||
5 | Index: configure | |
6 | =================================================================== | |
7 | --- configure (revision 16736) | |
8 | +++ configure (revision 16739) | |
9 | @@ -32628,7 +32628,7 @@ | |
10 | fi | |
11 | ||
12 | # LM-SENSORS-MIB support | |
13 | -echo " $module_list " | grep " ucd-snmp/lmSensors " > /dev/null | |
14 | +echo " $module_list " | $GREP -i "ucd-snmp/lmsensor" > /dev/null | |
15 | if test $? -eq 0 ; then | |
16 | { echo "$as_me:$LINENO: checking for sensors support" >&5 | |
17 | echo $ECHO_N "checking for sensors support... $ECHO_C" >&6; } | |
18 | Index: include/net-snmp/agent/hardware/sensors.h | |
19 | =================================================================== | |
20 | --- include/net-snmp/agent/hardware/sensors.h (revision 0) | |
21 | +++ include/net-snmp/agent/hardware/sensors.h (revision 16739) | |
22 | @@ -0,0 +1,48 @@ | |
23 | +/* | |
24 | + * Hardware Abstraction Layer - Sensors module | |
25 | + * | |
26 | + * Public interface | |
27 | + */ | |
28 | + | |
29 | +#define NETSNMP_SENSOR_TYPE_OTHER 1 | |
30 | +#define NETSNMP_SENSOR_TYPE_VOLTAGE_AC 3 | |
31 | +#define NETSNMP_SENSOR_TYPE_VOLTAGE_DC 4 | |
32 | +#define NETSNMP_SENSOR_TYPE_CURRENT 5 | |
33 | +#define NETSNMP_SENSOR_TYPE_POWER 6 | |
34 | +#define NETSNMP_SENSOR_TYPE_FREQUENCY 7 | |
35 | +#define NETSNMP_SENSOR_TYPE_TEMPERATURE 8 | |
36 | +#define NETSNMP_SENSOR_TYPE_HUMIDITY 9 | |
37 | +#define NETSNMP_SENSOR_TYPE_RPM 10 | |
38 | +#define NETSNMP_SENSOR_TYPE_VOLUME 11 | |
39 | +#define NETSNMP_SENSOR_TYPE_BOOLEAN 12 | |
40 | + | |
41 | + | |
42 | +#define NETSNMP_SENSOR_FLAG_ACTIVE 0x01 | |
43 | +#define NETSNMP_SENSOR_FLAG_NAVAIL 0x02 | |
44 | +#define NETSNMP_SENSOR_FLAG_BROKEN 0x04 | |
45 | +#define NETSNMP_SENSOR_FLAG_DISABLE 0x08 | |
46 | + | |
47 | +#define NETSNMP_SENSOR_MASK_STATUS 0x06 /* NAVAIL|BROKEN */ | |
48 | + | |
49 | + | |
50 | +#define NETSNMP_SENSOR_FIND_CREATE 1 /* or use one of the sensor type values */ | |
51 | +#define NETSNMP_SENSOR_FIND_EXIST 0 | |
52 | + | |
53 | +typedef struct netsnmp_sensor_info_s netsnmp_sensor_info; | |
54 | +struct netsnmp_sensor_info_s { | |
55 | + | |
56 | + netsnmp_index idx; | |
57 | + /* int idx; */ | |
58 | + char name[256]; | |
59 | + | |
60 | + int type; | |
61 | + float value; | |
62 | + char descr[256]; | |
63 | + long flags; | |
64 | +}; | |
65 | + | |
66 | +netsnmp_container *get_sensor_container( void ); | |
67 | +netsnmp_cache *get_sensor_cache( void ); | |
68 | +netsnmp_sensor_info *sensor_by_name( char *, int ); | |
69 | +NetsnmpCacheLoad netsnmp_sensor_load; | |
70 | +NetsnmpCacheFree netsnmp_sensor_free; | |
71 | Index: configure.in | |
72 | =================================================================== | |
73 | --- configure.in (revision 16736) | |
74 | +++ configure.in (revision 16739) | |
75 | @@ -2885,7 +2885,7 @@ | |
76 | fi | |
77 | ||
78 | # LM-SENSORS-MIB support | |
79 | -echo " $module_list " | grep " ucd-snmp/lmSensors " > /dev/null | |
80 | +echo " $module_list " | $GREP -i "ucd-snmp/lmsensor" > /dev/null | |
81 | if test $? -eq 0 ; then | |
82 | AC_MSG_CHECKING([for sensors support]) | |
83 | case $target_os in | |
84 | Index: agent/mibgroup/ucd-snmp/lmsensorsMib.c | |
85 | =================================================================== | |
86 | --- agent/mibgroup/ucd-snmp/lmsensorsMib.c (revision 0) | |
87 | +++ agent/mibgroup/ucd-snmp/lmsensorsMib.c (revision 16739) | |
88 | @@ -0,0 +1,205 @@ | |
89 | +#include <net-snmp/net-snmp-config.h> | |
90 | +#include <net-snmp/net-snmp-includes.h> | |
91 | +#include <net-snmp/agent/net-snmp-agent-includes.h> | |
92 | +#include <net-snmp/agent/hardware/sensors.h> | |
93 | +#include "ucd-snmp/lmsensorsMib.h" | |
94 | + | |
95 | +netsnmp_container *sensorContainer = NULL; | |
96 | + | |
97 | +void initialize_lmSensorsTable(const char *tableName, oid *tableOID, | |
98 | + netsnmp_container_op *filter, int mult ); | |
99 | + | |
100 | +int _sensor_filter_temp( netsnmp_container *c, const void *v ); | |
101 | +int _sensor_filter_fan( netsnmp_container *c, const void *v ); | |
102 | +int _sensor_filter_volt( netsnmp_container *c, const void *v ); | |
103 | +int _sensor_filter_misc( netsnmp_container *c, const void *v ); | |
104 | + | |
105 | +static oid lmTempSensorsTable_oid[] = {1,3,6,1,4,1,2021,13,16,2}; | |
106 | +static oid lmFanSensorsTable_oid[] = {1,3,6,1,4,1,2021,13,16,3}; | |
107 | +static oid lmVoltSensorsTable_oid[] = {1,3,6,1,4,1,2021,13,16,4}; | |
108 | +static oid lmMiscSensorsTable_oid[] = {1,3,6,1,4,1,2021,13,16,5}; | |
109 | + /* All the tables have the same length root OID */ | |
110 | +size_t lmSensorsTables_oid_len = OID_LENGTH(lmMiscSensorsTable_oid); | |
111 | + | |
112 | + | |
113 | +/* Initialise the LM Sensors MIB module */ | |
114 | +void | |
115 | +init_lmsensorsMib(void) | |
116 | +{ | |
117 | + DEBUGMSGTL(("ucd-snmp/lmsensorsMib","Initializing LM-SENSORS-MIB tables\n")); | |
118 | + | |
119 | + /* | |
120 | + * Initialise the four LM-SENSORS-MIB tables | |
121 | + * | |
122 | + * They are almost identical, so we can use the same registration code. | |
123 | + */ | |
124 | + initialize_lmSensorsTable( "lmTempSensorsTable", lmTempSensorsTable_oid, | |
125 | + _sensor_filter_temp, 1000 ); /* MIB asks for mC */ | |
126 | + initialize_lmSensorsTable( "lmFanSensorsTable", lmFanSensorsTable_oid, | |
127 | + _sensor_filter_fan, 1); | |
128 | + initialize_lmSensorsTable( "lmVoltSensorsTable", lmVoltSensorsTable_oid, | |
129 | + _sensor_filter_volt, 1000 ); /* MIB asks for mV */ | |
130 | + initialize_lmSensorsTable( "lmMiscSensorsTable", lmMiscSensorsTable_oid, | |
131 | + _sensor_filter_misc, 1 ); | |
132 | +} | |
133 | + | |
134 | +/* | |
135 | + * Common initialisation code, used for setting up all four tables | |
136 | + */ | |
137 | +void | |
138 | +initialize_lmSensorsTable(const char *tableName, oid *tableOID, | |
139 | + netsnmp_container_op *filter, int mult ) | |
140 | +{ | |
141 | + netsnmp_handler_registration *reg; | |
142 | + netsnmp_table_registration_info *table_info; | |
143 | + netsnmp_cache *cache; | |
144 | + netsnmp_container *container; | |
145 | + | |
146 | + /* | |
147 | + * Ensure the HAL sensors module has been initialised, | |
148 | + * and retrieve the main sensors container. | |
149 | + * This table will then be registered using a filter on this container. | |
150 | + */ | |
151 | + sensorContainer = get_sensor_container(); | |
152 | + if ( !sensorContainer ) { | |
153 | + init_hw_sensors( ); | |
154 | + sensorContainer = get_sensor_container(); | |
155 | + } | |
156 | + container = netsnmp_container_find("sensorTable:table_container"); | |
157 | + container->insert_filter = filter; | |
158 | + netsnmp_container_add_index( sensorContainer, container ); | |
159 | + | |
160 | + | |
161 | + /* | |
162 | + * Create a basic registration structure for the table | |
163 | + */ | |
164 | + reg = netsnmp_create_handler_registration( | |
165 | + tableName, lmSensorsTables_handler, | |
166 | + tableOID, lmSensorsTables_oid_len, HANDLER_CAN_RONLY | |
167 | + ); | |
168 | + | |
169 | + /* | |
170 | + * Register the table using the filtered container | |
171 | + * Include an indicator of any scaling to be applied to the sensor value | |
172 | + */ | |
173 | + reg->my_reg_void = (void *)mult; | |
174 | + table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info ); | |
175 | + netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, 0); | |
176 | + table_info->min_column = COLUMN_LMSENSORS_INDEX; | |
177 | + table_info->max_column = COLUMN_LMSENSORS_VALUE; | |
178 | + netsnmp_container_table_register( reg, table_info, container, 0 ); | |
179 | + | |
180 | + /* | |
181 | + * If the HAL sensors module was configured as an on-demand caching | |
182 | + * module (rather than being automatically loaded regularly), | |
183 | + * then ensure this table makes use of that cache. | |
184 | + */ | |
185 | + cache = get_sensor_cache(); | |
186 | + if ( cache ) { | |
187 | + netsnmp_inject_handler_before( reg, netsnmp_cache_handler_get( cache ), | |
188 | + "table_container"); | |
189 | + } | |
190 | + | |
191 | +} | |
192 | + | |
193 | + | |
194 | +/* | |
195 | + * Container filters for the four tables | |
196 | + * | |
197 | + * Used to ensure that sensor entries appear in the appropriate table. | |
198 | + */ | |
199 | +int _sensor_filter_temp( netsnmp_container *c, const void *v ) { | |
200 | + const netsnmp_sensor_info *sp = (const netsnmp_sensor_info *)v; | |
201 | + /* Only matches temperature sensors */ | |
202 | + return (( sp->type == NETSNMP_SENSOR_TYPE_TEMPERATURE ) ? 0 : 1 ); | |
203 | +} | |
204 | + | |
205 | +int _sensor_filter_fan( netsnmp_container *c, const void *v ) { | |
206 | + const netsnmp_sensor_info *sp = (const netsnmp_sensor_info *)v; | |
207 | + /* Only matches fan sensors */ | |
208 | + return (( sp->type == NETSNMP_SENSOR_TYPE_RPM ) ? 0 : 1 ); | |
209 | +} | |
210 | + | |
211 | +int _sensor_filter_volt( netsnmp_container *c, const void *v ) { | |
212 | + const netsnmp_sensor_info *sp = (const netsnmp_sensor_info *)v; | |
213 | + /* Only matches voltage sensors (AC or DC) */ | |
214 | + return ((( sp->type == NETSNMP_SENSOR_TYPE_VOLTAGE_DC ) || | |
215 | + ( sp->type == NETSNMP_SENSOR_TYPE_VOLTAGE_AC )) ? 0 : 1 ); | |
216 | +} | |
217 | + | |
218 | +int _sensor_filter_misc( netsnmp_container *c, const void *v ) { | |
219 | + const netsnmp_sensor_info *sp = (const netsnmp_sensor_info *)v; | |
220 | + /* Matches everything except temperature, fan or voltage sensors */ | |
221 | + return ((( sp->type == NETSNMP_SENSOR_TYPE_TEMPERATURE ) || | |
222 | + ( sp->type == NETSNMP_SENSOR_TYPE_RPM ) || | |
223 | + ( sp->type == NETSNMP_SENSOR_TYPE_VOLTAGE_DC ) || | |
224 | + ( sp->type == NETSNMP_SENSOR_TYPE_VOLTAGE_AC )) ? 1 : 0 ); | |
225 | +} | |
226 | + | |
227 | + | |
228 | +/* | |
229 | + * Handle requests for any of the four lmXxxxSensorsTables | |
230 | + * | |
231 | + * This is possible because all the table share the | |
232 | + * same structure and behaviour. | |
233 | + */ | |
234 | +int | |
235 | +lmSensorsTables_handler( | |
236 | + netsnmp_mib_handler *handler, | |
237 | + netsnmp_handler_registration *reginfo, | |
238 | + netsnmp_agent_request_info *reqinfo, | |
239 | + netsnmp_request_info *requests) { | |
240 | + | |
241 | + netsnmp_request_info *request; | |
242 | + netsnmp_table_request_info *table_info; | |
243 | + netsnmp_sensor_info *sensor_info; | |
244 | + int mult = (int)reginfo->my_reg_void; | |
245 | + | |
246 | + DEBUGMSGTL(( "ucd-snmp/lmsensorsMib","lmSensorsTables_handler - root: ")); | |
247 | + DEBUGMSGOID(("ucd-snmp/lmsensorsMib", reginfo->rootoid, reginfo->rootoid_len)); | |
248 | + DEBUGMSG(( "ucd-snmp/lmsensorsMib",", mode %d\n", reqinfo->mode )); | |
249 | + /* | |
250 | + * This is a read-only table, so we only need to handle GET requests. | |
251 | + * (The container helper converts GETNEXT->GET requests automatically). | |
252 | + */ | |
253 | + switch (reqinfo->mode) { | |
254 | + case MODE_GET: | |
255 | + for (request=requests; request; request=request->next) { | |
256 | + sensor_info = (netsnmp_sensor_info *) | |
257 | + netsnmp_container_table_extract_context(request); | |
258 | + if ( !sensor_info ) { | |
259 | + netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); | |
260 | + continue; | |
261 | + } | |
262 | + | |
263 | + table_info = netsnmp_extract_table_info(request); | |
264 | + switch (table_info->colnum) { | |
265 | + case COLUMN_LMSENSORS_INDEX: | |
266 | + snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER, | |
267 | + sensor_info->idx.oids[0]); | |
268 | + break; | |
269 | + case COLUMN_LMSENSORS_DEVICE: | |
270 | + if ( sensor_info->descr[0] != '\0' ) { | |
271 | + snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR, | |
272 | + sensor_info->descr, strlen(sensor_info->descr)); | |
273 | + } else { | |
274 | + snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR, | |
275 | + sensor_info->name, strlen(sensor_info->name)); | |
276 | + } | |
277 | + break; | |
278 | + case COLUMN_LMSENSORS_VALUE: | |
279 | + /* Multiply the value by the appropriate scaling factor for this table */ | |
280 | + snmp_set_var_typed_integer( request->requestvb, ASN_GAUGE, | |
281 | + (int)(mult*sensor_info->value)); | |
282 | + break; | |
283 | + default: | |
284 | + netsnmp_set_request_error(reqinfo, request, | |
285 | + SNMP_NOSUCHOBJECT); | |
286 | + break; | |
287 | + } | |
288 | + } | |
289 | + break; | |
290 | + | |
291 | + } | |
292 | + return SNMP_ERR_NOERROR; | |
293 | +} | |
294 | Index: agent/mibgroup/ucd-snmp/lmsensorsMib.h | |
295 | =================================================================== | |
296 | --- agent/mibgroup/ucd-snmp/lmsensorsMib.h (revision 0) | |
297 | +++ agent/mibgroup/ucd-snmp/lmsensorsMib.h (revision 16739) | |
298 | @@ -0,0 +1,23 @@ | |
299 | +#ifndef LM_SENSORS_MIB_H | |
300 | +#define LM_SENSORS_MIB_H | |
301 | + | |
302 | +config_require(hardware/sensors) | |
303 | +config_add_mib(LM-SENSORS-MIB) | |
304 | + | |
305 | +/* function declarations */ | |
306 | +void init_lmsensorsMib(void); | |
307 | + | |
308 | +/* | |
309 | + * Handler and Column definitions for lmXxxxSensorsTable | |
310 | + * | |
311 | + * Note that the same handler (and hence the same | |
312 | + * column identifiers) are used for all four tables. | |
313 | + * This is possible because all the table share the | |
314 | + * same structure and behaviour. | |
315 | + */ | |
316 | +Netsnmp_Node_Handler lmSensorsTables_handler; | |
317 | +#define COLUMN_LMSENSORS_INDEX 1 | |
318 | +#define COLUMN_LMSENSORS_DEVICE 2 | |
319 | +#define COLUMN_LMSENSORS_VALUE 3 | |
320 | + | |
321 | +#endif /* LM_SENSORS_MIB_H */ | |
322 | Index: agent/mibgroup/hardware/sensors.h | |
323 | =================================================================== | |
324 | --- agent/mibgroup/hardware/sensors.h (revision 0) | |
325 | +++ agent/mibgroup/hardware/sensors.h (revision 16739) | |
326 | @@ -0,0 +1,13 @@ | |
327 | +config_require(hardware/sensors/hw_sensors) | |
328 | + | |
329 | +#if defined(solaris) | |
330 | +# if defined(HAVE_PICL_H) | |
331 | +config_require(hardware/sensors/picld_sensors) | |
332 | +# else | |
333 | +config_require(hardware/sensors/kstat_sensors) | |
334 | +# endif | |
335 | +#else | |
336 | +config_require(hardware/sensors/lmsensors_v3) | |
337 | +#endif | |
338 | + | |
339 | +//config_require(hardware/sensors/dummy_sensors) | |
340 | Index: agent/mibgroup/hardware/sensors/hw_sensors.h | |
341 | =================================================================== | |
342 | --- agent/mibgroup/hardware/sensors/hw_sensors.h (revision 0) | |
343 | +++ agent/mibgroup/hardware/sensors/hw_sensors.h (revision 16739) | |
344 | @@ -0,0 +1 @@ | |
345 | +void init_hw_sensors( void ); | |
346 | Index: agent/mibgroup/hardware/sensors/lmsensors_v2.h | |
347 | =================================================================== | |
348 | --- agent/mibgroup/hardware/sensors/lmsensors_v2.h (revision 0) | |
349 | +++ agent/mibgroup/hardware/sensors/lmsensors_v2.h (revision 16739) | |
350 | @@ -0,0 +1 @@ | |
351 | +config_require(hardware/sensors/hw_sensors) | |
352 | Index: agent/mibgroup/hardware/sensors/kstat_sensors.c | |
353 | =================================================================== | |
354 | --- agent/mibgroup/hardware/sensors/kstat_sensors.c (revision 0) | |
355 | +++ agent/mibgroup/hardware/sensors/kstat_sensors.c (revision 16739) | |
356 | @@ -0,0 +1,161 @@ | |
357 | +#include <net-snmp/net-snmp-config.h> | |
358 | +#include <net-snmp/net-snmp-includes.h> | |
359 | +#include <net-snmp/agent/net-snmp-agent-includes.h> | |
360 | +#include <net-snmp/agent/hardware/sensors.h> | |
361 | + | |
362 | +#include "util_funcs.h" | |
363 | +#include <time.h> | |
364 | + | |
365 | +#include <kstat.h> | |
366 | +#include </usr/platform/sun4u/include/sys/envctrl.h> | |
367 | + | |
368 | +void netsnmp_sensor_arch_init( void ) { | |
369 | + DEBUGMSGTL(("sensors:arch", "Initialise KStat Sensors module\n")); | |
370 | +} | |
371 | + | |
372 | + | |
373 | +int | |
374 | +netsnmp_sensor_arch_load(netsnmp_cache *cache, void *vp) { | |
375 | + netsnmp_sensor_info *sp; | |
376 | + | |
377 | + int i; | |
378 | + const char *fantypes[]={"CPU","PWR","AFB"}; | |
379 | + char name[ 256 ]; | |
380 | + | |
381 | + kstat_ctl_t *kc; | |
382 | + kstat_t *kp; | |
383 | + envctrl_fan_t *fan_info; | |
384 | + envctrl_ps_t *power_info; | |
385 | + envctrl_encl_t *enc_info; | |
386 | + | |
387 | + | |
388 | + DEBUGMSGTL(("sensors:arch", "Reload KStat Sensors module\n")); | |
389 | + | |
390 | + kc = kstat_open(); | |
391 | + if ( kc == 0) { | |
392 | + DEBUGMSGTL(("sensors:arch", "Couldn't open kstat\n")); | |
393 | + return 1; | |
394 | + } | |
395 | + | |
396 | + | |
397 | + /* | |
398 | + * Retrieve fan information | |
399 | + */ | |
400 | + kp = kstat_lookup( kc, ENVCTRL_MODULE_NAME, 0, ENVCTRL_KSTAT_FANSTAT); | |
401 | + if (( kp == 0 ) || (kstat_read( kc, kp, 0 ) == -1 )) { | |
402 | + DEBUGMSGTL(("sensors:arch", "No fan information\n")); | |
403 | + } else { | |
404 | + fan_info = (envctrl_fan_t *)kp->ks_data; | |
405 | + for (i=0; i<kp->ks_ndata; i++) { | |
406 | + memset( name, 0, 256 ); | |
407 | + snprintf( name, 255, "%s%d", fantypes[fan_info->type], fan_info->instance ); | |
408 | + | |
409 | + sp = sensor_by_name( name, NETSNMP_SENSOR_TYPE_RPM ); | |
410 | + if ( sp ) { | |
411 | + sp->value = fan_info->fanspeed; | |
412 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
413 | + snprintf( sp->descr, 255, "fan type %s number %d", | |
414 | + fantypes[fan_info->type], fan_info->instance ); | |
415 | + } | |
416 | + | |
417 | + fan_info++; | |
418 | + } | |
419 | + } | |
420 | + | |
421 | + | |
422 | + /* | |
423 | + * Retrieve Power Supply information | |
424 | + */ | |
425 | + kp = kstat_lookup( kc, ENVCTRL_MODULE_NAME, 0, ENVCTRL_KSTAT_PSNAME); | |
426 | + if (( kp == 0 ) || (kstat_read( kc, kp, 0 ) == -1 )) { | |
427 | + DEBUGMSGTL(("sensors:arch", "No PSU information\n")); | |
428 | + } else { | |
429 | + power_info = (envctrl_ps_t *)kp->ks_data; | |
430 | + for (i=0; i<kp->ks_ndata; i++) { | |
431 | + memset( name, 0, 256 ); | |
432 | + snprintf( name, 255, "PSU%d", power_info->instance ); | |
433 | + | |
434 | + sp = sensor_by_name( name, NETSNMP_SENSOR_TYPE_TEMPERATURE); | |
435 | + if ( sp ) { | |
436 | + sp->value = power_info->ps_tempr; | |
437 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
438 | + snprintf( sp->descr, 255, "power supply %d", power_info->instance ); | |
439 | + } | |
440 | + | |
441 | + power_info++; | |
442 | + } | |
443 | + } | |
444 | + | |
445 | + | |
446 | + /* | |
447 | + * Retrieve Enclosure information | |
448 | + */ | |
449 | + kp = kstat_lookup( kc, ENVCTRL_MODULE_NAME, 0, ENVCTRL_KSTAT_ENCL); | |
450 | + if (( kp == 0 ) || (kstat_read( kc, kp, 0 ) == -1 )) { | |
451 | + DEBUGMSGTL(("sensors:arch", "No enclosure information\n")); | |
452 | + } else { | |
453 | + enc_info = (envctrl_encl_t *)kp->ks_data; | |
454 | + for (i=0; i<kp->ks_ndata; i++) { | |
455 | + /* | |
456 | + * The enclosure information covers several different types of sensor | |
457 | + */ | |
458 | + switch ( enc_info->type ) { | |
459 | + case ENVCTRL_ENCL_FSP: | |
460 | + DEBUGMSGTL(("sensors:arch:detail", "Enclosure Front Panel\n")); | |
461 | + sp = sensor_by_name( "FSP", NETSNMP_SENSOR_TYPE_OTHER); | |
462 | + if ( sp ) { | |
463 | + sp->value = enc_info->value; | |
464 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
465 | + } | |
466 | + break; | |
467 | + | |
468 | + case ENVCTRL_ENCL_AMBTEMPR: | |
469 | + DEBUGMSGTL(("sensors:arch:detail", "Enclosure Ambient Temperature\n")); | |
470 | + sp = sensor_by_name( "Ambient", NETSNMP_SENSOR_TYPE_TEMPERATURE); | |
471 | + if ( sp ) { | |
472 | + sp->value = enc_info->value; | |
473 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
474 | + } | |
475 | + break; | |
476 | + | |
477 | + case ENVCTRL_ENCL_CPUTEMPR: | |
478 | + DEBUGMSGTL(("sensors:arch:detail", "Enclosure CPU Temperature\n")); | |
479 | + memset( name, 0, 256 ); | |
480 | + snprintf( name, 255, "CPU%d", enc_info->instance ); | |
481 | + sp = sensor_by_name( name, NETSNMP_SENSOR_TYPE_TEMPERATURE); | |
482 | + if ( sp ) { | |
483 | + sp->value = enc_info->value; | |
484 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
485 | + snprintf( sp->descr, 255, "CPU%d temperature", enc_info->instance ); | |
486 | + } | |
487 | + break; | |
488 | + | |
489 | + case ENVCTRL_ENCL_BACKPLANE4: | |
490 | + DEBUGMSGTL(("sensors:arch:detail", "Enclosure Backplane4\n")); | |
491 | + sp = sensor_by_name( "Backplane4", NETSNMP_SENSOR_TYPE_OTHER); | |
492 | + if ( sp ) { | |
493 | + sp->value = enc_info->value; | |
494 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
495 | + } | |
496 | + break; | |
497 | + | |
498 | + case ENVCTRL_ENCL_BACKPLANE8: | |
499 | + DEBUGMSGTL(("sensors:arch:detail", "Enclosure Backplane4\n")); | |
500 | + sp = sensor_by_name( "Backplane4", NETSNMP_SENSOR_TYPE_OTHER); | |
501 | + if ( sp ) { | |
502 | + sp->value = enc_info->value; | |
503 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
504 | + } | |
505 | + break; | |
506 | + | |
507 | + default: | |
508 | + DEBUGMSGTL(("sensors:arch:detail", "Unrecognised Enclosure entry (%d)n", | |
509 | + enc_info->type)); | |
510 | + } | |
511 | + | |
512 | + enc_info++; | |
513 | + } | |
514 | + } | |
515 | + | |
516 | + return 0; | |
517 | +} | |
518 | Index: agent/mibgroup/hardware/sensors/lmsensors_v3.h | |
519 | =================================================================== | |
520 | --- agent/mibgroup/hardware/sensors/lmsensors_v3.h (revision 0) | |
521 | +++ agent/mibgroup/hardware/sensors/lmsensors_v3.h (revision 16739) | |
522 | @@ -0,0 +1 @@ | |
523 | +config_require(hardware/sensors/hw_sensors) | |
524 | Index: agent/mibgroup/hardware/sensors/dummy_sensors.c | |
525 | =================================================================== | |
526 | --- agent/mibgroup/hardware/sensors/dummy_sensors.c (revision 0) | |
527 | +++ agent/mibgroup/hardware/sensors/dummy_sensors.c (revision 16739) | |
528 | @@ -0,0 +1,60 @@ | |
529 | +#include <net-snmp/net-snmp-config.h> | |
530 | +#include <net-snmp/net-snmp-includes.h> | |
531 | +#include <net-snmp/agent/net-snmp-agent-includes.h> | |
532 | +#include <net-snmp/agent/hardware/sensors.h> | |
533 | + | |
534 | + | |
535 | +void netsnmp_sensor_arch_init( void ) { | |
536 | + /* Nothing to do */ | |
537 | + DEBUGMSGTL(("sensors:arch", "Initialise Dummy Sensors module\n")); | |
538 | +} | |
539 | + | |
540 | +int | |
541 | +netsnmp_sensor_arch_load(netsnmp_cache *cache, void *vp) { | |
542 | + time_t now; | |
543 | + struct tm *tm; | |
544 | + netsnmp_sensor_info *sp; | |
545 | + | |
546 | + time(&now); | |
547 | + tm = localtime(&now); | |
548 | + | |
549 | + DEBUGMSGTL(("sensors:arch", "Reload Dummy Sensors module\n")); | |
550 | + | |
551 | + /* First pseudo-sensor - slowly-rising temperature */ | |
552 | + sp = sensor_by_name( "minute", NETSNMP_SENSOR_TYPE_TEMPERATURE ); | |
553 | + sp->value = tm->tm_min; | |
554 | + snprintf( sp->descr, 256, "Minute-based pseudo-sensor - slowly-rising temperature" ); | |
555 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
556 | + | |
557 | + /* Second pseudo-sensor - quickly-rising temperature */ | |
558 | + sp = sensor_by_name( "second", NETSNMP_SENSOR_TYPE_TEMPERATURE ); | |
559 | + sp->value = tm->tm_sec; | |
560 | + snprintf( sp->descr, 256, "Second-based pseudo-sensor - quickly-rising temperature" ); | |
561 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
562 | + | |
563 | + /* Third pseudo-sensor - annual fan speed */ | |
564 | + sp = sensor_by_name( "year", NETSNMP_SENSOR_TYPE_RPM ); | |
565 | + sp->value = tm->tm_year + 1900; | |
566 | + snprintf( sp->descr, 256, "RPM pseudo-sensor - annual fan speed" ); | |
567 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
568 | + | |
569 | + /* Fourth pseudo-sensor - daily voltage */ | |
570 | + sp = sensor_by_name( "day", NETSNMP_SENSOR_TYPE_VOLTAGE_DC ); | |
571 | + sp->value = tm->tm_mday-20; | |
572 | + snprintf( sp->descr, 256, "Day-based pseudo-sensor - positive or negative voltage" ); | |
573 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
574 | + | |
575 | + /* Fifth pseudo-sensor - monthly voltage */ | |
576 | + sp = sensor_by_name( "month", NETSNMP_SENSOR_TYPE_VOLTAGE_DC ); | |
577 | + sp->value = tm->tm_mon; | |
578 | + snprintf( sp->descr, 256, "Month-based pseudo-sensor - positive voltage" ); | |
579 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
580 | + | |
581 | + /* Sixth pseudo-sensor - annual daily something */ | |
582 | + sp = sensor_by_name( "yday", NETSNMP_SENSOR_TYPE_OTHER ); | |
583 | + sp->value = tm->tm_yday; | |
584 | + snprintf( sp->descr, 256, "Day-based pseudo-sensor - annual something" ); | |
585 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
586 | + | |
587 | + return 0; | |
588 | +} | |
589 | Index: agent/mibgroup/hardware/sensors/kstat_sensors.h | |
590 | =================================================================== | |
591 | --- agent/mibgroup/hardware/sensors/kstat_sensors.h (revision 0) | |
592 | +++ agent/mibgroup/hardware/sensors/kstat_sensors.h (revision 16739) | |
593 | @@ -0,0 +1 @@ | |
594 | +config_require(hardware/sensors/hw_sensors) | |
595 | Index: agent/mibgroup/hardware/sensors/picld_sensors.c | |
596 | =================================================================== | |
597 | --- agent/mibgroup/hardware/sensors/picld_sensors.c (revision 0) | |
598 | +++ agent/mibgroup/hardware/sensors/picld_sensors.c (revision 16739) | |
599 | @@ -0,0 +1,341 @@ | |
600 | +#include <net-snmp/net-snmp-config.h> | |
601 | +#include <net-snmp/net-snmp-includes.h> | |
602 | +#include <net-snmp/agent/net-snmp-agent-includes.h> | |
603 | +#include <net-snmp/agent/hardware/sensors.h> | |
604 | + | |
605 | +#include "util_funcs.h" | |
606 | +#include <time.h> | |
607 | + | |
608 | +#include <picl.h> | |
609 | +#include </usr/platform/sun4u/include/sys/envctrl.h> | |
610 | + | |
611 | +void netsnmp_sensor_arch_init( void ) { | |
612 | + DEBUGMSGTL(("sensors:arch", "Initialise PICLd Sensors module\n")); | |
613 | + picl_initialize(); | |
614 | +} | |
615 | + | |
616 | + | |
617 | +/* | |
618 | + * Handle a numeric-valued sensor | |
619 | + */ | |
620 | +static int | |
621 | +read_num_sensor( picl_nodehdl_t childh, char *propval, float *value ) | |
622 | +{ | |
623 | + picl_nodehdl_t sensorh; | |
624 | + picl_propinfo_t sensor_info; | |
625 | + picl_errno_t error_code; | |
626 | + | |
627 | + union valu { | |
628 | + char buf[PICL_PROPSIZE_MAX]; | |
629 | + uint32_t us4; | |
630 | + uint16_t us2; | |
631 | + int32_t is4; | |
632 | + int16_t is2; | |
633 | + float f; | |
634 | + } val; | |
635 | + | |
636 | + /* | |
637 | + * Retrieve the specified sensor information and value | |
638 | + */ | |
639 | + error_code = picl_get_propinfo_by_name(childh, propval, &sensor_info, &sensorh); | |
640 | + if ( error_code != PICL_SUCCESS ) { | |
641 | + DEBUGMSGTL(("sensors:arch:detail", "sensor info lookup failed (%d)\n", | |
642 | + error_code)); | |
643 | + return( error_code ); | |
644 | + } | |
645 | + | |
646 | + error_code = picl_get_propval(sensorh, &val.buf, sensor_info.size); | |
647 | + if ( error_code != PICL_SUCCESS ) { | |
648 | + DEBUGMSGTL(("sensors:arch:detail", "sensor value lookup failed (%d)\n", | |
649 | + error_code)); | |
650 | + return( error_code ); | |
651 | + } | |
652 | + | |
653 | + /* | |
654 | + * Check the validity (type and size) of this value | |
655 | + */ | |
656 | + if ( sensor_info.type == PICL_PTYPE_FLOAT ) { | |
657 | + *value = val.f; | |
658 | + } else if ( sensor_info.type == PICL_PTYPE_UNSIGNED_INT ) { | |
659 | + /* 16-bit or 32-bit unsigned integers */ | |
660 | + if ( sensor_info.size == 2 ) { | |
661 | + *value = val.us2; | |
662 | + } else if ( sensor_info.size == 4 ) { | |
663 | + *value = val.us4; | |
664 | + } else { | |
665 | + DEBUGMSGTL(("sensors:arch:detail", "unsigned integer (%d bit)\n", | |
666 | + sensor_info.size * 8)); | |
667 | + return PICL_FAILURE; | |
668 | + } | |
669 | + } else if ( sensor_info.type == PICL_PTYPE_INT ) { | |
670 | + /* 16-bit or 32-bit signed integers */ | |
671 | + if ( sensor_info.size == 2 ) { | |
672 | + *value = val.is2; | |
673 | + } else if ( sensor_info.size == 4 ) { | |
674 | + *value = val.is4; | |
675 | + } else { | |
676 | + DEBUGMSGTL(("sensors:arch:detail", "signed integer (%d bit)\n", | |
677 | + sensor_info.size * 8)); | |
678 | + return PICL_FAILURE; | |
679 | + } | |
680 | + } else { | |
681 | + DEBUGMSGTL(("sensors:arch:detail", "unrecognised type (%d)\n", | |
682 | + sensor_info.type)); | |
683 | + return PICL_FAILURE; | |
684 | + } | |
685 | + | |
686 | + return error_code; | |
687 | +} | |
688 | + | |
689 | +static int | |
690 | +process_num_sensor( picl_nodehdl_t childh, char *propname, char *propval, int typ ) | |
691 | +{ | |
692 | + netsnmp_sensor_info *sp; | |
693 | + float value; | |
694 | + picl_errno_t error_code; | |
695 | + | |
696 | + sp = sensor_by_name( propname, typ ); | |
697 | + if ( !sp ) { | |
698 | + return -1; | |
699 | + } | |
700 | + | |
701 | + error_code = read_num_sensor( childh, propval, &value ); | |
702 | + if ( error_code == PICL_SUCCESS ) { | |
703 | + sp->value = value; | |
704 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
705 | + } else { | |
706 | + DEBUGMSGTL(("sensors:arch:detail", "Failed to read %s sensor value (%d)\n", | |
707 | + propname, error_code)); | |
708 | + return -1; | |
709 | + } | |
710 | + return 0; | |
711 | +} | |
712 | + | |
713 | + | |
714 | + | |
715 | +/* | |
716 | + * Handle an enumeration-valued sensor | |
717 | + */ | |
718 | +char *switch_settings[] = { "OFF","ON","NORMAL","LOCKED", | |
719 | + "UNKNOWN","DIAG","SECURE", | |
720 | + NULL }; | |
721 | +char *led_settings[] = { "OFF","ON","BLINK", | |
722 | + NULL }; | |
723 | +char *i2c_settings[] = { "OK", | |
724 | + NULL }; | |
725 | + | |
726 | +static int | |
727 | +read_enum_sensor( picl_nodehdl_t childh, float *value, char **options ) | |
728 | +{ | |
729 | + picl_nodehdl_t sensorh; | |
730 | + picl_propinfo_t sensor_info; | |
731 | + picl_errno_t error_code; | |
732 | + char state[PICL_PROPSIZE_MAX]; | |
733 | + int i; | |
734 | + | |
735 | + /* | |
736 | + * Retrieve the specified sensor information and value | |
737 | + */ | |
738 | + error_code = picl_get_propinfo_by_name(childh, "State", &sensor_info, &sensorh); | |
739 | + if ( error_code != PICL_SUCCESS ) { | |
740 | + DEBUGMSGTL(("sensors:arch:detail", "sensor info lookup failed (%d)\n", | |
741 | + error_code)); | |
742 | + return( error_code ); | |
743 | + } | |
744 | + | |
745 | + error_code = picl_get_propval(sensorh, state, sensor_info.size); | |
746 | + if ( error_code != PICL_SUCCESS ) { | |
747 | + DEBUGMSGTL(("sensors:arch:detail", "sensor value lookup failed (%d)\n", | |
748 | + error_code)); | |
749 | + return( error_code ); | |
750 | + } | |
751 | + | |
752 | + /* | |
753 | + * Try to find a matching entry in the list of options. | |
754 | + * Note that some platforms may use upper or lower case | |
755 | + * versions of these enumeration values | |
756 | + * (so the checks are case insensitive) | |
757 | + */ | |
758 | + *value = 99; /* Dummy value */ | |
759 | + for ( i=0; options[i] != NULL; i++ ) { | |
760 | + if (strncasecmp(state, options[i], strlen(options[i])) == 0) { | |
761 | + *value = i; | |
762 | + return 0; | |
763 | + } | |
764 | + } | |
765 | + | |
766 | + DEBUGMSGTL(("sensors:arch:detail", "Enumeration state %s not matched\n", | |
767 | + state)); | |
768 | + return 0; /* Or an error ? */ | |
769 | +} | |
770 | + | |
771 | +static int | |
772 | +process_enum_sensor( picl_nodehdl_t childh, char *propname, int typ, char **options ) | |
773 | +{ | |
774 | + netsnmp_sensor_info *sp; | |
775 | + float value; | |
776 | + picl_errno_t error_code; | |
777 | + | |
778 | + sp = sensor_by_name( propname, typ ); | |
779 | + if ( !sp ) { | |
780 | + return -1; | |
781 | + } | |
782 | + | |
783 | + error_code = read_enum_sensor( childh, &value, options ); | |
784 | + if ( error_code == PICL_SUCCESS ) { | |
785 | + sp->value = value; | |
786 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
787 | + } else { | |
788 | + DEBUGMSGTL(("sensors:arch:detail", "Failed to read %s sensor value (%d)\n", | |
789 | + propname, error_code)); | |
790 | + return -1; | |
791 | + } | |
792 | + return 0; | |
793 | +} | |
794 | +static int | |
795 | +process_enum_sensor( picl_nodehdl_t childh, char *propname, int typ, char **options ) | |
796 | +{ | |
797 | + return 0; | |
798 | +} | |
799 | + | |
800 | + | |
801 | + | |
802 | +/* | |
803 | + * Recursively walk through the tree of sensors | |
804 | + */ | |
805 | +static int | |
806 | +process_sensors( int level, picl_nodehdl_t nodeh ) { | |
807 | + picl_nodehdl_t childh, nexth; | |
808 | + char propname[ PICL_PROPNAMELEN_MAX ]; | |
809 | + char propclass[ PICL_CLASSNAMELEN_MAX ]; | |
810 | + picl_errno_t error_code; | |
811 | + | |
812 | + level++; | |
813 | + DEBUGMSGTL(("sensors:arch:detail", "process_sensors - level %d\n", level)); | |
814 | + | |
815 | + /* Look up the first child node at this level */ | |
816 | + error_code = pick_get_propval_by_name( nodeh, PICL_PROP_CHILD, | |
817 | + &childh, sizeof(childh)); | |
818 | + if ( error_code != PICL_SUCCESS ) { | |
819 | + DEBUGMSGTL(("sensors:arch:detail", "Failed to get first child node (%d)\n", | |
820 | + error_code)); | |
821 | + return( error_code ); | |
822 | + } | |
823 | + | |
824 | + /* Step through the child nodes, retrieving the name and class of each one */ | |
825 | + while ( error_code == PICL_SUCCESS ) { | |
826 | + error_code = pick_get_propval_by_name( childh, PICL_PROP_NAME, | |
827 | + propname, sizeof(propname)-1); | |
828 | + if ( error_code != PICL_SUCCESS ) { | |
829 | + /* The Node With No Name */ | |
830 | + DEBUGMSGTL(("sensors:arch:detail", "get property name failed (%d)\n", | |
831 | + error_code)); | |
832 | + return( error_code ); | |
833 | + } | |
834 | + | |
835 | + error_code = pick_get_propval_by_name( childh, PICL_PROP_CLASSNAME, | |
836 | + propclass, sizeof(propclass)-1); | |
837 | + if ( error_code != PICL_SUCCESS ) { | |
838 | + /* The Classless Society */ | |
839 | + DEBUGMSGTL(("sensors:arch:detail", "get property class failed (%d)\n", | |
840 | + error_code)); | |
841 | + return( error_code ); | |
842 | + } | |
843 | + | |
844 | + DEBUGMSGTL(("sensors:arch:detail", "Name: %s, Class %s\n", | |
845 | + propname, propclass )); | |
846 | + | |
847 | + | |
848 | + /* | |
849 | + * Three classes represent further groups of sensors, etc. | |
850 | + * Call 'process_sensors' recursively to handle this next level | |
851 | + */ | |
852 | + if (( strstr( propclass, "picl" )) || | |
853 | + ( strstr( propclass, "frutree" )) || | |
854 | + ( strstr( propclass, "obp" ))) { | |
855 | + process_sensors( level, childh ); | |
856 | + } | |
857 | + /* | |
858 | + * Otherwise retrieve the value appropriately based on the | |
859 | + * class of the sensor. | |
860 | + * | |
861 | + * We need to specify the name of the PICL property to retrieve | |
862 | + * for this class of sensor, and the Net-SNMP sensor type. | |
863 | + */ | |
864 | + else if ( strstr( propclass, "fan-tachometer" )) { | |
865 | + process_num_sensor( childh, propname, "AtoDSensorValue", | |
866 | + NETSNMP_SENSOR_TYPE_RPM ); | |
867 | + } else if ( strstr( propclass, "fan" )) { | |
868 | + process_num_sensor( childh, propname, "Speed", | |
869 | + NETSNMP_SENSOR_TYPE_RPM ); | |
870 | + } else if ( strstr( propclass, "temperature-sensor" )) { | |
871 | + process_num_sensor( childh, propname, "Temperature", | |
872 | + NETSNMP_SENSOR_TYPE_TEMPERATURE ); | |
873 | + } else if ( strstr( propclass, "voltage-sensor" )) { | |
874 | + process_num_sensor( childh, propname, "Voltage", | |
875 | + /* ?? */ NETSNMP_SENSOR_TYPE_VOLTAGE_DC ); | |
876 | + } else if ( strstr( propclass, "digital-sensor" )) { | |
877 | + process_num_sensor( childh, propname, "AtoDSensorValue", | |
878 | + /* ?? */ NETSNMP_SENSOR_TYPE_VOLTAGE_DC ); | |
879 | + /* | |
880 | + * Enumeration-valued sensors use a fixed PICL property ("State"), | |
881 | + * but take a list of the values appropriate for that sensor, | |
882 | + * as well as the Net-SNMP sensor type. | |
883 | + */ | |
884 | + } else if ( strstr( propclass, "switch" )) { | |
885 | + process_enum_sensor( childh, propname, NETSNMP_SENSOR_TYPE_OTHER, | |
886 | + switch_settings ); | |
887 | + } else if ( strstr( propclass, "led" )) { | |
888 | + process_enum_sensor( childh, propname, NETSNMP_SENSOR_TYPE_OTHER, | |
889 | + led_settings ); | |
890 | + } else if ( strstr( propclass, "i2c" )) { | |
891 | + process_enum_sensor( childh, propname, NETSNMP_SENSOR_TYPE_BOOLEAN, /* ?? */ | |
892 | + i2c_settings ); | |
893 | + } else { | |
894 | + /* Skip other classes of sensor */ | |
895 | + DEBUGMSGTL(("sensors:arch:detail", "Skipping class %s\n", propclass )); | |
896 | + } | |
897 | + | |
898 | + /* | |
899 | + * Move on to the next child node at the current level (if any) | |
900 | + */ | |
901 | + error_code = pick_get_propval_by_name( childh, PICL_PROP_PEER, | |
902 | + &nexth, sizeof(nexth)); | |
903 | + if ( error_code != PICL_SUCCESS ) { | |
904 | + /* That's All Folks! */ | |
905 | + return (( error_code == PICL_PROPNOTFOUND ) | |
906 | + ? PICL_SUCCESS : error_code ); | |
907 | + } | |
908 | + childh = nexth; | |
909 | + } | |
910 | + | |
911 | + return error_code; | |
912 | +} | |
913 | + | |
914 | + | |
915 | +int | |
916 | +netsnmp_sensor_arch_load(netsnmp_cache *cache, void *vp) { | |
917 | + int error_code; | |
918 | + picl_nodehdl_t rooth; | |
919 | + | |
920 | + DEBUGMSGTL(("sensors:arch", "Reload PICLd Sensors module\n")); | |
921 | + | |
922 | + error_code = picl_get_root(&rooth); | |
923 | + if ( error_code != PICL_SUCCESS) { | |
924 | + DEBUGMSGTL(("sensors:arch", "Couldn't get root node (error %d)\n", error_code)); | |
925 | + return 1; | |
926 | + } | |
927 | + | |
928 | + error_code = process_sensors(0, rooth); | |
929 | + if ( error_code != 255 ) | |
930 | + if ( error_code != 7 ) /* ignore PICL_PROPNOTFOUND error */ | |
931 | + DEBUGMSGTL(("sensors:arch", "Internal PICLd problem (error %d)\n", error_code)); | |
932 | + | |
933 | + return 0; | |
934 | +} | |
935 | + | |
936 | +void netsnmp_sensor_arch_shutdown( void ) { | |
937 | + DEBUGMSGTL(("sensors:arch", "Shutdown PicLD Sensors module\n")); | |
938 | + picl_shutdown(); | |
939 | +} | |
940 | + | |
941 | Index: agent/mibgroup/hardware/sensors/hw_sensors.c | |
942 | =================================================================== | |
943 | --- agent/mibgroup/hardware/sensors/hw_sensors.c (revision 0) | |
944 | +++ agent/mibgroup/hardware/sensors/hw_sensors.c (revision 16739) | |
945 | @@ -0,0 +1,183 @@ | |
946 | +#include <net-snmp/net-snmp-config.h> | |
947 | +#include <net-snmp/net-snmp-includes.h> | |
948 | +#include <net-snmp/agent/net-snmp-agent-includes.h> | |
949 | +#include <net-snmp/agent/hardware/sensors.h> | |
950 | + | |
951 | + | |
952 | +extern NetsnmpCacheLoad netsnmp_sensor_arch_load; | |
953 | +extern void netsnmp_sensor_arch_init( void ); | |
954 | +static int _sensor_load( void ); | |
955 | +static void _sensor_free( void ); | |
956 | + | |
957 | +static int _sensorAutoUpdate = 0; /* 0 means on-demand caching */ | |
958 | +static void _sensor_update_stats( unsigned int, void* ); | |
959 | + | |
960 | +netsnmp_cache *_sensor_cache = NULL; | |
961 | +netsnmp_container *_sensor_container = NULL; | |
962 | +static int _sensor_idx = 0; | |
963 | + | |
964 | +void init_hw_sensors( void ) { | |
965 | + | |
966 | + if ( _sensor_container ) | |
967 | + return; /* Already initialised */ | |
968 | + | |
969 | + DEBUGMSGTL(("sensors", "Initialise Hardware Sensors module\n")); | |
970 | + | |
971 | + /* | |
972 | + * Define a container to hold the basic list of sensors | |
973 | + * The four LM-SENSOR-MIB containers will be created in | |
974 | + * the relevant initialisation routine(s) | |
975 | + */ | |
976 | + _sensor_container = netsnmp_container_find("sensorTable:table_container"); | |
977 | + if ( NULL == _sensor_container ) { | |
978 | + snmp_log( LOG_ERR, "failed to create container for sensorTable"); | |
979 | + return; | |
980 | + } | |
981 | + netsnmp_sensor_arch_init( ); | |
982 | + | |
983 | + /* | |
984 | + * If we're sampling the sensor information automatically, | |
985 | + * then arrange for this to be triggered regularly. | |
986 | + * | |
987 | + * If we're not sampling these values regularly, | |
988 | + * create a suitable cache handler instead. | |
989 | + */ | |
990 | + if ( _sensorAutoUpdate ) { | |
991 | + DEBUGMSGTL(("sensors", "Reloading Hardware Sensors automatically (%d)\n", | |
992 | + _sensorAutoUpdate)); | |
993 | + snmp_alarm_register( _sensorAutoUpdate, SA_REPEAT, | |
994 | + _sensor_update_stats, NULL ); | |
995 | + } | |
996 | + else { | |
997 | + _sensor_cache = netsnmp_cache_create( 5, netsnmp_sensor_load, | |
998 | + netsnmp_sensor_free, NULL, 0 ); | |
999 | + DEBUGMSGTL(("sensors", "Reloading Hardware Sensors on-demand (%p)\n", | |
1000 | + _sensor_cache)); | |
1001 | + } | |
1002 | +} | |
1003 | + | |
1004 | +void shutdown_hw_sensors( void ) { | |
1005 | + _sensor_free(); | |
1006 | +} | |
1007 | + | |
1008 | +/* | |
1009 | + * Return the main sensor container | |
1010 | + */ | |
1011 | +netsnmp_container *get_sensor_container( void ) { return _sensor_container; } | |
1012 | + | |
1013 | +/* | |
1014 | + * Return the main sensor cache control structure (if defined) | |
1015 | + */ | |
1016 | +netsnmp_cache *get_sensor_cache( void ) { return _sensor_cache; } | |
1017 | + | |
1018 | + | |
1019 | +/* | |
1020 | + * Wrapper routine for automatically updating sensor statistics | |
1021 | + */ | |
1022 | +void | |
1023 | +_sensor_update_stats( unsigned int clientreg, void *data ) | |
1024 | +{ | |
1025 | + _sensor_free(); | |
1026 | + _sensor_load(); | |
1027 | +} | |
1028 | + | |
1029 | +/* | |
1030 | + * Wrapper routine for re-loading sensor statistics on demand | |
1031 | + */ | |
1032 | +int | |
1033 | +netsnmp_sensor_load( netsnmp_cache *cache, void *data ) | |
1034 | +{ | |
1035 | + return _sensor_load(); | |
1036 | +} | |
1037 | + | |
1038 | +/* | |
1039 | + * Wrapper routine for releasing expired sensor statistics | |
1040 | + */ | |
1041 | +void | |
1042 | +netsnmp_sensor_free( netsnmp_cache *cache, void *data ) | |
1043 | +{ | |
1044 | + _sensor_free(); | |
1045 | +} | |
1046 | + | |
1047 | + | |
1048 | +/* | |
1049 | + * Architecture-independent processing of loading sensor statistics | |
1050 | + */ | |
1051 | +static int | |
1052 | +_sensor_load( void ) | |
1053 | +{ | |
1054 | + netsnmp_sensor_arch_load( NULL, NULL ); | |
1055 | +} | |
1056 | + | |
1057 | +/* | |
1058 | + * Architecture-independent release of sensor statistics | |
1059 | + */ | |
1060 | +static void | |
1061 | +_sensor_free( void ) | |
1062 | +{ | |
1063 | + netsnmp_sensor_info *sp; | |
1064 | + | |
1065 | + for (sp = CONTAINER_FIRST( _sensor_container ); | |
1066 | + sp; | |
1067 | + sp = CONTAINER_NEXT( _sensor_container, sp )) { | |
1068 | + | |
1069 | + sp->flags &= ~ NETSNMP_SENSOR_FLAG_ACTIVE; | |
1070 | + } | |
1071 | +} | |
1072 | + | |
1073 | + | |
1074 | +/* | |
1075 | + * Retrieve a sensor entry by name, | |
1076 | + * or (optionally) insert a new one into the container | |
1077 | + */ | |
1078 | +netsnmp_sensor_info * | |
1079 | +sensor_by_name( char *name, int create_type ) | |
1080 | +{ | |
1081 | + netsnmp_sensor_info *sp; | |
1082 | + | |
1083 | + DEBUGMSGTL(("sensors:name", "Get sensor entry (%s)\n", name)); | |
1084 | + | |
1085 | + /* | |
1086 | + * Look through the list for a matching entry | |
1087 | + */ | |
1088 | + /* .. or use a secondary index container ?? */ | |
1089 | + for (sp = CONTAINER_FIRST( _sensor_container ); | |
1090 | + sp; | |
1091 | + sp = CONTAINER_NEXT( _sensor_container, sp )) { | |
1092 | + | |
1093 | + if ( !strcmp( name, sp->name )) | |
1094 | + return sp; | |
1095 | + } | |
1096 | + | |
1097 | + /* | |
1098 | + * Not found... | |
1099 | + */ | |
1100 | + if ( create_type == NETSNMP_SENSOR_FIND_EXIST ) { | |
1101 | + DEBUGMSGTL(("sensors:name", "No such sensor entry\n")); | |
1102 | + return NULL; | |
1103 | + } | |
1104 | + | |
1105 | + /* | |
1106 | + * ... so let's create a new one, using the type supplied | |
1107 | + */ | |
1108 | + sp = SNMP_MALLOC_TYPEDEF( netsnmp_sensor_info ); | |
1109 | + if ( sp ) { | |
1110 | + strcpy( sp->name, name ); | |
1111 | + sp->type = create_type; | |
1112 | + /* | |
1113 | + * Set up the index value. | |
1114 | + * | |
1115 | + * All this trouble, just for a simple integer. | |
1116 | + * Surely there must be a better way? | |
1117 | + */ | |
1118 | + sp->idx.len = 1; | |
1119 | + sp->idx.oids = SNMP_MALLOC_TYPEDEF( oid ); | |
1120 | + sp->idx.oids[0] = ++_sensor_idx; | |
1121 | + } | |
1122 | + | |
1123 | + DEBUGMSGTL(("sensors:name", "Create sensor entry (type = %d, index = %d\n", | |
1124 | + create_type, _sensor_idx)); | |
1125 | + CONTAINER_INSERT( _sensor_container, sp ); | |
1126 | + return sp; | |
1127 | +} | |
1128 | + | |
1129 | Index: agent/mibgroup/hardware/sensors/dummy_sensors.h | |
1130 | =================================================================== | |
1131 | --- agent/mibgroup/hardware/sensors/dummy_sensors.h (revision 0) | |
1132 | +++ agent/mibgroup/hardware/sensors/dummy_sensors.h (revision 16739) | |
1133 | @@ -0,0 +1 @@ | |
1134 | +config_require(hardware/sensors/hw_sensors) | |
1135 | Index: agent/mibgroup/hardware/sensors/lmsensors_v2.c | |
1136 | =================================================================== | |
1137 | --- agent/mibgroup/hardware/sensors/lmsensors_v2.c (revision 0) | |
1138 | +++ agent/mibgroup/hardware/sensors/lmsensors_v2.c (revision 16739) | |
1139 | @@ -0,0 +1,75 @@ | |
1140 | +#include <net-snmp/net-snmp-config.h> | |
1141 | +#include <net-snmp/net-snmp-includes.h> | |
1142 | +#include <net-snmp/agent/net-snmp-agent-includes.h> | |
1143 | +#include <net-snmp/agent/hardware/sensors.h> | |
1144 | + | |
1145 | +#include "util_funcs.h" | |
1146 | +#include <time.h> | |
1147 | +#include <sensors/sensors.h> | |
1148 | + | |
1149 | +void netsnmp_sensor_arch_init( void ) { | |
1150 | + FILE *fp = fopen("/etc/sensors.conf", "r"); | |
1151 | + DEBUGMSGTL(("sensors:arch", "Initialise LM Sensors module\n")); | |
1152 | + sensors_init( fp ); | |
1153 | +} | |
1154 | + | |
1155 | +int | |
1156 | +netsnmp_sensor_arch_load(netsnmp_cache *cache, void *vp) { | |
1157 | + netsnmp_sensor_info *sp; | |
1158 | + const sensors_chip_name *chip; | |
1159 | + const sensors_feature_data *data; | |
1160 | + int chip_nr = 0; | |
1161 | + | |
1162 | + DEBUGMSGTL(("sensors:arch", "Reload LM Sensors module\n")); | |
1163 | + while ((chip = sensors_get_detected_chips(&chip_nr))) { | |
1164 | + int a = 0; | |
1165 | + int b = 0; | |
1166 | + | |
1167 | + while ((data = sensors_get_all_features(*chip, &a, &b))) { | |
1168 | + DEBUGMSGTL(("sensors:arch:detail", "get_all_features (%d, %d)\n", a, b)); | |
1169 | + char *label = NULL; | |
1170 | + double val; | |
1171 | + int type = NETSNMP_SENSOR_TYPE_OTHER; | |
1172 | + | |
1173 | + if ((data->mode & SENSORS_MODE_R) && | |
1174 | + (data->mapping == SENSORS_NO_MAPPING) && | |
1175 | + !sensors_get_label(*chip, data->number, &label) && | |
1176 | + !sensors_get_feature(*chip, data->number, &val)) { | |
1177 | + | |
1178 | + DEBUGMSGTL(("sensors:arch:detail", "%s = %f\n", label, val)); | |
1179 | + /* | |
1180 | + * Determine the type of sensor from the description. | |
1181 | + * | |
1182 | + * If the text being looked for below is not in the label of a | |
1183 | + * given sensor (e.g., the temp1 sensor has been labeled 'CPU' | |
1184 | + * rather than 'CPU temp') it will be categorised as OTHER. | |
1185 | + */ | |
1186 | + if (strstr(label, "V")) { | |
1187 | + type = NETSNMP_SENSOR_TYPE_VOLTAGE_DC; | |
1188 | + } | |
1189 | + if (strstr(label, "fan") || strstr(label, "Fan")) { | |
1190 | + type = NETSNMP_SENSOR_TYPE_RPM; | |
1191 | + } | |
1192 | + if (strstr(label, "temp") || strstr(label, "Temp")) { | |
1193 | + type = NETSNMP_SENSOR_TYPE_TEMPERATURE; | |
1194 | + } | |
1195 | + | |
1196 | + /* | |
1197 | + * Use this type to create a new sensor entry | |
1198 | + * (inserting it in the appropriate sub-containers) | |
1199 | + */ | |
1200 | + sp = sensor_by_name( label, type ); | |
1201 | + if ( sp ) { | |
1202 | + sp->value = val; | |
1203 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
1204 | + } | |
1205 | + } | |
1206 | + if (label) { | |
1207 | + free(label); | |
1208 | + label = NULL; | |
1209 | + } | |
1210 | + } /* end while data */ | |
1211 | + } /* end while chip */ | |
1212 | + | |
1213 | + return 0; | |
1214 | +} | |
1215 | Index: agent/mibgroup/hardware/sensors/picld_sensors.h | |
1216 | =================================================================== | |
1217 | --- agent/mibgroup/hardware/sensors/picld_sensors.h (revision 0) | |
1218 | +++ agent/mibgroup/hardware/sensors/picld_sensors.h (revision 16739) | |
1219 | @@ -0,0 +1 @@ | |
1220 | +config_require(hardware/sensors/hw_sensors) | |
1221 | Index: agent/mibgroup/hardware/sensors/lmsensors_v3.c | |
1222 | =================================================================== | |
1223 | --- agent/mibgroup/hardware/sensors/lmsensors_v3.c (revision 0) | |
1224 | +++ agent/mibgroup/hardware/sensors/lmsensors_v3.c (revision 16739) | |
1225 | @@ -0,0 +1,101 @@ | |
1226 | +#include <net-snmp/net-snmp-config.h> | |
1227 | +#include <net-snmp/net-snmp-includes.h> | |
1228 | +#include <net-snmp/agent/net-snmp-agent-includes.h> | |
1229 | +#include <net-snmp/agent/hardware/sensors.h> | |
1230 | + | |
1231 | +#include "util_funcs.h" | |
1232 | +#include <time.h> | |
1233 | +#include <sensors/sensors.h> | |
1234 | + | |
1235 | + | |
1236 | +void netsnmp_sensor_arch_init( void ) { | |
1237 | + FILE *fp = fopen("/etc/sensors.conf", "r"); | |
1238 | + DEBUGMSGTL(("sensors:arch", "Initialise v3 LM Sensors module\n")); | |
1239 | + sensors_init( fp ); | |
1240 | +} | |
1241 | + | |
1242 | +int | |
1243 | +netsnmp_sensor_arch_load(netsnmp_cache *cache, void *vp) { | |
1244 | + netsnmp_sensor_info *sp; | |
1245 | + const sensors_chip_name *chip; | |
1246 | + const sensors_feature *data; | |
1247 | + const sensors_subfeature *data2; | |
1248 | + int chip_nr = 0; | |
1249 | + | |
1250 | + DEBUGMSGTL(("sensors:arch", "Reload v3 LM Sensors module\n")); | |
1251 | + while ((chip = sensors_get_detected_chips( NULL, &chip_nr))) { | |
1252 | + int a = 0; | |
1253 | + | |
1254 | + while ((data = sensors_get_features( chip, &a))) { | |
1255 | + DEBUGMSGTL(("sensors:arch:detail", "get_features (%s, %d)\n", data->name, data->number)); | |
1256 | + int b = 0; | |
1257 | + | |
1258 | + | |
1259 | + while ((data2 = sensors_get_all_subfeatures( chip, data, &b))) { | |
1260 | + char *label = NULL; | |
1261 | + double val; | |
1262 | + int type = NETSNMP_SENSOR_TYPE_OTHER; | |
1263 | + | |
1264 | + DEBUGMSGTL(("sensors:arch:detail", " get_subfeatures (%s, %d)\n", data2->name, data2->number)); | |
1265 | + /* | |
1266 | + * Check the type of this subfeature, | |
1267 | + * concentrating on the main "input" measurements. | |
1268 | + */ | |
1269 | + switch ( data2->type ) { | |
1270 | + case SENSORS_SUBFEATURE_IN_INPUT: | |
1271 | + type = NETSNMP_SENSOR_TYPE_VOLTAGE_DC; | |
1272 | + break; | |
1273 | + case SENSORS_SUBFEATURE_FAN_INPUT: | |
1274 | + type = NETSNMP_SENSOR_TYPE_RPM; | |
1275 | + break; | |
1276 | + case SENSORS_SUBFEATURE_TEMP_INPUT: | |
1277 | + type = NETSNMP_SENSOR_TYPE_TEMPERATURE; | |
1278 | + break; | |
1279 | + case SENSORS_SUBFEATURE_VID: | |
1280 | + type = NETSNMP_SENSOR_TYPE_VOLTAGE_DC; | |
1281 | + break; | |
1282 | + default: | |
1283 | + /* Skip everything other than these basic sensor features - ??? */ | |
1284 | + DEBUGMSGTL(("sensors:arch:detail", " Skip type %x\n", data2->type)); | |
1285 | + continue; | |
1286 | + } | |
1287 | + | |
1288 | + /* | |
1289 | + * Get the name and value of this subfeature | |
1290 | + */ | |
1291 | +/* | |
1292 | + if (!(label = sensors_get_label(chip, data))) { | |
1293 | + DEBUGMSGTL(("sensors:arch:detail", " Can't get name (%s)\n", label)); | |
1294 | + continue; | |
1295 | + } | |
1296 | + if (sensors_get_value(chip, data2->number, &val) < 0) { | |
1297 | + DEBUGMSGTL(("sensors:arch:detail", " Can't get value (%f)\n", val)); | |
1298 | + continue; | |
1299 | + } | |
1300 | +*/ | |
1301 | + if (!(label = sensors_get_label(chip, data)) || | |
1302 | + (sensors_get_value(chip, data2->number, &val) < 0)) { | |
1303 | + DEBUGMSGTL(("sensors:arch:detail", " Can't get name/value (%s, %f)\n", label, val)); | |
1304 | + continue; | |
1305 | + } | |
1306 | + DEBUGMSGTL(("sensors:arch:detail", "%s = %f\n", label, val)); | |
1307 | + | |
1308 | + /* | |
1309 | + * Use this type to create a new sensor entry | |
1310 | + * (inserting it in the appropriate sub-containers) | |
1311 | + */ | |
1312 | + sp = sensor_by_name( label, type ); | |
1313 | + if ( sp ) { | |
1314 | + sp->value = val; | |
1315 | + sp->flags|= NETSNMP_SENSOR_FLAG_ACTIVE; | |
1316 | + } | |
1317 | + if (label) { | |
1318 | + free(label); | |
1319 | + label = NULL; | |
1320 | + } | |
1321 | + } /* end while data2 */ | |
1322 | + } /* end while data */ | |
1323 | + } /* end while chip */ | |
1324 | + | |
1325 | + return 0; | |
1326 | +} |