diff options
author | netchild <netchild@FreeBSD.org> | 2007-10-14 10:45:31 +0000 |
---|---|---|
committer | netchild <netchild@FreeBSD.org> | 2007-10-14 10:45:31 +0000 |
commit | 4af9918bc0e8f388ffda416ed716c9b17ca6c0fd (patch) | |
tree | e7d76e2d64fce20db3bf8837259e3d37e4f7d3ec /sbin/sysctl | |
parent | 57a6302920d738a0f943ec56aa7d87683e443246 (diff) | |
download | FreeBSD-src-4af9918bc0e8f388ffda416ed716c9b17ca6c0fd.zip FreeBSD-src-4af9918bc0e8f388ffda416ed716c9b17ca6c0fd.tar.gz |
Import OpenBSD's sysctl hardware sensors framework.
This commit includes the following core components:
* sample configuration file for sensorsd
* rc(8) script and glue code for sensorsd(8)
* sysctl(3) doc fixes for CTL_HW tree
* sysctl(3) documentation for hardware sensors
* sysctl(8) documentation for hardware sensors
* support for the sensor structure for sysctl(8)
* rc.conf(5) documentation for starting sensorsd(8)
* sensor_attach(9) et al documentation
* /sys/kern/kern_sensors.c
o sensor_attach(9) API for drivers to register ksensors
o sensor_task_register(9) API for the update task
o sysctl(3) glue code
o hw.sensors shadow tree for sysctl(8) internal magic
* <sys/sensors.h>
* HW_SENSORS definition for <sys/sysctl.h>
* sensors display for systat(1), including documentation
* sensorsd(8) and all applicable documentation
The userland part of the framework is entirely source-code
compatible with OpenBSD 4.1, 4.2 and -current as of today.
All sensor readings can be viewed with `sysctl hw.sensors`,
monitored in semi-realtime with `systat -sensors` and also
logged with `sensorsd`.
Submitted by: Constantine A. Murenin <cnst@FreeBSD.org>
Sponsored by: Google Summer of Code 2007 (GSoC2007/cnst-sensors)
Mentored by: syrinx
Tested by: many
OKed by: kensmith
Obtained from: OpenBSD (parts)
Diffstat (limited to 'sbin/sysctl')
-rw-r--r-- | sbin/sysctl/sysctl.8 | 1 | ||||
-rw-r--r-- | sbin/sysctl/sysctl.c | 140 |
2 files changed, 141 insertions, 0 deletions
diff --git a/sbin/sysctl/sysctl.8 b/sbin/sysctl/sysctl.8 index 942fd7c..1e656ad 100644 --- a/sbin/sysctl/sysctl.8 +++ b/sbin/sysctl/sysctl.8 @@ -215,6 +215,7 @@ denote .It "hw.floatingpoint integer no .It "hw.machine_arch string no .It "hw.realmem integer no +.It "hw.sensors.<xname>.<type><numt> struct no .It "machdep.console_device dev_t no .It "machdep.adjkerntz integer yes .It "machdep.disable_rtc_set integer yes diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c index 9dcfcb0..e4aa86b 100644 --- a/sbin/sysctl/sysctl.c +++ b/sbin/sysctl/sysctl.c @@ -44,6 +44,7 @@ static const char rcsid[] = #include <sys/param.h> #include <sys/time.h> #include <sys/resource.h> +#include <sys/sensors.h> #include <sys/stat.h> #include <sys/sysctl.h> #include <sys/vmmeter.h> @@ -408,6 +409,143 @@ S_vmtotal(int l2, void *p) } static int +S_sensor(int l2, void *p) +{ + struct sensor *s = (struct sensor *)p; + + if (l2 != sizeof(*s)) { + warnx("S_sensor %d != %d", l2, sizeof(*s)); + return (1); + } + + if (s->flags & SENSOR_FINVALID) { + /* + * XXX: with this flag, the node should be entirely ignored, + * but as the magic-based sysctl(8) is not too flexible, we + * simply have to print out that the sensor is invalid. + */ + printf("invalid"); + return (0); + } + + if (s->flags & SENSOR_FUNKNOWN) + printf("unknown"); + else { + switch (s->type) { + case SENSOR_TEMP: + printf("%.2f degC", + (s->value - 273150000) / 1000000.0); + break; + case SENSOR_FANRPM: + printf("%lld RPM", s->value); + break; + case SENSOR_VOLTS_DC: + printf("%.2f VDC", s->value / 1000000.0); + break; + case SENSOR_AMPS: + printf("%.2f A", s->value / 1000000.0); + break; + case SENSOR_WATTHOUR: + printf("%.2f Wh", s->value / 1000000.0); + break; + case SENSOR_AMPHOUR: + printf("%.2f Ah", s->value / 1000000.0); + break; + case SENSOR_INDICATOR: + printf("%s", s->value ? "On" : "Off"); + break; + case SENSOR_INTEGER: + printf("%lld", s->value); + break; + case SENSOR_PERCENT: + printf("%.2f%%", s->value / 1000.0); + break; + case SENSOR_LUX: + printf("%.2f lx", s->value / 1000000.0); + break; + case SENSOR_DRIVE: + { + const char *name; + + switch (s->value) { + case SENSOR_DRIVE_EMPTY: + name = "empty"; + break; + case SENSOR_DRIVE_READY: + name = "ready"; + break; + case SENSOR_DRIVE_POWERUP: + name = "powering up"; + break; + case SENSOR_DRIVE_ONLINE: + name = "online"; + break; + case SENSOR_DRIVE_IDLE: + name = "idle"; + break; + case SENSOR_DRIVE_ACTIVE: + name = "active"; + break; + case SENSOR_DRIVE_REBUILD: + name = "rebuilding"; + break; + case SENSOR_DRIVE_POWERDOWN: + name = "powering down"; + break; + case SENSOR_DRIVE_FAIL: + name = "failed"; + break; + case SENSOR_DRIVE_PFAIL: + name = "degraded"; + break; + default: + name = "unknown"; + break; + } + printf(name); + break; + } + case SENSOR_TIMEDELTA: + printf("%.6f secs", s->value / 1000000000.0); + break; + default: + printf("unknown"); + } + } + + if (s->desc[0] != '\0') + printf(" (%s)", s->desc); + + switch (s->status) { + case SENSOR_S_UNSPEC: + break; + case SENSOR_S_OK: + printf(", OK"); + break; + case SENSOR_S_WARN: + printf(", WARNING"); + break; + case SENSOR_S_CRIT: + printf(", CRITICAL"); + break; + case SENSOR_S_UNKNOWN: + printf(", UNKNOWN"); + break; + } + + if (s->tv.tv_sec) { + time_t t = s->tv.tv_sec; + char ct[26]; + + ctime_r(&t, ct); + ct[19] = '\0'; + printf(", %s.%03ld", ct, s->tv.tv_usec / 1000); + } + + return (0); +} + +static int T_dev_t(int l2, void *p) { dev_t *d = (dev_t *)p; @@ -678,6 +816,8 @@ show_var(int *oid, int nlen) func = S_loadavg; else if (strcmp(fmt, "S,vmtotal") == 0) func = S_vmtotal; + else if (strcmp(fmt, "S,sensor") == 0) + func = S_sensor; else if (strcmp(fmt, "T,dev_t") == 0) func = T_dev_t; else |