Skip to content

upsd: reclaim connections to complete configuration reloads - #3706

Open
user01010111 wants to merge 5 commits into
networkupstools:masterfrom
user01010111:fix/upsd-config-open-retry
Open

user01010111 wants to merge 5 commits into
networkupstools:masterfrom
user01010111:fix/upsd-config-open-retry

Conversation

@user01010111

@user01010111 user01010111 commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Configuration reloads can run out of file descriptors after connecting a newly added driver, even when the initial configuration-file check succeeded. Retry only after reclaiming a connection, so a reload cannot loop indefinitely when no client remains.

On POSIX systems, reclaim the least recently active client first, then a connected driver once clients are exhausted. Retry the file open after each closure and stop when no connection remains. Driver connections use the existing disconnect/reconnect path, which clears cached data and requests a fresh dump. Windows retains its client-only recovery and retry limits because named-pipe handles do not release CRT file descriptors. Also finish the parser context and preserve errno when a nonfatal ups.conf open fails, as that reader can now be retried repeatedly.

Native Linux before/after testing confirms that a reload which skipped the changed configuration at the previous PR head now applies it and reconnects the drivers. Controls cover client ordering and login cleanup, retained FSD/device state, subsequent reloads, and startup/unreadable-file failure behaviour. The focused tests also cover more than ten ineffective client closures, driver ordering, already-disconnected drivers, exhausted connections, and parser cleanup/errno preservation.

Validation: focused tests (282 checks), full make check, GNU89 builds with warnings as errors, source/style/spelling/documentation checks, and make distcheck-light. Native Windows GCC builds and all 273 focused checks also pass, including the unchanged precheck retry limit and shared parser cleanup.

Related to #3365. AI assistance: OpenAI Codex (gpt-6-astra). The contributor reviews and takes responsibility for the submitted change.

Report whether close_oldest_client() disconnected a client and retry
configuration opens only after progress. This prevents an endless reload
loop when EMFILE persists and no client connections remain, while keeping
the existing retry limits and final failure handling.

Cover recovery and no-progress paths in test_upsdconf and update NEWS.
Related to networkupstools#3365.

AI assistance: OpenAI Codex (gpt-6-astra) was used for source review,
implementation, tests and drafting. The contributor reviewed the change
and remains responsible for it.

Signed-off-by: user01010111 <lapses.50.booster@icloud.com>
@jimklimov jimklimov added enhancement service/daemon start/stop General subject for starting and stopping NUT daemons (drivers, server, monitor); also BG/FG/Debug AI For good or bad, machine tools are upon us. Humans are still the responsible ones. labels Sep 23, 2026
@jimklimov

Copy link
Copy Markdown
Member

In context of that discussion, I wonder if it makes sense to also try closing driver connections (at least when reloading) if there was no effect from closing the clients...

Retry configuration opens after reclaiming clients, then connected drivers,
with retries bounded by the remaining connections. Reuse the existing
state cleanup and reconnect path, preserving Windows retry behaviour.

Finish the parser context and preserve errno after a nonfatal ups.conf
open failure. Cover repeated recovery and cleanup in the existing tests,
and document the temporary driver disconnection during reload.

AI assistance: OpenAI Codex (gpt-6-astra) was used for source review,
implementation, tests and drafting. The contributor reviewed the change
and remains responsible for it.

Signed-off-by: user01010111 <lapses.50.booster@icloud.com>
@user01010111 user01010111 changed the title upsd: stop configuration-open retries when no client can be closed upsd: reclaim connections to complete configuration reloads Sep 24, 2026
@user01010111

Copy link
Copy Markdown
Contributor Author

The native Linux regression now applies the changed configuration and reconnects the drivers under the descriptor pressure that made the previous PR head skip that file. Client ordering/login cleanup, retained FSD/device state and the existing failure controls also pass.

The follow-up closes clients first, then connected drivers, retrying the open after each closure. It reuses sstate_disconnect() and the normal reconnect/DUMPALL path. The driver fallback is POSIX-only because Windows named-pipe handles do not release CRT file descriptors; Windows keeps its existing retry limits. Repeated ups.conf attempts also needed parser cleanup that preserves errno.

Linux build, test, GNU89, memory and distribution checks pass. The native Windows build and all 273 focused checks pass too.

Signed-off-by: user01010111 <lapses.50.booster@icloud.com>
@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

A ZIP file with standard source tarball and another tarball with pre-built docs for commit 297c7d1 is temporarily available: NUT-tarballs-PR-3706.zip.

Comment thread tests/test_upsdconf.c
newer.last_heard = 20;
disconnected.next = &newer;
newer.next = &oldest;
firstups = &disconnected;
Comment thread tests/test_upsdconf.c Dismissed
Comment thread tests/test_upsdconf.c
Comment on lines +338 to +343
if (result != recover || close_calls != expected_close_calls
|| parser_contexts != 0 || oldest.numlogins != 3 || !oldest.fsd || !oldest.retain
|| (!effective_client && (VALID_FD(oldest.sock_fd) || oldest.inforoot || oldest.cmdlist))
|| (effective_client && (INVALID_FD(oldest.sock_fd) || !oldest.inforoot || !oldest.cmdlist))
|| (recover && INVALID_FD(newer.sock_fd))
|| (!recover && VALID_FD(newer.sock_fd))
user01010111 and others added 2 commits October 14, 2026 14:39
Merge master at 73c4502, retaining both the LISTEN and reload-recovery
fixtures in tests/test_upsdconf.c.

Local validation passed: 362 focused checks, fresh upsd build, GNU89
build, stylecheck and distcheck-light.

AI assistance: OpenAI Codex.
Earlier PR review: Claude Code (claude-opus-5-5).

Signed-off-by: user01010111 <lapses.50.booster@icloud.com>
@github-actions github-actions Bot deleted a comment from AppVeyorBot Oct 23, 2026
@github-actions github-actions Bot deleted a comment from AppVeyorBot Oct 23, 2026
@github-actions github-actions Bot deleted a comment from AppVeyorBot Oct 23, 2026
@github-actions github-actions Bot deleted a comment from AppVeyorBot Oct 23, 2026
@github-actions github-actions Bot deleted a comment from AppVeyorBot Oct 23, 2026
@AppVeyorBot

Copy link
Copy Markdown

✅ Build nut 2.8.5.5895-master completed (commit b439516d0c by @jimklimov)

@AppVeyorBot

Copy link
Copy Markdown

@jimklimov jimklimov added this to the 2.8.6 milestone Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI For good or bad, machine tools are upon us. Humans are still the responsible ones. enhancement service/daemon start/stop General subject for starting and stopping NUT daemons (drivers, server, monitor); also BG/FG/Debug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants