Summary
Neither ignorelb nor override.* values can be applied via SIGHUP config reload (systemctl reload nut-driver@<name>). Both require a full driver restart to take effect. These two settings are always used together (e.g., ignorelb + override.battery.runtime.low) to implement software-defined low-battery thresholds, so the inability to reload either one makes SIGHUP reload unusable for this use case.
NUT version
2.8.4 (also verified on master @ d25dde3, 2026-03-25)
Driver
apc_modbus via serial Modbus (but the code is in drivers/main.c, so affects all drivers)
Steps to reproduce
Test 1: ignorelb not activated via reload
# Start driver WITHOUT ignorelb in [ups] section
systemctl start nut-driver@ups
upsc ups driver.flag.ignorelb
# → "Error: Variable not supported by UPS"
# Add "ignorelb" + "override.battery.runtime.low = 120" to [ups] in ups.conf
systemctl reload nut-driver@ups
upsc ups driver.flag.ignorelb
# → "Error: Variable not supported by UPS" ← NOT applied
upsc ups battery.runtime.low
# → "120" ← value applied, but not functional without ignorelb
Test 2: override.battery.runtime.low not updated via reload
# Start driver WITH ignorelb + override.battery.runtime.low = 120
systemctl restart nut-driver@ups
upsc ups driver.flag.ignorelb # → "enabled"
upsc ups battery.runtime.low # → "120"
# Change override value to 6060 in ups.conf (keep ignorelb)
systemctl reload nut-driver@ups
upsc ups battery.runtime.low # → "120" ← NOT updated (expected 6060)
upsc ups driver.parameter.override.battery.runtime.low # → "120" (stale)
Expected behavior
Both ignorelb and override.* values should be applied during SIGHUP reload.
Actual behavior
ignorelb: silently skipped during reload (debug-level-6 message only)
override.*: dstate_setinfo() is called during reload but ST_FLAG_IMMUTABLE on the variable prevents the update; value from initial startup persists
Root cause in source
1. ignorelb — drivers/main.c ~line 1244 (master @ d25dde3):
/* FIXME: this one we could potentially reload, but need to figure
* out that the flag line was commented away or deleted -- there is
* no setting value to flip in configs here
*/
if (!strcmp(var, "ignorelb")) {
if (reload_flag) {
upsdebugx(6, "%s: SKIP: flag var='%s' currently can not be reloaded", __func__, var);
} else {
dstate_setinfo("driver.flag.ignorelb", "enabled");
}
return 1; /* handled */
}
2. override.* — drivers/main.c ~line 412 (master @ d25dde3):
if (!strncasecmp(var, "override.", 9)) {
dstate_setinfo(var+9, "%s", val);
dstate_setflags(var+9, ST_FLAG_IMMUTABLE);
/* note these are not immutable since we can reload
* although the effect of this is questionable (FIXME)
*/
dparam_setinfo(var, val);
return;
}
Both have existing FIXME comments acknowledging the limitations.
Use case / impact
ignorelb + override.battery.runtime.low is the standard way to implement software-defined low-battery thresholds on UPS hardware that only provides a hardware LB signal (e.g., APC Smart-UPS via Modbus).
During a power outage, operators may need to dynamically adjust the LB threshold as battery drains. Currently this requires a driver restart, which:
- Drops the UPS communication link for 2-4 seconds
- Triggers
COMMBAD broadcast messages to all logged-in users
- Risks unexpected FSD if
ALARMCRITICAL is not set to 0
Making both reloadable via SIGHUP would eliminate the communication gap risk entirely.
Workaround
Always use systemctl restart nut-driver@<name> instead of reload. Set ALARMCRITICAL 0 in upsmon.conf to prevent the brief comms gap from triggering FSD.
Possible solution
For ignorelb: Track whether the flag was seen during the reload parse. After reload: if not seen → clear driver.flag.ignorelb; if seen → set it.
For override.*: Temporarily clear ST_FLAG_IMMUTABLE before re-setting the override value during reload, or handle immutable values specially in dstate_setinfo() when called from a reload context.
Summary
Neither
ignorelbnoroverride.*values can be applied via SIGHUP config reload (systemctl reload nut-driver@<name>). Both require a full driver restart to take effect. These two settings are always used together (e.g.,ignorelb+override.battery.runtime.low) to implement software-defined low-battery thresholds, so the inability to reload either one makes SIGHUP reload unusable for this use case.NUT version
2.8.4 (also verified on master @ d25dde3, 2026-03-25)
Driver
apc_modbusvia serial Modbus (but the code is indrivers/main.c, so affects all drivers)Steps to reproduce
Test 1:
ignorelbnot activated via reloadTest 2:
override.battery.runtime.lownot updated via reloadExpected behavior
Both
ignorelbandoverride.*values should be applied during SIGHUP reload.Actual behavior
ignorelb: silently skipped during reload (debug-level-6 message only)override.*:dstate_setinfo()is called during reload butST_FLAG_IMMUTABLEon the variable prevents the update; value from initial startup persistsRoot cause in source
1.
ignorelb—drivers/main.c~line 1244 (master @ d25dde3):2.
override.*—drivers/main.c~line 412 (master @ d25dde3):Both have existing
FIXMEcomments acknowledging the limitations.Use case / impact
ignorelb+override.battery.runtime.lowis the standard way to implement software-defined low-battery thresholds on UPS hardware that only provides a hardware LB signal (e.g., APC Smart-UPS via Modbus).During a power outage, operators may need to dynamically adjust the LB threshold as battery drains. Currently this requires a driver restart, which:
COMMBADbroadcast messages to all logged-in usersALARMCRITICALis not set to 0Making both reloadable via SIGHUP would eliminate the communication gap risk entirely.
Workaround
Always use
systemctl restart nut-driver@<name>instead of reload. SetALARMCRITICAL 0in upsmon.conf to prevent the brief comms gap from triggering FSD.Possible solution
For
ignorelb: Track whether the flag was seen during the reload parse. After reload: if not seen → cleardriver.flag.ignorelb; if seen → set it.For
override.*: Temporarily clearST_FLAG_IMMUTABLEbefore re-setting the override value during reload, or handle immutable values specially indstate_setinfo()when called from a reload context.