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(&timespec);
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], &timespec);
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], &timespec, 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 						&timespec, 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, &timespec,
762 					items[i].state, results[i].msg);
763 		}
764 
765 		DCpoller_requeue_items(&items[i].itemid, &items[i].state, &timespec.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