Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cacti-spine for openSUSE:Factory checked in at 2021-08-23 10:08:09 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cacti-spine (Old) and /work/SRC/openSUSE:Factory/.cacti-spine.new.1899 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cacti-spine" Mon Aug 23 10:08:09 2021 rev:33 rq:913439 version:1.2.18 Changes: -------- --- /work/SRC/openSUSE:Factory/cacti-spine/cacti-spine.changes 2021-05-06 22:53:13.510601553 +0200 +++ /work/SRC/openSUSE:Factory/.cacti-spine.new.1899/cacti-spine.changes 2021-08-23 10:09:15.520170215 +0200 @@ -1,0 +2,7 @@ +Sat Aug 21 07:56:34 UTC 2021 - Andreas Stieger <[email protected]> + +- cacti-spine 1.2.18: + * Fix missing time parameter on FROM_UNIXTIME function +- add cacti-spine-1.2.18-Fix-non-void-return.patch to fix the same + +------------------------------------------------------------------- Old: ---- cacti-spine-1.2.17.tar.gz New: ---- cacti-spine-1.2.18-Fix-non-void-return.patch cacti-spine-1.2.18.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cacti-spine.spec ++++++ --- /var/tmp/diff_new_pack.m63dEX/_old 2021-08-23 10:09:16.120169515 +0200 +++ /var/tmp/diff_new_pack.m63dEX/_new 2021-08-23 10:09:16.120169515 +0200 @@ -18,12 +18,13 @@ %{!?make_build: %define make_build make %{?_smp_mflags}} Name: cacti-spine -Version: 1.2.17 +Version: 1.2.18 Release: 0 Summary: Threaded poller for Cacti written in C License: LGPL-2.1-or-later URL: https://www.cacti.net/spine_info.php Source: https://www.cacti.net/downloads/spine/%{name}-%{version}.tar.gz +Patch0: cacti-spine-1.2.18-Fix-non-void-return.patch BuildRequires: help2man BuildRequires: libtool BuildRequires: mysql-devel @@ -38,6 +39,7 @@ %prep %setup -q +%patch0 -p1 %build ./bootstrap ++++++ cacti-spine-1.2.18-Fix-non-void-return.patch ++++++ >From 61193457bd0d3f5fc23180e10fd6a7141392c1d6 Mon Sep 17 00:00:00 2001 From: Andreas Stieger <[email protected]> Date: Sat, 21 Aug 2021 09:50:34 +0200 Subject: [PATCH] Fix non-void return warnings --- locks.c | 5 +++++ 1 file changed, 5 insertions(+) Index: cacti-spine-1.2.18/locks.c =================================================================== --- cacti-spine-1.2.18.orig/locks.c +++ cacti-spine-1.2.18/locks.c @@ -235,4 +235,5 @@ int thread_mutex_trylock(int mutex) { SPINE_LOG_DEVDBG(( "LOCKS: [START] Mutex try lock for %s", get_name(mutex) )); int ret_val = pthread_mutex_trylock(get_lock(mutex)); SPINE_LOG_DEVDBG(( "LOCKS: [ END ] Mutex try lock for %s, result = %d", get_name(mutex), ret_val )); + return ret_val; } ++++++ cacti-spine-1.2.17.tar.gz -> cacti-spine-1.2.18.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.17/CHANGELOG new/cacti-spine-1.2.18/CHANGELOG --- old/cacti-spine-1.2.17/CHANGELOG 2021-05-03 18:08:09.000000000 +0200 +++ new/cacti-spine-1.2.18/CHANGELOG 2021-07-04 23:30:26.000000000 +0200 @@ -1,5 +1,8 @@ The Cacti Group | spine +1.2.18 +-issue#207: Missing time parameter on FROM_UNIXTIME function + 1.2.17 -issue#178: When building spine, errors with Percona libraries may appear by tersmitten -issue#184: When building spine, make process can report problems with backtrace @@ -15,6 +18,7 @@ -issue#203: Backtracing support checks do not work -issue#204: MySQL Retry Count capability check always fails -feature: Make spine immune to DST changes +-feature#181: Parse hostnames from tcp[6]:hostname:port [not fully implemented] -feature#188: On large systems, more concurrent script servers are needed 1.2.16 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.17/configure.ac new/cacti-spine-1.2.18/configure.ac --- old/cacti-spine-1.2.17/configure.ac 2021-05-03 18:08:09.000000000 +0200 +++ new/cacti-spine-1.2.18/configure.ac 2021-07-04 23:30:26.000000000 +0200 @@ -1,5 +1,5 @@ AC_PREREQ(2.53) -AC_INIT(Spine Poller, 1.2.17, http://www.cacti.net/issues.php) +AC_INIT(Spine Poller, 1.2.18, http://www.cacti.net/issues.php) AC_CONFIG_AUX_DIR(config) AC_SUBST(ac_aux_dir) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.17/debug new/cacti-spine-1.2.18/debug --- old/cacti-spine-1.2.17/debug 1970-01-01 01:00:00.000000000 +0100 +++ new/cacti-spine-1.2.18/debug 2021-07-04 23:30:26.000000000 +0200 @@ -0,0 +1,12 @@ +if [[ -z $SPINE_CONFIG ]]; then + export SPINE_CONFIG="/etc/spine.conf"; +fi +make +if [[ $? -eq 0 ]]; then + echo + echo ------ + echo Debugging using SPINE_CONFIG = $SPINE_CONFIG + echo + echo + gdb -quiet -ex run --args ./spine -R -V 5 -C $SPINE_CONFIG +fi \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.17/locks.c new/cacti-spine-1.2.18/locks.c --- old/cacti-spine-1.2.17/locks.c 2021-05-03 18:08:09.000000000 +0200 +++ new/cacti-spine-1.2.18/locks.c 2021-07-04 23:30:26.000000000 +0200 @@ -44,6 +44,7 @@ #define DEFINE_SPINE_LOCK(name) \ static pthread_mutex_t name ## _lock; \ static pthread_once_t name ## _lock_o = PTHREAD_ONCE_INIT; \ + static pthread_cond_t name ## _cond = PTHREAD_COND_INITIALIZER; \ static void init_ ## name ## _lock(void) { \ pthread_mutex_init(&name ## _lock, PTHREAD_MUTEXATTR_DEFAULT); \ } @@ -54,7 +55,6 @@ DEFINE_SPINE_LOCK(pool) DEFINE_SPINE_LOCK(syslog) DEFINE_SPINE_LOCK(php) -DEFINE_SPINE_LOCK(pend) DEFINE_SPINE_LOCK(php_proc_0) DEFINE_SPINE_LOCK(php_proc_1) DEFINE_SPINE_LOCK(php_proc_2) @@ -78,7 +78,6 @@ pthread_once((pthread_once_t*) get_attr(LOCK_POOL_O), init_pool_lock); pthread_once((pthread_once_t*) get_attr(LOCK_SYSLOG_O), init_syslog_lock); pthread_once((pthread_once_t*) get_attr(LOCK_PHP_O), init_php_lock); - pthread_once((pthread_once_t*) get_attr(LOCK_PEND_O), init_pend_lock); pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_0_O), init_php_proc_0_lock); pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_1_O), init_php_proc_1_lock); pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_2_O), init_php_proc_2_lock); @@ -96,34 +95,95 @@ pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_14_O), init_php_proc_14_lock); } +const char* get_name(int lock) { + switch (lock) { + case LOCK_SNMP: return "snmp"; + case LOCK_SETEUID: return "seteuid"; + case LOCK_GHBN: return "ghbn"; + case LOCK_POOL: return "pool"; + case LOCK_SYSLOG: return "syslog"; + case LOCK_PHP: return "php"; + case LOCK_PHP_PROC_0: return "php_proc_0"; + case LOCK_PHP_PROC_1: return "php_proc_1"; + case LOCK_PHP_PROC_2: return "php_proc_2"; + case LOCK_PHP_PROC_3: return "php_proc_3"; + case LOCK_PHP_PROC_4: return "php_proc_4"; + case LOCK_PHP_PROC_5: return "php_proc_5"; + case LOCK_PHP_PROC_6: return "php_proc_6"; + case LOCK_PHP_PROC_7: return "php_proc_7"; + case LOCK_PHP_PROC_8: return "php_proc_8"; + case LOCK_PHP_PROC_9: return "php_proc_9"; + case LOCK_PHP_PROC_10: return "php_proc_10"; + case LOCK_PHP_PROC_11: return "php_proc_11"; + case LOCK_PHP_PROC_12: return "php_proc_12"; + case LOCK_PHP_PROC_13: return "php_proc_13"; + case LOCK_PHP_PROC_14: return "php_proc_14"; + } + + return "Unknown lock"; +} + +pthread_cond_t* get_cond(int lock) { + pthread_cond_t *ret_val = NULL; + + switch (lock) { + case LOCK_SNMP: ret_val = &snmp_cond; break; + case LOCK_SETEUID: ret_val = &seteuid_cond; break; + case LOCK_GHBN: ret_val = &ghbn_cond; break; + case LOCK_POOL: ret_val = &pool_cond; break; + case LOCK_SYSLOG: ret_val = &syslog_cond; break; + case LOCK_PHP: ret_val = &php_cond; break; + case LOCK_PHP_PROC_0: ret_val = &php_proc_0_cond; break; + case LOCK_PHP_PROC_1: ret_val = &php_proc_1_cond; break; + case LOCK_PHP_PROC_2: ret_val = &php_proc_2_cond; break; + case LOCK_PHP_PROC_3: ret_val = &php_proc_3_cond; break; + case LOCK_PHP_PROC_4: ret_val = &php_proc_4_cond; break; + case LOCK_PHP_PROC_5: ret_val = &php_proc_5_cond; break; + case LOCK_PHP_PROC_6: ret_val = &php_proc_6_cond; break; + case LOCK_PHP_PROC_7: ret_val = &php_proc_7_cond; break; + case LOCK_PHP_PROC_8: ret_val = &php_proc_8_cond; break; + case LOCK_PHP_PROC_9: ret_val = &php_proc_9_cond; break; + case LOCK_PHP_PROC_10: ret_val = &php_proc_10_cond; break; + case LOCK_PHP_PROC_11: ret_val = &php_proc_11_cond; break; + case LOCK_PHP_PROC_12: ret_val = &php_proc_12_cond; break; + case LOCK_PHP_PROC_13: ret_val = &php_proc_13_cond; break; + case LOCK_PHP_PROC_14: ret_val = &php_proc_14_cond; break; + } + + SPINE_LOG_DEVDBG(( "LOCKS: [ RET ] Returning cond for %s", get_name(lock) )); + + return ret_val; +} + pthread_mutex_t* get_lock(int lock) { pthread_mutex_t *ret_val = NULL; switch (lock) { - case LOCK_SNMP: ret_val = &snmp_lock; break; - case LOCK_SETEUID: ret_val = &seteuid_lock; break; - case LOCK_GHBN: ret_val = &ghbn_lock; break; - case LOCK_POOL: ret_val = &pool_lock; break; - case LOCK_SYSLOG: ret_val = &syslog_lock; break; - case LOCK_PHP: ret_val = &php_lock; break; - case LOCK_PHP_PROC_0: ret_val = &php_proc_0_lock; break; - case LOCK_PHP_PROC_1: ret_val = &php_proc_1_lock; break; - case LOCK_PHP_PROC_2: ret_val = &php_proc_2_lock; break; - case LOCK_PHP_PROC_3: ret_val = &php_proc_3_lock; break; - case LOCK_PHP_PROC_4: ret_val = &php_proc_4_lock; break; - case LOCK_PHP_PROC_5: ret_val = &php_proc_5_lock; break; - case LOCK_PHP_PROC_6: ret_val = &php_proc_6_lock; break; - case LOCK_PHP_PROC_7: ret_val = &php_proc_7_lock; break; - case LOCK_PHP_PROC_8: ret_val = &php_proc_8_lock; break; - case LOCK_PHP_PROC_9: ret_val = &php_proc_9_lock; break; - case LOCK_PHP_PROC_10: ret_val = &php_proc_10_lock; break; - case LOCK_PHP_PROC_11: ret_val = &php_proc_11_lock; break; - case LOCK_PHP_PROC_12: ret_val = &php_proc_12_lock; break; - case LOCK_PHP_PROC_13: ret_val = &php_proc_13_lock; break; - case LOCK_PHP_PROC_14: ret_val = &php_proc_14_lock; break; - case LOCK_PEND: ret_val = &pend_lock; break; + case LOCK_SNMP: ret_val = &snmp_lock; break; + case LOCK_SETEUID: ret_val = &seteuid_lock; break; + case LOCK_GHBN: ret_val = &ghbn_lock; break; + case LOCK_POOL: ret_val = &pool_lock; break; + case LOCK_SYSLOG: ret_val = &syslog_lock; break; + case LOCK_PHP: ret_val = &php_lock; break; + case LOCK_PHP_PROC_0: ret_val = &php_proc_0_lock; break; + case LOCK_PHP_PROC_1: ret_val = &php_proc_1_lock; break; + case LOCK_PHP_PROC_2: ret_val = &php_proc_2_lock; break; + case LOCK_PHP_PROC_3: ret_val = &php_proc_3_lock; break; + case LOCK_PHP_PROC_4: ret_val = &php_proc_4_lock; break; + case LOCK_PHP_PROC_5: ret_val = &php_proc_5_lock; break; + case LOCK_PHP_PROC_6: ret_val = &php_proc_6_lock; break; + case LOCK_PHP_PROC_7: ret_val = &php_proc_7_lock; break; + case LOCK_PHP_PROC_8: ret_val = &php_proc_8_lock; break; + case LOCK_PHP_PROC_9: ret_val = &php_proc_9_lock; break; + case LOCK_PHP_PROC_10: ret_val = &php_proc_10_lock; break; + case LOCK_PHP_PROC_11: ret_val = &php_proc_11_lock; break; + case LOCK_PHP_PROC_12: ret_val = &php_proc_12_lock; break; + case LOCK_PHP_PROC_13: ret_val = &php_proc_13_lock; break; + case LOCK_PHP_PROC_14: ret_val = &php_proc_14_lock; break; } + SPINE_LOG_DEVDBG(( "LOCKS: [ RET ] Returning lock for %s", get_name(lock) )); + return ret_val; } @@ -131,42 +191,48 @@ pthread_once_t *ret_val = NULL; switch (locko) { - case LOCK_SNMP_O: ret_val = &snmp_lock_o; break; - case LOCK_SETEUID_O: ret_val = &seteuid_lock_o; break; - case LOCK_GHBN_O: ret_val = &ghbn_lock_o; break; - case LOCK_POOL_O: ret_val = &pool_lock_o; break; - case LOCK_SYSLOG_O: ret_val = &syslog_lock_o; break; - case LOCK_PHP_O: ret_val = &php_lock_o; break; - case LOCK_PHP_PROC_0_O: ret_val = &php_proc_0_lock_o; break; - case LOCK_PHP_PROC_1_O: ret_val = &php_proc_1_lock_o; break; - case LOCK_PHP_PROC_2_O: ret_val = &php_proc_2_lock_o; break; - case LOCK_PHP_PROC_3_O: ret_val = &php_proc_3_lock_o; break; - case LOCK_PHP_PROC_4_O: ret_val = &php_proc_4_lock_o; break; - case LOCK_PHP_PROC_5_O: ret_val = &php_proc_5_lock_o; break; - case LOCK_PHP_PROC_6_O: ret_val = &php_proc_6_lock_o; break; - case LOCK_PHP_PROC_7_O: ret_val = &php_proc_7_lock_o; break; - case LOCK_PHP_PROC_8_O: ret_val = &php_proc_8_lock_o; break; - case LOCK_PHP_PROC_9_O: ret_val = &php_proc_9_lock_o; break; - case LOCK_PHP_PROC_10_O: ret_val = &php_proc_10_lock_o; break; - case LOCK_PHP_PROC_11_O: ret_val = &php_proc_11_lock_o; break; - case LOCK_PHP_PROC_12_O: ret_val = &php_proc_12_lock_o; break; - case LOCK_PHP_PROC_13_O: ret_val = &php_proc_13_lock_o; break; - case LOCK_PHP_PROC_14_O: ret_val = &php_proc_14_lock_o; break; - case LOCK_PEND_O: ret_val = &pend_lock_o; break; + case LOCK_SNMP_O: ret_val = &snmp_lock_o; break; + case LOCK_SETEUID_O: ret_val = &seteuid_lock_o; break; + case LOCK_GHBN_O: ret_val = &ghbn_lock_o; break; + case LOCK_POOL_O: ret_val = &pool_lock_o; break; + case LOCK_SYSLOG_O: ret_val = &syslog_lock_o; break; + case LOCK_PHP_O: ret_val = &php_lock_o; break; + case LOCK_PHP_PROC_0_O: ret_val = &php_proc_0_lock_o; break; + case LOCK_PHP_PROC_1_O: ret_val = &php_proc_1_lock_o; break; + case LOCK_PHP_PROC_2_O: ret_val = &php_proc_2_lock_o; break; + case LOCK_PHP_PROC_3_O: ret_val = &php_proc_3_lock_o; break; + case LOCK_PHP_PROC_4_O: ret_val = &php_proc_4_lock_o; break; + case LOCK_PHP_PROC_5_O: ret_val = &php_proc_5_lock_o; break; + case LOCK_PHP_PROC_6_O: ret_val = &php_proc_6_lock_o; break; + case LOCK_PHP_PROC_7_O: ret_val = &php_proc_7_lock_o; break; + case LOCK_PHP_PROC_8_O: ret_val = &php_proc_8_lock_o; break; + case LOCK_PHP_PROC_9_O: ret_val = &php_proc_9_lock_o; break; + case LOCK_PHP_PROC_10_O: ret_val = &php_proc_10_lock_o; break; + case LOCK_PHP_PROC_11_O: ret_val = &php_proc_11_lock_o; break; + case LOCK_PHP_PROC_12_O: ret_val = &php_proc_12_lock_o; break; + case LOCK_PHP_PROC_13_O: ret_val = &php_proc_13_lock_o; break; + case LOCK_PHP_PROC_14_O: ret_val = &php_proc_14_lock_o; break; } + SPINE_LOG_DEVDBG(( "LOCKS: [ RET ] Returning attr for %s", get_name(locko) )); + return ret_val; } void thread_mutex_lock(int mutex) { + SPINE_LOG_DEVDBG(( "LOCKS: [START] Mutex lock for %s", get_name(mutex) )); pthread_mutex_lock(get_lock(mutex)); + SPINE_LOG_DEVDBG(( "LOCKS: [ END ] Mutex lock for %s", get_name(mutex) )); } void thread_mutex_unlock(int mutex) { + SPINE_LOG_DEVDBG(( "LOCKS: [START] Mutex unlock for %s", get_name(mutex) )); pthread_mutex_unlock(get_lock(mutex)); + SPINE_LOG_DEVDBG(( "LOCKS: [ END ] Mutex unlock for %s", get_name(mutex) )); } int thread_mutex_trylock(int mutex) { - return pthread_mutex_trylock(get_lock(mutex)); + SPINE_LOG_DEVDBG(( "LOCKS: [START] Mutex try lock for %s", get_name(mutex) )); + int ret_val = pthread_mutex_trylock(get_lock(mutex)); + SPINE_LOG_DEVDBG(( "LOCKS: [ END ] Mutex try lock for %s, result = %d", get_name(mutex), ret_val )); } - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.17/locks.h new/cacti-spine-1.2.18/locks.h --- old/cacti-spine-1.2.17/locks.h 2021-05-03 18:08:09.000000000 +0200 +++ new/cacti-spine-1.2.18/locks.h 2021-07-04 23:30:26.000000000 +0200 @@ -35,5 +35,6 @@ extern void thread_mutex_lock(int mutex); extern void thread_mutex_unlock(int mutex); extern int thread_mutex_trylock(int mutex); +extern pthread_cond_t* get_cond(int lock); extern pthread_mutex_t* get_lock(int lock); extern pthread_once_t* get_attr(int locko); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.17/ping.c new/cacti-spine-1.2.18/ping.c --- old/cacti-spine-1.2.17/ping.c 2021-05-03 18:08:09.000000000 +0200 +++ new/cacti-spine-1.2.18/ping.c 2021-07-04 23:30:26.000000000 +0200 @@ -284,8 +284,11 @@ SPINE_LOG_DEBUG(("Device[%i] DEBUG: Entering ICMP Ping", host->id)); } - /* remove "tcp:" from hostname */ - new_hostname = remove_tcp_udp_from_hostname(host->hostname); + if (!(new_hostname = (char *) malloc(strlen(host->hostname)+1))) { + die("ERROR: Fatal malloc error: ping.c ping_icmp() - new_hostname!"); + } + + strcpy(host->hostname, new_hostname); /* get ICMP socket */ retry_count = 0; @@ -590,8 +593,11 @@ begin_time = get_time_as_double(); - /* remove "udp:" from hostname */ - new_hostname = remove_tcp_udp_from_hostname(host->hostname); + if (!(new_hostname = (char *) malloc(strlen(host->hostname)+1))) { + die("ERROR: Fatal malloc error: ping.c ping_icmp() - new_hostname!"); + } + + strcpy(host->hostname, new_hostname); /* convert the host timeout to a double precision number in seconds */ host_timeout = host->ping_timeout; @@ -757,8 +763,11 @@ SPINE_LOG_DEBUG(("Device[%i] DEBUG: Entering TCP Ping", host->id)); } - /* remove "tcp:" from hostname */ - new_hostname = remove_tcp_udp_from_hostname(host->hostname); + if (!(new_hostname = (char *) malloc(strlen(host->hostname)+1))) { + die("ERROR: Fatal malloc error: ping.c ping_icmp() - new_hostname!"); + } + + strcpy(host->hostname, new_hostname); /* convert the host timeout to a double precision number in seconds */ host_timeout = host->ping_timeout; @@ -992,32 +1001,96 @@ } } -/*! \fn char *remove_tcp_udp_from_hostname(char *hostname) - * \brief removes 'TCP[6]:' or 'UDP[6]:' from a hostname required to ping +/*! \fn name_t *get_namebyhost(char *hostname, name_t *name) + * \brief splits the hostname into method, name and port * - * \return char hostname a trimmed hostname + * \return name_t containing a trimmed hostname, port, and optional method * */ -char *remove_tcp_udp_from_hostname(char *hostname) { - char *cleaned_hostname; +name_t *get_namebyhost(char *hostname, name_t *name) { + if (name == NULL) { + SPINE_LOG_DEBUG(("get_namebyhost(%s) - Allocating name_t", hostname)); + if (!(name = (name_t *) malloc(sizeof(name_t)))) { + die("ERROR: Fatal malloc error: ping.c get_namebyhost->name"); + } + memset(name, '\0', sizeof(name_t)); + } + + int tokens = 0; + char *stack = NULL; + char *token = NULL; + + if (!(stack = (char *) malloc(strlen(hostname)+1))) { + die("ERROR: Fatal malloc error: ping.c get_namebyhost->stack"); + } + memset(stack, '\0', strlen(hostname)+1); + strncpy(stack, hostname, strlen(hostname)); + token = strtok(stack, ":"); + + if (token == NULL) { + SPINE_LOG_DEBUG(("get_namebyhost(%s) - No delimiter, assume full hostname", hostname)); + } + + while (token != NULL && tokens <= 3) { + tokens++; + SPINE_LOG_DEBUG(("get_namebyhost(%s) - Token #%i", hostname, tokens)); + if (tokens == 1) { + if (strlen(token) == 3) { + if (strncasecmp(token, "TCP", 3)) { + SPINE_LOG_DEBUG(("get_namebyhost(%s) - Have TCPv4 method", hostname)); + name->method = 1; + } else if (strncasecmp(hostname, "UDP", 3)) { + SPINE_LOG_DEBUG(("get_namebyhost(%s) - Have UDPv4 method", hostname)); + name->method = 2; + } else { + SPINE_LOG_DEBUG(("get_namebyhost(%s) - No matching method for 3 chars: %s", hostname, token)); + // assume we have had a method + tokens++; + } + } else if (strlen(token) == 4) { + if (strncasecmp(token, "TCP6", 3)) { + SPINE_LOG_DEBUG(("get_namebyhost(%s) - Have TCPv6 method", hostname)); + name->method = 3; + } else if (strncasecmp(hostname, "UDP6", 3)) { + SPINE_LOG_DEBUG(("get_namebyhost(%s) - Have UDPv6 method", hostname)); + name->method = 4; + } else { + SPINE_LOG_DEBUG(("get_namebyhost(%s) - No matching method for 4 chars: %s", hostname, token)); - if (!(cleaned_hostname = (char *) malloc(strlen(hostname)+1))) { - die("ERROR: Fatal malloc error: ping.c remove_tcp_udp_from_hostname"); + // assume we have had a method + tokens++; + } + } else { + SPINE_LOG_DEBUG(("get_hostbyname(%s) - No matching method for %li chars: %s", hostname, strlen(token), token)); + + // assume we have had a method + tokens++; + } + } + + if (tokens == 2) { + SPINE_LOG_DEBUG(("get_namebyhost(%s) - Setting hostname: %s", hostname, token)); + strncpy(name->hostname, token, sizeof(name->hostname)); + name->hostname[strlen(token)] = '\0'; + } + + if (tokens == 3 && strlen(token)) { + SPINE_LOG_DEBUG(("get_namebyhost(%s) - Setting port: %s", hostname, token)); + name->port = atoi(token); + } + + if (tokens > 3) { + SPINE_LOG_DEBUG(("get_namebyhost(%s) - Unexpected token: %i", hostname, tokens)); + } + token = strtok(NULL, ":"); } - if (!strncasecmp(hostname, "TCP:", 4) || - !strncasecmp(hostname, "UDP:", 4)) { - memcpy(cleaned_hostname, hostname+4, strlen(hostname)-4); - cleaned_hostname[strlen(hostname)-4] = '\0'; - } else if (!strncasecmp(hostname, "TCP6:", 5) || - !strncasecmp(hostname, "UDP6:", 5)) { - memcpy(cleaned_hostname, hostname+5, strlen(hostname)-5); - cleaned_hostname[strlen(hostname)-5] = '\0'; - } else { - strcpy(cleaned_hostname, hostname); + if (stack != NULL) { + free(stack); + stack = NULL; } - return(cleaned_hostname); + return name; } /*! \fn unsigned short int get_checksum(void* buf, int len) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.17/ping.h new/cacti-spine-1.2.18/ping.h --- old/cacti-spine-1.2.17/ping.h 2021-05-03 18:08:09.000000000 +0200 +++ new/cacti-spine-1.2.18/ping.h 2021-07-04 23:30:26.000000000 +0200 @@ -139,7 +139,7 @@ extern int ping_icmp(host_t *host, ping_t *ping); extern int ping_udp(host_t *host, ping_t *ping); extern int ping_tcp(host_t *host, ping_t *ping); -extern char *remove_tcp_udp_from_hostname(char *hostname); +extern name_t *get_namebyhost(char *hostname, name_t *name); extern void update_host_status(int status, host_t *host, ping_t *ping, int availability_method); extern int init_sockaddr(struct sockaddr_in *name, const char *hostname, unsigned short int port); extern int get_address_type(host_t *host); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.17/poller.c new/cacti-spine-1.2.18/poller.c --- old/cacti-spine-1.2.17/poller.c 2021-05-03 18:08:09.000000000 +0200 +++ new/cacti-spine-1.2.18/poller.c 2021-07-04 23:30:26.000000000 +0200 @@ -6,7 +6,7 @@ | This program is free software; you can redistribute it and/or | | modify it under the terms of the GNU Lesser General Public | | License as published by the Free Software Foundation; either | - | version 2.1 of the License, or (at your option) any later version. | + | version 2.1 of the License, or (at your option) any later version. | | | | This program is distributed in the hope that it will be useful, | | but WITHOUT ANY WARRANTY; without even the implied warranty of | @@ -34,7 +34,31 @@ #include "common.h" #include "spine.h" -extern int pending_threads; +void child_cleanup(void *arg) { + poller_thread_t poller_details = *(poller_thread_t*) arg; + + poller_details.complete = TRUE; + SPINE_LOG_DEVDBG(("DEBUG: PT[%ld] The child has cleaned up", pthread_self())); + child_cleanup_thread(arg); +} + +void child_cleanup_thread(void *arg) { + sem_post(&available_threads); + + int a_threads_value; + sem_getvalue(&available_threads, &a_threads_value); + + SPINE_LOG_DEVDBG(("DEBUG: PT[%ld] Available Threads is %i (%i outstanding)", pthread_self(), a_threads_value, set.threads - a_threads_value)); +} + +void child_cleanup_script(void *arg) { + sem_post(&available_scripts); + + int a_scripts_value; + sem_getvalue(&available_scripts, &a_scripts_value); + + SPINE_LOG_DEVDBG(("DEBUG: PT[%ld] Available Scripts is %i (%i outstanding)", pthread_self(), a_scripts_value, MAX_SIMULTANEOUS_SCRIPTS - a_scripts_value)); +} /*! \fn void *child(void *arg) * \brief function is called via the fork command and initiates a poll of a host @@ -46,6 +70,8 @@ * */ void *child(void *arg) { + pthread_cleanup_push(child_cleanup, arg); + int host_id; int host_thread; int last_host_thread; @@ -53,11 +79,11 @@ int host_errors; double host_time_double; char host_time[SMALL_BUFSIZE]; - int a_threads_value; host_errors = 0; poller_thread_t poller_details = *(poller_thread_t*) arg; + host_id = poller_details.host_id; host_thread = poller_details.host_thread; last_host_thread = poller_details.last_host_thread; @@ -76,22 +102,7 @@ poll_host(host_id, host_thread, last_host_thread, host_data_ids, host_time, &host_errors, host_time_double); - sem_post(&active_threads); - - sem_getvalue(&active_threads, &a_threads_value); - - if (is_debug_device(host_id)) { - SPINE_LOG(("DEBUG: The Value of Active Threads is %i for Device ID %i", set.threads - a_threads_value, host_id)); - } else { - SPINE_LOG_DEBUG(("DEBUG: The Value of Active Threads is %i for Device ID %i", set.threads - a_threads_value, host_id)); - } - - thread_mutex_lock(LOCK_PEND); - pending_threads--; - poller_details.complete = TRUE; - - SPINE_LOG_MEDIUM(("Active Threads is %i, Pending is %i", set.threads - a_threads_value, pending_threads)); - thread_mutex_unlock(LOCK_PEND); + pthread_cleanup_pop(1); /* end the thread */ pthread_exit(0); @@ -99,7 +110,7 @@ exit(0); } -/*! \fn void poll_host(int host_id, int host_thread, int last_host_thread, int host_data_ids, char *host_time, int *host_errors, double *host_time_double) +/*! \fn void poll_host(int host_id, int host_thread, int last_host_thread, int host_data_ids, char *host_time, int *host_errors, double host_time_double) * \brief core Spine function that polls a host * \param host_id integer value for the host_id from the hosts table in Cacti * @@ -204,6 +215,7 @@ reindex_t *reindex; host_t *host; ping_t *ping; + name_t *name; target_t *poller_items; snmp_oids_t *snmp_oids; @@ -244,6 +256,13 @@ /* set zeros */ memset(ping, 0, sizeof(ping_t)); + if (!(name = (name_t *) malloc(sizeof(name_t)))) { + die("ERROR: Fatal malloc error: poller.c name struct!"); + } + + /* set zeros */ + memset(name, 0, sizeof(name_t)); + if (!(reindex = (reindex_t *) malloc(sizeof(reindex_t)))) { die("ERROR: Fatal malloc error: poller.c reindex poll!"); } @@ -499,7 +518,11 @@ host->ignore_host = FALSE; if (row[0] != NULL) host->id = atoi(row[0]); - if (row[1] != NULL) STRNCOPY(host->hostname, row[1]); + if (row[1] != NULL) { + name = get_namebyhost(row[1], NULL); + STRNCOPY(host->hostname, name->hostname); + host->ping_port = name->port; + } if (row[2] != NULL) STRNCOPY(host->snmp_community, row[2]); if (row[3] != NULL) host->snmp_version = atoi(row[3]); @@ -1693,9 +1716,12 @@ free(host); free(reindex); free(ping); + free(name); /* update poller_items table for next polling interval */ if (host_thread == last_host_thread) { + SPINE_LOG_MEDIUM(("Device[%i] HT[%i] Updating Poller Items for Next Poll", host_id, host_thread)); + db_query(&mysql, LOCAL, query6); } @@ -1719,9 +1745,7 @@ db_release_connection(REMOTE, remote_cnn->id); } - #ifndef OLD_MYSQL mysql_thread_end(); - #endif if (is_debug_device(host_id)) { SPINE_LOG(("DEBUG: Device[%i] HT[%i] DEBUG: HOST COMPLETE: About to Exit Device Polling Thread Function", host_id, host_thread)); @@ -1935,7 +1959,6 @@ * */ char *exec_poll(host_t *current_host, char *command, int id, char *type) { - extern sem_t active_scripts; int cmd_fd; int pid; int close_fd = TRUE; @@ -1975,125 +1998,155 @@ timeout.tv_usec = 0; /* don't run too many scripts, operating systems do not like that. */ - sem_wait(&active_scripts); - - /* record start time */ - begin_time = get_time_as_double(); - - #ifdef USING_TPOPEN - fd = popen((char *)proc_command, "r"); - cmd_fd = fileno(fd); - if (is_debug_device(current_host->id)) { - SPINE_LOG(("DEBUG: Device[%i] DEBUG: The POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); - } else { - SPINE_LOG_DEBUG(("DEBUG: Device[%i] DEBUG: The POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); + int retries = 0; + int sem_err = 0; + int needs_cleanup = 0; + + pthread_cleanup_push(child_cleanup_script, NULL); + while (++retries < 100) { + sem_err = sem_trywait(&available_scripts); + if (sem_err == 0) { + break; + } else if (sem_err == EAGAIN || sem_err == EWOULDBLOCK) { + if (is_debug_device(current_host->id)) { + SPINE_LOG(("DEBUG: PT[%ld] Device[%i]: Pausing as unable to obtain a script execution lock", pthread_self(), current_host->id)); + } else { + SPINE_LOG_DEVDBG(("DEBUG: PT[%ld] Device[%i]: Pausing as unable to obtain a script execution lock", pthread_self(), current_host->id)); + } + } else { + if (is_debug_device(current_host->id)) { + SPINE_LOG(("DEBUG: PT[%ld] Device[%i]: Pausing as error %d whilst obtaining a script execution lock", pthread_self(), current_host->id, sem_err)); + } else { + SPINE_LOG_DEVDBG(("DEBUG: PT[%ld] Device[%i]: Pausing as error %d whilst obtaining a script execution lock", pthread_self(), current_host->id, sem_err)); + } + } + usleep(10000); } - #else - cmd_fd = nft_popen((char *)proc_command, "r"); - if (is_debug_device(current_host->id)) { - SPINE_LOG(("DEBUG: Device[%i] DEBUG: The NIFTY POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); + + if (sem_err) { + SPINE_LOG(("ERROR: PT[%ld] Device[%i]: Failed to obtain a script execution lock within 10 seconds", pthread_self(), current_host->id)); } else { - SPINE_LOG_DEBUG(("DEBUG: Device[%i] DEBUG: The NIFTY POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); - } - #endif + /* Mark for cleanup */ + needs_cleanup = 1; - if (cmd_fd > 0) { - retry: + /* record start time */ + begin_time = get_time_as_double(); - /* Initialize File Descriptors to Review for Input/Output */ - FD_ZERO(&fds); - FD_SET(cmd_fd, &fds); - - /* wait x seconds for pipe response */ - switch (select(FD_SETSIZE, &fds, NULL, NULL, &timeout)) { - case -1: - switch (errno) { - case EBADF: - SPINE_LOG(("Device[%i] ERROR: One or more of the file descriptor sets specified a file descriptor that is not a valid open file descriptor.", current_host->id)); - SET_UNDEFINED(result_string); - close_fd = FALSE; - break; - case EINTR: - #ifndef SOLAR_THREAD - /* take a moment */ - usleep(2000); - #endif + #ifdef USING_TPOPEN + fd = popen((char *)proc_command, "r"); + cmd_fd = fileno(fd); + if (is_debug_device(current_host->id)) { + SPINE_LOG(("DEBUG: Device[%i] DEBUG: The POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); + } else { + SPINE_LOG_DEBUG(("DEBUG: Device[%i] DEBUG: The POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); + } + #else + cmd_fd = nft_popen((char *)proc_command, "r"); + if (is_debug_device(current_host->id)) { + SPINE_LOG(("DEBUG: Device[%i] DEBUG: The NIFTY POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); + } else { + SPINE_LOG_DEBUG(("DEBUG: Device[%i] DEBUG: The NIFTY POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); + } + #endif - /* record end time */ - end_time = get_time_as_double(); + if (cmd_fd > 0) { + retry: - /* re-establish new timeout value */ - timeout.tv_sec = rint(floor(script_timeout-(end_time-begin_time))); - timeout.tv_usec = rint((script_timeout-(end_time-begin_time)-timeout.tv_sec)*1000000); + /* Initialize File Descriptors to Review for Input/Output */ + FD_ZERO(&fds); + FD_SET(cmd_fd, &fds); + + /* wait x seconds for pipe response */ + switch (select(FD_SETSIZE, &fds, NULL, NULL, &timeout)) { + case -1: + switch (errno) { + case EBADF: + SPINE_LOG(("Device[%i] ERROR: One or more of the file descriptor sets specified a file descriptor that is not a valid open file descriptor.", current_host->id)); + SET_UNDEFINED(result_string); + close_fd = FALSE; + break; + case EINTR: + #ifndef SOLAR_THREAD + /* take a moment */ + usleep(2000); + #endif + + /* record end time */ + end_time = get_time_as_double(); + + /* re-establish new timeout value */ + timeout.tv_sec = rint(floor(script_timeout-(end_time-begin_time))); + timeout.tv_usec = rint((script_timeout-(end_time-begin_time)-timeout.tv_sec)*1000000); - if ((end_time - begin_time) < set.script_timeout) { - goto retry; - } else { - SPINE_LOG(("WARNING: A script timed out while processing EINTR's.")); + if ((end_time - begin_time) < set.script_timeout) { + goto retry; + } else { + SPINE_LOG(("WARNING: A script timed out while processing EINTR's.")); + SET_UNDEFINED(result_string); + close_fd = FALSE; + } + break; + case EINVAL: + SPINE_LOG(("Device[%i] ERROR: Possible invalid timeout specified in select() statement.", current_host->id)); SET_UNDEFINED(result_string); close_fd = FALSE; + break; + default: + SPINE_LOG(("Device[%i] ERROR: The script/command select() failed", current_host->id)); + SET_UNDEFINED(result_string); + close_fd = FALSE; + break; } - break; - case EINVAL: - SPINE_LOG(("Device[%i] ERROR: Possible invalid timeout specified in select() statement.", current_host->id)); - SET_UNDEFINED(result_string); + case 0: + #ifdef USING_TPOPEN + SPINE_LOG_MEDIUM(("Device[%i] ERROR: The POPEN timed out", current_host->id)); + close_fd = FALSE; - break; - default: - SPINE_LOG(("Device[%i] ERROR: The script/command select() failed", current_host->id)); + #else + SPINE_LOG_MEDIUM(("Device[%i] ERROR: The NIFTY POPEN timed out", current_host->id)); + + pid = nft_pchild(cmd_fd); + kill(pid, SIGKILL); + #endif + SET_UNDEFINED(result_string); - close_fd = FALSE; break; + default: + /* get only one line of output, we will ignore the rest */ + bytes_read = read(cmd_fd, result_string, RESULTS_BUFFER-1); + if (bytes_read > 0) { + result_string[bytes_read] = '\0'; + } else { + if (STRIMATCH(type,"DS")) { + SPINE_LOG(("Device[%i] DS[%i] ERROR: Empty result [%s]: '%s'", current_host->id, id, current_host->hostname, command)); + } else { + SPINE_LOG(("Device[%i] DQ[%i] ERROR: Empty result [%s]: '%s'", current_host->id, id, current_host->hostname, command)); + } + SET_UNDEFINED(result_string); + } } - case 0: - #ifdef USING_TPOPEN - SPINE_LOG_MEDIUM(("Device[%i] ERROR: The POPEN timed out", current_host->id)); - close_fd = FALSE; + /* close pipe */ + #ifdef USING_TPOPEN + /* we leave the old fd open if it timed out. It will have to exit on it's own */ + if (close_fd) { + pclose(fd); + } #else - SPINE_LOG_MEDIUM(("Device[%i] ERROR: The NIFTY POPEN timed out", current_host->id)); - - pid = nft_pchild(cmd_fd); - kill(pid, SIGKILL); + nft_pclose(cmd_fd); #endif - + } else { + SPINE_LOG(("Device[%i] ERROR: Problem executing POPEN [%s]: '%s'", current_host->id, current_host->hostname, command)); SET_UNDEFINED(result_string); - break; - default: - /* get only one line of output, we will ignore the rest */ - bytes_read = read(cmd_fd, result_string, RESULTS_BUFFER-1); - if (bytes_read > 0) { - result_string[bytes_read] = '\0'; - } else { - if (STRIMATCH(type,"DS")) { - SPINE_LOG(("Device[%i] DS[%i] ERROR: Empty result [%s]: '%s'", current_host->id, id, current_host->hostname, command)); - } else { - SPINE_LOG(("Device[%i] DQ[%i] ERROR: Empty result [%s]: '%s'", current_host->id, id, current_host->hostname, command)); - } - SET_UNDEFINED(result_string); - } } - /* close pipe */ - #ifdef USING_TPOPEN - /* we leave the old fd open if it timed out. It will have to exit on it's own */ - if (close_fd) { - pclose(fd); - } - #else - nft_pclose(cmd_fd); + #if defined(__CYGWIN__) + free(proc_command); #endif - } else { - SPINE_LOG(("Device[%i] ERROR: Problem executing POPEN [%s]: '%s'", current_host->id, current_host->hostname, command)); - SET_UNDEFINED(result_string); } - #if defined(__CYGWIN__) - free(proc_command); - #endif - /* reduce the active script count */ - sem_post(&active_scripts); + pthread_cleanup_pop(needs_cleanup); return result_string; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.17/poller.h new/cacti-spine-1.2.18/poller.h --- old/cacti-spine-1.2.17/poller.h 2021-05-03 18:08:09.000000000 +0200 +++ new/cacti-spine-1.2.18/poller.h 2021-07-04 23:30:26.000000000 +0200 @@ -32,6 +32,9 @@ */ extern void *child(void *arg); +extern void child_cleanup(void *arg); +extern void child_cleanup_thread(void *arg); +extern void child_cleanup_script(void *arg); extern void poll_host(int host_id, int host_thread, int last_host_thread, int host_data_ids, char *host_time, int *host_errors, double host_time_double); extern char *exec_poll(host_t *current_host, char *command, int id, char *type); extern void get_system_information(host_t *host, MYSQL *mysql, int system); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.17/spine.c new/cacti-spine-1.2.18/spine.c --- old/cacti-spine-1.2.17/spine.c 2021-05-03 18:08:09.000000000 +0200 +++ new/cacti-spine-1.2.18/spine.c 2021-07-04 23:30:26.000000000 +0200 @@ -100,9 +100,8 @@ /* Global Variables */ int entries = 0; int num_hosts = 0; -int pending_threads = 0; -sem_t active_threads; -sem_t active_scripts; +sem_t available_threads; +sem_t available_scripts; double start_time; config_t set; @@ -198,7 +197,7 @@ char querybuf[MEGA_BUFSIZE], *qp = querybuf; char *host_time = NULL; double host_time_double = 0; - int itemsPT = 0; + int items_per_thread = 0; int device_threads; sem_t thread_init_sem; int a_threads_value; @@ -668,11 +667,11 @@ init_mutexes(); - /* initialize active_threads semaphore */ - sem_init(&active_threads, 0, set.threads); + /* initialize available_threads semaphore */ + sem_init(&available_threads, 0, set.threads); - /* initialize active_scripts semaphore */ - sem_init(&active_scripts, 0, MAX_SIMULTANEOUS_SCRIPTS); + /* initialize available_scripts semaphore */ + sem_init(&available_scripts, 0, MAX_SIMULTANEOUS_SCRIPTS); /* initialize thread initialization semaphore */ sem_init(&thread_init_sem, 0, 1); @@ -681,8 +680,8 @@ until_spec.tv_sec = (time_t)(set.poller_interval + begin_time - 0.2); until_spec.tv_nsec = 0; - sem_getvalue(&active_threads, &a_threads_value); - SPINE_LOG_MEDIUM(("DEBUG: Initial Value of Active Threads is %i", set.threads - a_threads_value)); + sem_getvalue(&available_threads, &a_threads_value); + SPINE_LOG_MEDIUM(("DEBUG: Initial Value of Available Threads is %i (%i outstanding)", a_threads_value, set.threads - a_threads_value)); /* tell fork processes that they are now active */ set.parent_fork = SPINE_FORK; @@ -735,18 +734,15 @@ tresult = db_query(&mysql, LOCAL, querybuf); mysql_row = mysql_fetch_row(tresult); - itemsPT = atoi(mysql_row[0]); - db_free_result(tresult); + items_per_thread = atoi(mysql_row[0]); - if (host_time) free(host_time); + db_free_result(tresult); host_time = get_host_poll_time(); host_time_double = get_time_as_double(); } } else { - itemsPT = 0; - - if (host_time) free(host_time); + items_per_thread = 0; host_time = get_host_poll_time(); host_time_double = get_time_as_double(); @@ -760,7 +756,7 @@ poller_details->host_id = host_id; poller_details->host_thread = current_thread; poller_details->last_host_thread = device_threads; - poller_details->host_data_ids = itemsPT; + poller_details->host_data_ids = items_per_thread; poller_details->host_time = host_time; poller_details->host_time_double = host_time_double; poller_details->thread_init_sem = &thread_init_sem; @@ -768,22 +764,63 @@ details[device_counter] = poller_details; - retry1: + /* dev note - errno was never primed at this point in previous version of code */ + int wait_retries = 0; + int sem_err = 0; + + while (++wait_retries < 100) { + sem_err = sem_trywait(&available_threads); - if (sem_timedwait(&active_threads, &until_spec) == -1) { - if (errno == ETIMEDOUT) { - SPINE_LOG(("ERROR: Spine Timed Out While Processing Devices Internal")); - canexit = TRUE; + if (sem_err == 0) { break; - } else if (errno == EINTR) { - usleep(10000); - goto retry1; + } else if (sem_err == EAGAIN || sem_err == EWOULDBLOCK) { + SPINE_LOG_DEVDBG(("WARNING: Spine Timed Out While Processing Available Thread Lock Internal")); + } else { + SPINE_LOG_DEVDBG(("WARNING: Spine Error %ld While Processing Available Thread Lock Internal", sem_err)); } + + usleep(10000); } - /* create child process */ - sem_wait(&thread_init_sem); + if (sem_err == EDEADLK) { + SPINE_LOG(("ERROR: Spine would have deadlocked Available Thread Lock")); + break; + } else if (sem_err == ETIMEDOUT || sem_err == EWOULDBLOCK || wait_retries >= 100) { + SPINE_LOG(("ERROR: Spine Timed Out While Processing Available Thread Lock")); + break; + } else if (sem_err != 0) { + SPINE_LOG(("ERROR: Spine Encounter Unexpected Error %d For Available Thread Lock", sem_err)); + break; + } + + wait_retries = 0; + while (++wait_retries < 100) { + sem_err = sem_trywait(&thread_init_sem); + + if (sem_err == 0) { + break; + } else if (sem_err == EAGAIN || sem_err == EWOULDBLOCK) { + SPINE_LOG_DEVDBG(("WARNING: Spine Timed Out While Processing Thread Initialization Lock")); + } else { + SPINE_LOG_DEVDBG(("WARNING: Spine Error %ld While Processing Thread Initialization Lock", sem_err)); + } + + usleep(10000); + } + + if (sem_err == EDEADLK) { + SPINE_LOG(("ERROR: Spine would have deadlocked Thread Initialization Lock")); + break; + } else if (sem_err == ETIMEDOUT || sem_err == EWOULDBLOCK || wait_retries >= 100) { + SPINE_LOG(("ERROR: Spine Timed Out While Processing Thread Initialization Lock")); + break; + } else if (sem_err != 0) { + SPINE_LOG(("ERROR: Spine Encountered Unexpected Error %d For Thread Initialization Lock", sem_err)); + break; + } + + /* create child process */ thread_status = pthread_create(&threads[device_counter], &attr, child, poller_details); switch (thread_status) { @@ -794,14 +831,9 @@ device_counter++; } - sem_wait(&thread_init_sem); - thread_mutex_lock(LOCK_PEND); - pending_threads++; - - sem_getvalue(&active_threads, &a_threads_value); - SPINE_LOG_MEDIUM(("Active Threads is %i, Pending is %i", set.threads - a_threads_value, pending_threads)); + sem_getvalue(&available_threads, &a_threads_value); + SPINE_LOG_MEDIUM(("DEBUG: Available Threads is %i (%i outstanding)", a_threads_value, set.threads - a_threads_value)); - thread_mutex_unlock(LOCK_PEND); sem_post(&thread_init_sem); SPINE_LOG_DEVDBG(("DEBUG: DTS: device = %d, host_id = %d, host_thread = %d," @@ -823,7 +855,7 @@ case EINVAL: SPINE_LOG(("ERROR: The Thread Attribute is Not Initialized")); break; default: - SPINE_LOG(("ERROR: Unknown Thread Creation Error")); + SPINE_LOG(("ERROR: Unknown Thread Creation Error - %d", thread_status)); break; } @@ -833,28 +865,24 @@ } } + sem_getvalue(&available_threads, &a_threads_value); + /* wait for all threads to 'complete' * using the mutex here as the semaphore will * show zero before the children are done */ - while (TRUE) { - thread_mutex_lock(LOCK_PEND); - + while (a_threads_value < set.threads) { cur_time = get_time_as_double(); - if (pending_threads == 0) { - break; - } else if (cur_time - begin_time > set.poller_interval) { - SPINE_LOG(("ERROR: Spine Timed Out While Waiting for %d Threads to End", pending_threads)); + if (cur_time - begin_time > set.poller_interval) { + SPINE_LOG(("ERROR: Spine Timed Out While Waiting for %d Threads to End", set.threads - a_threads_value)); break; } - thread_mutex_unlock(LOCK_PEND); - - usleep(100000); + SPINE_LOG_HIGH(("WARNING: Spine Sleeping While Waiting for %d Threads to End", set.threads - a_threads_value)); + usleep(500000); + sem_getvalue(&available_threads, &a_threads_value); } - sem_getvalue(&active_threads, &a_threads_value); - threads_final = set.threads - a_threads_value; if (threads_final) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.17/spine.h new/cacti-spine-1.2.18/spine.h --- old/cacti-spine-1.2.17/spine.h 2021-05-03 18:08:09.000000000 +0200 +++ new/cacti-spine-1.2.18/spine.h 2021-07-04 23:30:26.000000000 +0200 @@ -188,7 +188,6 @@ #define LOCK_PHP_PROC_12 19 #define LOCK_PHP_PROC_13 20 #define LOCK_PHP_PROC_14 21 -#define LOCK_PEND 30 #define LOCK_SNMP_O 0 #define LOCK_SETEUID_O 2 @@ -211,7 +210,6 @@ #define LOCK_PHP_PROC_12_O 19 #define LOCK_PHP_PROC_13_O 20 #define LOCK_PHP_PROC_14_O 21 -#define LOCK_PEND_O 30 /* poller actions */ #define POLLER_ACTION_SNMP 0 @@ -577,6 +575,18 @@ char snmp_response[SMALL_BUFSIZE]; } ping_t; +/*! Name Result Structure + * + * This structure holds the results of a name/port split + * + */ +typedef struct name_port { + // Method = 0 - default, 1 - tcp, 2 - udp + int method; + char hostname[SMALL_BUFSIZE]; + int port; +} name_t; + /*! MySQL Connection Pool Structure * * This structure holds the mysql connetion pool object. @@ -604,7 +614,8 @@ extern php_t *php_processes; extern char start_datetime[20]; extern char config_paths[CONFIG_PATHS][BUFSIZE]; -extern sem_t active_threads; +extern sem_t available_threads; +extern sem_t available_scripts; extern pool_t *db_pool_remote; extern pool_t *db_pool_local;
