📄 lmsensors.c
字号:
/* lmSensors.c * * Sections of this code were derived from the published API's of * some Sun products. Hence, portions of the code may be copyright * Sun Microsystems. * * This component allows net-snmp to report sensor information. * * In order to use it, the ./configure invocation must include... * * --with-mib-modules="ucd-snmp/lmSensors" * * It uses one of three different methodologies. Some platforms make * use of an lm_sensors driver to access the information on the * health monitoring hardware, such as the LM75 and LM78 chips. * * For further information see http://secure.netroedge.com/~lm78/ * * The Solaris platform uses the other two methodologies. Earlier * platforms such as the Enterprise 450 use kstat to report sensor * information. Later platforms, such as the V880 use the picld * daemon to control system resources and report sensor information. * Picld is supported only on Solaris 2.8 and later. * * Both these methodologies are implemented in a "read only" manner. * You cannot use this code to change anything eg. fan speeds. * * The lmSensors component delivers the information documented in the * LM-SENSORS-MIB. The information is divided up as follows: * * -temperatures (Celsius) * -fans (rpm's) * -voltages * -other (switches, LEDs and i2c's (things that use the i2c bus)) * NOTE: This version does not support gpio's. Still on the learning curve. * * Because the MIB only allows output of the datatype Gauge32 this * limits the amount of meaningful information that can be delivered * from "other" sensors. Hence, the code does a certain amount of * translating. See the source for individual sensor types. * * If an "other" sensor delivers a value 99, it means that it * is delivering a "status" that the code does not account for. * If you discover one of these, please pass it on and I'll * put it in. * * To see these messages, run the daemon as follows: * * /usr/local/sbin/snmpd -f -L -Ducd-snmp/lmSensors * * or using gdb: * * gdb snmpd * run -f -L -Ducd-snmp/lmSensors * * The component can record up to 256 instances of each type. * * The following should always be included first before anything else */#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>/* * minimal include directives */#include "util_funcs.h"#include <time.h>/* * Load required drivers and libraries. */#ifdef solaris2 #include <kstat.h> #ifdef HAVE_PICL_H #include <picl.h> /* accesses the picld daemon */ #endif #include </usr/platform/sun4u/include/sys/envctrl.h>#else #include <sensors/sensors.h> #define CONFIG_FILE_NAME "/etc/sensors.conf"#endif#include "lmSensors.h"#define N_TYPES (4)#ifdef solaris2 #define MAX_NAME (256) #define MAX_SENSORS (256) /* there's a lot of sensors on a v880 */#else #define MAX_NAME (64) #define MAX_SENSORS (128)#endif/* * lmSensors_variables_oid: * this is the top level oid that we want to register under. This * is essentially a prefix, with the suffix appearing in the * variable below. */oid lmSensors_variables_oid[] = { 1, 3, 6, 1, 4, 1, 2021, 13, 16 };/* * variable4 lmSensors_variables: * this variable defines function callbacks and type return information * for the lmSensors mib section */struct variable4 lmSensors_variables[] = { /* * magic number , variable type , ro/rw , callback fn , L, oidsuffix */#define LMTEMPSENSORSINDEX 3 {LMTEMPSENSORSINDEX, ASN_INTEGER, RONLY, var_lmSensorsTable, 3, {2, 1, 1}},#define LMTEMPSENSORSDEVICE 4 {LMTEMPSENSORSDEVICE, ASN_OCTET_STR, RONLY, var_lmSensorsTable, 3, {2, 1, 2}},#define LMTEMPSENSORSVALUE 5 {LMTEMPSENSORSVALUE, ASN_GAUGE, RONLY, var_lmSensorsTable, 3, {2, 1, 3}},#define LMFANSENSORSINDEX 8 {LMFANSENSORSINDEX, ASN_INTEGER, RONLY, var_lmSensorsTable, 3, {3, 1, 1}},#define LMFANSENSORSDEVICE 9 {LMFANSENSORSDEVICE, ASN_OCTET_STR, RONLY, var_lmSensorsTable, 3, {3, 1, 2}},#define LMFANSENSORSVALUE 10 {LMFANSENSORSVALUE, ASN_GAUGE, RONLY, var_lmSensorsTable, 3, {3, 1, 3}},#define LMVOLTSENSORSINDEX 13 {LMVOLTSENSORSINDEX, ASN_INTEGER, RONLY, var_lmSensorsTable, 3, {4, 1, 1}},#define LMVOLTSENSORSDEVICE 14 {LMVOLTSENSORSDEVICE, ASN_OCTET_STR, RONLY, var_lmSensorsTable, 3, {4, 1, 2}},#define LMVOLTSENSORSVALUE 15 {LMVOLTSENSORSVALUE, ASN_GAUGE, RONLY, var_lmSensorsTable, 3, {4, 1, 3}},#define LMMISCSENSORSINDEX 18 {LMMISCSENSORSINDEX, ASN_INTEGER, RONLY, var_lmSensorsTable, 3, {5, 1, 1}},#define LMMISCSENSORSDEVICE 19 {LMMISCSENSORSDEVICE, ASN_OCTET_STR, RONLY, var_lmSensorsTable, 3, {5, 1, 2}},#define LMMISCSENSORSVALUE 20 {LMMISCSENSORSVALUE, ASN_GAUGE, RONLY, var_lmSensorsTable, 3, {5, 1, 3}},};typedef struct {#ifdef solaris2 #ifdef HAVE_PICL_H char name[PICL_PROPNAMELEN_MAX]; /*required for picld*/ int value; #else char name[MAX_NAME]; int value; #endif#else char name[MAX_NAME]; int value;#endif} _sensor;typedef struct { int n; _sensor sensor[MAX_SENSORS];} _sensor_array;static _sensor_array sensor_array[N_TYPES];static clock_t timestamp;static int sensor_init(void);static void sensor_load(void);static void _sensor_load(clock_t t);/* * init_lmSensors(): * Initialization routine. This is called when the agent starts up. * At a minimum, registration of your variables should take place here. */voidinit_lmSensors(void){ sensor_init(); /* * register ourselves with the agent to handle our mib tree */ REGISTER_MIB("lmSensors", lmSensors_variables, variable4, lmSensors_variables_oid);}/* * var_lmSensorsTable(): * Handle this table separately from the scalar value case. * The workings of this are basically the same as for var_lmSensors above. */unsigned char *var_lmSensorsTable(struct variable *vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method){ static long long_ret; static unsigned char string[SPRINT_MAX_LEN]; int i; /* generates a variable not used error message in Solaris - that's OK */ int s_index; int s_type = -1; int n_sensors; _sensor s; sensor_load(); switch (vp->magic) { case LMTEMPSENSORSINDEX: case LMTEMPSENSORSDEVICE: case LMTEMPSENSORSVALUE: s_type = 0; n_sensors = sensor_array[0].n; break; case LMFANSENSORSINDEX: case LMFANSENSORSDEVICE: case LMFANSENSORSVALUE: s_type = 1; n_sensors = sensor_array[1].n; break; case LMVOLTSENSORSINDEX: case LMVOLTSENSORSDEVICE: case LMVOLTSENSORSVALUE: s_type = 2; n_sensors = sensor_array[2].n; break; case LMMISCSENSORSINDEX: case LMMISCSENSORSDEVICE: case LMMISCSENSORSVALUE: s_type = 3; n_sensors = sensor_array[3].n; break; default: s_type = -1; n_sensors = 0; } if (header_simple_table(vp, name, length, exact, var_len, write_method, n_sensors) == MATCH_FAILED) return NULL; if (s_type < 0) return NULL; s_index = name[*length - 1] - 1; s = sensor_array[s_type].sensor[s_index]; switch (vp->magic) { case LMTEMPSENSORSINDEX: case LMFANSENSORSINDEX: case LMVOLTSENSORSINDEX: case LMMISCSENSORSINDEX: long_ret = s_index; return (unsigned char *) &long_ret; case LMTEMPSENSORSDEVICE: case LMFANSENSORSDEVICE: case LMVOLTSENSORSDEVICE: case LMMISCSENSORSDEVICE: strncpy(string, s.name, SPRINT_MAX_LEN - 1); *var_len = strlen(string); return (unsigned char *) string; case LMTEMPSENSORSVALUE: case LMFANSENSORSVALUE: case LMVOLTSENSORSVALUE: case LMMISCSENSORSVALUE: long_ret = s.value; return (unsigned char *) &long_ret; default: ERROR_MSG("Unable to handle table request"); } return NULL;}static intsensor_init(void){#ifdef solaris2 clock_t t = time(NULL);#else int res; char filename[] = CONFIG_FILE_NAME; clock_t t = clock(); FILE *fp = fopen(filename, "r"); if (!fp) return 1; if (res = sensors_init(fp)) return 2; _sensor_load(t); /* I'll let the linux people decide whether they want to load right away */#endif return 0;}static voidsensor_load(void){#ifdef solaris2 clock_t t = time(NULL);#else clock_t t = clock();#endif if (t > timestamp + 6) /* this may require some tuning - currently 6 seconds*/ _sensor_load(t); return;}/* This next code block includes all kstat and picld code for the Solaris platform. * If you're not compiling on a Solaris that supports picld, it won't be included.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -