Skip to content

nut-scanner: continue scans after global semaphore initialisation fails - #3707

Open
user01010111 wants to merge 19 commits into
networkupstools:masterfrom
user01010111:fix/scanner-global-semaphore-fallback
Open

user01010111 wants to merge 19 commits into
networkupstools:masterfrom
user01010111:fix/scanner-global-semaphore-fallback

Conversation

@user01010111

Copy link
Copy Markdown
Contributor

When the global scan semaphore cannot be initialised, continue SNMP, IPMI, NUT, XML/HTTP and serial scans one target at a time. Reuse the existing synchronous workers and lifecycle-owned counter mutex, retaining SNMP failure reporting and argument ownership. Share semaphore setup and teardown between the library and CLI so failed initialisation never leaves an object in use.

This is a follow-up to Jim's fallback guidance, stacked on #3673 and its #3649 dependency. It addresses global semaphore initialisation failure, without claiming the broader #1166 refactoring complete.

Extend the existing offline scanner tests, document the fallback, and update libnutscan's interface version for the additional lifecycle helpers while retaining its existing shared-library major version.

Validation on Linux: GNU89 builds with warnings as errors; 20 project tests and 12 PyNUT tests; injected global initialisation/reinitialisation failures through all five scanner loops; exact-base CLI/library failure controls; ASan/UBSan/leak checks of all five scanner fixtures; NSS, counter and non-threaded configurations; documentation rendering and spelling; distribution checks. OpenSSL and NSS builds also return the same three devices from disposable loopback NUT responders under normal and injected-failure conditions, with one concurrent query during fallback.

Native macOS arm64 builds and NUT/serial fixtures pass the named-semaphore setup, failure, recovery and cleanup paths. Native Windows passes NUT/SNMP/XML/serial fixtures in ordinary and NDEBUG builds, 16 project tests, and staged DLL lifecycle/import-library checks. Native builds used recorded accommodations for pre-existing compiler diagnostics; the fallback mutex has paired initialisation and cleanup, with failed-initialisation and repeated-lifecycle coverage.

Prepared with assistance from OpenAI Codex.

user01010111 and others added 17 commits September 15, 2026 00:26
Skip inactive protocol semaphores, unwind partial admission, and return
owned permits when worker allocation or creation fails. Allocate tracking
entries before starting workers and keep NUT hostname and authentication
cleanup with the worker until it finishes.

Add offline regression tests using real threads and semaphores, preserve
the counter and non-threaded paths, and record the change in NEWS.

Related to networkupstools#1166. Global semaphore initialisation policy remains separate.

Prepared with assistance from OpenAI Codex (gpt-6-astra).

Signed-off-by: user01010111 <12504630+user01010111@users.noreply.github.com>
Pass the configured SSL include flags to the scanner tests for NSS
builds. Order scanner recursion after common and client dependencies,
and generate the SNMP header before compiling the test source.

Prepared with assistance from OpenAI Codex (gpt-6-astra).

Signed-off-by: user01010111 <12504630+user01010111@users.noreply.github.com>
Track the protocol semaphore only after successful initialisation, and
check destruction or close before clearing fixture state. Assert clean
state at scenario entry and clear the global semaphore after teardown.

Assisted by OpenAI Codex (gpt-6-astra).

Signed-off-by: user01010111 <12504630+user01010111@users.noreply.github.com>
Move the shared worker helpers into nutscan-thread.c and keep declarations in the header. Preserve internal symbol visibility and the existing failure-injection tests.

Assisted by OpenAI Codex (gpt-6-astra).

Signed-off-by: user01010111 <12504630+user01010111@users.noreply.github.com>
Retain SNMP hosts whose session open fails with EMFILE and retry them
serially after the original workers finish. Report persistent exhaustion
without requeueing, preserving admission accounting and target ownership.

Add focused recovery tests and a NEWS entry. This partially addresses
issue networkupstools#2576 and follows the admission helpers from PR networkupstools#3649.

Assisted by OpenAI Codex.

Signed-off-by: user01010111 <12504630+user01010111@users.noreply.github.com>
Keep test setup, scanner execution and checks active when built with -DNDEBUG.

