FreeBSD NUT Operations: Monitor UPS State and Test Shutdown Readiness
Operate Network UPS Tools on FreeBSD: identify drivers, validate monitoring, coordinate shutdown actions, and test power-loss behavior safely.
Network UPS Tools (NUT) connects an uninterruptible power supply to a monitoring and shutdown workflow. On FreeBSD it is installed from the Ports Collection, not the base system. NUT separates device drivers, a data server (upsd), and monitoring clients such as upsmon. A healthy daemon process is not proof that the UPS is communicating, that runtime state is current, or that the host will shut down before battery exhaustion.
The operational goal is to validate the entire chain: the correct physical UPS and transport, a supported NUT driver, a changing and plausible status feed, a policy that accounts for the load and battery runtime, and a shutdown action that works in a controlled test. NUT cannot make an undersized battery or incorrectly wired dual-power system safe by itself.
Identify the UPS and supported driver
Start with the device and package inventory before editing configuration:
usbconfig list
camcontrol devlist -v
pkg info | grep -i nut
Use the transport-specific inventory that matches the UPS. A USB device appearing in usbconfig proves bus enumeration, not protocol support. A serial or network UPS follows a different path. Check the NUT hardware support information and driver manual for the exact model, firmware, interface, and recommended connection method. Similar model names can use different protocols or USB identifiers.
The FreeBSD port installs NUT components and service scripts, but package options and defaults may evolve. Inspect the installed package file list and service scripts rather than assuming a path or enable variable from another release. The current Ports Collection Makefile identifies the rc scripts it installs; the generated files on the host are the final authority for local service behavior.
Before configuring the driver, confirm the UPS is not simultaneously claimed by another daemon or management process. A second process opening the same USB or serial interface can cause intermittent data loss or permission errors. Record the expected UPS name and driver for each physical unit, especially where multiple similar UPS devices are attached.
Configure the driver and data server deliberately
NUT’s ups.conf defines driver instances. A configuration section usually has a local UPS identifier and a driver-specific set of parameters; the exact driver and options must come from the NUT manual for the device. Do not copy a USB vendor/product identifier or serial port path from a different model.
Use the installed package’s sample files as a syntax starting point, then keep local configuration changes under version control with credentials removed. Protect files that contain usernames, passwords, or device control settings. Validate the configuration with the tools and diagnostics provided by the installed NUT version before starting the production service.
upsd exposes data and accepted commands to NUT clients. The NUT documentation describes TCP port 3493 as the default network protocol port. Keep a network listener bound only where remote monitoring is required and place clients on an approved management network. Do not expose the service to untrusted networks. Read the installed upsd.conf(5) and upsd.users(5) documentation for the supported address and authorization settings; do not assume local read access and remote command authorization are identical.
For a single-host setup, a local monitoring client can query the data server over the loopback path. For a multi-host design, decide which machine communicates directly with the UPS and which systems are clients. The primary device connection, management network, and shutdown dependencies must be documented; losing the data server must not be mistaken for a clean power state.
Verify data freshness and semantics
After the driver and data server are configured, query the UPS by its configured identifier:
upsc -l localhost
upsc ups@localhost
Replace ups with the actual identifier in the local NUT configuration. upsc reports values made available by the driver and server; it does not independently measure battery capacity. Check that status, charge, runtime, input voltage, and load fields exist for the device and change plausibly when the UPS state changes. Some devices do not expose every variable.
Record the exact variable names returned by the device. NUT variables and supported instant commands differ across drivers and hardware. Do not build a shutdown policy around an optional field until it has been verified on the production UPS model. Missing runtime data should be represented as unknown, not silently converted to an unlimited runtime.
Check freshness as well as value. A stale charge reading can look healthy even when the driver is disconnected. Review driver, upsd, and monitoring logs; compare the reported state with front-panel indicators and the physical power path. Test battery and line-state transitions with the UPS vendor’s recommended self-test procedure, not by pulling a live production plug as a first diagnostic.
Design the shutdown policy around the load
upsmon monitors UPS status and initiates local shutdown when its configured policy says the available power is no longer sufficient. In a multi-host environment, coordinate the monitor’s role and thresholds with the UPS wiring, critical load, and battery runtime. A server with multiple power supplies fed by different UPS units needs a policy that accounts for how many supplies are necessary for operation; merely monitoring every UPS does not compute this correctly.
Review the installed upsmon.conf(5) and NUT user manual for monitor declarations, supply counts, notification behavior, and shutdown command settings. Do not paste example credentials into a public repository. The exact SHUTDOWNCMD must be validated for the FreeBSD package and host’s shutdown process. Verify that the service manager does not restart a client after it has intentionally initiated shutdown.
Estimate runtime at the actual load and battery age. The UPS’s advertised runtime is not a guarantee for an aged battery, an overloaded outlet group, or a battery that has not completed charging. Set alerts before the point at which the host must begin a clean stop. Leave time for database checkpointing, filesystem flushes, VM shutdown, and the UPS’s own output cutoff behavior.
NUT monitoring is not a replacement for power-path design. If a switch, storage array, or hypervisor host loses power before its clients can shut down, a correct NUT configuration on the clients may still fail operationally. Order shutdown dependencies, network availability, and recovery sequencing as part of the facility runbook.
Test components without forcing a real shutdown
First validate each layer without triggering shutdown. Confirm the driver process is running and its logs show successful communication. Confirm upsd can read the driver state. Confirm upsc can retrieve current values. Confirm upsmon is attached to the intended UPS identifier and is receiving status updates. Use each installed service script’s status and local log configuration.
For end-to-end testing, use a dedicated test host, an approved UPS test facility, or a vendor-supported simulated state. Verify notifications, state transitions, and the exact shutdown path on a non-critical system. Never issue a force-shutdown command against a production UPS just to see whether a dashboard changes. Record the test plan, impact, and rollback before any test capable of stopping a host.
If the UPS has a physical self-test or controlled battery test, schedule it with facility staff and ensure redundant power paths are actually independent. A test can expose a weak battery or overloaded circuit. Monitor the host, UPS status, and critical downstream equipment throughout. Restore normal line power and verify the UPS returns to its expected charging and online state afterward.
Diagnose common failures by boundary
If no device appears, check the physical cable, transport, kernel enumeration, and whether another service owns the device. If the device appears but the driver cannot connect, verify model support, exact driver, permissions, and configuration syntax. If the driver runs but upsc cannot query it, investigate the data server socket, configured UPS name, access controls, and network path. If readings appear but upsmon does not act, inspect its monitor definition, thresholds, role, and logs without forcing a shutdown.
If only some fields are available, compare the driver-specific manual and the hardware support list. A missing field can be a device limitation rather than a transport fault. If the state changes unexpectedly, verify whether the UPS reports low battery, forced shutdown, communication loss, or a driver restart. Separate a real power event from an ordinary monitoring gap.
For networked UPS management, test DNS, routing, ACLs, and port reachability from the client. Do not widen the listener to all interfaces as a first response. Keep the data server’s credentials and command authorization aligned with operational needs, and verify that monitoring-only clients cannot issue control commands.
Acceptance checks and maintenance cadence
An acceptance record should identify the UPS, driver, NUT and FreeBSD versions, monitored variables, shutdown policy, client roles, and expected notification path. Verify fresh status data, run a safe self-test or lab transition, confirm alerts reach operators, and rehearse the documented shutdown and restoration procedure on a non-critical system.
Repeat checks after a NUT package upgrade, UPS firmware change, USB/serial cabling change, battery replacement, or host power-supply reconfiguration. Battery health should be reviewed on the manufacturer’s recommended schedule and after unexpected runtime loss. Do not treat “service is running” as the acceptance criterion.
NUT provides the software link between a UPS and system action. Reliability comes from confirming device support, measuring live status, planning load-aware thresholds, testing shutdown without risking production, and keeping independent power and recovery procedures current.
Related:
- FreeBSD daemon(8) Operations: Supervise Foreground Programs Predictably
- Operating FreeBSD Watchdogs Safely: Detection, Recovery, and Failure Modes
Sources: