Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2d7f275
nut-scanner: balance worker admission and cleanup
user01010111 Sep 15, 2026
e92e3fd
tests: fix scanner build dependencies
user01010111 Sep 15, 2026
d2691e0
tests: check scanner semaphore fixture lifetime
user01010111 Sep 15, 2026
dfb5384
nut-scanner: compile worker helpers once
user01010111 Sep 18, 2026
ebd506b
nut-scanner: retry SNMP session opens after descriptor exhaustion
user01010111 Sep 20, 2026
76a607b
tests: keep scanner assertions enabled with NDEBUG
user01010111 Sep 20, 2026
d008380
tests: initialise Winsock for SNMP retry checks
user01010111 Sep 20, 2026
c84b01a
tests/Makefile.am: group nut-scanner related dependencies on top, lik…
jimklimov Sep 21, 2026
c78dfd0
tools/nut-scanner/nutscan-thread.c: style fixes [#3673]
jimklimov Sep 21, 2026
5baa9c3
tools/nut-scanner/nutscan-thread.{c,h}: update (C) for transplanted c…
jimklimov Sep 21, 2026
a01ccb4
tools/nut-scanner/scan_*.c: restore debug-log after successful thread…
jimklimov Sep 21, 2026
20e2173
tools/nut-scanner/scan_nut.c: move nut_arg==NULL check into free_nut_…
jimklimov Sep 21, 2026
827e2cb
tools/nut-scanner/scan_*.c: when logging "pass" (bool_t), err on the …
jimklimov Sep 21, 2026
f9269a1
nut-scanner: clear freed scanner locals
user01010111 Sep 21, 2026
6272293
nut-scanner: balance serial worker admission and cleanup
user01010111 Sep 21, 2026
d31b3ac
Merge branch 'master' into fix/snmp-emfile-recovery
jimklimov Sep 23, 2026
958e807
tests: fix serial scanner test library link order
user01010111 Sep 28, 2026
0857234
tests: fix static scanner and retry linkage
user01010111 Oct 14, 2026
9d9686f
Merge branch 'master' into fix/snmp-emfile-recovery
jimklimov Oct 14, 2026
d961bb1
Merge branch 'master' into fix/snmp-emfile-recovery
jimklimov Oct 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -571,9 +571,9 @@ all/tests/NIT: all/clients all/server all-drivers all-recursive/tools all-recurs
### LIB-Requires-ext: #COMMENTED-AWAY# common/libcommon.la
### Requires-ext: common/libcommon.la common/libnutconf.la
### Requires-ext: clients/libnutclient.la clients/libnutclientstub.la
### Requires-ext: drivers/libdummy_mockdrv.la
### Requires-ext: drivers/libdummy_mockdrv.la tools/nut-scanner/libnutscan.la
### Requires-int: libdriverstubusb.la
all/tests: all-libs-local/tests all-libs-local/drivers all-libs-local/common all-libs-local/clients @dotMAKE@
all/tests: all-libs-local/tests all-libs-local/drivers all-libs-local/common all-libs-local/clients all-libs-local/tools/nut-scanner @dotMAKE@
+@NUT_VERSION_H_GENERATED=true; export NUT_VERSION_H_GENERATED; \
$(SUBDIR_TGT_RULE)

Expand Down
12 changes: 12 additions & 0 deletions NEWS.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@ https://github.com/networkupstools/nut/milestone/13
extracting the response. Returned keys and descriptions remain byte
sequences. [issue #3621]
* `nut-scanner` tool updates:
- Retry SNMP hosts whose session could not open because the process
ran out of file descriptors. After the original SNMP scans finish,
retry those hosts one at a time and report any remaining descriptor
exhaustion. Other scan types and their limits are unchanged.
[issue #2576]
- Keep serial scan permits balanced when admission or thread creation
fails, and retain port names until all started workers finish if
allocating thread tracking fails.
- Balance concurrency permits and worker ownership during SNMP, IPMI,
NUT and XML/HTTP scans, including disabled protocol limits and failed
thread creation. Keep NUT authentication data alive until the scan
worker has finished. [issue #1166]
- Mutexes used in parallelized scans were not properly released on
failure code paths (impacts likely all 2.8.x until now). [PR #3551]
- Third-party libraries which `nut-scanner` loads dynamically (libusb,
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -6444,6 +6444,7 @@ AC_SUBST(LIBGIO_CFLAGS)
AC_SUBST(LIBGIO_LIBS)
AC_SUBST(LIBNETSNMP_CFLAGS)
AC_SUBST(LIBNETSNMP_LIBS)
AC_SUBST(LIBNETSNMP_LIBS_EXEC)
AC_SUBST(LIBREGEX_LIBS)
AC_SUBST(LIBUSB_CFLAGS)
AC_SUBST(LIBUSB_LIBS)
Expand Down
14 changes: 13 additions & 1 deletion m4/nut_check_libnetsnmp.m4
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dnl Check for LIBNETSNMP compiler flags. On success, set
dnl nut_have_libnetsnmp="yes" and set LIBNETSNMP_CFLAGS and
dnl LIBNETSNMP_LIBS. On failure, set nut_have_libnetsnmp="no".
dnl LIBNETSNMP_LIBS and LIBNETSNMP_LIBS_EXEC. On failure, set nut_have_libnetsnmp="no".
dnl This macro can be run multiple times, but will do the
dnl checking only once.

Expand All @@ -18,6 +18,9 @@ AC_DEFUN([NUT_CHECK_LIBNETSNMP],
NUT_ARG_WITH_LIBOPTS_LIBS([snmp], [auto], [Net-SNMP])

nut_noncv_checked_libnetsnmp_now=no
dnl Refresh older caches which did not retain executable linker flags.
AS_IF([test "${nut_cv_LIBNETSNMP_LIBS_EXEC+set}" != set],
[AS_UNSET([nut_cv_checked_libnetsnmp])])
AC_CACHE_VAL([nut_cv_checked_libnetsnmp], [
nut_noncv_checked_libnetsnmp_now=yes

Expand Down Expand Up @@ -129,6 +132,8 @@ AC_DEFUN([NUT_CHECK_LIBNETSNMP],
)
AC_MSG_RESULT([${depLIBS} (source: ${depLIBS_SOURCE})])

depLIBS_EXEC="${depLIBS}"

dnl Check if the Net-SNMP library is usable
CFLAGS="${CFLAGS_ORIG} ${depCFLAGS}"
LIBS="${LIBS_ORIG} ${depLIBS}"
Expand All @@ -150,6 +155,8 @@ AC_DEFUN([NUT_CHECK_LIBNETSNMP],
[*mingw*], [
AC_MSG_NOTICE([mingw builds of net-snmp might provide only a static library - retrying for that])
depLIBS="`$PKG_CONFIG --silence-errors --libs --static netsnmp 2>/dev/null`"
dnl Executables need ordinary flags after their static libraries.
depLIBS_EXEC="${depLIBS}"
dnl # Some workarouds here, to avoid libtool bailing out like this:
dnl # *** Warning: This system cannot link to static lib archive /usr/x86_64-w64-mingw32/lib//libnetsnmp.la.
dnl # *** I have the capability to make that library automatically link in when
Expand All @@ -174,12 +181,14 @@ AC_DEFUN([NUT_CHECK_LIBNETSNMP],

nut_cv_LIBNETSNMP_CFLAGS=""
nut_cv_LIBNETSNMP_LIBS=""
nut_cv_LIBNETSNMP_LIBS_EXEC=""
nut_cv_SOFILE_LIBNETSNMP=""
nut_cv_SONAME_LIBNETSNMP=""
nut_cv_SOPATH_LIBNETSNMP=""
AS_IF([test "${nut_cv_have_libnetsnmp}" = "yes"], [
nut_cv_LIBNETSNMP_CFLAGS="${depCFLAGS}"
nut_cv_LIBNETSNMP_LIBS="${depLIBS}"
nut_cv_LIBNETSNMP_LIBS_EXEC="${depLIBS_EXEC}"

AC_CACHE_CHECK([for defined usmAESPrivProtocol],
[nut_cv_NUT_HAVE_LIBNETSNMP_usmAESPrivProtocol],
Expand Down Expand Up @@ -378,13 +387,15 @@ int num = NETSNMP_DRAFT_BLUMENTHAL_AES_04 + 1; /* if defined, NETSNMP_DRAFT_BLUM
AC_CACHE_VAL([nut_cv_prefer_NET_SNMP_CONFIG], [])
AC_CACHE_VAL([nut_cv_LIBNETSNMP_CFLAGS], [])
AC_CACHE_VAL([nut_cv_LIBNETSNMP_LIBS], [])
AC_CACHE_VAL([nut_cv_LIBNETSNMP_LIBS_EXEC], [])
AC_CACHE_VAL([nut_cv_LIBNETSNMP_CFLAGS_SOURCE], [])
AC_CACHE_VAL([nut_cv_LIBNETSNMP_LIBS_SOURCE], [])
AC_CACHE_VAL([nut_cv_SOFILE_LIBNETSNMP], [])
AC_CACHE_VAL([nut_cv_SOPATH_LIBNETSNMP], [])

unset depCFLAGS
unset depLIBS
unset depLIBS_EXEC
unset depCFLAGS_SOURCE
unset depLIBS_SOURCE

Expand Down Expand Up @@ -431,6 +442,7 @@ int num = NETSNMP_DRAFT_BLUMENTHAL_AES_04 + 1; /* if defined, NETSNMP_DRAFT_BLUM

LIBNETSNMP_CFLAGS="${nut_cv_LIBNETSNMP_CFLAGS}"
LIBNETSNMP_LIBS="${nut_cv_LIBNETSNMP_LIBS}"
LIBNETSNMP_LIBS_EXEC="${nut_cv_LIBNETSNMP_LIBS_EXEC}"

dnl For nut-scanner style autoloading:
SOPATH_LIBNETSNMP="${nut_cv_SOPATH_LIBNETSNMP}"
Expand Down
76 changes: 75 additions & 1 deletion tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ $(top_builddir)/common/libcommon.la \
$(top_builddir)/common/libparseconf.la \
$(top_builddir)/clients/libupsclient.la \
$(top_builddir)/clients/libnutclient.la \
$(top_builddir)/clients/libnutclientstub.la: dummy @dotMAKE@
$(top_builddir)/clients/libnutclientstub.la \
$(top_builddir)/tools/nut-scanner/nutscan-snmp.h \
$(top_builddir)/tools/nut-scanner/libnutscan.la: dummy @dotMAKE@
+@cd $(@D) && $(MAKE) $(AM_MAKEFLAGS) $(@F)

$(top_builddir)/clients/upslog$(EXEEXT): dummy @dotMAKE@
Expand All @@ -66,6 +68,9 @@ $(top_builddir)/clients/upslog$(EXEEXT): dummy @dotMAKE@
# started from scratch right in this dir get dependencies in proper order
# (sub-makes are independent as far as trying to write into same files):
$(top_builddir)/common/libcommon.la $(top_builddir)/common/libcommonclient.la: $(top_builddir)/common/libparseconf.la
# These independent sub-makes share the replacement-function objects.
# Finish one library before the other can rebuild those objects.
$(top_builddir)/common/libcommon.la: $(top_builddir)/common/libcommonclient.la
$(top_builddir)/common/libcommonversion.la: $(top_builddir)/include/nut_version.h
$(top_builddir)/clients/libnutclientstub.la: $(top_builddir)/clients/libnutclient.la

Expand Down Expand Up @@ -104,6 +109,13 @@ NUT_LIBCOMMON = $(top_builddir)/common/libcommon.la

endif !ENABLE_SHARED_PRIVATE_LIBS

# Finish shared dependencies before the scanner's independent sub-make
# (normally invoked only if building WITH_NUT_SCANNER).
$(top_builddir)/tools/nut-scanner/libnutscan.la: $(NUT_LIBCOMMON) $(top_builddir)/common/libcommonversion.la $(top_builddir)/clients/libupsclient.la
# The scanner library generates this header before the tests can include it
# (if building WITH_NUT_SCANNER and WITH_SNMP).
$(top_builddir)/tools/nut-scanner/nutscan-snmp.h: $(top_builddir)/tools/nut-scanner/libnutscan.la

TESTS += test_cgilib
test_cgilib_SOURCES = test_cgilib.c
nodist_test_cgilib_SOURCES = cgilib.c
Expand Down Expand Up @@ -312,6 +324,68 @@ endif !WITH_OPENSSL
endif WITH_SSL
endif WITH_SNMP

# Compile each scanner's actual admission loop with offline worker probes.
if WITH_NUT_SCANNER
NUTSCAN_TEST_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/tools/nut-scanner -I$(top_builddir)/tools/nut-scanner -I$(top_srcdir)/clients $(LIBIPMI_CFLAGS)
NUTSCAN_TEST_LDADD = $(NUT_LIBCOMMON) $(top_builddir)/tools/nut-scanner/libnutscan.la $(LIBLTDL_LIBS) $(SEMLIBS) $(NETLIBS)
if WITH_SSL
NUTSCAN_TEST_CFLAGS += $(LIBSSL_CFLAGS)
NUTSCAN_TEST_LDADD += $(LIBSSL_LIBS)
endif WITH_SSL
# Any fixture may pull the SNMP scanner from static libnutscan.
if WITH_SNMP_STATIC
NUTSCAN_TEST_LDADD += $(LIBNETSNMP_LIBS_EXEC)
endif WITH_SNMP_STATIC

if WITH_SNMP
nutscan-thread-test.c nutscan-snmp-retry-test.c: $(top_builddir)/tools/nut-scanner/nutscan-snmp.h

TESTS += nutscan-snmp-retry-test
nutscan_snmp_retry_test_SOURCES = nutscan-snmp-retry-test.c
nutscan_snmp_retry_test_CFLAGS = $(NUTSCAN_TEST_CFLAGS) $(LIBNETSNMP_CFLAGS)
nutscan_snmp_retry_test_LDADD = $(NUTSCAN_TEST_LDADD)
nutscan_snmp_retry_test_DEPENDENCIES = $(top_srcdir)/tools/nut-scanner/scan_snmp.c $(top_builddir)/tools/nut-scanner/nutscan-snmp.h $(top_srcdir)/tools/nut-scanner/nutscan-thread.h $(top_srcdir)/tools/nut-scanner/nutscan-thread.c $(top_builddir)/tools/nut-scanner/libnutscan.la $(NUT_LIBCOMMON)
endif WITH_SNMP

if WITH_THREADING
TESTS += nutscan-serial-test
nutscan_serial_test_SOURCES = nutscan-thread-test.c
nutscan_serial_test_CFLAGS = $(NUTSCAN_TEST_CFLAGS) -DNUTSCAN_TEST_PROTOCOL=5
nutscan_serial_test_LDADD = $(top_builddir)/drivers/libserial-nutscan.la $(NUTSCAN_TEST_LDADD) $(SERLIBS)
nutscan_serial_test_DEPENDENCIES = $(top_srcdir)/tools/nut-scanner/scan_eaton_serial.c $(top_srcdir)/tools/nut-scanner/nutscan-thread.h $(top_srcdir)/tools/nut-scanner/nutscan-thread.c $(top_builddir)/tools/nut-scanner/libnutscan.la $(NUT_LIBCOMMON)

TESTS += nutscan-nut-test
nutscan_nut_test_SOURCES = nutscan-thread-test.c
nutscan_nut_test_CFLAGS = $(NUTSCAN_TEST_CFLAGS) -DNUTSCAN_TEST_PROTOCOL=3
nutscan_nut_test_LDADD = $(NUTSCAN_TEST_LDADD)
nutscan_nut_test_DEPENDENCIES = $(top_srcdir)/tools/nut-scanner/scan_nut.c $(top_srcdir)/tools/nut-scanner/nutscan-thread.h $(top_srcdir)/tools/nut-scanner/nutscan-thread.c $(top_builddir)/tools/nut-scanner/libnutscan.la $(NUT_LIBCOMMON)

if WITH_SNMP
TESTS += nutscan-snmp-test
nutscan_snmp_test_SOURCES = nutscan-thread-test.c
nutscan_snmp_test_CFLAGS = $(NUTSCAN_TEST_CFLAGS) $(LIBNETSNMP_CFLAGS) -DNUTSCAN_TEST_PROTOCOL=1
nutscan_snmp_test_LDADD = $(NUTSCAN_TEST_LDADD)
nutscan_snmp_test_DEPENDENCIES = $(top_srcdir)/tools/nut-scanner/scan_snmp.c $(top_builddir)/tools/nut-scanner/nutscan-snmp.h $(top_srcdir)/tools/nut-scanner/nutscan-thread.h $(top_srcdir)/tools/nut-scanner/nutscan-thread.c $(top_builddir)/tools/nut-scanner/libnutscan.la $(NUT_LIBCOMMON)
endif WITH_SNMP

if WITH_IPMI
TESTS += nutscan-ipmi-test
nutscan_ipmi_test_SOURCES = nutscan-thread-test.c
nutscan_ipmi_test_CFLAGS = $(NUTSCAN_TEST_CFLAGS) -DNUTSCAN_TEST_PROTOCOL=2
nutscan_ipmi_test_LDADD = $(NUTSCAN_TEST_LDADD)
nutscan_ipmi_test_DEPENDENCIES = $(top_srcdir)/tools/nut-scanner/scan_ipmi.c $(top_srcdir)/tools/nut-scanner/nutscan-thread.h $(top_srcdir)/tools/nut-scanner/nutscan-thread.c $(top_builddir)/tools/nut-scanner/libnutscan.la $(NUT_LIBCOMMON)
endif WITH_IPMI

if WITH_NEON
TESTS += nutscan-xml-test
nutscan_xml_test_SOURCES = nutscan-thread-test.c
nutscan_xml_test_CFLAGS = $(NUTSCAN_TEST_CFLAGS) $(LIBNEON_CFLAGS) -DNUTSCAN_TEST_PROTOCOL=4
nutscan_xml_test_LDADD = $(NUTSCAN_TEST_LDADD)
nutscan_xml_test_DEPENDENCIES = $(top_srcdir)/tools/nut-scanner/scan_xml_http.c $(top_srcdir)/tools/nut-scanner/nutscan-thread.h $(top_srcdir)/tools/nut-scanner/nutscan-thread.c $(top_builddir)/tools/nut-scanner/libnutscan.la $(NUT_LIBCOMMON)
endif WITH_NEON
endif WITH_THREADING
endif WITH_NUT_SCANNER

### Optional tests which can not be built everywhere
# List of src files for CppUnit tests
CPPUNITTESTSRC = example.cpp nutclienttest.cpp
Expand Down
Loading
Loading