Skip to content

ignorelb + override.* not reloadable via SIGHUP -- requires driver restart #3377

@cardil

Description

@cardil

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. ignorelbdrivers/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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementimpacts-release-2.8.4Issues reported against NUT release 2.8.4 (maybe vanilla or with minor packaging tweaks)service/daemon start/stopGeneral subject for starting and stopping NUT daemons (drivers, server, monitor); also BG/FG/Debug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions