summaryrefslogtreecommitdiff
path: root/agent/mibgroup/hardware/sensors/hw_sensors.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/hardware/sensors/hw_sensors.c')
-rw-r--r--agent/mibgroup/hardware/sensors/hw_sensors.c189
1 files changed, 189 insertions, 0 deletions
diff --git a/agent/mibgroup/hardware/sensors/hw_sensors.c b/agent/mibgroup/hardware/sensors/hw_sensors.c
new file mode 100644
index 0000000..1a01645
--- /dev/null
+++ b/agent/mibgroup/hardware/sensors/hw_sensors.c
@@ -0,0 +1,189 @@
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <net-snmp/agent/hardware/sensors.h>
+
+
+extern NetsnmpCacheLoad netsnmp_sensor_arch_load;
+extern void netsnmp_sensor_arch_init( void );
+static int _sensor_load( void );
+static void _sensor_free( void );
+
+static int _sensorAutoUpdate = 0; /* 0 means on-demand caching */
+static void _sensor_update_stats( unsigned int, void* );
+
+netsnmp_cache *_sensor_cache = NULL;
+netsnmp_container *_sensor_container = NULL;
+static int _sensor_idx = 0;
+
+void init_hw_sensors( void ) {
+
+ if ( _sensor_container )
+ return; /* Already initialised */
+
+ DEBUGMSGTL(("sensors", "Initialise Hardware Sensors module\n"));
+
+ /*
+ * Define a container to hold the basic list of sensors
+ * The four LM-SENSOR-MIB containers will be created in
+ * the relevant initialisation routine(s)
+ */
+ _sensor_container = netsnmp_container_find("sensorTable:table_container");
+ if ( NULL == _sensor_container ) {
+ snmp_log( LOG_ERR, "failed to create container for sensorTable");
+ return;
+ }
+ netsnmp_sensor_arch_init( );
+
+ /*
+ * If we're sampling the sensor information automatically,
+ * then arrange for this to be triggered regularly.
+ *
+ * If we're not sampling these values regularly,
+ * create a suitable cache handler instead.
+ */
+ if ( _sensorAutoUpdate ) {
+ DEBUGMSGTL(("sensors", "Reloading Hardware Sensors automatically (%d)\n",
+ _sensorAutoUpdate));
+ snmp_alarm_register( _sensorAutoUpdate, SA_REPEAT,
+ _sensor_update_stats, NULL );
+ }
+ else {
+ _sensor_cache = netsnmp_cache_create( 5, netsnmp_sensor_load,
+ netsnmp_sensor_free, NULL, 0 );
+ DEBUGMSGTL(("sensors", "Reloading Hardware Sensors on-demand (%p)\n",
+ _sensor_cache));
+ }
+}
+
+void shutdown_hw_sensors( void ) {
+ _sensor_free();
+}
+
+/*
+ * Return the main sensor container
+ */
+netsnmp_container *get_sensor_container( void ) { return _sensor_container; }
+
+/*
+ * Return the main sensor cache control structure (if defined)
+ */
+netsnmp_cache *get_sensor_cache( void ) { return _sensor_cache; }
+
+
+/*
+ * Wrapper routine for automatically updating sensor statistics
+ */
+void
+_sensor_update_stats( unsigned int clientreg, void *data )
+{
+ _sensor_free();
+ _sensor_load();
+}
+
+/*
+ * Wrapper routine for re-loading sensor statistics on demand
+ */
+int
+netsnmp_sensor_load( netsnmp_cache *cache, void *data )
+{
+ return _sensor_load();
+}
+
+/*
+ * Wrapper routine for releasing expired sensor statistics
+ */
+void
+netsnmp_sensor_free( netsnmp_cache *cache, void *data )
+{
+ _sensor_free();
+}
+
+
+/*
+ * Architecture-independent processing of loading sensor statistics
+ */
+static int
+_sensor_load( void )
+{
+ netsnmp_sensor_arch_load( NULL, NULL );
+ return 0;
+}
+
+/*
+ * Architecture-independent release of sensor statistics
+ */
+static void
+_sensor_free( void )
+{
+ netsnmp_sensor_info *sp;
+
+ for (sp = CONTAINER_FIRST( _sensor_container );
+ sp;
+ sp = CONTAINER_NEXT( _sensor_container, sp )) {
+
+ sp->flags &= ~ NETSNMP_SENSOR_FLAG_ACTIVE;
+ }
+}
+
+
+/*
+ * Retrieve a sensor entry by name,
+ * or (optionally) insert a new one into the container
+ */
+netsnmp_sensor_info *
+sensor_by_name( const char *name, int create_type )
+{
+ netsnmp_sensor_info *sp;
+
+ DEBUGMSGTL(("sensors:name", "Get sensor entry (%s)\n", name));
+
+ /*
+ * Look through the list for a matching entry
+ */
+ /* .. or use a secondary index container ?? */
+ for (sp = CONTAINER_FIRST( _sensor_container );
+ sp;
+ sp = CONTAINER_NEXT( _sensor_container, sp )) {
+
+ if ( !strcmp( name, sp->name ))
+ return sp;
+ }
+
+ /*
+ * Not found...
+ */
+ if ( create_type == NETSNMP_SENSOR_FIND_EXIST ) {
+ DEBUGMSGTL(("sensors:name", "No such sensor entry\n"));
+ return NULL;
+ }
+
+ /*
+ * ... so let's create a new one, using the type supplied
+ */
+ sp = SNMP_MALLOC_TYPEDEF( netsnmp_sensor_info );
+ if ( sp ) {
+ if (strlen(name) >= sizeof(sp->name)) {
+ snmp_log(LOG_ERR, "Sensor name is too large: %s\n", name);
+ free(sp);
+ return NULL;
+ }
+ strcpy( sp->name, name );
+ sp->type = create_type;
+ /*
+ * Set up the index value.
+ *
+ * All this trouble, just for a simple integer.
+ * Surely there must be a better way?
+ */
+ sp->idx.len = 1;
+ sp->idx.oids = SNMP_MALLOC_TYPEDEF( oid );
+ sp->idx.oids[0] = ++_sensor_idx;
+ }
+
+ DEBUGMSGTL(("sensors:name", "Create sensor entry (type = %d, index = %d\n",
+ create_type, _sensor_idx));
+ CONTAINER_INSERT( _sensor_container, sp );
+ return sp;
+}
+