summaryrefslogtreecommitdiffstats
path: root/sbin/sysctl
diff options
context:
space:
mode:
authornetchild <netchild@FreeBSD.org>2007-10-14 10:45:31 +0000
committernetchild <netchild@FreeBSD.org>2007-10-14 10:45:31 +0000
commit4af9918bc0e8f388ffda416ed716c9b17ca6c0fd (patch)
treee7d76e2d64fce20db3bf8837259e3d37e4f7d3ec /sbin/sysctl
parent57a6302920d738a0f943ec56aa7d87683e443246 (diff)
downloadFreeBSD-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.81
-rw-r--r--sbin/sysctl/sysctl.c140
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
OpenPOWER on IntegriCloud