/* ** Zabbix ** Copyright (C) 2001-2023 Zabbix SIA ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 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 General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "checks_internal.h" #include "zbxstats.h" #include "checks_java.h" #include "zbxself.h" #include "preproc.h" #include "zbxtrends.h" #include "../vmware/vmware.h" #include "../../libs/zbxsysinfo/common/zabbix_stats.h" #include "zbxavailability.h" #include "zbxnum.h" #include "zbxsysinfo.h" #include "zbx_host_constants.h" extern unsigned char program_type; extern int CONFIG_FORKS[ZBX_PROCESS_TYPE_COUNT]; static int compare_interfaces(const void *p1, const void *p2) { const DC_INTERFACE2 *i1 = (const DC_INTERFACE2 *)p1, *i2 = (const DC_INTERFACE2 *)p2; if (i1->type > i2->type) /* 1st criterion: 'type' in ascending order */ return 1; if (i1->type < i2->type) return -1; if (i1->main > i2->main) /* 2nd criterion: 'main' in descending order */ return -1; if (i1->main < i2->main) return 1; if (i1->interfaceid > i2->interfaceid) /* 3rd criterion: 'interfaceid' in ascending order */ return 1; if (i1->interfaceid < i2->interfaceid) return -1; return 0; } /****************************************************************************** * * * Purpose: get data of all network interfaces for a host from configuration * * cache and pack into JSON for LLD * * * * Parameter: hostid - [IN] the host identifier * * j - [OUT] JSON with interface data * * error - [OUT] error message * * * * Return value: SUCCEED - interface data in JSON * * FAIL - host not found, 'error' message allocated * * * * Comments: if host is found but has no interfaces (should not happen) an * * empty JSON {"data":[]} is returned * * * ******************************************************************************/ static int zbx_host_interfaces_discovery(zbx_uint64_t hostid, struct zbx_json *j, char **error) { DC_INTERFACE2 *interfaces = NULL; int n = 0; /* number of interfaces */ int i; /* get interface data from configuration cache */ if (SUCCEED != zbx_dc_get_host_interfaces(hostid, &interfaces, &n)) { *error = zbx_strdup(*error, "host not found in configuration cache"); return FAIL; } /* sort results in a predictable order */ if (1 < n) qsort(interfaces, (size_t)n, sizeof(DC_INTERFACE2), compare_interfaces); /* repair 'addr' pointers broken by sorting */ for (i = 0; i < n; i++) interfaces[i].addr = (1 == interfaces[i].useip ? interfaces[i].ip_orig : interfaces[i].dns_orig); /* pack results into JSON */ zbx_json_initarray(j, ZBX_JSON_STAT_BUF_LEN); for (i = 0; i < n; i++) { const char *p; char buf[16]; zbx_json_addobject(j, NULL); zbx_json_addstring(j, "{#IF.CONN}", interfaces[i].addr, ZBX_JSON_TYPE_STRING); zbx_json_addstring(j, "{#IF.IP}", interfaces[i].ip_orig, ZBX_JSON_TYPE_STRING); zbx_json_addstring(j, "{#IF.DNS}", interfaces[i].dns_orig, ZBX_JSON_TYPE_STRING); zbx_json_addstring(j, "{#IF.PORT}", interfaces[i].port_orig, ZBX_JSON_TYPE_STRING); switch (interfaces[i].type) { case INTERFACE_TYPE_AGENT: p = "AGENT"; break; case INTERFACE_TYPE_SNMP: p = "SNMP"; break; case INTERFACE_TYPE_IPMI: p = "IPMI"; break; case INTERFACE_TYPE_JMX: p = "JMX"; break; case INTERFACE_TYPE_UNKNOWN: default: p = "UNKNOWN"; } zbx_json_addstring(j, "{#IF.TYPE}", p, ZBX_JSON_TYPE_STRING); zbx_snprintf(buf, sizeof(buf), "%hhu", interfaces[i].main); zbx_json_addstring(j, "{#IF.DEFAULT}", buf, ZBX_JSON_TYPE_INT); if (INTERFACE_TYPE_SNMP == interfaces[i].type) { zbx_snprintf(buf, sizeof(buf), "%hhu", interfaces[i].bulk); zbx_json_addstring(j, "{#IF.SNMP.BULK}", buf, ZBX_JSON_TYPE_INT); switch (interfaces[i].snmp_version) { case ZBX_IF_SNMP_VERSION_1: p = "SNMPv1"; break; case ZBX_IF_SNMP_VERSION_2: p = "SNMPv2c"; break; case ZBX_IF_SNMP_VERSION_3: p = "SNMPv3"; break; default: p = "UNKNOWN"; } zbx_json_addstring(j, "{#IF.SNMP.VERSION}", p, ZBX_JSON_TYPE_STRING); } zbx_json_close(j); } zbx_json_close(j); zbx_free(interfaces); return SUCCEED; } static double get_selfmon_stat(double busy, unsigned char state) { return (ZBX_PROCESS_STATE_BUSY == state ? busy : 100.0 - busy); } static int get_preprocessor_selfmon_stats(unsigned char aggr_func, int proc_num, unsigned char state, double *value, char **error) { zbx_vector_dbl_t usage; int ret, count; zbx_vector_dbl_create(&usage); if (SUCCEED != (ret = zbx_preprocessor_get_usage_stats(&usage, &count, error))) goto out; if (0 == usage.values_num) { *value = 0; goto out; } if (ZBX_SELFMON_AGGR_FUNC_ONE == aggr_func) { *value = get_selfmon_stat(usage.values[proc_num - 1], state); } else { double min, max, total; min = max = total = usage.values[0]; for (int i = 1; i < usage.values_num; i++) { if (usage.values[i] < min) min = usage.values[i]; if (usage.values[i] > max) max = usage.values[i]; total += usage.values[i]; } switch (aggr_func) { case ZBX_SELFMON_AGGR_FUNC_AVG: *value = get_selfmon_stat(total / usage.values_num, state); break; case ZBX_SELFMON_AGGR_FUNC_MIN: *value = get_selfmon_stat(min, state); break; case ZBX_SELFMON_AGGR_FUNC_MAX: *value = get_selfmon_stat(max, state); break; } } out: zbx_vector_dbl_destroy(&usage); return ret; } /****************************************************************************** * * * Purpose: retrieve data from Zabbix server (internally supported items) * * * * Parameters: item - [IN] item we are interested in * * result - [OUT] value of the requested item * * config_comms - [IN] Zabbix server/proxy configuration * * for communication * * config_startup_time - [IN] program startup time * * * * Return value: SUCCEED - data successfully retrieved and stored in result * * NOTSUPPORTED - requested item is not supported * * * ******************************************************************************/ int get_value_internal(const DC_ITEM *item, AGENT_RESULT *result, const zbx_config_comms_args_t *config_comms, int config_startup_time) { AGENT_REQUEST request; int ret = NOTSUPPORTED, nparams; const char *tmp, *tmp1; zbx_init_agent_request(&request); if (SUCCEED != zbx_parse_item_key(item->key, &request)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid item key format.")); goto out; } if (0 != strcmp("zabbix", get_rkey(&request))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Unsupported item key for this item type.")); goto out; } /* NULL check to silence analyzer warning */ if (0 == (nparams = get_rparams_num(&request)) || NULL == (tmp = get_rparam(&request, 0))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } if (FAIL != (ret = zbx_get_value_internal_ext(tmp, &request, result))) goto out; ret = NOTSUPPORTED; if (0 == strcmp(tmp, "items")) /* zabbix["items"] */ { if (1 != nparams) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } SET_UI64_RESULT(result, DCget_item_count(0)); } else if (0 == strcmp(tmp, "version")) /* zabbix["version"] */ { if (1 != nparams) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } SET_STR_RESULT(result, zbx_strdup(NULL, ZABBIX_VERSION)); } else if (0 == strcmp(tmp, "items_unsupported")) /* zabbix["items_unsupported"] */ { if (1 != nparams) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } SET_UI64_RESULT(result, DCget_item_unsupported_count(0)); } else if (0 == strcmp(tmp, "hosts")) /* zabbix["hosts"] */ { if (1 != nparams) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } SET_UI64_RESULT(result, DCget_host_count()); } else if (0 == strcmp(tmp, "queue")) /* zabbix["queue",<from>,<to>] */ { int from = ZBX_QUEUE_FROM_DEFAULT, to = ZBX_QUEUE_TO_INFINITY; if (3 < nparams) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } if (NULL != (tmp = get_rparam(&request, 1)) && '\0' != *tmp && FAIL == zbx_is_time_suffix(tmp, &from, ZBX_LENGTH_UNLIMITED)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); goto out; } if (NULL != (tmp = get_rparam(&request, 2)) && '\0' != *tmp && FAIL == zbx_is_time_suffix(tmp, &to, ZBX_LENGTH_UNLIMITED)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); goto out; } if (ZBX_QUEUE_TO_INFINITY != to && from > to) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Parameters represent an invalid interval.")); goto out; } SET_UI64_RESULT(result, DCget_item_queue(NULL, from, to)); } else if (0 == strcmp(tmp, "requiredperformance")) /* zabbix["requiredperformance"] */ { if (1 != nparams) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } SET_DBL_RESULT(result, DCget_required_performance()); } else if (0 == strcmp(tmp, "uptime")) /* zabbix["uptime"] */ { if (1 != nparams) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } SET_UI64_RESULT(result, time(NULL) - config_startup_time); } else if (0 == strcmp(tmp, "boottime")) /* zabbix["boottime"] */ { if (1 != nparams) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } SET_UI64_RESULT(result, config_startup_time); } else if (0 == strcmp(tmp, "host")) /* zabbix["host",*] */ { if (3 != nparams) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } tmp = get_rparam(&request, 2); if (0 == strcmp(tmp, "available")) /* zabbix["host",<type>,"available"] */ { zbx_agent_availability_t agents[ZBX_AGENT_MAX]; int i; zbx_get_host_interfaces_availability(item->host.hostid, agents); for (i = 0; i < ZBX_AGENT_MAX; i++) zbx_free(agents[i].error); tmp = get_rparam(&request, 1); if (0 == strcmp(tmp, "agent")) SET_UI64_RESULT(result, agents[ZBX_AGENT_ZABBIX].available); else if (0 == strcmp(tmp, "snmp")) SET_UI64_RESULT(result, agents[ZBX_AGENT_SNMP].available); else if (0 == strcmp(tmp, "ipmi")) SET_UI64_RESULT(result, agents[ZBX_AGENT_IPMI].available); else if (0 == strcmp(tmp, "jmx")) SET_UI64_RESULT(result, agents[ZBX_AGENT_JMX].available); else if (0 == strcmp(tmp, "active_agent")) { SET_UI64_RESULT(result, zbx_get_active_agent_availability(item->host.hostid)); ret = SUCCEED; goto out; } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); goto out; } result->ui64 = 2 - result->ui64; } else if (0 == strcmp(tmp, "maintenance")) /* zabbix["host",,"maintenance"] */ { /* this item is always processed by server */ if (NULL != (tmp = get_rparam(&request, 1)) && '\0' != *tmp) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); goto out; } if (HOST_MAINTENANCE_STATUS_ON == item->host.maintenance_status) SET_UI64_RESULT(result, item->host.maintenance_type + 1); else SET_UI64_RESULT(result, 0); } else if (0 == strcmp(tmp, "items")) /* zabbix["host",,"items"] */ { /* this item is always processed by server */ if (NULL != (tmp = get_rparam(&request, 1)) && '\0' != *tmp) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); goto out; } SET_UI64_RESULT(result, DCget_item_count(item->host.hostid)); } else if (0 == strcmp(tmp, "items_unsupported")) /* zabbix["host",,"items_unsupported"] */ { /* this item is always processed by server */ if (NULL != (tmp = get_rparam(&request, 1)) && '\0' != *tmp) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); goto out; } SET_UI64_RESULT(result, DCget_item_unsupported_count(item->host.hostid)); } else if (0 == strcmp(tmp, "interfaces")) /* zabbix["host","discovery","interfaces"] */ { struct zbx_json j; char *error = NULL; /* this item is always processed by server */ if (NULL == (tmp = get_rparam(&request, 1)) || 0 != strcmp(tmp, "discovery")) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); goto out; } if (SUCCEED != zbx_host_interfaces_discovery(item->host.hostid, &j, &error)) { SET_MSG_RESULT(result, error); goto out; } SET_STR_RESULT(result, zbx_strdup(NULL, j.buffer)); zbx_json_free(&j); } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); goto out; } } else if (0 == strcmp(tmp, "java")) /* zabbix["java",...] */ { int res; zbx_alarm_on((unsigned int)config_comms->config_timeout); res = get_value_java(ZBX_JAVA_GATEWAY_REQUEST_INTERNAL, item, result, config_comms->config_timeout); zbx_alarm_off(); if (SUCCEED != res) { tmp1 = get_rparam(&request, 2); /* the default error code "NOTSUPPORTED" renders nodata() trigger function nonfunctional */ if (NULL != tmp1 && 0 == strcmp(tmp1, "ping")) ret = GATEWAY_ERROR; goto out; } } else if (0 == strcmp(tmp, "process")) /* zabbix["process",<type>,<mode>,<state>] */ { unsigned char process_type = ZBX_PROCESS_TYPE_UNKNOWN; int process_forks; double value; if (2 > nparams || nparams > 4) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } process_type = (unsigned char)get_process_type_by_name(get_rparam(&request, 1)); switch (process_type) { case ZBX_PROCESS_TYPE_ALERTMANAGER: case ZBX_PROCESS_TYPE_ALERTER: case ZBX_PROCESS_TYPE_ESCALATOR: case ZBX_PROCESS_TYPE_PROXYPOLLER: case ZBX_PROCESS_TYPE_TIMER: if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER)) process_type = ZBX_PROCESS_TYPE_UNKNOWN; break; case ZBX_PROCESS_TYPE_DATASENDER: if (0 == (program_type & ZBX_PROGRAM_TYPE_PROXY)) process_type = ZBX_PROCESS_TYPE_UNKNOWN; break; } if (ZBX_PROCESS_TYPE_UNKNOWN == process_type) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); goto out; } process_forks = ZBX_PROCESS_TYPE_COUNT > process_type ? CONFIG_FORKS[process_type] : 0; if (NULL == (tmp = get_rparam(&request, 2))) tmp = ""; if (0 == strcmp(tmp, "count")) { if (4 == nparams) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } SET_UI64_RESULT(result, process_forks); } else { unsigned char aggr_func, state; unsigned short process_num = 0; if ('\0' == *tmp || 0 == strcmp(tmp, "avg")) aggr_func = ZBX_SELFMON_AGGR_FUNC_AVG; else if (0 == strcmp(tmp, "max")) aggr_func = ZBX_SELFMON_AGGR_FUNC_MAX; else if (0 == strcmp(tmp, "min")) aggr_func = ZBX_SELFMON_AGGR_FUNC_MIN; else if (SUCCEED == zbx_is_ushort(tmp, &process_num) && 0 < process_num) aggr_func = ZBX_SELFMON_AGGR_FUNC_ONE; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); goto out; } if (0 == process_forks) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "No \"%s\" processes started.", get_process_type_string(process_type))); goto out; } else if (process_num > process_forks) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Process \"%s #%d\" is not started.", get_process_type_string(process_type), process_num)); goto out; } if (NULL == (tmp = get_rparam(&request, 3)) || '\0' == *tmp || 0 == strcmp(tmp, "busy")) state = ZBX_PROCESS_STATE_BUSY; else if (0 == strcmp(tmp, "idle")) state = ZBX_PROCESS_STATE_IDLE; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fourth parameter.")); goto out; } if (ZBX_PROCESS_TYPE_PREPROCESSOR != process_type) { zbx_get_selfmon_stats(process_type, aggr_func, process_num, state, &value); } else { char *error = NULL; if (SUCCEED != get_preprocessor_selfmon_stats(aggr_func, process_num, state, &value, &error)) { SET_MSG_RESULT(result, error); goto out; } } SET_DBL_RESULT(result, value); } } else if (0 == strcmp(tmp, "wcache")) /* zabbix[wcache,<cache>,<mode>] */ { if (2 > nparams || nparams > 3) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } tmp = get_rparam(&request, 1); tmp1 = get_rparam(&request, 2); if (0 == strcmp(tmp, "values")) { if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "all")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_COUNTER)); else if (0 == strcmp(tmp1, "float")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_FLOAT_COUNTER)); else if (0 == strcmp(tmp1, "uint")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_UINT_COUNTER)); else if (0 == strcmp(tmp1, "str")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_STR_COUNTER)); else if (0 == strcmp(tmp1, "log")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_LOG_COUNTER)); else if (0 == strcmp(tmp1, "text")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_TEXT_COUNTER)); else if (0 == strcmp(tmp1, "not supported")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_NOTSUPPORTED_COUNTER)); else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); goto out; } } else if (0 == strcmp(tmp, "history")) { if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "pfree")) SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_HISTORY_PFREE)); else if (0 == strcmp(tmp1, "total")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_TOTAL)); else if (0 == strcmp(tmp1, "used")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_USED)); else if (0 == strcmp(tmp1, "free")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_FREE)); else if (0 == strcmp(tmp1, "pused")) SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_HISTORY_PUSED)); else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); goto out; } } else if (0 == strcmp(tmp, "trend")) { if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); goto out; } if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "pfree")) SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_TREND_PFREE)); else if (0 == strcmp(tmp1, "total")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_TOTAL)); else if (0 == strcmp(tmp1, "used")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_USED)); else if (0 == strcmp(tmp1, "free")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_FREE)); else if (0 == strcmp(tmp1, "pused")) SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_TREND_PUSED)); else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); goto out; } } else if (0 == strcmp(tmp, "index")) { if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "pfree")) SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_HISTORY_INDEX_PFREE)); else if (0 == strcmp(tmp1, "total")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_INDEX_TOTAL)); else if (0 == strcmp(tmp1, "used")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_INDEX_USED)); else if (0 == strcmp(tmp1, "free")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_INDEX_FREE)); else if (0 == strcmp(tmp1, "pused")) SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_HISTORY_INDEX_PUSED)); else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); goto out; } } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); goto out; } } else if (0 == strcmp(tmp, "rcache")) /* zabbix[rcache,<cache>,<mode>] */ { if (2 > nparams || nparams > 3) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } tmp = get_rparam(&request, 1); tmp1 = get_rparam(&request, 2); if (0 == strcmp(tmp, "buffer")) { if (NULL == tmp1 || '\0' == *tmp1 || 0 == strcmp(tmp1, "pfree")) SET_DBL_RESULT(result, *(double *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_PFREE)); else if (0 == strcmp(tmp1, "total")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_TOTAL)); else if (0 == strcmp(tmp1, "used")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_USED)); else if (0 == strcmp(tmp1, "free")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_FREE)); else if (0 == strcmp(tmp1, "pused")) SET_DBL_RESULT(result, *(double *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_PUSED)); else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); goto out; } } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); goto out; } } else if (0 == strcmp(tmp, "vmware")) { zbx_vmware_stats_t stats; if (FAIL == zbx_vmware_get_statistics(&stats)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "No \"%s\" processes started.", get_process_type_string(ZBX_PROCESS_TYPE_VMWARE))); goto out; } if (2 > nparams || nparams > 3) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } tmp = get_rparam(&request, 1); if (NULL == (tmp1 = get_rparam(&request, 2))) tmp1 = ""; if (0 == strcmp(tmp, "buffer")) { if (0 == strcmp(tmp1, "free")) { SET_UI64_RESULT(result, stats.memory_total - stats.memory_used); } else if (0 == strcmp(tmp1, "pfree")) { SET_DBL_RESULT(result, (double)(stats.memory_total - stats.memory_used) / (double)stats.memory_total * 100); } else if (0 == strcmp(tmp1, "total")) { SET_UI64_RESULT(result, stats.memory_total); } else if (0 == strcmp(tmp1, "used")) { SET_UI64_RESULT(result, stats.memory_used); } else if (0 == strcmp(tmp1, "pused")) { SET_DBL_RESULT(result, (double)stats.memory_used / (double)stats.memory_total * 100); } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); goto out; } } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); goto out; } } else if (0 == strcmp(tmp, "stats")) /* zabbix[stats,...] */ { const char *ip_str, *port_str, *ip; unsigned short port_number; struct zbx_json json; if (6 < nparams) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } if (NULL == (ip_str = get_rparam(&request, 1)) || '\0' == *ip_str) ip = "127.0.0.1"; else ip = ip_str; if (NULL == (port_str = get_rparam(&request, 2)) || '\0' == *port_str) { port_number = ZBX_DEFAULT_SERVER_PORT; } else if (SUCCEED != zbx_is_ushort(port_str, &port_number)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); goto out; } if (3 >= nparams) { if ((NULL == ip_str || '\0' == *ip_str) && (NULL == port_str || '\0' == *port_str)) { zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); /* Adding "data" object to JSON structure to make identical JSONPath expressions */ /* work for both data received from internal and external source. */ zbx_json_addobject(&json, ZBX_PROTO_TAG_DATA); zbx_zabbix_stats_get(&json, config_startup_time); zbx_json_close(&json); zbx_set_agent_result_type(result, ITEM_VALUE_TYPE_TEXT, json.buffer); zbx_json_free(&json); } else if (SUCCEED != zbx_get_remote_zabbix_stats(ip, port_number, result)) goto out; } else { tmp1 = get_rparam(&request, 3); if (0 == strcmp(tmp1, ZBX_PROTO_VALUE_ZABBIX_STATS_QUEUE)) { tmp = get_rparam(&request, 4); /* from */ tmp1 = get_rparam(&request, 5); /* to */ if ((NULL == ip_str || '\0' == *ip_str) && (NULL == port_str || '\0' == *port_str)) { int from = ZBX_QUEUE_FROM_DEFAULT, to = ZBX_QUEUE_TO_INFINITY; if (NULL != tmp && '\0' != *tmp && FAIL == zbx_is_time_suffix(tmp, &from, ZBX_LENGTH_UNLIMITED)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fifth parameter.")); goto out; } if (NULL != tmp1 && '\0' != *tmp1 && FAIL == zbx_is_time_suffix(tmp1, &to, ZBX_LENGTH_UNLIMITED)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid sixth parameter.")); goto out; } if (ZBX_QUEUE_TO_INFINITY != to && from > to) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Parameters represent an" " invalid interval.")); goto out; } zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addint64(&json, ZBX_PROTO_VALUE_ZABBIX_STATS_QUEUE, DCget_item_queue(NULL, from, to)); zbx_set_agent_result_type(result, ITEM_VALUE_TYPE_TEXT, json.buffer); zbx_json_free(&json); } else if (SUCCEED != zbx_get_remote_zabbix_stats_queue(ip, port_number, tmp, tmp1, result)) { goto out; } } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid forth parameter.")); goto out; } } } else if (0 == strcmp(tmp, "preprocessing_queue")) { if (1 != nparams) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } SET_UI64_RESULT(result, zbx_preprocessor_get_queue_size()); } else if (0 == strcmp(tmp, "tcache")) /* zabbix[tcache,cache,<parameter>] */ { char *error = NULL; zbx_tfc_stats_t stats; if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); goto out; } if (2 > nparams || 3 < nparams) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters.")); goto out; } tmp1 = get_rparam(&request, 1); if (0 != strcmp(tmp1, "cache")) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); goto out; } tmp = get_rparam(&request, 2); if (FAIL == zbx_tfc_get_stats(&stats, &error)) { SET_MSG_RESULT(result, error); goto out; } if (NULL == tmp || 0 == strcmp(tmp, "all")) { SET_UI64_RESULT(result, stats.hits + stats.misses); } else if (0 == strcmp(tmp, "hits")) { SET_UI64_RESULT(result, stats.hits); } else if (0 == strcmp(tmp, "misses")) { SET_UI64_RESULT(result, stats.misses); } else if (0 == strcmp(tmp, "items")) { SET_UI64_RESULT(result, stats.items_num); } else if (0 == strcmp(tmp, "requests")) { SET_UI64_RESULT(result, stats.requests_num); } else if (0 == strcmp(tmp, "pmisses")) { zbx_uint64_t total = stats.hits + stats.misses; SET_DBL_RESULT(result, (0 == total ? 0 : (double)stats.misses / (double)total * 100)); } else if (0 == strcmp(tmp, "phits")) { zbx_uint64_t total = stats.hits + stats.misses; SET_DBL_RESULT(result, (0 == total ? 0 : (double)stats.hits / (double)total * 100)); } else if (0 == strcmp(tmp, "pitems")) { zbx_uint64_t total = stats.items_num + stats.requests_num; SET_DBL_RESULT(result, (0 == total ? 0 : (double)stats.items_num / (double)total * 100)); } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); goto out; } } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); goto out; } ret = SUCCEED; out: if (NOTSUPPORTED == ret && !ZBX_ISSET_MSG(result)) SET_MSG_RESULT(result, zbx_strdup(NULL, "Internal check is not supported.")); zbx_free_agent_request(&request); return ret; }