Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 4 additions & 0 deletions NEWS.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,10 @@ https://github.com/networkupstools/nut/milestone/12
built-in NUT configuration path on all platforms, but to also consider
`NUT_CONFPATH` and other fallback locations, like other code does.
[PR #3249]
* Enhance debug-logging of dynamic library loading with information about
any missing method in the library discovered at run-time, if lack of such
prevents us from using that library, and blocks scanning of corresponding
protocol and/or media to discover possibly supported devices. [PR #3310]
* Introduced `nut-scanner` support for new `nut-upower` driver. [PR #3293]

- `upsd` data server updates:
Expand Down
71 changes: 50 additions & 21 deletions tools/nut-scanner/scan_avahi.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2011-2024 Arnaud Quette (Design and part of implementation)
* Copyright (C) 2011 - EATON
* Copyright (C) 2020-2024 - Jim Klimov <jimklimov+nut@gmail.com> - support and modernization of codebase
* Copyright (C) 2020-2026 - Jim Klimov <jimklimov+nut@gmail.com> - support and modernization of codebase
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -108,6 +108,8 @@ int nutscan_unload_avahi_library(void)
int nutscan_load_avahi_library(const char *libname_path);
int nutscan_load_avahi_library(const char *libname_path)
{
char *symbol = NULL;

if (dl_handle != NULL) {
/* if previous init failed */
if (dl_handle == (lt_dlhandle)1) {
Expand All @@ -133,99 +135,122 @@ int nutscan_load_avahi_library(const char *libname_path)
goto err;
}

upsdebugx(2, "%s: lt_dlopen() succeeded, searching for needed methods", __func__);

/* Clear any existing error */
lt_dlerror();

*(void **) (&nut_avahi_service_browser_get_client) = lt_dlsym(dl_handle, "avahi_service_browser_get_client");
*(void **) (&nut_avahi_service_browser_get_client) = lt_dlsym(dl_handle,
symbol = "avahi_service_browser_get_client");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_simple_poll_loop) = lt_dlsym(dl_handle, "avahi_simple_poll_loop");
*(void **) (&nut_avahi_simple_poll_loop) = lt_dlsym(dl_handle,
symbol = "avahi_simple_poll_loop");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_client_free) = lt_dlsym(dl_handle, "avahi_client_free");
*(void **) (&nut_avahi_client_free) = lt_dlsym(dl_handle,
symbol = "avahi_client_free");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_client_errno) = lt_dlsym(dl_handle, "avahi_client_errno");
*(void **) (&nut_avahi_client_errno) = lt_dlsym(dl_handle,
symbol = "avahi_client_errno");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_free) = lt_dlsym(dl_handle, "avahi_free");
*(void **) (&nut_avahi_free) = lt_dlsym(dl_handle,
symbol = "avahi_free");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_simple_poll_quit) = lt_dlsym(dl_handle, "avahi_simple_poll_quit");
*(void **) (&nut_avahi_simple_poll_quit) = lt_dlsym(dl_handle,
symbol = "avahi_simple_poll_quit");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_client_new) = lt_dlsym(dl_handle, "avahi_client_new");
*(void **) (&nut_avahi_client_new) = lt_dlsym(dl_handle,
symbol = "avahi_client_new");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_simple_poll_free) = lt_dlsym(dl_handle, "avahi_simple_poll_free");
*(void **) (&nut_avahi_simple_poll_free) = lt_dlsym(dl_handle,
symbol = "avahi_simple_poll_free");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_service_resolver_new) = lt_dlsym(dl_handle, "avahi_service_resolver_new");
*(void **) (&nut_avahi_service_resolver_new) = lt_dlsym(dl_handle,
symbol = "avahi_service_resolver_new");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_strerror) = lt_dlsym(dl_handle, "avahi_strerror");
*(void **) (&nut_avahi_strerror) = lt_dlsym(dl_handle,
symbol = "avahi_strerror");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_service_resolver_get_client) = lt_dlsym(dl_handle, "avahi_service_resolver_get_client");
*(void **) (&nut_avahi_service_resolver_get_client) = lt_dlsym(dl_handle,
symbol = "avahi_service_resolver_get_client");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_service_browser_new) = lt_dlsym(dl_handle, "avahi_service_browser_new");
*(void **) (&nut_avahi_service_browser_new) = lt_dlsym(dl_handle,
symbol = "avahi_service_browser_new");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_service_resolver_free) = lt_dlsym(dl_handle, "avahi_service_resolver_free");
*(void **) (&nut_avahi_service_resolver_free) = lt_dlsym(dl_handle,
symbol = "avahi_service_resolver_free");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_simple_poll_new) = lt_dlsym(dl_handle, "avahi_simple_poll_new");
*(void **) (&nut_avahi_simple_poll_new) = lt_dlsym(dl_handle,
symbol = "avahi_simple_poll_new");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_string_list_to_string) = lt_dlsym(dl_handle, "avahi_string_list_to_string");
*(void **) (&nut_avahi_string_list_to_string) = lt_dlsym(dl_handle,
symbol = "avahi_string_list_to_string");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_service_browser_free) = lt_dlsym(dl_handle, "avahi_service_browser_free");
*(void **) (&nut_avahi_service_browser_free) = lt_dlsym(dl_handle,
symbol = "avahi_service_browser_free");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_address_snprint) = lt_dlsym(dl_handle, "avahi_address_snprint");
*(void **) (&nut_avahi_address_snprint) = lt_dlsym(dl_handle,
symbol = "avahi_address_snprint");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_avahi_simple_poll_get) = lt_dlsym(dl_handle, "avahi_simple_poll_get");
*(void **) (&nut_avahi_simple_poll_get) = lt_dlsym(dl_handle,
symbol = "avahi_simple_poll_get");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

/* Passed final lt_dlsym() */
symbol = NULL;

if (dl_saved_libname)
free(dl_saved_libname);
dl_saved_libname = xstrdup(libname_path);
Expand All @@ -234,8 +259,12 @@ int nutscan_load_avahi_library(const char *libname_path)

err:
upsdebugx(0,
"Cannot load AVAHI library (%s) : %s. AVAHI search disabled.",
libname_path, dl_error);
"Cannot load AVAHI library (%s) : %s%s%s%s. AVAHI search disabled.",
libname_path, dl_error,
symbol ? " Error happened during search for symbol '" : "",
symbol ? symbol : "",
symbol ? "'" : ""
);
dl_handle = (lt_dlhandle)1;
lt_dlexit();
if (dl_saved_libname) {
Expand Down
71 changes: 50 additions & 21 deletions tools/nut-scanner/scan_ipmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Copyright (C)
* 2011 - 2012 Arnaud Quette <arnaud.quette@free.fr>
* 2016 - 2021 EATON - Various threads-related improvements
* 2020 - 2024 Jim Klimov <jimklimov+nut@gmail.com>
* 2020 - 2026 Jim Klimov <jimklimov+nut@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -150,6 +150,8 @@ int nutscan_unload_ipmi_library(void)
int nutscan_load_ipmi_library(const char *libname_path);
int nutscan_load_ipmi_library(const char *libname_path)
{
char *symbol = NULL;

if (dl_handle != NULL) {
/* if previous init failed */
if (dl_handle == (lt_dlhandle)1) {
Expand All @@ -175,104 +177,127 @@ int nutscan_load_ipmi_library(const char *libname_path)
goto err;
}

upsdebugx(2, "%s: lt_dlopen() succeeded, searching for needed methods", __func__);

/* Clear any existing error */
lt_dlerror();

*(void **) (&nut_ipmi_fru_close_device_id) = lt_dlsym(dl_handle, IPMI_FRU_CLOSE_DEVICE_ID);
*(void **) (&nut_ipmi_fru_close_device_id) = lt_dlsym(dl_handle,
symbol = IPMI_FRU_CLOSE_DEVICE_ID);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_ipmi_fru_ctx_destroy) = lt_dlsym(dl_handle, IPMI_FRU_CTX_DESTROY);
*(void **) (&nut_ipmi_fru_ctx_destroy) = lt_dlsym(dl_handle,
symbol = IPMI_FRU_CTX_DESTROY);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

#ifdef HAVE_FREEIPMI_11X_12X

*(void **) (&nut_ipmi_sdr_ctx_destroy) = lt_dlsym(dl_handle, "ipmi_sdr_ctx_destroy");
*(void **) (&nut_ipmi_sdr_ctx_destroy) = lt_dlsym(dl_handle,
symbol = "ipmi_sdr_ctx_destroy");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

#else /* HAVE_FREEIPMI_11X_12X */

*(void **) (&nut_ipmi_sdr_cache_ctx_destroy) = lt_dlsym(dl_handle, "ipmi_sdr_cache_ctx_destroy");
*(void **) (&nut_ipmi_sdr_cache_ctx_destroy) = lt_dlsym(dl_handle,
symbol = "ipmi_sdr_cache_ctx_destroy");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_ipmi_sdr_parse_ctx_destroy) = lt_dlsym(dl_handle, "ipmi_sdr_parse_ctx_destroy");
*(void **) (&nut_ipmi_sdr_parse_ctx_destroy) = lt_dlsym(dl_handle,
symbol = "ipmi_sdr_parse_ctx_destroy");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}
#endif /* HAVE_FREEIPMI_11X_12X */

