Include more inline comments to document the nut-server initscript and
usb hotplug.
Also trim an extraneous space in a comment.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
A previous PR missed updating the hotplug scripts for the
new find_runas and find_statepath functions which emit
the value on stdout instead of setting a variable in the
caller's scope. Update that usage and handle error conditions.
Also ensure we fully handle finding the group of the RUNAS user for
the serial usb hotplug case, and handle error conditions for that.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
The match against known device was badly formatted, and was
not being used as a result. Fix that.
Also, completely ignore events which are incomplete for our purposes
(that is, which are missing ACTION or DEVNAME).
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
On boot, hotplug events were causing excessive start and stop action
for the upsd daemon and driver daemons. We fix that with two primary
actions:
1. Don't restart service daemons on hotplug until after first boot
has completed.
2. Use more robust handling of procd instance starts by ensuring
that the first start starts the nut-server service and all
others add to the nut-server service (rather than replacing it).
Ignore hotplug events without a DEVNAME.
In addition clean up some logging.
In the process, this fixes#30375 "hotplugging for setting usb access
right[s] doesn't work anymore"
Closes: #30375
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
Short-circuit not applicable portions of hotplug script on remove, and
make sure we ignore events with incomplete information (no DEVNAME
or no ACTION).
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
The uci-defaults scripts are already sourced and removed
by default_postinst so nut-server and nut-upsmon postinsts in this
Makefile are not needed.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
Create a group to allow sharing directories files between upsd and
upsmon, and create a shared NSS certificate/key database on postinst
of nut-common (providing the database dir does not already exist).
Also enables preserving the shared database across sysupgrades.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
Enable CERTVERIFY, CERTREQUEST, and related options for requiring
verified certificates from peers.
While we are at it, alphabetize the list of PKG_CONFIG_DEPENDS in the
Makefile
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
To satisfy the CI (because of project style) use spaces instead of tab
in the Makefile, except for Make 'recipes' (which require tabs).
To be consistent do this through the file, no only where CI complained.
There is unusual spacing on the nested define recipes as Make's rules for
those is very particular.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
NUT (upstream) logging has changed. With the introduction of
NUT_DEBUG_SYSLOG we can set it to "stderr" and have NUT's messages
go to stderr only.
This avoid most duplicate messages when procd sends stderr to syslog.
The reverse (syslog only from NUT) is not a current configuration
option. See the section for NUT_DEBUG_SYSLOG at
https://networkupstools.org/docs/man/nut.conf.html#_directives
This is needed because we use '-FF' so that the daemons remain in the
foreground, which is required for procd to manage them. When using
'-FF' logging behaves differently in NUT than when backgrounded.
Unfortunately, there is still some work to be done upstream to
completely eliminate duplicate messages, so some message continue to
appear twice, though not neccessarily with the same facility.priority.
See also
https://github.com/jimklimov/nut/blob/0c3eed09b89cce1e5c0c65ca03d05b4612371cb8/UPGRADING.adoc#changes-from-282-to-283
and
https://github.com/openwrt/packages/pull/29896#issuecomment-5012737643
Conversely, the log messages the initscripts emit are now configured to
emit only to syslog and not to stderr. This avoids duplicates messages
caused by procd's automatic (not configurable) behaviour of sending
the initscript's stderr to syslog, while preserving the syslogid,
facility and priority we want.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
Using add_interface_triggers and check_interface_up is a
better separation of concerns and the code has little in
common (no duplication of code concerns).
While we are at it make both nut-monitor and nut-server failure of
add_interface_triggers non-fatal with a logged error message.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
Factor out some common validation code into some validator functions,
and add more UCI config validation.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
We claimed we only supported a single upsd section named 'upsd' and a
single uspmon section named 'upsmon', but when determining RUNAS
and STATEPATH we were using overly-complex functions as we were
attempting to support multiple upsd and upsmon sections.
Simplify the logic by adhering to our stated support.
While were are at it we make RUNAS handling more consistent between
nut-server (upsd) and nut-monitor (upsmon).
We no longer try to limp along if RUNAS is not set by find_runas; to do
this properly would require over-complicated logic when setting file
and directory permissions and ownership.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
* Fixes a missing word in a comment
* Fixes inconsistent indentation in sample configurations
* Drops redundant default assignment in find_statepath()
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
The scripts were a mess. Attempting even a simple update caused many
Copilot complaints. So we rewrite the scripts to be cleaner and
resolve the issues found by automated code review (such as Copilot).
Made extensive use of Qwen3.6-27B, LATE, and llama.ccp for local AI
code reviews during development.
In the process we deduplicate the nut-server and nut-monitor
initscripts and split them into several files, for easier automatic
and human review.
Incorporates and supersedes: #28308
Should supersede #21014Closes: #28298
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
Apparently the CI wants to 'see' the version not just get a return code,
so emit the version when we have one.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
Extra quotes were being interpreted literally, preventing proper
ups driver stop and/or reload.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
Add previously missed migration script (uci-defaults) for changes
to nut-monitor initscript.
Created with the help of iterative code reviews by
Qwen3.6-27B (LLM model) running on llama.cpp (local LLM server),
controlled by LATE.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
Prompted by
https://github.com/openwrt/luci/pull/8420#issuecomment-4071252681
we update upsmon configs to ensure they are correct according to
upstream. We reorder the options so that they match upstream
documentation at
<https://networkupstools.org/docs/man/upsmon.conf.html> to be sure
we have not missed any items.
While at it, we add configuration options from the upstream
documentation that are not currently present in the UCI configs.
Some years ago upstream changed the names the primary/secondary
UPS system/monitor from master/slave to primary/secondary. It
is uncertain how much longer these deprecated names will be
accepted by NUT.
Therefore update naming to match upstream documentation and
configuration. See
<https://networkupstools.org/docs/man/upsmon.html>,
<https://networkupstools.org/docs/man/upsmon.conf.html>, and
<https://networkupstools.org/docs/man/upsd.users.html>.
At the same time, prompted by
https://github.com/openwrt/packages/pull/28875#issuecomment-4079307540
we simplify the configuration and add checks to avoid bad configs
due to misspellings/typos of configuation options by users.
A sample config
config upsmon 'upsmon'
option notifycmd '/usr/bin/logger -t nut-monitor-exec '
config monitor
option type primary
option upsname upsname
option hostname localhost
option username upsuser
option password upspassword
config notifications 'ONLINE'
option message "UPS %s is on line power"
option flag "SYSLOG"
config notifications 'ONBATT'
option message "UPS %s is on battery power"
option flag "SYSLOG+EXEC"
In order to iterate through the notifications, we use named
'notifications' sections and compare the section name to list of
notification events defined by NUT. If they don't match, warn
during initscript startup.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
When a USB UPS is first configured, the permissions on the device under
`/dev/bus/usb` have not yet been set to allow the nut user access. This
resulted in errors such as:
Fri Feb 13 23:39:01 2026 daemon.debug upsd[3504]: [D1] mainloop: UPS
[eco550ups] is not currently connected, trying to reconnect
Fri Feb 13 23:39:01 2026 daemon.debug upsd[3504]: [D1] mainloop: UPS
[eco550ups] is still not connected (FD -1)
Fri Feb 13 23:39:03 2026 daemon.debug upsd[3504]: [D1] mainloop: UPS
[eco550ups] is not currently connected, trying to reconnect
Fri Feb 13 23:39:03 2026 daemon.debug upsd[3504]: [D1] mainloop: UPS
[eco550ups] is still not connected (FD -1)
or
Fri Feb 13 23:38:44 2026 daemon.err usbhid-ups[3083]: No matching HID
UPS found
Fri Feb 13 23:38:49 2026 daemon.warn procd: failed adding instance
cgroup for nut-server: No error information
Fri Feb 13 23:38:49 2026 daemon.err usbhid-ups[3115]: libusb1: Could not
open any HID devices: insufficient permissions on everything
Fri Feb 13 23:38:49 2026 daemon.err usbhid-ups[3115]: No matching HID
UPS found
Fri Feb 13 23:38:54 2026 daemon.warn procd: failed adding instance
cgroup for nut-server: No error information
and upsd would enter a procd crashloop.
We fix that by looking in `sysfs` (under `/sys/devices`) to find the
correct USB device and set its ownership and permissions to allow acces
to the user the driver is running under.
Copilot complained about a few things
* nut-server.init had potential word-splitting issues in various spots.
* it also had some commands missing an argument
* improved documentation was required to clarify a dependency
* an incorrect sed could mangle names as well as remove the intended
name
Additionally, while fixing those issues the author noticed that the case
of multiple UPS devices with the same vendorid:productid were not
correctly handled. A check of the serial number, if provided, was added
along with a fallback to allowing NUT communications with all UPS
devices with a given vendorid:productid, if no serial number was given.
Improve efficiency and decrease McCabe complexity of
ensure_usb_ups_access, while also fixing Copilot complaints.
$@ in case is a problem, and we only handle the first parameter in any
event, so change $@ to "$1"
Copilot caught a missing 2>&1 and we silence some shellcheck
false positives
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
Attempt to de-mystify the nut-server initscript by adding comments
and factoring out some common code that adds to complexity of the
functions of which it is part.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
Ensure that when a ups is removed from the configuration that its
driver instance is stopped.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
Updated configuration was not being applied after config change. This
was due to the means used to do the daemon reloads.
Closes#28298 "Drivers not restarted on config change"
Enable creating PID files for the server, driver, and monitor daemon
processes. This allows to use NUT's built-in facilities for signalling
the daemon's.
For server, when reloading:
1. Check if upsd is running
1. If not, start it.
2. If it is send reload signal to upsd
2. For each driver:
1. Check if the driver is running
1. If it is, send reload-or-exit signal to driver
2. If driver is not running, start it
3. Attempt to start server (upsd and drivers) if service was stopped.
For server, when stopping:
1. Check if upsd is running
1. If it is send stop signal to upsd
2. Ensure it really is stopped
2. For each driver:
1. Check if the driver is running
1. If it is, send stop signal to driver
2. If driver is still running, stop it.
3. If the server process is active (even with not upsd or drivers),
stop it.
For monitor, send the reload signal on config change, with fallback to
stopping and starting the daemon.
Change the names of variables and functions to make it more clear what
is being acted on, configured, or otherwise touched.
Avoid confusing messages in syslog
* Avoid attempting to remove a procd server instance that does not exist
as doing so results in confusing/scary messages in syslog, such as:
Command failed: ubus call service delete
{ "name": "nut-server", "instance": "upsd" } (Not found)
In NUT some models of UPS use shutdown_delay rather than offdelay, and
yet others use usd for the same purpose. shutdown_delay and usd were
previously not available in the list of available driver options, so
add them.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
shellcheck is a useful linter if a bit pedantic and overzealous so
add overrides to silence false positives
Also, fix issues found by the linting.
* misspelling meant initscript could skip updating configuration in
certain circumstances
* minor: assignment of the result of execution as the time of creating
local. This has been separated.
Fix whitespace and comment typos
Fix typo in Config.in option text
* This is cosmetic, but user-facing (for users building via SDK or
buildroot).
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
nut was recently upgraded to 2.8.1 which includes a change in
configure.ac that uses /run for the pidfile if it exists during build.
Explicitly specify --with-pidpath to use the path that was used with
2.8.0 and prior.
The symptom here was that there'd be leftover processes when nut-monitor
was restarted.
Fixes: 82f36e0c78 ("nut: update to 2.8.1")
Fixes: https://github.com/openwrt/packages/issues/24106
Signed-off-by: Matt Merhar <mattmerhar@protonmail.com>
Automatically compute and substitute current values for all
$(AUTORELEASE) instances as this feature is deprecated and shouldn't be
used.
The following temporary change was made to the core:
diff --git a/rules.mk b/rules.mk
index 57d7995d4fa8..f16367de87a8 100644
--- a/rules.mk
+++ b/rules.mk
@@ -429,7 +429,7 @@ endef
abi_version_str = $(subst -,,$(subst _,,$(subst .,,$(1))))
COMMITCOUNT = $(if $(DUMP),0,$(call commitcount))
-AUTORELEASE = $(if $(DUMP),0,$(call commitcount,1))
+AUTORELEASE = $(if $(DUMP),0,$(shell sed -i "s/\$$(AUTORELEASE)/$(call commitcount,1)/" $(CURDIR)/Makefile))
all:
FORCE: ;
And this command used to fix affected packages:
for i in $(cd feeds/packages; git grep -l PKG_RELEASE:=.*AUTORELEASE | \
sed 's^.*/\([^/]*\)/Makefile^\1^';);
do
make package/$i/download
done
Signed-off-by: Paul Fertser <fercerpav@gmail.com>
Use an upstream commit to ensure time_t is defined in upsclient.h,
fixing a compile failure in collectd.
Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
Add --without-linux-i2c to configure arguments to avoid using i2c if
found in the staging dir.
Switch to AUTORELEASE.
Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>