1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
|
/*
ex: set tabstop=4 shiftwidth=4 autoindent:
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2024 The Cacti Group |
| |
| 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. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public |
| License along with this library; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| 02110-1301, USA |
| |
+-------------------------------------------------------------------------+
| spine: a backend data gatherer for cacti |
+-------------------------------------------------------------------------+
| This poller would not have been possible without: |
| - Larry Adams (current development and enhancements) |
| - Rivo Nurges (rrd support, mysql poller cache, misc functions) |
| - RTG (core poller code, pthreads, snmp, autoconf examples) |
| - Brady Alleman/Doug Warner (threading ideas, implimentation details) |
+-------------------------------------------------------------------------+
| - Cacti - http://www.cacti.net/ |
+-------------------------------------------------------------------------+
*/
#include "common.h"
#include "spine.h"
/*
* each lock requires a handful of parts: a mutex, an init structure, and an
* init helper function. We are NOT allowed to use these in an array (doesn
* not work with pthreads), so we are stuck setting these up individually.
* This macro defines these helpers in a single step.
*/
#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); \
}
DEFINE_SPINE_LOCK(snmp)
DEFINE_SPINE_LOCK(seteuid)
DEFINE_SPINE_LOCK(ghbn)
DEFINE_SPINE_LOCK(pool)
DEFINE_SPINE_LOCK(syslog)
DEFINE_SPINE_LOCK(php)
DEFINE_SPINE_LOCK(php_proc_0)
DEFINE_SPINE_LOCK(php_proc_1)
DEFINE_SPINE_LOCK(php_proc_2)
DEFINE_SPINE_LOCK(php_proc_3)
DEFINE_SPINE_LOCK(php_proc_4)
DEFINE_SPINE_LOCK(php_proc_5)
DEFINE_SPINE_LOCK(php_proc_6)
DEFINE_SPINE_LOCK(php_proc_7)
DEFINE_SPINE_LOCK(php_proc_8)
DEFINE_SPINE_LOCK(php_proc_9)
DEFINE_SPINE_LOCK(php_proc_10)
DEFINE_SPINE_LOCK(php_proc_11)
DEFINE_SPINE_LOCK(php_proc_12)
DEFINE_SPINE_LOCK(php_proc_13)
DEFINE_SPINE_LOCK(php_proc_14)
DEFINE_SPINE_LOCK(thdet)
DEFINE_SPINE_LOCK(host_time)
void init_mutexes() {
pthread_once((pthread_once_t*) get_attr(LOCK_SNMP_O), init_snmp_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_SETEUID_O), init_seteuid_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_GHBN_O), init_ghbn_lock);
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_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);
pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_3_O), init_php_proc_3_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_4_O), init_php_proc_4_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_5_O), init_php_proc_5_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_6_O), init_php_proc_6_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_7_O), init_php_proc_7_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_8_O), init_php_proc_8_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_9_O), init_php_proc_9_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_10_O), init_php_proc_10_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_11_O), init_php_proc_11_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_12_O), init_php_proc_12_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_13_O), init_php_proc_13_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_PHP_PROC_14_O), init_php_proc_14_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_THDET_O), init_thdet_lock);
pthread_once((pthread_once_t*) get_attr(LOCK_HOST_TIME_O), init_host_time_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";
case LOCK_THDET: return "thdet";
case LOCK_HOST_TIME: return "host_time";
}
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;
case LOCK_THDET: ret_val = &thdet_cond; break;
case LOCK_HOST_TIME: ret_val = &host_time_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_THDET: ret_val = &thdet_lock; break;
case LOCK_HOST_TIME: ret_val = &host_time_lock; break;
}
SPINE_LOG_DEVDBG(("LOCKS: [RET] Returning lock for %s", get_name(lock)));
return ret_val;
}
pthread_once_t* get_attr(int locko) {
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_THDET_O: ret_val = &thdet_lock_o; break;
case LOCK_HOST_TIME_O: ret_val = &host_time_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) {
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;
}
|