*(void **) (&nut_ipmi_fru_ctx_create) = lt_dlsym(dl_handle, IPMI_FRU_CTX_CREATE);
*(void **) (&nut_ipmi_fru_ctx_create) = lt_dlsym(dl_handle,
symbol = IPMI_FRU_CTX_CREATE);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_ipmi_fru_ctx_set_flags) = lt_dlsym(dl_handle, IPMI_FRU_CTX_SET_FLAGS);
*(void **) (&nut_ipmi_fru_ctx_set_flags) = lt_dlsym(dl_handle,
symbol = IPMI_FRU_CTX_SET_FLAGS);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_ipmi_fru_open_device_id) = lt_dlsym(dl_handle, IPMI_FRU_OPEN_DEVICE_ID);
*(void **) (&nut_ipmi_fru_open_device_id) = lt_dlsym(dl_handle,
symbol = IPMI_FRU_OPEN_DEVICE_ID);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_ipmi_fru_ctx_errormsg) = lt_dlsym(dl_handle, IPMI_FRU_CTX_ERRORMSG);
*(void **) (&nut_ipmi_fru_ctx_errormsg) = lt_dlsym(dl_handle,
symbol = IPMI_FRU_CTX_ERRORMSG);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_ipmi_fru_read_data_area) = lt_dlsym(dl_handle, IPMI_FRU_READ_DATA_AREA);
*(void **) (&nut_ipmi_fru_read_data_area) = lt_dlsym(dl_handle,
symbol = IPMI_FRU_READ_DATA_AREA);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_ipmi_fru_next) = lt_dlsym(dl_handle, IPMI_FRU_PARSE_NEXT);
*(void **) (&nut_ipmi_fru_next) = lt_dlsym(dl_handle,
symbol = IPMI_FRU_PARSE_NEXT);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_ipmi_ctx_create) = lt_dlsym(dl_handle, "ipmi_ctx_create");
*(void **) (&nut_ipmi_ctx_create) = lt_dlsym(dl_handle,
symbol = "ipmi_ctx_create");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_ipmi_ctx_find_inband) = lt_dlsym(dl_handle, "ipmi_ctx_find_inband");
*(void **) (&nut_ipmi_ctx_find_inband) = lt_dlsym(dl_handle,
symbol = "ipmi_ctx_find_inband");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_ipmi_ctx_open_outofband) = lt_dlsym(dl_handle, "ipmi_ctx_open_outofband");
*(void **) (&nut_ipmi_ctx_open_outofband) = lt_dlsym(dl_handle,
symbol = "ipmi_ctx_open_outofband");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_ipmi_ctx_errnum) = lt_dlsym(dl_handle, "ipmi_ctx_errnum");
*(void **) (&nut_ipmi_ctx_errnum) = lt_dlsym(dl_handle,
symbol = "ipmi_ctx_errnum");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_ipmi_ctx_errormsg) = lt_dlsym(dl_handle, "ipmi_ctx_errormsg");
*(void **) (&nut_ipmi_ctx_errormsg) = lt_dlsym(dl_handle,
symbol = "ipmi_ctx_errormsg");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_ipmi_ctx_close) = lt_dlsym(dl_handle, "ipmi_ctx_close");
*(void **) (&nut_ipmi_ctx_close) = lt_dlsym(dl_handle,
symbol = "ipmi_ctx_close");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

*(void **) (&nut_ipmi_ctx_destroy) = lt_dlsym(dl_handle, "ipmi_ctx_destroy");
*(void **) (&nut_ipmi_ctx_destroy) = lt_dlsym(dl_handle,
symbol = "ipmi_ctx_destroy");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}

/* Passed final lt_dlsym() */
symbol = NULL;

if (dl_saved_libname)
free(dl_saved_libname);
dl_saved_libname = xstrdup(libname_path);
Expand All @@ -281,8 +306,12 @@ int nutscan_load_ipmi_library(const char *libname_path)

err:
upsdebugx(0,
"Cannot load IPMI library (%s) : %s. IPMI search disabled.",
libname_path, dl_error);
"Cannot load IPMI library (%s) : %s%s%s%s. IPMI search disabled.",
libname_path, dl_error,
symbol ? " Error happened during search for symbol '" : "",
symbol ? symbol : "",
symbol ? "'" : ""
);
dl_handle = (lt_dlhandle)1;
lt_dlexit();
if (dl_saved_libname) {
Expand Down
Loading
Loading