From 88e99eda5ace853b2d7e3261349915470bb7688a Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 17 Jul 2024 21:21:31 +0200 Subject: [PATCH] tools/nut-scanner/*: add ability to use named semaphores [#2522] Signed-off-by: Jim Klimov --- configure.ac | 2 +- tools/nut-scanner/nut-scan.h | 22 ++++++-- tools/nut-scanner/nut-scanner.c | 73 ++++++++++++++++++++------- tools/nut-scanner/nutscan-init.c | 50 +++++++++++++++--- tools/nut-scanner/scan_eaton_serial.c | 16 +++--- tools/nut-scanner/scan_ipmi.c | 62 +++++++++++++++-------- tools/nut-scanner/scan_nut.c | 58 ++++++++++++++------- tools/nut-scanner/scan_snmp.c | 56 +++++++++++++------- tools/nut-scanner/scan_xml_http.c | 62 +++++++++++++++-------- 9 files changed, 287 insertions(+), 114 deletions(-) diff --git a/configure.ac b/configure.ac index 13de5de6dd..13af96e42d 100644 --- a/configure.ac +++ b/configure.ac @@ -796,7 +796,7 @@ sem_destroy(&semaphore); * normally check for non-zero meaning to look in errno */ ] )], - [AC_DEFINE([HAVE_SEMAPHORE], [1], + [AC_DEFINE([HAVE_SEMAPHORE_UNNAMED], [1], [Define to 1 if you have with usable sem_t, sem_init() and sem_destroy() for unnamed semaphores.]) AC_MSG_RESULT([ok]) diff --git a/tools/nut-scanner/nut-scan.h b/tools/nut-scanner/nut-scan.h index 4b09db2578..7af30e7913 100644 --- a/tools/nut-scanner/nut-scan.h +++ b/tools/nut-scanner/nut-scan.h @@ -70,7 +70,7 @@ #ifdef HAVE_PTHREAD # include -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) # include # endif #endif @@ -82,10 +82,25 @@ extern "C" { #endif #ifdef HAVE_PTHREAD -# if (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE) +# if (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) extern size_t max_threads, curr_threads, max_threads_netxml, max_threads_oldnut, max_threads_netsnmp, max_threads_ipmi; # endif +# if defined HAVE_SEMAPHORE_UNNAMED +# define REPORT_SEM_INIT_METHOD "sem_init" +# elif defined HAVE_SEMAPHORE_NAMED +# define REPORT_SEM_INIT_METHOD "sem_open" +# endif + +# ifdef HAVE_SEMAPHORE_NAMED +# define SEMNAME_TOPLEVEL "/libnutscan-toplevel-bus-scans" +# define SEMNAME_NETXML "/libnutscan-netxml" +# define SEMNAME_UPSCLIENT "/libnutscan-upsclient" +# define SEMNAME_EATON_SERIAL "/libnutscan-eaton-serial" +# define SEMNAME_SNMP "/libnutscan-snmp" +# define SEMNAME_IPMI "/libnutscan-ipmi" +# endif + # ifdef HAVE_PTHREAD_TRYJOIN extern pthread_mutex_t threadcount_mutex; # endif @@ -185,10 +200,11 @@ nutscan_device_t * nutscan_scan_ip_range_ipmi(nutscan_ip_range_list_t * irl, nut nutscan_device_t * nutscan_scan_eaton_serial(const char* ports_list); #ifdef HAVE_PTHREAD -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) /* Expose shared libnutscan semaphore for overall thread count * limited across different scanning methods (protocols/media): */ sem_t * nutscan_semaphore(void); +void nutscan_semaphore_set(sem_t *s); # endif #endif diff --git a/tools/nut-scanner/nut-scanner.c b/tools/nut-scanner/nut-scanner.c index 66358fc6bb..e8cd183eb1 100644 --- a/tools/nut-scanner/nut-scanner.c +++ b/tools/nut-scanner/nut-scanner.c @@ -65,10 +65,10 @@ #ifdef HAVE_PTHREAD # include -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) # include # endif -# if (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE) +# if (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) # include "nut_stdint.h" # ifdef HAVE_SYS_RESOURCE_H # include /* for getrlimit() and struct rlimit */ @@ -81,7 +81,7 @@ */ # define RESERVE_FD_COUNT 3 # endif /* HAVE_SYS_RESOURCE_H */ -# endif /* HAVE_PTHREAD_TRYJOIN || HAVE_SEMAPHORE */ +# endif /* HAVE_PTHREAD_TRYJOIN || HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ #include "nut-scan.h" @@ -997,7 +997,7 @@ static void show_usage(void) printf(" -E, --eaton_serial : Scan serial Eaton devices (XCP, SHUT and Q1).\n"); -#if (defined HAVE_PTHREAD) && ( (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE) ) +#if (defined HAVE_PTHREAD) && ( (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) ) printf(" -T, --thread : Limit the amount of scanning threads running simultaneously (default: %" PRIuSIZE ").\n", max_threads); #else printf(" -T, --thread : Limit the amount of scanning threads running simultaneously (not implemented in this build: no pthread support)\n"); @@ -1164,11 +1164,11 @@ int main(int argc, char *argv[]) void (*display_func)(nutscan_device_t * device); int ret_code = EXIT_SUCCESS; #ifdef HAVE_PTHREAD -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) sem_t *current_sem; # endif #endif -#if (defined HAVE_PTHREAD) && ( (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE) ) && (defined HAVE_SYS_RESOURCE_H) +#if (defined HAVE_PTHREAD) && ( (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) ) && (defined HAVE_SYS_RESOURCE_H) struct rlimit nofile_limit; /* Limit the max scanning thread count by the amount of allowed open @@ -1197,7 +1197,7 @@ int main(int argc, char *argv[]) } } } -#endif /* HAVE_PTHREAD && ( HAVE_PTHREAD_TRYJOIN || HAVE_SEMAPHORE ) && HAVE_SYS_RESOURCE_H */ +#endif /* HAVE_PTHREAD && ( HAVE_PTHREAD_TRYJOIN || HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED ) && HAVE_SYS_RESOURCE_H */ memset(&snmp_sec, 0, sizeof(snmp_sec)); memset(&ipmi_sec, 0, sizeof(ipmi_sec)); @@ -1428,7 +1428,7 @@ int main(int argc, char *argv[]) port = strdup(optarg); break; case 'T': { -#if (defined HAVE_PTHREAD) && ( (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE) ) +#if (defined HAVE_PTHREAD) && ( (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) ) char* endptr; long val = strtol(optarg, &endptr, 10); /* With endptr we check that no chars were left in optarg @@ -1569,21 +1569,40 @@ int main(int argc, char *argv[]) } #ifdef HAVE_PTHREAD -# if (defined HAVE_PTHREAD_TRYJOIN) && (defined HAVE_SEMAPHORE) - upsdebugx(1, "Parallel scan support: HAVE_PTHREAD && HAVE_PTHREAD_TRYJOIN && HAVE_SEMAPHORE"); + { /* scoping for the string */ +# if defined HAVE_SEMAPHORE_UNNAMED + char * semsuf = "_UNNAMED"; +# elif defined HAVE_SEMAPHORE_NAMED + char * semsuf = "_NAMED"; +# else + char * semsuf = "*"; +# endif + NUT_UNUSED_VARIABLE(semsuf); /* just in case */ + +# if (defined HAVE_PTHREAD_TRYJOIN) && ((defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED)) + upsdebugx(1, "Parallel scan support: HAVE_PTHREAD && HAVE_PTHREAD_TRYJOIN && HAVE_SEMAPHORE%s", semsuf); # elif (defined HAVE_PTHREAD_TRYJOIN) - upsdebugx(1, "Parallel scan support: HAVE_PTHREAD && HAVE_PTHREAD_TRYJOIN && !HAVE_SEMAPHORE"); -# elif (defined HAVE_SEMAPHORE) - upsdebugx(1, "Parallel scan support: HAVE_PTHREAD && !HAVE_PTHREAD_TRYJOIN && HAVE_SEMAPHORE"); + upsdebugx(1, "Parallel scan support: HAVE_PTHREAD && HAVE_PTHREAD_TRYJOIN && !HAVE_SEMAPHORE*"); +# elif (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) + upsdebugx(1, "Parallel scan support: HAVE_PTHREAD && !HAVE_PTHREAD_TRYJOIN && HAVE_SEMAPHORE%s", semsuf); # else - upsdebugx(1, "Parallel scan support: HAVE_PTHREAD && !HAVE_PTHREAD_TRYJOIN && !HAVE_SEMAPHORE"); + upsdebugx(1, "Parallel scan support: HAVE_PTHREAD && !HAVE_PTHREAD_TRYJOIN && !HAVE_SEMAPHORE*"); # endif -# ifdef HAVE_SEMAPHORE + } + +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) /* FIXME: Currently sem_init already done on nutscan-init for lib need. We need to destroy it before re-init. We currently can't change "sem value" on lib (need to be thread safe). */ current_sem = nutscan_semaphore(); +# ifdef HAVE_SEMAPHORE_UNNAMED sem_destroy(current_sem); +# elif defined HAVE_SEMAPHORE_NAMED + if (current_sem) { + sem_unlink(SEMNAME_TOPLEVEL); + sem_close(current_sem); + } +# endif #ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE #pragma GCC diagnostic push #endif @@ -1603,15 +1622,27 @@ int main(int argc, char *argv[]) #pragma GCC diagnostic pop #endif fprintf(stderr, "\n\n" - "WARNING: Limiting max_threads to range acceptable for sem_init()\n\n"); + "WARNING: Limiting max_threads to range acceptable for " + REPORT_SEM_INIT_METHOD "()\n\n"); max_threads = UINT_MAX - 1; } upsdebugx(1, "Parallel scan support: max_threads=%" PRIuSIZE, max_threads); +# ifdef HAVE_SEMAPHORE_UNNAMED if (sem_init(current_sem, 0, (unsigned int)max_threads)) { /* Show this one to end-users so they know */ - upsdebug_with_errno(0, "Parallel scan support: sem_init() failed"); + upsdebug_with_errno(0, "Parallel scan support: " REPORT_SEM_INIT_METHOD "() failed"); } +# elif defined HAVE_SEMAPHORE_NAMED + /* FIXME: Do we need O_EXCL here? */ + if (SEM_FAILED == (current_sem = sem_open(SEMNAME_TOPLEVEL, O_CREAT, 0644, (unsigned int)max_threads))) { + /* Show this one to end-users so they know */ + upsdebug_with_errno(0, "Parallel scan support: " REPORT_SEM_INIT_METHOD "() failed"); + current_sem = NULL; + } + nutscan_semaphore_set(current_sem); +# endif + # endif #else upsdebugx(1, "Parallel scan support: !HAVE_PTHREAD"); @@ -1887,8 +1918,14 @@ int main(int argc, char *argv[]) nutscan_free_device(dev[TYPE_EATON_SERIAL]); #ifdef HAVE_PTHREAD -# ifdef HAVE_SEMAPHORE +# ifdef HAVE_SEMAPHORE_UNNAMED sem_destroy(nutscan_semaphore()); +# elif defined HAVE_SEMAPHORE_NAMED + if (nutscan_semaphore()) { + sem_unlink(SEMNAME_TOPLEVEL); + sem_close(nutscan_semaphore()); + nutscan_semaphore_set(NULL); + } # endif #endif diff --git a/tools/nut-scanner/nutscan-init.c b/tools/nut-scanner/nutscan-init.c index 609c9a04d2..5c81da464e 100644 --- a/tools/nut-scanner/nutscan-init.c +++ b/tools/nut-scanner/nutscan-init.c @@ -74,7 +74,7 @@ int nutscan_load_upsclient_library(const char *libname_path); int nutscan_unload_upsclient_library(void); #ifdef HAVE_PTHREAD -# ifdef HAVE_SEMAPHORE +# ifdef HAVE_SEMAPHORE_UNNAMED /* Shared by library consumers, exposed by nutscan_semaphore() below */ static sem_t semaphore; @@ -82,13 +82,33 @@ sem_t * nutscan_semaphore(void) { return &semaphore; } -# endif /* HAVE_SEMAPHORE */ + +void nutscan_semaphore_set(sem_t *s) +{ + NUT_UNUSED_VARIABLE(s); +} +# elif defined HAVE_SEMAPHORE_NAMED +/* Shared by library consumers, exposed by nutscan_semaphore() below. + * Methods like sem_open() return the pointer and sem_close() frees its data. + */ +static sem_t *semaphore = NULL; /* TOTHINK: maybe SEM_FAILED? */ + +sem_t * nutscan_semaphore(void) +{ + return semaphore; +} + +void nutscan_semaphore_set(sem_t *s) +{ + semaphore = s; +} +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ # ifdef HAVE_PTHREAD_TRYJOIN pthread_mutex_t threadcount_mutex; # endif -# if (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE) +# if (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) /* We have 3 networked scan types: nut, snmp, xml, * and users typically give their /24 subnet as "-m" arg. * With some systems having a 1024 default (u)limit to @@ -113,7 +133,7 @@ size_t max_threads_netsnmp = 0; /* 10240; */ */ size_t max_threads_ipmi = 0; /* limits not yet known */ -# endif /* HAVE_PTHREAD_TRYJOIN || HAVE_SEMAPHORE */ +# endif /* HAVE_PTHREAD_TRYJOIN || HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ @@ -148,7 +168,7 @@ void nutscan_init(void) * and the more naive but portable methods be an * if-else proposition? At least when initializing? */ -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) /* NOTE: This semaphore may get re-initialized in nut-scanner program * after parsing command-line arguments. It calls nutscan_init() before * parsing CLI, to know about available libs and to set defaults below. @@ -172,16 +192,24 @@ void nutscan_init(void) #pragma GCC diagnostic pop #endif upsdebugx(1, - "WARNING: %s: Limiting max_threads to range acceptable for sem_init()", + "WARNING: %s: Limiting max_threads to range acceptable for " REPORT_SEM_INIT_METHOD "()", __func__); max_threads = UINT_MAX - 1; } upsdebugx(1, "%s: Parallel scan support: max_threads=%" PRIuSIZE, __func__, max_threads); +# ifdef HAVE_SEMAPHORE_UNNAMED if (sem_init(&semaphore, 0, (unsigned int)max_threads)) { - upsdebug_with_errno(4, "%s: Parallel scan support: sem_init() failed", __func__); + upsdebug_with_errno(4, "%s: Parallel scan support: " REPORT_SEM_INIT_METHOD "() failed", __func__); + } +# elif defined HAVE_SEMAPHORE_NAMED + /* FIXME: Do we need O_EXCL here? */ + if (SEM_FAILED == (semaphore = sem_open(SEMNAME_TOPLEVEL, O_CREAT, 0644, (unsigned int)max_threads))) { + upsdebug_with_errno(4, "%s: Parallel scan support: " REPORT_SEM_INIT_METHOD "() failed", __func__); + semaphore = NULL; } +# endif # endif # ifdef HAVE_PTHREAD_TRYJOIN @@ -674,8 +702,14 @@ void nutscan_free(void) #ifdef HAVE_PTHREAD /* TOTHINK: See comments near mutex/semaphore init code above */ -# ifdef HAVE_SEMAPHORE +# ifdef HAVE_SEMAPHORE_UNNAMED sem_destroy(nutscan_semaphore()); +# elif defined HAVE_SEMAPHORE_NAMED + if (nutscan_semaphore()) { + sem_unlink(SEMNAME_TOPLEVEL); + sem_close(nutscan_semaphore()); + nutscan_semaphore_set(NULL); + } # endif # ifdef HAVE_PTHREAD_TRYJOIN diff --git a/tools/nut-scanner/scan_eaton_serial.c b/tools/nut-scanner/scan_eaton_serial.c index 93f95875bf..e823a748b4 100644 --- a/tools/nut-scanner/scan_eaton_serial.c +++ b/tools/nut-scanner/scan_eaton_serial.c @@ -419,13 +419,13 @@ nutscan_device_t * nutscan_scan_eaton_serial(const char* ports_range) int current_port_nb; #ifdef HAVE_PTHREAD -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) sem_t * semaphore = nutscan_semaphore(); /* TODO? Port semaphore_scantype / max_threads_scantype * from sibling sources? We do not have that many serial * ports to care much, usually... right? */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ pthread_t thread; nutscan_thread_t * thread_array = NULL; size_t thread_count = 0, i; @@ -467,7 +467,7 @@ nutscan_device_t * nutscan_scan_eaton_serial(const char* ports_range) * for below in pthread_join()... */ -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) /* Just wait for someone to free a semaphored slot, * if none are available, and then/otherwise grab one */ @@ -547,7 +547,7 @@ nutscan_device_t * nutscan_scan_eaton_serial(const char* ports_range) /* NOTE: No change to default "pass" in this ifdef: * if we got to this line, we have a slot to use */ # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ if (pass) { @@ -586,7 +586,7 @@ nutscan_device_t * nutscan_scan_eaton_serial(const char* ports_range) current_port_nb++; } else { /* if not pass -- all slots busy */ #ifdef HAVE_PTHREAD -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) /* Wait for all current scans to complete */ if (thread_array != NULL) { upsdebugx (2, "%s: Running too many scanning threads (%" @@ -619,7 +619,7 @@ nutscan_device_t * nutscan_scan_eaton_serial(const char* ports_range) # ifdef HAVE_PTHREAD_TRYJOIN /* TODO: Move the wait-loop for TRYJOIN here? */ # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ } /* if: could we "pass" or not? */ } /* while */ @@ -638,7 +638,7 @@ nutscan_device_t * nutscan_scan_eaton_serial(const char* ports_range) __func__, ret); } thread_array[i].active = FALSE; -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) sem_post(semaphore); # else # ifdef HAVE_PTHREAD_TRYJOIN @@ -653,7 +653,7 @@ nutscan_device_t * nutscan_scan_eaton_serial(const char* ports_range) } pthread_mutex_unlock(&threadcount_mutex); # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ } free(thread_array); upsdebugx(2, "%s: all threads freed", __func__); diff --git a/tools/nut-scanner/scan_ipmi.c b/tools/nut-scanner/scan_ipmi.c index 316f15bd15..efbefa6425 100644 --- a/tools/nut-scanner/scan_ipmi.c +++ b/tools/nut-scanner/scan_ipmi.c @@ -736,18 +736,22 @@ nutscan_device_t * nutscan_scan_ip_range_ipmi(nutscan_ip_range_list_t * irl, nut char * ip_str = NULL; #ifdef HAVE_PTHREAD -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) sem_t * semaphore = nutscan_semaphore(); +# if (defined HAVE_SEMAPHORE_UNNAMED) sem_t semaphore_scantype_inst; sem_t * semaphore_scantype = &semaphore_scantype_inst; -# endif /* HAVE_SEMAPHORE */ +# elif (defined HAVE_SEMAPHORE_NAMED) + sem_t * semaphore_scantype = NULL; +# endif +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ pthread_t thread; nutscan_thread_t * thread_array = NULL; size_t thread_count = 0, i; -# if (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE) +# if (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) size_t max_threads_scantype = max_threads_ipmi; # endif -#endif +#endif /* HAVE_PTHREAD */ if (irl->ip_ranges_count == 1 && (irl->ip_ranges->start_ip == irl->ip_ranges->end_ip @@ -763,7 +767,7 @@ nutscan_device_t * nutscan_scan_ip_range_ipmi(nutscan_ip_range_list_t * irl, nut #ifdef HAVE_PTHREAD pthread_mutex_init(&dev_mutex, NULL); -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) if (max_threads_scantype > 0) { #ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE #pragma GCC diagnostic push @@ -784,17 +788,26 @@ nutscan_device_t * nutscan_scan_ip_range_ipmi(nutscan_ip_range_list_t * irl, nut #pragma GCC diagnostic pop #endif upsdebugx(1, - "WARNING: %s: Limiting max_threads_scantype to range acceptable for sem_init()", + "WARNING: %s: Limiting max_threads_scantype to range acceptable for " REPORT_SEM_INIT_METHOD "()", __func__); max_threads_scantype = UINT_MAX - 1; } - upsdebugx(4, "%s: sem_init() for %" PRIuSIZE " threads", __func__, max_threads_scantype); + upsdebugx(4, "%s: " REPORT_SEM_INIT_METHOD "() for %" PRIuSIZE " threads", __func__, max_threads_scantype); +# if (defined HAVE_SEMAPHORE_UNNAMED) if (sem_init(semaphore_scantype, 0, (unsigned int)max_threads_scantype)) { - upsdebug_with_errno(4, "%s: sem_init() failed", __func__); + upsdebug_with_errno(4, "%s: " REPORT_SEM_INIT_METHOD "() failed", __func__); + max_threads_scantype = 0; + } +# elif (defined HAVE_SEMAPHORE_NAMED) + if (SEM_FAILED == (semaphore_scantype = sem_open(SEMNAME_IPMI, O_CREAT, 0644, (unsigned int)max_threads_scantype))) { + upsdebug_with_errno(4, "%s: " REPORT_SEM_INIT_METHOD "() failed", __func__); + semaphore_scantype = NULL; + max_threads_scantype = 0; } +# endif } -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ @@ -809,7 +822,7 @@ nutscan_device_t * nutscan_scan_ip_range_ipmi(nutscan_ip_range_list_t * irl, nut * for below in pthread_join()... */ -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) /* Just wait for someone to free a semaphored slot, * if none are available, and then/otherwise grab one */ @@ -912,7 +925,7 @@ nutscan_device_t * nutscan_scan_ip_range_ipmi(nutscan_ip_range_list_t * irl, nut /* NOTE: No change to default "pass" in this ifdef: * if we got to this line, we have a slot to use */ # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ if (pass) { @@ -950,9 +963,9 @@ nutscan_device_t * nutscan_scan_ip_range_ipmi(nutscan_ip_range_list_t * irl, nut pthread_mutex_unlock(&threadcount_mutex); # endif /* HAVE_PTHREAD_TRYJOIN */ } -#else /* if not HAVE_PTHREAD */ +#else /* if not HAVE_PTHREAD */ nutscan_scan_ipmi_device_thready(tmp_sec); -#endif /* if HAVE_PTHREAD */ +#endif /* if HAVE_PTHREAD */ /* Prepare the next iteration; note that * nutscan_scan_ipmi_device_thready() @@ -963,7 +976,7 @@ nutscan_device_t * nutscan_scan_ip_range_ipmi(nutscan_ip_range_list_t * irl, nut ip_str = nutscan_ip_ranges_iter_inc(&ip); } else { /* if not pass -- all slots busy */ #ifdef HAVE_PTHREAD -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) /* Wait for all current scans to complete */ if (thread_array != NULL) { upsdebugx (2, "%s: Running too many scanning threads (%" @@ -1000,7 +1013,7 @@ nutscan_device_t * nutscan_scan_ip_range_ipmi(nutscan_ip_range_list_t * irl, nut # ifdef HAVE_PTHREAD_TRYJOIN /* TODO: Move the wait-loop for TRYJOIN here? */ # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ } /* if: could we "pass" or not? */ } /* while */ @@ -1019,7 +1032,7 @@ nutscan_device_t * nutscan_scan_ip_range_ipmi(nutscan_ip_range_list_t * irl, nut __func__, ret); } thread_array[i].active = FALSE; -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) sem_post(semaphore); if (max_threads_scantype > 0) sem_post(semaphore_scantype); @@ -1036,17 +1049,26 @@ nutscan_device_t * nutscan_scan_ip_range_ipmi(nutscan_ip_range_list_t * irl, nut } pthread_mutex_unlock(&threadcount_mutex); # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ } free(thread_array); upsdebugx(2, "%s: all threads freed", __func__); } pthread_mutex_destroy(&dev_mutex); -# ifdef HAVE_SEMAPHORE - if (max_threads_scantype > 0) +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) + if (max_threads_scantype > 0) { +# if (defined HAVE_SEMAPHORE_UNNAMED) sem_destroy(semaphore_scantype); -# endif /* HAVE_SEMAPHORE */ +# elif (defined HAVE_SEMAPHORE_NAMED) + if (semaphore_scantype) { + sem_unlink(SEMNAME_IPMI); + sem_close(semaphore_scantype); + semaphore_scantype = NULL; + } +# endif + } +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ } /* end of: scan range of 1+ IP address(es), maybe in parallel */ diff --git a/tools/nut-scanner/scan_nut.c b/tools/nut-scanner/scan_nut.c index da11aa53a5..0783cd9511 100644 --- a/tools/nut-scanner/scan_nut.c +++ b/tools/nut-scanner/scan_nut.c @@ -333,23 +333,25 @@ nutscan_device_t * nutscan_scan_ip_range_nut(nutscan_ip_range_list_t * irl, cons struct scan_nut_arg *nut_arg; #ifdef HAVE_PTHREAD -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) sem_t * semaphore = nutscan_semaphore(); +# if (defined HAVE_SEMAPHORE_UNNAMED) sem_t semaphore_scantype_inst; sem_t * semaphore_scantype = &semaphore_scantype_inst; -# endif /* HAVE_SEMAPHORE */ +# elif (defined HAVE_SEMAPHORE_NAMED) + sem_t * semaphore_scantype = NULL; +# endif +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ pthread_t thread; nutscan_thread_t * thread_array = NULL; size_t thread_count = 0, i; -# if (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE) +# if (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) size_t max_threads_scantype = max_threads_oldnut; # endif -#endif /* HAVE_PTHREAD */ -#ifdef HAVE_PTHREAD pthread_mutex_init(&dev_mutex, NULL); -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) if (max_threads_scantype > 0) { #ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE #pragma GCC diagnostic push @@ -370,17 +372,26 @@ nutscan_device_t * nutscan_scan_ip_range_nut(nutscan_ip_range_list_t * irl, cons #pragma GCC diagnostic pop #endif upsdebugx(1, - "WARNING: %s: Limiting max_threads_scantype to range acceptable for sem_init()", + "WARNING: %s: Limiting max_threads_scantype to range acceptable for " REPORT_SEM_INIT_METHOD "()", __func__); max_threads_scantype = UINT_MAX - 1; } - upsdebugx(4, "%s: sem_init() for %" PRIuSIZE " threads", __func__, max_threads_scantype); + upsdebugx(4, "%s: " REPORT_SEM_INIT_METHOD "() for %" PRIuSIZE " threads", __func__, max_threads_scantype); +# if (defined HAVE_SEMAPHORE_UNNAMED) if (sem_init(semaphore_scantype, 0, (unsigned int)max_threads_scantype)) { - upsdebug_with_errno(4, "%s: sem_init() failed", __func__); + upsdebug_with_errno(4, "%s: " REPORT_SEM_INIT_METHOD "() failed", __func__); + max_threads_scantype = 0; + } +# elif (defined HAVE_SEMAPHORE_NAMED) + if (SEM_FAILED == (semaphore_scantype = sem_open(SEMNAME_UPSCLIENT, O_CREAT, 0644, (unsigned int)max_threads_scantype))) { + upsdebug_with_errno(4, "%s: " REPORT_SEM_INIT_METHOD "() failed", __func__); + semaphore_scantype = NULL; + max_threads_scantype = 0; } +# endif } -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ @@ -433,7 +444,7 @@ nutscan_device_t * nutscan_scan_ip_range_nut(nutscan_ip_range_list_t * irl, cons * for below in pthread_join()... */ -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) /* Just wait for someone to free a semaphored slot, * if none are available, and then/otherwise grab one */ @@ -536,7 +547,7 @@ nutscan_device_t * nutscan_scan_ip_range_nut(nutscan_ip_range_list_t * irl, cons /* NOTE: No change to default "pass" in this ifdef: * if we got to this line, we have a slot to use */ # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ if (pass) { @@ -602,7 +613,7 @@ nutscan_device_t * nutscan_scan_ip_range_nut(nutscan_ip_range_list_t * irl, cons ip_str = nutscan_ip_ranges_iter_inc(&ip); } else { /* if not pass -- all slots busy */ #ifdef HAVE_PTHREAD -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) /* Wait for all current scans to complete */ if (thread_array != NULL) { upsdebugx (2, "%s: Running too many scanning threads (%" @@ -639,7 +650,7 @@ nutscan_device_t * nutscan_scan_ip_range_nut(nutscan_ip_range_list_t * irl, cons # ifdef HAVE_PTHREAD_TRYJOIN /* TODO: Move the wait-loop for TRYJOIN here? */ # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ } /* if: could we "pass" or not? */ } /* while */ @@ -658,7 +669,7 @@ nutscan_device_t * nutscan_scan_ip_range_nut(nutscan_ip_range_list_t * irl, cons __func__, ret); } thread_array[i].active = FALSE; -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) sem_post(semaphore); if (max_threads_scantype > 0) sem_post(semaphore_scantype); @@ -675,17 +686,26 @@ nutscan_device_t * nutscan_scan_ip_range_nut(nutscan_ip_range_list_t * irl, cons } pthread_mutex_unlock(&threadcount_mutex); # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ } free(thread_array); upsdebugx(2, "%s: all threads freed", __func__); } pthread_mutex_destroy(&dev_mutex); -# ifdef HAVE_SEMAPHORE - if (max_threads_scantype > 0) +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) + if (max_threads_scantype > 0) { +# if (defined HAVE_SEMAPHORE_UNNAMED) sem_destroy(semaphore_scantype); -# endif /* HAVE_SEMAPHORE */ +# elif (defined HAVE_SEMAPHORE_NAMED) + if (semaphore_scantype) { + sem_unlink(SEMNAME_UPSCLIENT); + sem_close(semaphore_scantype); + semaphore_scantype = NULL; + } +# endif + } +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ #ifndef WIN32 diff --git a/tools/nut-scanner/scan_snmp.c b/tools/nut-scanner/scan_snmp.c index c2f09e7d51..e09c6df93d 100644 --- a/tools/nut-scanner/scan_snmp.c +++ b/tools/nut-scanner/scan_snmp.c @@ -1107,21 +1107,25 @@ nutscan_device_t * nutscan_scan_ip_range_snmp(nutscan_ip_range_list_t * irl, char * ip_str = NULL; #ifdef HAVE_PTHREAD -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) sem_t * semaphore = nutscan_semaphore(); +# if (defined HAVE_SEMAPHORE_UNNAMED) sem_t semaphore_scantype_inst; sem_t * semaphore_scantype = &semaphore_scantype_inst; -# endif /* HAVE_SEMAPHORE */ +# elif (defined HAVE_SEMAPHORE_NAMED) + sem_t * semaphore_scantype = NULL; +# endif +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ pthread_t thread; nutscan_thread_t * thread_array = NULL; size_t thread_count = 0, i; -# if (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE) +# if (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) size_t max_threads_scantype = max_threads_netsnmp; # endif pthread_mutex_init(&dev_mutex, NULL); -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) if (max_threads_scantype > 0) { #ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE #pragma GCC diagnostic push @@ -1142,17 +1146,26 @@ nutscan_device_t * nutscan_scan_ip_range_snmp(nutscan_ip_range_list_t * irl, #pragma GCC diagnostic pop #endif upsdebugx(1, - "WARNING: %s: Limiting max_threads_scantype to range acceptable for sem_init()", + "WARNING: %s: Limiting max_threads_scantype to range acceptable for " REPORT_SEM_INIT_METHOD "()", __func__); max_threads_scantype = UINT_MAX - 1; } - upsdebugx(4, "%s: sem_init() for %" PRIuSIZE " threads", __func__, max_threads_scantype); + upsdebugx(4, "%s: " REPORT_SEM_INIT_METHOD "() for %" PRIuSIZE " threads", __func__, max_threads_scantype); +# if (defined HAVE_SEMAPHORE_UNNAMED) if (sem_init(semaphore_scantype, 0, (unsigned int)max_threads_scantype)) { - upsdebug_with_errno(4, "%s: sem_init() failed", __func__); + upsdebug_with_errno(4, "%s: " REPORT_SEM_INIT_METHOD "() failed", __func__); + max_threads_scantype = 0; } +# elif (defined HAVE_SEMAPHORE_NAMED) + if (SEM_FAILED == (semaphore_scantype = sem_open(SEMNAME_SNMP, O_CREAT, 0644, (unsigned int)max_threads_scantype))) { + upsdebug_with_errno(4, "%s: " REPORT_SEM_INIT_METHOD "() failed", __func__); + semaphore_scantype = NULL; + max_threads_scantype = 0; + } +# endif } -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ @@ -1199,7 +1212,7 @@ nutscan_device_t * nutscan_scan_ip_range_snmp(nutscan_ip_range_list_t * irl, * for below in pthread_join()... */ -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) /* Just wait for someone to free a semaphored slot, * if none are available, and then/otherwise grab one */ @@ -1302,7 +1315,7 @@ nutscan_device_t * nutscan_scan_ip_range_snmp(nutscan_ip_range_list_t * irl, /* NOTE: No change to default "pass" in this ifdef: * if we got to this line, we have a slot to use */ # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ if (pass) { @@ -1353,7 +1366,7 @@ nutscan_device_t * nutscan_scan_ip_range_snmp(nutscan_ip_range_list_t * irl, ip_str = nutscan_ip_ranges_iter_inc(&ip); } else { /* if not pass -- all slots busy */ #ifdef HAVE_PTHREAD -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) /* Wait for all current scans to complete */ if (thread_array != NULL) { upsdebugx (2, "%s: Running too many scanning threads (%" @@ -1390,7 +1403,7 @@ nutscan_device_t * nutscan_scan_ip_range_snmp(nutscan_ip_range_list_t * irl, # ifdef HAVE_PTHREAD_TRYJOIN /* TODO: Move the wait-loop for TRYJOIN here? */ # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ } /* if: could we "pass" or not? */ } /* while */ @@ -1409,7 +1422,7 @@ nutscan_device_t * nutscan_scan_ip_range_snmp(nutscan_ip_range_list_t * irl, __func__, ret); } thread_array[i].active = FALSE; -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) sem_post(semaphore); if (max_threads_scantype > 0) sem_post(semaphore_scantype); @@ -1426,17 +1439,26 @@ nutscan_device_t * nutscan_scan_ip_range_snmp(nutscan_ip_range_list_t * irl, } pthread_mutex_unlock(&threadcount_mutex); # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ } free(thread_array); upsdebugx(2, "%s: all threads freed", __func__); } pthread_mutex_destroy(&dev_mutex); -# ifdef HAVE_SEMAPHORE - if (max_threads_scantype > 0) +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) + if (max_threads_scantype > 0) { +# if (defined HAVE_SEMAPHORE_UNNAMED) sem_destroy(semaphore_scantype); -# endif /* HAVE_SEMAPHORE */ +# elif (defined HAVE_SEMAPHORE_NAMED) + if (semaphore_scantype) { + sem_unlink(SEMNAME_SNMP); + sem_close(semaphore_scantype); + semaphore_scantype = NULL; + } +# endif + } +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ result = nutscan_rewind_device(dev_ret); diff --git a/tools/nut-scanner/scan_xml_http.c b/tools/nut-scanner/scan_xml_http.c index 9bec46f37b..3a8ad95d9b 100644 --- a/tools/nut-scanner/scan_xml_http.c +++ b/tools/nut-scanner/scan_xml_http.c @@ -505,18 +505,22 @@ nutscan_device_t * nutscan_scan_ip_range_xml_http(nutscan_ip_range_list_t * irl, char * ip_str = NULL; #ifdef HAVE_PTHREAD -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) sem_t * semaphore = nutscan_semaphore(); +# if (defined HAVE_SEMAPHORE_UNNAMED) sem_t semaphore_scantype_inst; sem_t * semaphore_scantype = &semaphore_scantype_inst; -# endif /* HAVE_SEMAPHORE */ +# elif (defined HAVE_SEMAPHORE_NAMED) + sem_t * semaphore_scantype = NULL; +# endif +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ pthread_t thread; nutscan_thread_t * thread_array = NULL; size_t thread_count = 0, i; -# if (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE) +# if (defined HAVE_PTHREAD_TRYJOIN) || (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) size_t max_threads_scantype = max_threads_netxml; # endif -#endif +#endif /* HAVE_PTHREAD */ if (irl->ip_ranges_count == 1 && (irl->ip_ranges->start_ip == irl->ip_ranges->end_ip @@ -532,7 +536,7 @@ nutscan_device_t * nutscan_scan_ip_range_xml_http(nutscan_ip_range_list_t * irl, #ifdef HAVE_PTHREAD pthread_mutex_init(&dev_mutex, NULL); -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) if (max_threads_scantype > 0) { #ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE #pragma GCC diagnostic push @@ -553,17 +557,26 @@ nutscan_device_t * nutscan_scan_ip_range_xml_http(nutscan_ip_range_list_t * irl, #pragma GCC diagnostic pop #endif upsdebugx(1, - "WARNING: %s: Limiting max_threads_scantype to range acceptable for sem_init()", + "WARNING: %s: Limiting max_threads_scantype to range acceptable for " REPORT_SEM_INIT_METHOD "()", __func__); max_threads_scantype = UINT_MAX - 1; } - upsdebugx(4, "%s: sem_init() for %" PRIuSIZE " threads", __func__, max_threads_scantype); + upsdebugx(4, "%s: " REPORT_SEM_INIT_METHOD "() for %" PRIuSIZE " threads", __func__, max_threads_scantype); +# if (defined HAVE_SEMAPHORE_UNNAMED) if (sem_init(semaphore_scantype, 0, (unsigned int)max_threads_scantype)) { - upsdebug_with_errno(4, "%s: sem_init() failed", __func__); + upsdebug_with_errno(4, "%s: " REPORT_SEM_INIT_METHOD "() failed", __func__); + max_threads_scantype = 0; + } +# elif (defined HAVE_SEMAPHORE_NAMED) + if (SEM_FAILED == (semaphore_scantype = sem_open(SEMNAME_NETXML, O_CREAT, 0644, (unsigned int)max_threads_scantype))) { + upsdebug_with_errno(4, "%s: " REPORT_SEM_INIT_METHOD "() failed", __func__); + semaphore_scantype = NULL; + max_threads_scantype = 0; } +# endif } -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ @@ -578,7 +591,7 @@ nutscan_device_t * nutscan_scan_ip_range_xml_http(nutscan_ip_range_list_t * irl, * for below in pthread_join()... */ -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) /* Just wait for someone to free a semaphored slot, * if none are available, and then/otherwise grab one */ @@ -681,7 +694,7 @@ nutscan_device_t * nutscan_scan_ip_range_xml_http(nutscan_ip_range_list_t * irl, /* NOTE: No change to default "pass" in this ifdef: * if we got to this line, we have a slot to use */ # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ if (pass) { @@ -722,9 +735,9 @@ nutscan_device_t * nutscan_scan_ip_range_xml_http(nutscan_ip_range_list_t * irl, pthread_mutex_unlock(&threadcount_mutex); # endif /* HAVE_PTHREAD_TRYJOIN */ } -#else /* if not HAVE_PTHREAD */ +#else /* if not HAVE_PTHREAD */ nutscan_scan_xml_http_thready(tmp_sec); -#endif /* if HAVE_PTHREAD */ +#endif /* if HAVE_PTHREAD */ /* Prepare the next iteration; note that * nutscan_scan_xml_http_thready() @@ -735,7 +748,7 @@ nutscan_device_t * nutscan_scan_ip_range_xml_http(nutscan_ip_range_list_t * irl, ip_str = nutscan_ip_ranges_iter_inc(&ip); } else { /* if not pass -- all slots busy */ #ifdef HAVE_PTHREAD -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) /* Wait for all current scans to complete */ if (thread_array != NULL) { upsdebugx (2, "%s: Running too many scanning threads (%" @@ -772,7 +785,7 @@ nutscan_device_t * nutscan_scan_ip_range_xml_http(nutscan_ip_range_list_t * irl, # ifdef HAVE_PTHREAD_TRYJOIN /* TODO: Move the wait-loop for TRYJOIN here? */ # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ } /* if: could we "pass" or not? */ } /* while */ @@ -791,7 +804,7 @@ nutscan_device_t * nutscan_scan_ip_range_xml_http(nutscan_ip_range_list_t * irl, __func__, ret); } thread_array[i].active = FALSE; -# ifdef HAVE_SEMAPHORE +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) sem_post(semaphore); if (max_threads_scantype > 0) sem_post(semaphore_scantype); @@ -808,17 +821,26 @@ nutscan_device_t * nutscan_scan_ip_range_xml_http(nutscan_ip_range_list_t * irl, } pthread_mutex_unlock(&threadcount_mutex); # endif /* HAVE_PTHREAD_TRYJOIN */ -# endif /* HAVE_SEMAPHORE */ +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ } free(thread_array); upsdebugx(2, "%s: all threads freed", __func__); } pthread_mutex_destroy(&dev_mutex); -# ifdef HAVE_SEMAPHORE - if (max_threads_scantype > 0) +# if (defined HAVE_SEMAPHORE_UNNAMED) || (defined HAVE_SEMAPHORE_NAMED) + if (max_threads_scantype > 0) { +# if (defined HAVE_SEMAPHORE_UNNAMED) sem_destroy(semaphore_scantype); -# endif /* HAVE_SEMAPHORE */ +# elif (defined HAVE_SEMAPHORE_NAMED) + if (semaphore_scantype) { + sem_unlink(SEMNAME_NETXML); + sem_close(semaphore_scantype); + semaphore_scantype = NULL; + } +# endif + } +# endif /* HAVE_SEMAPHORE_UNNAMED || HAVE_SEMAPHORE_NAMED */ #endif /* HAVE_PTHREAD */ result = nutscan_rewind_device(dev_ret);