summaryrefslogtreecommitdiff
path: root/usr.sbin/sensorsd
diff options
context:
space:
mode:
authorHans-Joerg Hoexer <hshoexer@cvs.openbsd.org>2005-04-01 22:10:24 +0000
committerHans-Joerg Hoexer <hshoexer@cvs.openbsd.org>2005-04-01 22:10:24 +0000
commita79d93b1fa6cb131136c3e41382ffde1addfafa2 (patch)
tree0103e9a1811008cf05bbff4c88dd1a5598f5a6c6 /usr.sbin/sensorsd
parent36e2c747372b1e097aa424f5389a520bfe7acdd8 (diff)
sensorsd(8) execute command on exceeding limits
from matthew.gream@pobox.com, thanks! cleaning and ok deraadt@
Diffstat (limited to 'usr.sbin/sensorsd')
-rw-r--r--usr.sbin/sensorsd/sensorsd.811
-rw-r--r--usr.sbin/sensorsd/sensorsd.c130
-rw-r--r--usr.sbin/sensorsd/sensorsd.conf.517
3 files changed, 132 insertions, 26 deletions
diff --git a/usr.sbin/sensorsd/sensorsd.8 b/usr.sbin/sensorsd/sensorsd.8
index 8f0f245f44f..2f30e6bb72f 100644
--- a/usr.sbin/sensorsd/sensorsd.8
+++ b/usr.sbin/sensorsd/sensorsd.8
@@ -1,6 +1,7 @@
-.\" $OpenBSD: sensorsd.8,v 1.4 2004/06/27 22:48:27 jmc Exp $
+.\" $OpenBSD: sensorsd.8,v 1.5 2005/04/01 22:10:23 hshoexer Exp $
.\"
.\" Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
+.\" Copyright (c) 2005 Matthew Gream <matthew.gream@pobox.com>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd September 20, 2003
+.Dd March 15, 2005
.Dt SENSORSD 8
.Os
.Sh NAME
@@ -28,11 +29,11 @@ The
utility retrieves hardware sensor monitoring data like fan speeds,
temperatures and voltages, via
.Xr sysctl 3 .
-It uses
+If the data is out of given limits, an alert is sent using
.Xr syslog 3
-to send an alert if they are out of the given limits.
+and a command, if specified, is executed.
.Pp
-Limits for a particular sensor may be specified in the
+Limit and command values for a particular sensor may be specified in the
.Xr sensorsd.conf 5
configuration file.
.Sh FILES
diff --git a/usr.sbin/sensorsd/sensorsd.c b/usr.sbin/sensorsd/sensorsd.c
index 8e9a61aa6bb..11a59d09868 100644
--- a/usr.sbin/sensorsd/sensorsd.c
+++ b/usr.sbin/sensorsd/sensorsd.c
@@ -1,7 +1,8 @@
-/* $OpenBSD: sensorsd.c,v 1.11 2004/09/14 23:24:41 deraadt Exp $ */
+/* $OpenBSD: sensorsd.c,v 1.12 2005/04/01 22:10:23 hshoexer Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
+ * Copyright (c) 2005 Matthew Gream <matthew.gream@pobox.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -55,6 +56,7 @@ struct limits_t {
enum sensor_type type; /* sensor type */
int64_t lower; /* lower limit */
int64_t upper; /* upper limit */
+ char *command; /* failure command */
enum sensor_status status; /* last status */
time_t status_changed;
int64_t last_val;
@@ -64,6 +66,15 @@ TAILQ_HEAD(limits, limits_t) limits = TAILQ_HEAD_INITIALIZER(limits);
char *configfile;
volatile sig_atomic_t reload = 0;
+int debug = 0;
+
+void
+usage(void)
+{
+ extern char *__progname;
+ fprintf(stderr, "usage: %s [-d]\n", __progname);
+ exit(1);
+}
int
main(int argc, char *argv[])
@@ -75,6 +86,17 @@ main(int argc, char *argv[])
time_t next_check;
int mib[3];
int i, sleeptime, watch_cnt;
+ int ch;
+
+ while ((ch = getopt(argc, argv, "d")) != -1) {
+ switch (ch) {
+ case 'd':
+ debug = 1;
+ break;
+ default:
+ usage();
+ }
+ }
mib[0] = CTL_HW;
mib[1] = HW_SENSORS;
@@ -109,10 +131,11 @@ main(int argc, char *argv[])
if (watch_cnt == 0)
errx(1, "no watches defined");
- if (daemon(0, 0) == -1)
+ if (debug == 0 && daemon(0, 0) == -1)
err(1, "unable to fork");
signal(SIGHUP, reparse_cfg);
+ signal(SIGCHLD, SIG_IGN);
syslog(LOG_INFO, "startup, %d watches for %d sensors", watch_cnt, i);
@@ -181,25 +204,96 @@ check_sensors(void)
}
void
+execute(char *command)
+{
+ char *argp[] = {"sh", "-c", command, NULL};
+
+ switch (fork ()) {
+ case -1:
+ syslog(LOG_CRIT, "execute: fork() failed");
+ break;
+ case 0:
+ execv("/bin/sh", argp);
+ _exit(1);
+ /* NOTREACHED */
+ default:
+ break;
+ }
+}
+
+void
report(time_t last_report)
{
struct limits_t *limit = NULL;
- TAILQ_FOREACH(limit, &limits, entries)
- if (limit->status_changed > last_report) {
- if (limit->status == STATUS_FAIL)
- syslog(LOG_ALERT,
- "failure for hw.sensors.%d: "
- "%s not within limits",
- limit->num,
- print_sensor(limit->type, limit->last_val));
- else
- syslog(LOG_ALERT,
- "hw.sensors.%d within limits again, "
- "current value %s",
- limit->num,
- print_sensor(limit->type, limit->last_val));
+ TAILQ_FOREACH(limit, &limits, entries) {
+ if (limit->status_changed <= last_report)
+ continue;
+
+ syslog(LOG_ALERT, "hw.sensors.%d: %s limits, value: %s",
+ limit->num,
+ (limit->status == STATUS_FAIL) ? "exceed" : "within",
+ print_sensor(limit->type, limit->last_val));
+ if (limit->command) {
+ int i = 0, n = 0, r;
+ char *cmd = limit->command;
+ char buf[BUFSIZ];
+ int len = sizeof(buf);
+
+ buf[0] = '\0';
+ for (i = n = 0; n < len; ++i) {
+ if (cmd[i] == '\0') {
+ buf[n++] = '\0';
+ break;
+ }
+ if (cmd[i] != '%') {
+ buf[n++] = limit->command[i];
+ continue;
+ }
+ i++;
+ if (cmd[i] == '\0') {
+ buf[n++] = '\0';
+ break;
+ }
+
+ switch (cmd[i]) {
+ case '1':
+ r = snprintf(&buf[n], len, "%d",
+ limit->num);
+ break;
+ case '2':
+ r = snprintf(&buf[n], len, "%s",
+ print_sensor(limit->type,
+ limit->last_val));
+ break;
+ case '3':
+ r = snprintf(&buf[n], len, "%s",
+ print_sensor(limit->type,
+ limit->lower));
+ break;
+ case '4':
+ r = snprintf(&buf[n], len, "%s",
+ print_sensor(limit->type,
+ limit->upper));
+ break;
+ default:
+ r = snprintf(&buf[n], len, "%%%c",
+ cmd[i]);
+ break;
+ }
+ if (r > len) {
+ buf[n] = '\0';
+ break;
+ }
+ if (r > 0) {
+ len -= r;
+ n += r;
+ }
+ }
+ if (buf[0])
+ execute(buf);
}
+ }
}
static char *
@@ -260,6 +354,10 @@ parse_config(char *cf)
if (cgetstr(buf, "high", &ebuf) < 0)
ebuf = NULL;
p->upper = get_val(ebuf, 1, p->type);
+ if (cgetstr(buf, "command", &ebuf) < 0)
+ ebuf = NULL;
+ if (ebuf)
+ asprintf(&(p->command), "%s", ebuf);
free(buf);
buf = NULL;
}
diff --git a/usr.sbin/sensorsd/sensorsd.conf.5 b/usr.sbin/sensorsd/sensorsd.conf.5
index af3495165d9..31c1bca8ff9 100644
--- a/usr.sbin/sensorsd/sensorsd.conf.5
+++ b/usr.sbin/sensorsd/sensorsd.conf.5
@@ -1,6 +1,7 @@
-.\" $OpenBSD: sensorsd.conf.5,v 1.1 2003/09/24 20:32:49 henning Exp $
+.\" $OpenBSD: sensorsd.conf.5,v 1.2 2005/04/01 22:10:23 hshoexer Exp $
.\"
.\" Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
+.\" Copyright (c) 2005 Matthew Gream <matthew.gream@pobox.com>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd September 20, 2003
+.Dd March 15, 2005
.Dt SENSORSD.CONF 5
.Os
.Sh NAME
@@ -30,9 +31,10 @@ file is read by
.Xr sensorsd 8
to configure hardware sensor monitoring.
Each entry represents one sensor and may specify high and low limits.
-If the sensor data is out of range of the low and the high limits,
+If the limits are crossed,
.Xr sensorsd 8 's
-alert functionality is triggered.
+alert functionality is triggered and the command, if specified, is
+executed.
.Pp
.Nm
follows the syntax of configuration databases as documented in
@@ -40,7 +42,7 @@ follows the syntax of configuration databases as documented in
.Pp
Example:
.Bd -literal -offset indent
-hw.sensors.0:high=80C
+hw.sensors.0:high=80C:command=/etc/sensorsd/log_warning %1 %2
hw.sensors.1:high=170F
hw.sensors.2:low=4.8V:high=5.2V
hw.sensors.3:low=1000:high=8000
@@ -49,6 +51,11 @@ hw.sensors.3:low=1000:high=8000
The values for temperature sensors can be given in degrees Celsius or
Fahrenheit, for voltage sensors in volts, and fan speed sensors take a
unit-less number representing RPM.
+.Pp
+The command is executed on transitions out of, and back into, given
+limits. Tokens in the command are substituted as follows: %1 with
+the sensor number, %2 with the sensor's current value, %3 with the
+sensor's low limit, and %4 with the sensor's high limit.
.Sh FILES
.Bl -tag -width "/etc/sensorsd.conf"
.It /etc/sensorsd.conf