Skip to content

Commit 995a82c

Browse files
authored
Merge branch 'master' into modernize-drv-alarms
2 parents 6c5631d + 8decca2 commit 995a82c

File tree

8 files changed

+276
-111
lines changed

8 files changed

+276
-111
lines changed

AUTHORS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,12 @@ E: [email protected]
196196
D: Updating device support docs after unnecessarily writing a redundant
197197
D: driver first
198198

199+
N: desertwitch
200+
201+
D: Primarily contributions to upsmon, PR discussions, as well as small-scale
202+
D: QOL improvements throughout both UPS driver code and other project parts.
203+
P: 4096R/06FD918F FDE5 DBCF 1792 4276 532B FBCA DDA4 D1A9 06FD 918F
204+
199205
N: Marco Trevisan (Treviño)
200206
201207
W: https://3v1n0.net

NEWS.adoc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ https://github.com/networkupstools/nut/milestone/9
7373
and misfired on some platforms, and the way to print had a theoretical
7474
potential for buffer overflow. [#2915]
7575

76+
- common driver code:
77+
* Removed workarounds trying to migrate legacy driver raised `ALARM`
78+
status tokens into modern `alarm_*` function logic. Rather, we keep
79+
supporting them as separate from the modern logic, seeing as `upsmon`
80+
does not care where the token itself was raised for its notifications.
81+
Driver-code related test-cases were updated to reflect these changes.
82+
[issue #2928, PRs #2931 and #2934]
83+
7684
- `dummy-ups` driver updates:
7785
* A new instruction `ALARM` was added for the `Dummy Mode` operation
7886
of the driver, enabling simulation of UPS alarm states more closely

clients/upsmon.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,8 @@ static void ups_is_alarm(utype_t *ups)
820820
do_notify(ups, NOTIFY_ALARM, alarms);
821821
}
822822
} else {
823-
upsdebugx(4, "%s: %s: still on alarm, failed to get current ups.alarm value",
823+
upsdebugx(4, "%s: %s: still on alarm, failed to get current ups.alarm value, "
824+
"perhaps it is just a legacy driver (but we keep probing it to be safe)",
824825
__func__, ups->sys);
825826
}
826827
return;
@@ -842,9 +843,10 @@ static void ups_is_alarm(utype_t *ups)
842843
__func__, ups->sys, alarms);
843844
do_notify(ups, NOTIFY_ALARM, alarms);
844845
} else {
845-
upsdebugx(4, "%s: %s: failed to get current ups.alarm value",
846+
upsdebugx(4, "%s: %s: failed to get current ups.alarm value, perhaps "
847+
"it is just a legacy driver (but we keep probing it to be safe)",
846848
__func__, ups->sys);
847-
do_notify(ups, NOTIFY_ALARM, NULL);
849+
do_notify(ups, NOTIFY_ALARM, "n/a");
848850
alarms[0] = '\0';
849851
}
850852
strncpy(alarms_prev, alarms, sizeof(alarms_prev));

docs/developers.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ function avoid_vla(int len)
202202
}
203203
--------------------------------------------------------------------------------
204204

205-
This should be sued instead (preferably with `size_t` arguments right away),
205+
This should be used instead (preferably with `size_t` arguments right away),
206206
be sure to `free()` anywhere you `return` from the function:
207207
--------------------------------------------------------------------------------
208208
int use_xcalloc(size_t len)

docs/new-drivers.txt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@ formatting string to those expectations. In this case, you would use
218218
char *fmt = "Mega-Zapper %d";
219219
dstate_setinfo_dynamic("ups.model", fmt, "%d", rating);
220220

221+
Please note that `ups.alarm` should no longer be manually set, but rather
222+
the appropriate alarm functions should be used instead. For more details,
223+
see below in the `UPS alarms` section.
224+
221225
Setting flags
222226
~~~~~~~~~~~~~
223227

@@ -261,9 +265,10 @@ Possible values for status_set:
261265
BOOST -- UPS is boosting incoming voltage
262266
FSD -- Forced Shutdown (restricted use, see the note below)
263267

264-
Internally, an `ALARM` value would be added (typically as first in the list)
265-
if the `ups.alarm` is currently not empty. For more details, see below in
266-
`alarm_set()` description.
268+
`ALARM` should no longer be raised through the UPS status.
269+
An `ALARM` value will be added internally (typically as first in the list)
270+
if an alarm was set and committed through the appropriate alarm functions.
271+
For more details, see below in the `UPS alarms` section.
267272

268273
[NOTE]
269274
======

docs/nut.dict

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
personal_ws-1.1 en 3480 utf-8
1+
personal_ws-1.1 en 3493 utf-8
22
AAC
33
AAS
44
ABI
@@ -232,9 +232,11 @@ CygWin
232232
Cygwin
233233
DATACABLE
234234
DATAPATH
235+
DBCF
235236
DCE
236237
DCF
237238
DCO
239+
DDA
238240
DDD
239241
DDDDD
240242
DDDDDD
@@ -369,7 +371,9 @@ Exar
369371
ExecCGI
370372
ExecStart
371373
ExecStartPre
374+
FBCA
372375
FD
376+
FDE
373377
FEMEA
374378
FFF
375379
FH
@@ -1029,6 +1033,7 @@ QLDL
10291033
QMD
10301034
QMF
10311035
QMOD
1036+
QOL
10321037
QP
10331038
QPAR
10341039
QPD
@@ -1893,6 +1898,7 @@ desc
18931898
deschis
18941899
descr
18951900
desde
1901+
desertwitch
18961902
designator
18971903
dev
18981904
devclient

