diff options
author | Hans-Joerg Hoexer <hshoexer@cvs.openbsd.org> | 2005-04-01 22:10:24 +0000 |
---|---|---|
committer | Hans-Joerg Hoexer <hshoexer@cvs.openbsd.org> | 2005-04-01 22:10:24 +0000 |
commit | a79d93b1fa6cb131136c3e41382ffde1addfafa2 (patch) | |
tree | 0103e9a1811008cf05bbff4c88dd1a5598f5a6c6 | |
parent | 36e2c747372b1e097aa424f5389a520bfe7acdd8 (diff) |
sensorsd(8) execute command on exceeding limits
from matthew.gream@pobox.com, thanks!
cleaning and ok deraadt@
-rw-r--r-- | usr.sbin/sensorsd/sensorsd.8 | 11 | ||||
-rw-r--r-- | usr.sbin/sensorsd/sensorsd.c | 130 | ||||
-rw-r--r-- | usr.sbin/sensorsd/sensorsd.conf.5 | 17 |
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 |