1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 **/
19
20 #include "common.h"
21
22 #include "db.h"
23 #include "dbcache.h"
24 #include "daemon.h"
25 #include "zbxserver.h"
26 #include "zbxself.h"
27 #include "../events.h"
28
29 #include "poller.h"
30
31 #include "checks_agent.h"
32 #include "checks_aggregate.h"
33 #include "checks_external.h"
34 #include "checks_internal.h"
35 #include "checks_simple.h"
36 #include "checks_snmp.h"
37 #include "checks_ipmi.h"
38 #include "checks_db.h"
39 #ifdef HAVE_SSH2
40 # include "checks_ssh.h"
41 #endif
42 #include "checks_telnet.h"
43 #include "checks_java.h"
44 #include "checks_calculated.h"
45 #include "../../libs/zbxcrypto/tls.h"
46
47 extern unsigned char process_type, program_type;
48 extern int server_num, process_num;
49
update_triggers_status_to_unknown(zbx_uint64_t hostid,zbx_item_type_t type,zbx_timespec_t * ts,char * reason)50 static void update_triggers_status_to_unknown(zbx_uint64_t hostid, zbx_item_type_t type, zbx_timespec_t *ts,
51 char *reason)
52 {
53 const char *__function_name = "update_triggers_status_to_unknown";
54 DB_RESULT result;
55 DB_ROW row;
56 char failed_type_buf[8];
57 char *sql = NULL;
58 size_t sql_alloc = 0, sql_offset = 0;
59 DC_TRIGGER trigger;
60
61 zabbix_log(LOG_LEVEL_DEBUG, "In %s() hostid:" ZBX_FS_UI64, __function_name, hostid);
62
63 /* determine failed item type */
64 switch (type)
65 {
66 case ITEM_TYPE_ZABBIX:
67 zbx_snprintf(failed_type_buf, sizeof(failed_type_buf), "%d", ITEM_TYPE_ZABBIX);
68 break;
69 case ITEM_TYPE_SNMPv1:
70 case ITEM_TYPE_SNMPv2c:
71 case ITEM_TYPE_SNMPv3:
72 zbx_snprintf(failed_type_buf, sizeof(failed_type_buf), "%d,%d,%d",
73 ITEM_TYPE_SNMPv1, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3);
74 break;
75 case ITEM_TYPE_IPMI:
76 zbx_snprintf(failed_type_buf, sizeof(failed_type_buf), "%d", ITEM_TYPE_IPMI);
77 break;
78 case ITEM_TYPE_JMX:
79 zbx_snprintf(failed_type_buf, sizeof(failed_type_buf), "%d", ITEM_TYPE_JMX);
80 break;
81 default:
82 zbx_error("unknown item type: %d", type);
83 THIS_SHOULD_NEVER_HAPPEN;
84 }
85
86 /*************************************************************************
87 * Let's say an item MYITEM returns error. There is a trigger associated *
88 * with it. We set that trigger status to UNKNOWN if ALL are true: *
89 * - MYITEM status is ACTIVE *
90 * - MYITEM state is NORMAL *
91 * - trigger does not reference time-based function *
92 * - trigger status is ENABLED *
93 * - trigger and MYITEM reference the same host *
94 * - trigger host status is MONITORED *
95 * - trigger does NOT reference an item that has ALL true: *
96 * - item status is ACTIVE *
97 * - item host status is MONITORED *
98 * - item trigger references time-based function *
99 * OR *
100 * item and MYITEM types differ AND item host status is AVAILABLE *
101 *************************************************************************/
102 result = DBselect(
103 "select distinct t.triggerid,t.description,t.expression,t.priority,t.type,t.value,t.state,"
104 "t.error,t.lastchange"
105 " from items i,functions f,triggers t,hosts h"
106 " where i.itemid=f.itemid"
107 " and f.triggerid=t.triggerid"
108 " and i.hostid=h.hostid"
109 " and i.status=%d"
110 " and i.state=%d"
111 " and i.type in (%s)"
112 " and f.function not in (" ZBX_SQL_TIME_FUNCTIONS ")"
113 " and t.status=%d"
114 " and t.flags in (%d,%d)"
115 " and h.hostid=" ZBX_FS_UI64
116 " and h.status=%d"
117 " and not exists ("
118 "select 1"
119 " from functions f2,items i2,hosts h2"
120 " where f2.triggerid=f.triggerid"
121 " and f2.itemid=i2.itemid"
122 " and i2.hostid=h2.hostid"
123 " and ("
124 "f2.function in (" ZBX_SQL_TIME_FUNCTIONS ")"
125 " or ("
126 "i2.type not in (%s)"
127 " and ("
128 "i2.type not in (%d,%d,%d,%d,%d,%d)"
129 " or (i2.type in (%d) and h2.available=%d)"
130 " or (i2.type in (%d,%d,%d) and h2.snmp_available=%d)"
131 " or (i2.type in (%d) and h2.ipmi_available=%d)"
132 " or (i2.type in (%d) and h2.jmx_available=%d)"
133 ")"
134 ")"
135 ")"
136 " and i2.status=%d"
137 " and i2.state=%d"
138 " and h2.status=%d"
139 ")"
140 " order by t.triggerid",
141 ITEM_STATUS_ACTIVE,
142 ITEM_STATE_NORMAL,
143 failed_type_buf,
144 TRIGGER_STATUS_ENABLED,
145 ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_CREATED,
146 hostid,
147 HOST_STATUS_MONITORED,
148 failed_type_buf,
149 ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, ITEM_TYPE_IPMI,
150 ITEM_TYPE_JMX,
151 ITEM_TYPE_ZABBIX, HOST_AVAILABLE_TRUE,
152 ITEM_TYPE_SNMPv1, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, HOST_AVAILABLE_TRUE,
153 ITEM_TYPE_IPMI, HOST_AVAILABLE_TRUE,
154 ITEM_TYPE_JMX, HOST_AVAILABLE_TRUE,
155 ITEM_STATUS_ACTIVE,
156 ITEM_STATE_NORMAL,
157 HOST_STATUS_MONITORED);
158
159 while (NULL != (row = DBfetch(result)))
160 {
161 ZBX_STR2UINT64(trigger.triggerid, row[0]);
162 trigger.description = row[1];
163 trigger.expression_orig = row[2];
164 ZBX_STR2UCHAR(trigger.priority, row[3]);
165 ZBX_STR2UCHAR(trigger.type, row[4]);
166 trigger.value = atoi(row[5]);
167 trigger.state = atoi(row[6]);
168 trigger.error = row[7];
169 trigger.lastchange = atoi(row[8]);
170 trigger.new_value = TRIGGER_VALUE_UNKNOWN;
171 trigger.new_error = reason;
172 trigger.timespec = *ts;
173
174 sql_offset = 0;
175
176 if (SUCCEED == process_trigger(&sql, &sql_alloc, &sql_offset, &trigger))
177 {
178 DBbegin();
179 DBexecute("%s", sql);
180 DBcommit();
181 }
182 }
183
184 zbx_free(sql);
185 DBfree_result(result);
186
187 DBbegin();
188 process_events(NULL);
189 DBcommit();
190
191 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
192 }
193
194 /******************************************************************************
195 * *
196 * Function: db_host_update_availability *
197 * *
198 * Purpose: write host availability changes into database *
199 * *
200 * Parameters: ha - [IN] the host availability data *
201 * *
202 * Return value: SUCCEED - the availability changes were written into db *
203 * FAIL - no changes in availability data were detected *
204 * *
205 ******************************************************************************/
db_host_update_availability(const zbx_host_availability_t * ha)206 static int db_host_update_availability(const zbx_host_availability_t *ha)
207 {
208 char *sql = NULL;
209 size_t sql_alloc = 0, sql_offset = 0;
210
211 if (SUCCEED == zbx_sql_add_host_availability(&sql, &sql_alloc, &sql_offset, ha))
212 {
213 DBbegin();
214 DBexecute("%s", sql);
215 DBcommit();
216
217 zbx_free(sql);
218
219 return SUCCEED;
220 }
221
222 return FAIL;
223 }
224
225 /******************************************************************************
226 * *
227 * Function: host_get_availability *
228 * *
229 * Purpose: get host availability data based on the specified item type *
230 * *
231 * Parameters: dc_host - [IN] the host *
232 * type - [IN] the item type *
233 * availability - [OUT] the host availability data *
234 * *
235 * Return value: SUCCEED - the host availability data was retrieved *
236 * successfully *
237 * FAIL - failed to retrieve host availability data, *
238 * unrecognized item type was specified *
239 * *
240 ******************************************************************************/
host_get_availability(const DC_HOST * dc_host,unsigned char agent,zbx_host_availability_t * ha)241 static int host_get_availability(const DC_HOST *dc_host, unsigned char agent, zbx_host_availability_t *ha)
242 {
243 zbx_agent_availability_t *availability = &ha->agents[agent];
244
245 availability->flags = ZBX_FLAGS_AGENT_STATUS;
246
247 switch (agent)
248 {
249 case ZBX_AGENT_ZABBIX:
250 availability->available = dc_host->available;
251 availability->error = zbx_strdup(NULL, dc_host->error);
252 availability->errors_from = dc_host->errors_from;
253 availability->disable_until = dc_host->disable_until;
254 break;
255 case ZBX_AGENT_SNMP:
256 availability->available = dc_host->snmp_available;
257 availability->error = zbx_strdup(NULL, dc_host->snmp_error);
258 availability->errors_from = dc_host->snmp_errors_from;
259 availability->disable_until = dc_host->snmp_disable_until;
260 break;
261 case ZBX_AGENT_IPMI:
262 availability->available = dc_host->ipmi_available;
263 availability->error = zbx_strdup(NULL, dc_host->ipmi_error);
264 availability->errors_from = dc_host->ipmi_errors_from;
265 availability->disable_until = dc_host->ipmi_disable_until;
266 break;
267 case ZBX_AGENT_JMX:
268 availability->available = dc_host->jmx_available;
269 availability->error = zbx_strdup(NULL, dc_host->jmx_error);
270 availability->disable_until = dc_host->jmx_disable_until;
271 availability->errors_from = dc_host->jmx_errors_from;
272 break;
273 default:
274 return FAIL;
275 }
276
277 ha->hostid = dc_host->hostid;
278
279 return SUCCEED;
280 }
281
host_availability_agent_by_item_type(unsigned char type)282 static unsigned char host_availability_agent_by_item_type(unsigned char type)
283 {
284 switch (type)
285 {
286 case ITEM_TYPE_ZABBIX:
287 return ZBX_AGENT_ZABBIX;
288 break;
289 case ITEM_TYPE_SNMPv1:
290 case ITEM_TYPE_SNMPv2c:
291 case ITEM_TYPE_SNMPv3:
292 return ZBX_AGENT_SNMP;
293 break;
294 case ITEM_TYPE_IPMI:
295 return ZBX_AGENT_IPMI;
296 break;
297 case ITEM_TYPE_JMX:
298 return ZBX_AGENT_JMX;
299 break;
300 default:
301 return ZBX_AGENT_UNKNOWN;
302 }
303 }
304
activate_host(DC_ITEM * item,zbx_timespec_t * ts)305 static void activate_host(DC_ITEM *item, zbx_timespec_t *ts)
306 {
307 const char *__function_name = "activate_host";
308 zbx_host_availability_t in, out;
309 unsigned char agent_type;
310
311 zabbix_log(LOG_LEVEL_DEBUG, "In %s() hostid:" ZBX_FS_UI64 " itemid:" ZBX_FS_UI64 " type:%d",
312 __function_name, item->host.hostid, item->itemid, (int)item->type);
313
314 zbx_host_availability_init(&in, item->host.hostid);
315 zbx_host_availability_init(&out,item->host.hostid);
316
317 if (ZBX_AGENT_UNKNOWN == (agent_type = host_availability_agent_by_item_type(item->type)))
318 goto out;
319
320 if (FAIL == host_get_availability(&item->host, agent_type, &in))
321 goto out;
322
323 if (FAIL == DChost_activate(item->host.hostid, agent_type, ts, &in.agents[agent_type], &out.agents[agent_type]))
324 goto out;
325
326 if (FAIL == db_host_update_availability(&out))
327 goto out;
328
329 if (HOST_AVAILABLE_TRUE == in.agents[agent_type].available)
330 {
331 zabbix_log(LOG_LEVEL_WARNING, "resuming %s checks on host \"%s\": connection restored",
332 zbx_agent_type_string(item->type), item->host.host);
333 }
334 else
335 {
336 zabbix_log(LOG_LEVEL_WARNING, "enabling %s checks on host \"%s\": host became available",
337 zbx_agent_type_string(item->type), item->host.host);
338 }
339 out:
340 zbx_host_availability_clean(&out);
341 zbx_host_availability_clean(&in);
342
343 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
344 }
345
deactivate_host(DC_ITEM * item,zbx_timespec_t * ts,const char * error)346 static void deactivate_host(DC_ITEM *item, zbx_timespec_t *ts, const char *error)
347 {
348 const char *__function_name = "deactivate_host";
349 zbx_host_availability_t in, out;
350 unsigned char agent_type;
351
352 zabbix_log(LOG_LEVEL_DEBUG, "In %s() hostid:" ZBX_FS_UI64 " itemid:" ZBX_FS_UI64 " type:%d",
353 __function_name, item->host.hostid, item->itemid, (int)item->type);
354
355 zbx_host_availability_init(&in, item->host.hostid);
356 zbx_host_availability_init(&out,item->host.hostid);
357
358 if (ZBX_AGENT_UNKNOWN == (agent_type = host_availability_agent_by_item_type(item->type)))
359 goto out;
360
361 if (FAIL == host_get_availability(&item->host, agent_type, &in))
362 goto out;
363
364 if (FAIL == DChost_deactivate(item->host.hostid, agent_type, ts, &in.agents[agent_type],
365 &out.agents[agent_type], error))
366 {
367 goto out;
368 }
369
370 if (FAIL == db_host_update_availability(&out))
371 goto out;
372
373 if (0 == in.agents[agent_type].errors_from)
374 {
375 zabbix_log(LOG_LEVEL_WARNING, "%s item \"%s\" on host \"%s\" failed:"
376 " first network error, wait for %d seconds",
377 zbx_agent_type_string(item->type), item->key_orig, item->host.host,
378 out.agents[agent_type].disable_until - ts->sec);
379 }
380 else
381 {
382 if (HOST_AVAILABLE_FALSE != in.agents[agent_type].available)
383 {
384 if (HOST_AVAILABLE_FALSE != out.agents[agent_type].available)
385 {
386 zabbix_log(LOG_LEVEL_WARNING, "%s item \"%s\" on host \"%s\" failed:"
387 " another network error, wait for %d seconds",
388 zbx_agent_type_string(item->type), item->key_orig, item->host.host,
389 out.agents[agent_type].disable_until - ts->sec);
390 }
391 else
392 {
393 zabbix_log(LOG_LEVEL_WARNING, "temporarily disabling %s checks on host \"%s\":"
394 " host unavailable",
395 zbx_agent_type_string(item->type), item->host.host);
396
397 update_triggers_status_to_unknown(item->host.hostid, item->type, ts,
398 "Agent is unavailable.");
399 }
400 }
401 }
402
403 zabbix_log(LOG_LEVEL_DEBUG, "%s() errors_from:%d available:%d", __function_name,
404 out.agents[agent_type].errors_from, out.agents[agent_type].available);
405 out:
406 zbx_host_availability_clean(&out);
407 zbx_host_availability_clean(&in);
408
409 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
410 }
411
free_result_ptr(AGENT_RESULT * result)412 static void free_result_ptr(AGENT_RESULT *result)
413 {
414 free_result(result);
415 zbx_free(result);
416 }
417
get_value(DC_ITEM * item,AGENT_RESULT * result,zbx_vector_ptr_t * add_results)418 static int get_value(DC_ITEM *item, AGENT_RESULT *result, zbx_vector_ptr_t *add_results)
419 {
420 const char *__function_name = "get_value";
421 int res = FAIL;
422
423 zabbix_log(LOG_LEVEL_DEBUG, "In %s() key:'%s'", __function_name, item->key_orig);
424
425 switch (item->type)
426 {
427 case ITEM_TYPE_ZABBIX:
428 zbx_alarm_on(CONFIG_TIMEOUT);
429 res = get_value_agent(item, result);
430 zbx_alarm_off();
431 break;
432 case ITEM_TYPE_IPMI:
433 #ifdef HAVE_OPENIPMI
434 res = get_value_ipmi(item, result);
435 #else
436 SET_MSG_RESULT(result, zbx_strdup(NULL, "Support for IPMI checks was not compiled in."));
437 res = CONFIG_ERROR;
438 #endif
439 break;
440 case ITEM_TYPE_SIMPLE:
441 /* simple checks use their own timeouts */
442 res = get_value_simple(item, result, add_results);
443 break;
444 case ITEM_TYPE_INTERNAL:
445 res = get_value_internal(item, result);
446 break;
447 case ITEM_TYPE_DB_MONITOR:
448 #ifdef HAVE_UNIXODBC
449 zbx_alarm_on(CONFIG_TIMEOUT);
450 res = get_value_db(item, result);
451 zbx_alarm_off();
452 #else
453 SET_MSG_RESULT(result,
454 zbx_strdup(NULL, "Support for Database monitor checks was not compiled in."));
455 res = CONFIG_ERROR;
456 #endif
457 break;
458 case ITEM_TYPE_AGGREGATE:
459 res = get_value_aggregate(item, result);
460 break;
461 case ITEM_TYPE_EXTERNAL:
462 /* external checks use their own timeouts */
463 res = get_value_external(item, result);
464 break;
465 case ITEM_TYPE_SSH:
466 #ifdef HAVE_SSH2
467 zbx_alarm_on(CONFIG_TIMEOUT);
468 res = get_value_ssh(item, result);
469 zbx_alarm_off();
470 #else
471 SET_MSG_RESULT(result, zbx_strdup(NULL, "Support for SSH checks was not compiled in."));
472 res = CONFIG_ERROR;
473 #endif
474 break;
475 case ITEM_TYPE_TELNET:
476 zbx_alarm_on(CONFIG_TIMEOUT);
477 res = get_value_telnet(item, result);
478 zbx_alarm_off();
479 break;
480 case ITEM_TYPE_CALCULATED:
481 res = get_value_calculated(item, result);
482 break;
483 default:
484 SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Not supported item type:%d", item->type));
485 res = CONFIG_ERROR;
486 }
487
488 if (SUCCEED != res)
489 {
490 if (!ISSET_MSG(result))
491 SET_MSG_RESULT(result, zbx_strdup(NULL, ZBX_NOTSUPPORTED_MSG));
492
493 zabbix_log(LOG_LEVEL_DEBUG, "Item [%s:%s] error: %s", item->host.host, item->key_orig, result->msg);
494 }
495
496 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res));
497
498 return res;
499 }
500
501 /******************************************************************************
502 * *
503 * Function: get_values *
504 * *
505 * Purpose: retrieve values of metrics from monitored hosts *
506 * *
507 * Parameters: poller_type - [IN] poller type (ZBX_POLLER_TYPE_...) *
508 * *
509 * Return value: number of items processed *
510 * *
511 * Author: Alexei Vladishev *
512 * *
513 * Comments: processes single item at a time except for Java, SNMP items, *
514 * see DCconfig_get_poller_items() *
515 * *
516 ******************************************************************************/
get_values(unsigned char poller_type,int * nextcheck)517 static int get_values(unsigned char poller_type, int *nextcheck)
518 {
519 const char *__function_name = "get_values";
520 DC_ITEM items[MAX_POLLER_ITEMS];
521 AGENT_RESULT results[MAX_POLLER_ITEMS];
522 int errcodes[MAX_POLLER_ITEMS];
523 zbx_timespec_t timespec;
524 char *port = NULL, error[ITEM_ERROR_LEN_MAX];
525 int i, num, last_available = HOST_AVAILABLE_UNKNOWN;
526 zbx_vector_ptr_t add_results;
527
528 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
529
530 num = DCconfig_get_poller_items(poller_type, items);
531
532 if (0 == num)
533 {
534 *nextcheck = DCconfig_get_poller_nextcheck(poller_type);
535 goto exit;
536 }
537
538 /* prepare items */
539 for (i = 0; i < num; i++)
540 {
541 init_result(&results[i]);
542 errcodes[i] = SUCCEED;
543
544 ZBX_STRDUP(items[i].key, items[i].key_orig);
545 if (SUCCEED != substitute_key_macros(&items[i].key, NULL, &items[i], NULL,
546 MACRO_TYPE_ITEM_KEY, error, sizeof(error)))
547 {
548 SET_MSG_RESULT(&results[i], zbx_strdup(NULL, error));
549 errcodes[i] = CONFIG_ERROR;
550 continue;
551 }
552
553 switch (items[i].type)
554 {
555 case ITEM_TYPE_ZABBIX:
556 case ITEM_TYPE_SNMPv1:
557 case ITEM_TYPE_SNMPv2c:
558 case ITEM_TYPE_SNMPv3:
559 case ITEM_TYPE_IPMI:
560 case ITEM_TYPE_JMX:
561 ZBX_STRDUP(port, items[i].interface.port_orig);
562 substitute_simple_macros(NULL, NULL, NULL, NULL, &items[i].host.hostid, NULL,
563 NULL, NULL, &port, MACRO_TYPE_COMMON, NULL, 0);
564 if (FAIL == is_ushort(port, &items[i].interface.port))
565 {
566 SET_MSG_RESULT(&results[i], zbx_dsprintf(NULL, "Invalid port number [%s]",
567 items[i].interface.port_orig));
568 errcodes[i] = CONFIG_ERROR;
569 continue;
570 }
571 break;
572 }
573
574 switch (items[i].type)
575 {
576 case ITEM_TYPE_SNMPv3:
577 ZBX_STRDUP(items[i].snmpv3_securityname, items[i].snmpv3_securityname_orig);
578 ZBX_STRDUP(items[i].snmpv3_authpassphrase, items[i].snmpv3_authpassphrase_orig);
579 ZBX_STRDUP(items[i].snmpv3_privpassphrase, items[i].snmpv3_privpassphrase_orig);
580 ZBX_STRDUP(items[i].snmpv3_contextname, items[i].snmpv3_contextname_orig);
581
582 substitute_simple_macros(NULL, NULL, NULL, NULL, &items[i].host.hostid, NULL,
583 NULL, NULL, &items[i].snmpv3_securityname, MACRO_TYPE_COMMON, NULL, 0);
584 substitute_simple_macros(NULL, NULL, NULL, NULL, &items[i].host.hostid, NULL,
585 NULL, NULL, &items[i].snmpv3_authpassphrase, MACRO_TYPE_COMMON, NULL, 0);
586 substitute_simple_macros(NULL, NULL, NULL, NULL, &items[i].host.hostid, NULL,
587 NULL, NULL, &items[i].snmpv3_privpassphrase, MACRO_TYPE_COMMON, NULL, 0);
588 substitute_simple_macros(NULL, NULL, NULL, NULL, &items[i].host.hostid, NULL,
589 NULL, NULL, &items[i].snmpv3_contextname, MACRO_TYPE_COMMON, NULL, 0);
590 /* break; is not missing here */
591 case ITEM_TYPE_SNMPv1:
592 case ITEM_TYPE_SNMPv2c:
593 ZBX_STRDUP(items[i].snmp_community, items[i].snmp_community_orig);
594 ZBX_STRDUP(items[i].snmp_oid, items[i].snmp_oid_orig);
595
596 substitute_simple_macros(NULL, NULL, NULL, NULL, &items[i].host.hostid, NULL,
597 NULL, NULL, &items[i].snmp_community, MACRO_TYPE_COMMON, NULL, 0);
598 if (SUCCEED != substitute_key_macros(&items[i].snmp_oid, &items[i].host.hostid, NULL,
599 NULL, MACRO_TYPE_SNMP_OID, error, sizeof(error)))
600 {
601 SET_MSG_RESULT(&results[i], zbx_strdup(NULL, error));
602 errcodes[i] = CONFIG_ERROR;
603 continue;
604 }
605 break;
606 case ITEM_TYPE_SSH:
607 ZBX_STRDUP(items[i].publickey, items[i].publickey_orig);
608 ZBX_STRDUP(items[i].privatekey, items[i].privatekey_orig);
609
610 substitute_simple_macros(NULL, NULL, NULL, NULL, &items[i].host.hostid, NULL,
611 NULL, NULL, &items[i].publickey, MACRO_TYPE_COMMON, NULL, 0);
612 substitute_simple_macros(NULL, NULL, NULL, NULL, &items[i].host.hostid, NULL,
613 NULL, NULL, &items[i].privatekey, MACRO_TYPE_COMMON, NULL, 0);
614 /* break; is not missing here */
615 case ITEM_TYPE_TELNET:
616 case ITEM_TYPE_DB_MONITOR:
617 substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, NULL, &items[i],
618 NULL, &items[i].params, MACRO_TYPE_PARAMS_FIELD, NULL, 0);
619 /* break; is not missing here */
620 case ITEM_TYPE_SIMPLE:
621 case ITEM_TYPE_JMX:
622 items[i].username = zbx_strdup(items[i].username, items[i].username_orig);
623 items[i].password = zbx_strdup(items[i].password, items[i].password_orig);
624
625 substitute_simple_macros(NULL, NULL, NULL, NULL, &items[i].host.hostid, NULL,
626 NULL, NULL, &items[i].username, MACRO_TYPE_COMMON, NULL, 0);
627 substitute_simple_macros(NULL, NULL, NULL, NULL, &items[i].host.hostid, NULL,
628 NULL, NULL, &items[i].password, MACRO_TYPE_COMMON, NULL, 0);
629 break;
630 }
631 }
632
633 zbx_free(port);
634
635 zbx_vector_ptr_create(&add_results);
636
637 /* retrieve item values */
638 if (SUCCEED == is_snmp_type(items[0].type))
639 {
640 #ifdef HAVE_NETSNMP
641 /* SNMP checks use their own timeouts */
642 get_values_snmp(items, results, errcodes, num);
643 #else
644 for (i = 0; i < num; i++)
645 {
646 if (SUCCEED != errcodes[i])
647 continue;
648
649 SET_MSG_RESULT(&results[i], zbx_strdup(NULL, "Support for SNMP checks was not compiled in."));
650 errcodes[i] = CONFIG_ERROR;
651 }
652 #endif
653 }
654 else if (ITEM_TYPE_JMX == items[0].type)
655 {
656 zbx_alarm_on(CONFIG_TIMEOUT);
657 get_values_java(ZBX_JAVA_GATEWAY_REQUEST_JMX, items, results, errcodes, num);
658 zbx_alarm_off();
659 }
660 else if (1 == num)
661 {
662 if (SUCCEED == errcodes[0])
663 errcodes[0] = get_value(&items[0], &results[0], &add_results);
664 }
665 else
666 THIS_SHOULD_NEVER_HAPPEN;
667
668 zbx_timespec(×pec);
669
670 /* process item values */
671 for (i = 0; i < num; i++)
672 {
673 zbx_uint64_t lastlogsize, *plastlogsize = NULL;
674
675 switch (errcodes[i])
676 {
677 case SUCCEED:
678 case NOTSUPPORTED:
679 case AGENT_ERROR:
680 if (HOST_AVAILABLE_TRUE != last_available)
681 {
682 activate_host(&items[i], ×pec);
683 last_available = HOST_AVAILABLE_TRUE;
684 }
685 break;
686 case NETWORK_ERROR:
687 case GATEWAY_ERROR:
688 case TIMEOUT_ERROR:
689 if (HOST_AVAILABLE_FALSE != last_available)
690 {
691 deactivate_host(&items[i], ×pec, results[i].msg);
692 last_available = HOST_AVAILABLE_FALSE;
693 }
694 break;
695 case CONFIG_ERROR:
696 /* nothing to do */
697 break;
698 default:
699 zbx_error("unknown response code returned: %d", errcodes[i]);
700 THIS_SHOULD_NEVER_HAPPEN;
701 }
702
703 if (SUCCEED == errcodes[i])
704 {
705 /* remove formatting symbols from the end of the result */
706 /* so it could be checked by "is_uint64" and "is_double" functions */
707 /* when we try to get "int" or "float" values from "string" result */
708 if (0 != ISSET_STR(&results[i]))
709 zbx_rtrim(results[i].str, ZBX_WHITESPACE);
710 if (0 != ISSET_TEXT(&results[i]))
711 zbx_rtrim(results[i].text, ZBX_WHITESPACE);
712
713 if (0 == add_results.values_num)
714 {
715 items[i].state = ITEM_STATE_NORMAL;
716 dc_add_history(items[i].itemid, items[i].value_type, items[i].flags, &results[i],
717 ×pec, items[i].state, NULL);
718 }
719 else
720 {
721 /* vmware.eventlog item returns vector of AGENT_RESULT representing events */
722
723 int j;
724 zbx_timespec_t ts_tmp = timespec;
725
726 for (j = 0; j < add_results.values_num; j++)
727 {
728 AGENT_RESULT *add_result = add_results.values[j];
729
730 if (ISSET_MSG(add_result))
731 {
732 items[i].state = ITEM_STATE_NOTSUPPORTED;
733 dc_add_history(items[i].itemid, items[i].value_type, items[i].flags,
734 NULL, &ts_tmp, items[i].state, add_result->msg);
735 }
736 else
737 {
738 items[i].state = ITEM_STATE_NORMAL;
739 dc_add_history(items[i].itemid, items[i].value_type, items[i].flags,
740 add_result, &ts_tmp, items[i].state, NULL);
741
742 if (0 != ISSET_META(add_result))
743 {
744 plastlogsize = &lastlogsize;
745 lastlogsize = add_result->lastlogsize;
746 }
747 }
748
749 /* ensure that every log item value timestamp is unique */
750 if (++ts_tmp.ns == 1000000000)
751 {
752 ts_tmp.sec++;
753 ts_tmp.ns = 0;
754 }
755 }
756 }
757 }
758 else if (NOTSUPPORTED == errcodes[i] || AGENT_ERROR == errcodes[i] || CONFIG_ERROR == errcodes[i])
759 {
760 items[i].state = ITEM_STATE_NOTSUPPORTED;
761 dc_add_history(items[i].itemid, items[i].value_type, items[i].flags, NULL, ×pec,
762 items[i].state, results[i].msg);
763 }
764
765 DCpoller_requeue_items(&items[i].itemid, &items[i].state, ×pec.sec, plastlogsize, NULL,
766 &errcodes[i], 1, poller_type, nextcheck);
767
768 zbx_free(items[i].key);
769
770 switch (items[i].type)
771 {
772 case ITEM_TYPE_SNMPv3:
773 zbx_free(items[i].snmpv3_securityname);
774 zbx_free(items[i].snmpv3_authpassphrase);
775 zbx_free(items[i].snmpv3_privpassphrase);
776 zbx_free(items[i].snmpv3_contextname);
777 /* break; is not missing here */
778 case ITEM_TYPE_SNMPv1:
779 case ITEM_TYPE_SNMPv2c:
780 zbx_free(items[i].snmp_community);
781 zbx_free(items[i].snmp_oid);
782 break;
783 case ITEM_TYPE_SSH:
784 zbx_free(items[i].publickey);
785 zbx_free(items[i].privatekey);
786 /* break; is not missing here */
787 case ITEM_TYPE_TELNET:
788 case ITEM_TYPE_DB_MONITOR:
789 case ITEM_TYPE_SIMPLE:
790 case ITEM_TYPE_JMX:
791 zbx_free(items[i].username);
792 zbx_free(items[i].password);
793 break;
794 }
795
796 free_result(&results[i]);
797 }
798
799 zbx_vector_ptr_clear_ext(&add_results, (zbx_mem_free_func_t)free_result_ptr);
800 zbx_vector_ptr_destroy(&add_results);
801
802 DCconfig_clean_items(items, NULL, num);
803
804 dc_flush_history();
805 exit:
806 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, num);
807
808 return num;
809 }
810
ZBX_THREAD_ENTRY(poller_thread,args)811 ZBX_THREAD_ENTRY(poller_thread, args)
812 {
813 int nextcheck, sleeptime = -1, processed = 0, old_processed = 0;
814 double sec, total_sec = 0.0, old_total_sec = 0.0;
815 time_t last_stat_time, last_ipmi_host_check;
816 unsigned char poller_type;
817
818 #define STAT_INTERVAL 5 /* if a process is busy and does not sleep then update status not faster than */
819 /* once in STAT_INTERVAL seconds */
820
821 poller_type = *(unsigned char *)((zbx_thread_args_t *)args)->args;
822 process_type = ((zbx_thread_args_t *)args)->process_type;
823
824 server_num = ((zbx_thread_args_t *)args)->server_num;
825 process_num = ((zbx_thread_args_t *)args)->process_num;
826
827 zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
828 server_num, get_process_type_string(process_type), process_num);
829 #ifdef HAVE_NETSNMP
830 if (ZBX_POLLER_TYPE_NORMAL == poller_type || ZBX_POLLER_TYPE_UNREACHABLE == poller_type)
831 zbx_init_snmp();
832 #endif
833
834 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
835 zbx_tls_init_child();
836 #endif
837 zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num);
838 last_stat_time = last_ipmi_host_check = time(NULL);
839
840 DBconnect(ZBX_DB_CONNECT_NORMAL);
841
842 for (;;)
843 {
844 zbx_handle_log();
845
846 if (0 != sleeptime)
847 {
848 zbx_setproctitle("%s #%d [got %d values in " ZBX_FS_DBL " sec, getting values]",
849 get_process_type_string(process_type), process_num, old_processed,
850 old_total_sec);
851 }
852
853 sec = zbx_time();
854 processed += get_values(poller_type, &nextcheck);
855 total_sec += zbx_time() - sec;
856 #ifdef HAVE_OPENIPMI
857 if ((ZBX_POLLER_TYPE_IPMI == poller_type || ZBX_POLLER_TYPE_UNREACHABLE == poller_type) &&
858 SEC_PER_HOUR < time(NULL) - last_ipmi_host_check)
859 {
860 last_ipmi_host_check = time(NULL);
861 zbx_delete_inactive_ipmi_hosts(last_ipmi_host_check);
862 }
863 #endif
864 sleeptime = calculate_sleeptime(nextcheck, POLLER_DELAY);
865
866 if (0 != sleeptime || STAT_INTERVAL <= time(NULL) - last_stat_time)
867 {
868 if (0 == sleeptime)
869 {
870 zbx_setproctitle("%s #%d [got %d values in " ZBX_FS_DBL " sec, getting values]",
871 get_process_type_string(process_type), process_num, processed, total_sec);
872 }
873 else
874 {
875 zbx_setproctitle("%s #%d [got %d values in " ZBX_FS_DBL " sec, idle %d sec]",
876 get_process_type_string(process_type), process_num, processed, total_sec,
877 sleeptime);
878 old_processed = processed;
879 old_total_sec = total_sec;
880 }
881 processed = 0;
882 total_sec = 0.0;
883 last_stat_time = time(NULL);
884 }
885
886 zbx_sleep_loop(sleeptime);
887
888 #if !defined(_WINDOWS) && defined(HAVE_RESOLV_H)
889 zbx_update_resolver_conf(); /* handle /etc/resolv.conf update */
890 #endif
891 }
892
893 #undef STAT_INTERVAL
894 }
895