Signed-off-by: user01010111 <12504630+user01010111@users.noreply.github.com>
Signed-off-by: user01010111 <12504630+user01010111@users.noreply.github.com>
…e other out-of-dir stuff [networkupstools#3673]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…ode [networkupstools#3673]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
… acquire [networkupstools#3673]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…arg() for simplicity [networkupstools#3673]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…safe side to cast it as (unsigned int) [networkupstools#3673]

...This may get revisited after we consistently use
one boolean type in the code base.

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
Clear local pointers after releasing scanner-owned storage.

Assisted by OpenAI Codex.

Signed-off-by: user01010111 <12504630+user01010111@users.noreply.github.com>
Reuse the shared admission and thread helpers for serial scans, release
permits when worker creation fails, and join workers before freeing their
borrowed port names or destroying the device mutex.

Extend the existing offline admission test for serial scans and record
the change in NEWS.

Assisted by OpenAI Codex.

Signed-off-by: user01010111 <12504630+user01010111@users.noreply.github.com>
Share semaphore setup and cleanup between the library and CLI. Fall back
to existing synchronous workers for SNMP, IPMI, NUT, XML/HTTP and serial,
using the lifecycle-owned counter mutex to admit one target at a time.

Extend existing failure and lifecycle checks, document the fallback, and
retain libnutscan's shared-library major version with the added API.

Prepared with assistance from OpenAI Codex.

Signed-off-by: user01010111 <12504630+user01010111@users.noreply.github.com>
@jimklimov jimklimov added enhancement nut-scanner Connection stability issues Issues about driver<->device and/or networked connections (upsd<->upsmon...) going AWOL over time AI For good or bad, machine tools are upon us. Humans are still the responsible ones. labels Sep 23, 2026
@jimklimov jimklimov added this to the 2.8.6 milestone Sep 23, 2026
Comment thread tests/nutscan-thread-test.c
@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 8bff2ba is temporarily available: NUT-tarballs-PR-3707.zip.

}
ret = sem_init(sem, shared, value);
assert(ret == 0);
global_sem = sem;
Comment thread tests/nutscan-thread-test.c Dismissed
void *arg;
};

static void *offline_worker(void *opaque)
Comment thread tests/nutscan-thread-test.c Dismissed
semaphore = &semaphore_inst;
}
# else
/* FIXME: Do we need O_EXCL here? */
@AppVeyorBot

Copy link
Copy Markdown

Carry the common scanner-test executable Net-SNMP flags, SSL dependency and
serial archive ordering. Preserve the library passthrough flags and cache
both forms through the existing dependency macro.

Keep the retry fixture mutex separate from libnutscan; the main fixture
owns the initialiser definitions. Order the common-library sub-makes to
prevent races over shared replacement-function objects.

Validated clean two-job builds and scanner fixtures on Linux and native
MinGW Windows, plus named-semaphore NUT/serial fixtures on macOS and
Linux distcheck-light with install/uninstall.

Prepared with OpenAI Codex (GPT-6) assistance, following the earlier
Claude Opus 5.5 review.

Signed-off-by: user01010111 <12504630+user01010111@users.noreply.github.com>
Restore the historical no-op setter on unnamed-semaphore platforms. Library
initialisation already selects its own semaphore directly; named-semaphore
selection remains unchanged. Document that distinction in the public header.

Extend the NUT fixture to check caller semaphore and NULL arguments before
and after initialisation, and preserve the caller semaphore during cleanup.

The setter regression fails against the submitted implementation and passes
on native Linux and Windows. Linux static/shared, counter-only and no-thread
checks pass, as do macOS named-semaphore NUT/serial checks and distcheck-light.

Prepared with OpenAI Codex (GPT-6) assistance, following the earlier
Claude Opus 5.5 review.

Signed-off-by: user01010111 <12504630+user01010111@users.noreply.github.com>
@user01010111

Copy link
Copy Markdown
Contributor Author

The Linux static/shared, counter-only and no-thread checks pass, along with the MinGW Windows static scanner tests and macOS named-semaphore NUT and serial tests. The new setter regression passes with the historical unnamed-semaphore behaviour restored: nutscan_semaphore_set() leaves the library-owned semaphore alone, including when passed NULL. Library initialisation still selects its semaphore directly, and named-semaphore selection is unchanged. The header now states that distinction.

This carries the common scanner test-link corrections from the earlier PRs, including the executable Net-SNMP dependency flags and serial-library ordering. The retry fixture's mutex is separate from libnutscan's; the main fixture retains the mutex supplied by its included initialiser. The common-library prerequisites now prevent parallel sub-makes from rebuilding the same replacement-function objects. Clean builds with two jobs and the distribution/install checks pass.

Prepared with Codex assistance, following the earlier Claude Opus 5.5 review.

@user01010111
user01010111 marked this pull request as ready for review October 14, 2026 02:46
@AppVeyorBot

Copy link
Copy Markdown

✅ Build nut 2.8.5.5674-master completed (commit 30fd566851 by @user01010111)

@AppVeyorBot

Copy link
Copy Markdown

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. Connection stability issues Issues about driver<->device and/or networked connections (upsd<->upsmon...) going AWOL over time enhancement nut-scanner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants