blob: c466eacb7f94ae6349c1fad2e745aa63a350f22c [file] [log] [blame]
#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( 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;
}