drivers/dstate.c

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
2008 Arjen de Korte <[email protected]>
66
2012-2017 Arnaud Quette <[email protected]>
77
2020-2025 Jim Klimov <[email protected]>
8+
2025 desertwitch <[email protected]>
89
910
This program is free software; you can redistribute it and/or modify
1011
it under the terms of the GNU General Public License as published by
@@ -50,7 +51,8 @@
5051
static OVERLAPPED connect_overlapped;
5152
static char *pipename = NULL;
5253
#endif /* WIN32 */
53-
static int stale = 1, alarm_active = 0, alarm_status = 0, ignorelb = 0;
54+
static int stale = 1, alarm_active = 0, alarm_status = 0, ignorelb = 0,
55+
alarm_legacy_status = 0;
5456
static char status_buf[ST_MAX_VALUE_LEN], alarm_buf[ST_MAX_VALUE_LEN],
5557
buzzmode_buf[ST_MAX_VALUE_LEN];
5658
static conn_t *connhead = NULL;
@@ -1766,12 +1768,12 @@ int dstate_is_stale(void)
17661768
/* clean out the temp space for a new pass */
17671769
void status_init(void)
17681770
{
1769-
if (dstate_getinfo("driver.flag.ignorelb")) {
1770-
ignorelb = 1;
1771-
}
1771+
/* This does not normally change in driver run-time, but can in tests */
1772+
ignorelb = (dstate_getinfo("driver.flag.ignorelb") ? 1 : 0);
17721773

17731774
memset(status_buf, 0, sizeof(status_buf));
17741775
alarm_status = 0;
1776+
alarm_legacy_status = 0;
17751777
}
17761778

17771779
/* check if a status element has been set, return 0 if not, 1 if yes
@@ -1795,17 +1797,23 @@ static int status_set_callback(char *tgt, size_t tgtsize, const char *token)
17951797
}
17961798

17971799
if (!strcasecmp(token, "ALARM")) {
1798-
/* Drivers really should not raise alarms this way,
1799-
* but for the sake of third-party forks, we handle
1800-
* the possibility...
1800+
/* Drivers should not do this anymore, but we continue
1801+
* to support it. The upsmon notifiers do not care where
1802+
* alarm tokens get set and legacy drivers may still use
1803+
* this older method. The only real limitations are that
1804+
* the alarm state is very tightly coupled to the UPS
1805+
* status, and the ups.alarm variables do not get published
1806+
* in a controlled manner. Rather, these are very dependent
1807+
* on the (legacy) driver, and alarm notifications via upsmon
1808+
* will show placeholder "n/a" if all values are missing.
1809+
* The status token is ignored to prepend it to other tokens
1810+
* later, within the status_commit() function.
1811+
* For more information, see this discussion:
1812+
* https://github.com/networkupstools/nut/pull/2931#issuecomment-2841705269
18011813
*/
1802-
upsdebugx(2, "%s: (almost) ignoring ALARM set as a status", __func__);
1803-
if (!alarm_status && !alarm_active && strlen(alarm_buf) == 0) {
1804-
alarm_init(); /* no-op currently, but better be proper about it */
1805-
alarm_set("[N/A]");
1806-
}
1807-
alarm_status++;
1808-
return 0;
1814+
upsdebugx(6, "%s: caller set ALARM as a status, this is deprecated - please fix the NUT driver code", __func__);
1815+
alarm_legacy_status = 1;
1816+
return 0; /* ignore it */
18091817
}
18101818

18111819
/* Proceed adding the token */
@@ -1848,36 +1856,15 @@ void status_commit(void)
18481856
break;
18491857
}
18501858

1851-
/* NOTE: Not sure if any clients rely on ALARM being first if raised,
1852-
* but note that if someone also uses status_set("ALARM") we can end
1853-
* up with a "[N/A]" alarm value injected (if no other alarm was set)
1854-
* and only add the token here so it remains first.
1855-
*
1856-
* NOTE: alarm_commit() must be executed before status_commit() for
1857-
* this report to work!
1858-
* * If a driver only called status_set("ALARM") and did not bother
1859-
* with alarm_commit(), the "ups.alarm" value queries would have
1860-
* returned NULL if not for the "sloppy driver" fix below, although
1861-
* the "ups.status" value would report an ALARM token.
1862-
* * If a driver properly used alarm_init() and alarm_set(), but then
1863-
* called status_commit() before alarm_commit(), the "ups.status"
1864-
* value would not know to report an ALARM token, as before.
1865-
* * If a driver used both status_set("ALARM") and alarm_set() later,
1866-
* the injected "[N/A]" value of the alarm (if that's its complete
1867-
* value) would be overwritten by the explicitly assigned contents,
1868-
* and an explicit alarm_commit() would be required for proper
1869-
* reporting from a non-sloppy driver.
1870-
*/
1871-
1872-
if (!alarm_active && alarm_status && !strcmp(alarm_buf, "[N/A]")) {
1873-
upsdebugx(2, "%s: Assume sloppy driver coding that ignored alarm methods and used status_set(\"ALARM\") instead: commit the injected N/A ups.alarm value", __func__);
1874-
alarm_commit();
1875-
}
1876-
1877-
if (alarm_active) {
1878-
dstate_setinfo("ups.status", "ALARM %s", status_buf);
1859+
if (alarm_active || alarm_legacy_status) {
1860+
if (*status_buf != '\0') {
1861+
dstate_setinfo("ups.status", "ALARM %s", status_buf);
1862+
} else {
1863+
dstate_setinfo("ups.status", "ALARM");
1864+
}
18791865
} else {
18801866
dstate_setinfo("ups.status", "%s", status_buf);
1867+
alarm_legacy_status = 0; /* just to be sure */
18811868
}
18821869
}
18831870

0 commit comments

Comments
 (0)