diff options
author | Constantine A. Murenin <cnst@cvs.openbsd.org> | 2008-06-11 05:54:23 +0000 |
---|---|---|
committer | Constantine A. Murenin <cnst@cvs.openbsd.org> | 2008-06-11 05:54:23 +0000 |
commit | e066d625d113d9f5ae8a7ec7deb270370b8cdadf (patch) | |
tree | 3c50d8a94bf58ce6f53e474de390bb6376751211 /usr.sbin/sensorsd | |
parent | 19bd3957dcae701353d7ded2db29ad9e6bcff394 (diff) |
Support hotpluggable sensors (e.g. the post-4.2 ipmi0 created by the
deferred thread, as well as some timedelta sensors).
ok henning, ckuethe
Diffstat (limited to 'usr.sbin/sensorsd')
-rw-r--r-- | usr.sbin/sensorsd/sensorsd.c | 89 |
1 files changed, 85 insertions, 4 deletions
diff --git a/usr.sbin/sensorsd/sensorsd.c b/usr.sbin/sensorsd/sensorsd.c index 1501c9a0f6a..75b7a61d520 100644 --- a/usr.sbin/sensorsd/sensorsd.c +++ b/usr.sbin/sensorsd/sensorsd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sensorsd.c,v 1.42 2008/05/12 19:15:02 pyr Exp $ */ +/* $OpenBSD: sensorsd.c,v 1.43 2008/06/11 05:54:22 cnst Exp $ */ /* * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> @@ -75,6 +75,7 @@ struct sdlim_t { void usage(void); struct sdlim_t *create_sdlim(struct sensordev *); +void destroy_sdlim(struct sdlim_t *); void check(time_t); void check_sdlim(struct sdlim_t *, time_t); void execute(char *); @@ -86,7 +87,8 @@ void parse_config_sdlim(struct sdlim_t *, char **); int64_t get_val(char *, int, enum sensor_type); void reparse_cfg(int); -TAILQ_HEAD(, sdlim_t) sdlims = TAILQ_HEAD_INITIALIZER(sdlims); +TAILQ_HEAD(sdlimhead_t, sdlim_t); +struct sdlimhead_t sdlims = TAILQ_HEAD_INITIALIZER(sdlims); char *configfile; volatile sig_atomic_t reload = 0; @@ -225,12 +227,91 @@ create_sdlim(struct sensordev *snsrdev) } void +destroy_sdlim(struct sdlim_t *sdlim) +{ + struct limits_t *limit; + + while((limit = TAILQ_FIRST(&sdlim->limits)) != NULL) { + TAILQ_REMOVE(&sdlim->limits, limit, entries); + if (limit->command != NULL) + free(limit->command); + free(limit); + } + free(sdlim); +} + +void check(time_t this_check) { - struct sdlim_t *sdlim; + struct sensordev sensordev; + struct sdlim_t *sdlim, *next; + int mib[3]; + int h, t, i; + size_t sdlen = sizeof(sensordev); + + if (TAILQ_EMPTY(&sdlims)) { + h = 0; + t = -1; + } else { + h = TAILQ_FIRST(&sdlims)->dev; + t = TAILQ_LAST(&sdlims, sdlimhead_t)->dev; + } + sdlim = TAILQ_FIRST(&sdlims); - TAILQ_FOREACH(sdlim, &sdlims, entries) + mib[0] = CTL_HW; + mib[1] = HW_SENSORS; + /* look ahead for 4 more sensordevs */ + for (i = h; i <= t + 4; i++) { + if (sdlim != NULL && i > sdlim->dev) + sdlim = TAILQ_NEXT(sdlim, entries); + if (sdlim == NULL && i <= t) + syslog(LOG_ALERT, "inconsistent sdlim logic"); + mib[2] = i; + if (sysctl(mib, 3, &sensordev, &sdlen, NULL, 0) == -1) { + if (errno != ENOENT) + warn("sysctl"); + if (sdlim != NULL && i == sdlim->dev) { + next = TAILQ_NEXT(sdlim, entries); + TAILQ_REMOVE(&sdlims, sdlim, entries); + syslog(LOG_INFO, "%s has disappeared", + sdlim->dxname); + destroy_sdlim(sdlim); + sdlim = next; + } + continue; + } + if (sdlim != NULL && i == sdlim->dev) { + if (strcmp(sdlim->dxname, sensordev.xname) == 0) { + check_sdlim(sdlim, this_check); + continue; + } else { + next = TAILQ_NEXT(sdlim, entries); + TAILQ_REMOVE(&sdlims, sdlim, entries); + syslog(LOG_INFO, "%s has been replaced", + sdlim->dxname); + destroy_sdlim(sdlim); + sdlim = next; + } + } + next = create_sdlim(&sensordev); + /* inserting next before sdlim */ + if (sdlim != NULL) + TAILQ_INSERT_BEFORE(sdlim, next, entries); + else + TAILQ_INSERT_TAIL(&sdlims, next, entries); + syslog(LOG_INFO, "%s has appeared", next->dxname); + sdlim = next; + parse_config(configfile); + syslog(LOG_INFO, "configuration reloaded"); check_sdlim(sdlim, this_check); + } + + /* Ensure that our queue is consistent. */ + for (sdlim = TAILQ_FIRST(&sdlims); + (next = TAILQ_NEXT(sdlim, entries)) != NULL; + sdlim = next) + if (sdlim->dev > next->dev) + syslog(LOG_ALERT, "inconsistent sdlims queue"); } void |