diff --git a/clients/upsmon.c b/clients/upsmon.c index 39c61ba6dc..a08a453888 100644 --- a/clients/upsmon.c +++ b/clients/upsmon.c @@ -657,6 +657,19 @@ static int is_ups_critical(utype_t *ups) /* must be OB+LB now */ + /* if UPS is calibrating, don't declare it critical */ + /* FIXME: Consider UPSes where we can know if they have other power + * circuits (bypass, etc.) and whether those do currently provide + * wall power to the host - and that we do not have both calibration + * and a real outage, when we still should shut down right now. + */ + if (flag_isset(ups->status, ST_CAL)) { + upslogx(LOG_WARNING, "%s: seems that UPS [%s] is OB+LB now, but " + "it is also calibrating - not declaring a critical state", + __func__, ups->upsname); + return 0; + } + /* if we're a master, declare it critical so we set FSD on it */ if (flag_isset(ups->status, ST_MASTER)) return 1; @@ -743,6 +756,21 @@ static void upsreplbatt(utype_t *ups) } } +static void ups_cal(utype_t *ups) +{ + if (flag_isset(ups->status, ST_CAL)) { /* no change */ + upsdebugx(4, "%s: %s (no change)", __func__, ups->sys); + return; + } + + upsdebugx(3, "%s: %s (first time)", __func__, ups->sys); + + /* must have changed from !CAL to CAL, so notify */ + + do_notify(ups, NOTIFY_CAL); + setflag(&ups->status, ST_CAL); +} + static void ups_fsd(utype_t *ups) { if (flag_isset(ups->status, ST_FSD)) { /* no change */ @@ -1372,9 +1400,10 @@ static void setup_signals(void) /* remember the last time the ups was not critical (OB + LB) */ static void update_crittimer(utype_t *ups) { - /* if !OB or !LB, then it's not critical, so log the time */ - if ((!flag_isset(ups->status, ST_ONBATT)) || - (!flag_isset(ups->status, ST_LOWBATT))) { + /* if !OB, !LB, or CAL, then it's not critical, so log the time */ + if ((!flag_isset(ups->status, ST_ONBATT)) || + (!flag_isset(ups->status, ST_LOWBATT)) || + (flag_isset(ups->status, ST_CAL))) { time(&ups->lastnoncrit); return; @@ -1492,6 +1521,8 @@ static void parse_status(utype_t *ups, char *status) ups_low_batt(ups); if (!strcasecmp(statword, "RB")) upsreplbatt(ups); + if (!strcasecmp(statword, "CAL")) + ups_cal(ups); /* do it last to override any possible OL */ if (!strcasecmp(statword, "FSD")) diff --git a/clients/upsmon.h b/clients/upsmon.h index 2504370cf1..7fe98eb827 100644 --- a/clients/upsmon.h +++ b/clients/upsmon.h @@ -26,6 +26,7 @@ #define ST_MASTER (1 << 4) /* we are the master on this UPS */ #define ST_LOGIN (1 << 5) /* we are logged into this UPS */ #define ST_CONNECTED (1 << 6) /* upscli_connect returned OK */ +#define ST_CAL (1 << 7) /* UPS calibration in progress (CAL) */ /* required contents of flag file */ #define SDMAGIC "upsmon-shutdown-file" @@ -75,6 +76,7 @@ typedef struct { #define NOTIFY_REPLBATT 7 /* UPS battery needs to be replaced */ #define NOTIFY_NOCOMM 8 /* UPS hasn't been contacted in awhile */ #define NOTIFY_NOPARENT 9 /* privileged parent process died */ +#define NOTIFY_CAL 10 /* UPS is performing calibration */ /* notify flag values */ @@ -104,6 +106,7 @@ struct { { NOTIFY_REPLBATT, "REPLBATT", NULL, "UPS %s battery needs to be replaced", NOTIFY_SYSLOG | NOTIFY_WALL }, { NOTIFY_NOCOMM, "NOCOMM", NULL, "UPS %s is unavailable", NOTIFY_SYSLOG | NOTIFY_WALL }, { NOTIFY_NOPARENT, "NOPARENT", NULL, "upsmon parent process died - shutdown impossible", NOTIFY_SYSLOG | NOTIFY_WALL }, + { NOTIFY_CAL, "CAL", NULL, "UPS %s: calibration in progress", NOTIFY_SYSLOG }, { 0, NULL, NULL, NULL, 0 } };