📄 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. * * Additional code provided by Mike Fisher and Thomas E. Lackley * * 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 (in thousandsths of a Celsius degree) * -fans (rpm's) * -voltages (in milliVolts) * -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. * * It was recently discovered that the sensors code had not be following * the MIB for some sensors. The MIB required reporting some items * in mV and mC. These changes have been noted in the source. * * To see debugging messages, run the daemon as follows: * * /usr/local/sbin/snmpd -f -L -Ducd-snmp/lmSensors * (change path to wherever you installed it) * * 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 /* the following should be sufficient for any Sun-based sensors */ #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 TEMP_TYPE (0)#define FAN_TYPE (1)#define VOLT_TYPE (2)#define MISC_TYPE (3)#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 DEFAULT_SENSORS (256)#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;#ifdef solaris2 _sensor sensor[MAX_SENSORS];#else _sensor* sensor; size_t current_len;#endif} _sensor_array;static _sensor_array sensor_array[N_TYPES];static time_t timestamp;static int sensor_init(void);static int sensor_load(void);static int _sensor_load(time_t t);#ifndef solaris2static void free_sensor_arrays(void);#endif/* * 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);}/* * shutdown_lmSensors(): * A shutdown/cleanup routine. This is called when the agent shutsdown. */voidshutdown_lmSensors(void){#ifndef solaris2 DEBUGMSG(("ucd-snmp/lmSensors", "=> shutdown_lmSensors\n")); free_sensor_arrays(); DEBUGMSG(("ucd-snmp/lmSensors", "<= shutdown_lmSensors\n"));#endif} /* shutdown_lmSensors *//* * 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 s_index; int s_type = -1; int n_sensors; unsigned char* ret = NULL; _sensor s; if (sensor_load()) { ret = NULL; goto leaving; } switch (vp->magic) { case LMTEMPSENSORSINDEX: case LMTEMPSENSORSDEVICE: case LMTEMPSENSORSVALUE: s_type = TEMP_TYPE; n_sensors = sensor_array[s_type].n; break; case LMFANSENSORSINDEX: case LMFANSENSORSDEVICE: case LMFANSENSORSVALUE: s_type = FAN_TYPE; n_sensors = sensor_array[s_type].n; break; case LMVOLTSENSORSINDEX: case LMVOLTSENSORSDEVICE: case LMVOLTSENSORSVALUE: s_type = VOLT_TYPE; n_sensors = sensor_array[s_type].n; break; case LMMISCSENSORSINDEX: case LMMISCSENSORSDEVICE: case LMMISCSENSORSVALUE: s_type = MISC_TYPE; n_sensors = sensor_array[s_type].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) { ret = NULL; goto leaving; } if (s_type < 0) { ret = NULL; goto leaving; } 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; ret = (unsigned char *) &long_ret; goto leaving; case LMTEMPSENSORSDEVICE: case LMFANSENSORSDEVICE: case LMVOLTSENSORSDEVICE: case LMMISCSENSORSDEVICE: strncpy(string, s.name, SPRINT_MAX_LEN - 1); *var_len = strlen(string); ret = (unsigned char *) string; goto leaving; case LMTEMPSENSORSVALUE: case LMFANSENSORSVALUE: case LMVOLTSENSORSVALUE: case LMMISCSENSORSVALUE: long_ret = s.value; ret = (unsigned char *) &long_ret; goto leaving; default: ERROR_MSG("Unable to handle table request"); }leaving: return ret;}static intsensor_init(void){ int res;#ifndef solaris2 char filename[] = CONFIG_FILE_NAME;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -