Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexander Vladishev <aleksander.vladishev@zabbix.com>2021-05-07 18:39:56 +0300
committerAlexander Vladishev <aleksander.vladishev@zabbix.com>2021-05-07 18:39:56 +0300
commitd3d1b6340db4bd59900ef61db90f5cc927dcd59b (patch)
tree2710aea0bb61e17af0b994b86a1656a04dc77ba0 /src
parent27d4e37650a3cd785ffc481dcb5c831c7b58f9e1 (diff)
parent6ef36762644b5d57dc2c96b4aa8392bc7af561f5 (diff)
.......... [ZBXNEXT-6451,ZBXNEXT-6455] updated to the latest master; fixed conflicts in:
- create/src/schema.tmpl - include/db.h - include/zbxhistory.h - src/libs/zbxdbupgrade/dbupgrade_5030.c - src/libs/zbxhistory/history.c - ui/include/defines.inc.php
Diffstat (limited to 'src')
-rw-r--r--src/go/cmd/zabbix_agent2/service_windows.go37
-rw-r--r--src/go/plugins/windows/services/services_windows.go2
-rw-r--r--src/libs/zbxdb/db.c301
-rw-r--r--src/libs/zbxdbhigh/db.c76
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_5030.c20
-rw-r--r--src/libs/zbxhistory/history.c13
-rw-r--r--src/libs/zbxhistory/history.h4
-rw-r--r--src/libs/zbxhistory/history_elastic.c127
-rw-r--r--src/libs/zbxjson/json.c6
-rw-r--r--src/libs/zbxtrends/cache.c4
-rw-r--r--src/zabbix_server/events.c1
-rw-r--r--src/zabbix_server/server.c21
12 files changed, 565 insertions, 47 deletions
diff --git a/src/go/cmd/zabbix_agent2/service_windows.go b/src/go/cmd/zabbix_agent2/service_windows.go
index 441de2b96c7..e7f21ce59a3 100644
--- a/src/go/cmd/zabbix_agent2/service_windows.go
+++ b/src/go/cmd/zabbix_agent2/service_windows.go
@@ -463,7 +463,7 @@ loop:
closeChan <- true
break loop
default:
- log.Warningf("unsupported windows service command received")
+ log.Debugf("unsupported windows service command '%s' received", getCmdName(c.Cmd))
}
case <-stopChan:
changes <- svc.Status{State: svc.StopPending}
@@ -478,3 +478,38 @@ loop:
return
}
+
+func getCmdName(cmd svc.Cmd) string {
+ switch cmd {
+ case svc.Stop:
+ return "Stop"
+ case svc.Pause:
+ return "Pause"
+ case svc.Continue:
+ return "Continue"
+ case svc.Interrogate:
+ return "Interrogate"
+ case svc.Shutdown:
+ return "Shutdown"
+ case svc.ParamChange:
+ return "ParamChange"
+ case svc.NetBindAdd:
+ return "NetBindAdd"
+ case svc.NetBindRemove:
+ return "NetBindRemove"
+ case svc.NetBindEnable:
+ return "NetBindEnable"
+ case svc.NetBindDisable:
+ return "NetBindDisable"
+ case svc.DeviceEvent:
+ return "DeviceEvent"
+ case svc.HardwareProfileChange:
+ return "HardwareProfileChange"
+ case svc.PowerEvent:
+ return "PowerEvent"
+ case svc.SessionChange:
+ return "SessionChange"
+ default:
+ return "unknown"
+ }
+}
diff --git a/src/go/plugins/windows/services/services_windows.go b/src/go/plugins/windows/services/services_windows.go
index 0e14aa9fb20..e179ff08180 100644
--- a/src/go/plugins/windows/services/services_windows.go
+++ b/src/go/plugins/windows/services/services_windows.go
@@ -420,7 +420,7 @@ func (p *Plugin) exportServices(params []string) (result interface{}, err error)
}
stateFilter := stateFlagAll
- if len(params) > 1 && params[1] != "" {
+ if len(params) > 1 && params[1] != "all" && params[1] != "" {
switch params[1] {
case "stopped":
stateFilter = stateFlagStopped
diff --git a/src/libs/zbxdb/db.c b/src/libs/zbxdb/db.c
index 8a385625755..672f5226b67 100644
--- a/src/libs/zbxdb/db.c
+++ b/src/libs/zbxdb/db.c
@@ -45,7 +45,7 @@ struct zbx_db_result
MYSQL_RES *result;
#elif defined(HAVE_ORACLE)
OCIStmt *stmthp; /* the statement handle for select operations */
- int ncolumn;
+ int ncolumn;
DB_ROW values;
ub4 *values_alloc;
OCILobLocator **clobs;
@@ -76,6 +76,8 @@ static int db_auto_increment;
#if defined(HAVE_MYSQL)
static MYSQL *conn = NULL;
+static zbx_uint32_t ZBX_MYSQL_SVERSION = ZBX_DBVERSION_UNDEFINED;
+static int ZBX_MARIADB_SFORK = OFF;
#elif defined(HAVE_ORACLE)
#include "zbxalgo.h"
@@ -90,6 +92,8 @@ typedef struct
}
zbx_oracle_db_handle_t;
+static zbx_uint32_t ZBX_ORACLE_SVERSION = ZBX_DBVERSION_UNDEFINED;
+
static zbx_oracle_db_handle_t oracle;
static ub4 OCI_DBserver_status(void);
@@ -97,7 +101,8 @@ static ub4 OCI_DBserver_status(void);
#elif defined(HAVE_POSTGRESQL)
static PGconn *conn = NULL;
static unsigned int ZBX_PG_BYTEAOID = 0;
-static int ZBX_PG_SVERSION = 0, ZBX_TSDB_VERSION = -1;
+static int ZBX_TSDB_VERSION = -1;
+static zbx_uint32_t ZBX_PG_SVERSION = ZBX_DBVERSION_UNDEFINED;
char ZBX_PG_ESCAPE_BACKSLASH = 1;
#elif defined(HAVE_SQLITE3)
static sqlite3 *conn = NULL;
@@ -786,9 +791,6 @@ int zbx_db_connect(char *host, char *user, char *password, char *dbname, char *d
ZBX_PG_BYTEAOID = atoi(row[0]);
DBfree_result(result);
- ZBX_PG_SVERSION = PQserverVersion(conn);
- zabbix_log(LOG_LEVEL_DEBUG, "PostgreSQL Server version: %d", ZBX_PG_SVERSION);
-
/* disable "nonstandard use of \' in a string literal" warning */
if (0 < (ret = zbx_db_execute("set escape_string_warning to off")))
ret = ZBX_DB_OK;
@@ -2438,31 +2440,304 @@ char *zbx_db_dyn_escape_like_pattern(const char *src)
* Return value: the string length in bytes *
* *
******************************************************************************/
-int zbx_db_strlen_n(const char *text, size_t maxlen)
+int zbx_db_strlen_n(const char *text_loc, size_t maxlen)
{
- return zbx_strlen_utf8_nchars(text, maxlen);
+ return zbx_strlen_utf8_nchars(text_loc, maxlen);
}
-#if defined(HAVE_POSTGRESQL)
/******************************************************************************
* *
- * Function: zbx_dbms_get_version *
+ * Function: zbx_db_version_check *
+ * *
+ * Purpose: determine if a vendor database(MySQL, MariaDB, PostgreSQL, *
+ * Oracle, ElasticDB) version satisfies Zabbix requirements *
+ * *
+ * Parameters: database - [IN] database name *
+ * current_version - [IN] detected numeric version *
+ * min_version - [IN] minimum required numeric version *
+ * max_version - [IN] maximum required numeric version *
+ * *
+ * Return value: resulting status flag *
+ * *
+ ******************************************************************************/
+int zbx_db_version_check(const char *database, zbx_uint32_t current_version, zbx_uint32_t min_version,
+ zbx_uint32_t max_version)
+{
+ int flag;
+
+ if (ZBX_DBVERSION_UNDEFINED == current_version)
+ {
+ flag = DB_VERSION_FAILED_TO_RETRIEVE;
+ zabbix_log(LOG_LEVEL_WARNING, "Failed to retrieve %s version", database);
+ }
+ else if (min_version > current_version && ZBX_DBVERSION_UNDEFINED != min_version)
+ {
+ flag = DB_VERSION_LOWER_THAN_MINIMUM;
+ zabbix_log(LOG_LEVEL_WARNING, "Unsupported DB! %s version is %lu which is smaller than minimum of %lu",
+ database, (unsigned long)current_version, (unsigned long)min_version);
+ }
+ else if (max_version < current_version && ZBX_DBVERSION_UNDEFINED != max_version)
+ {
+ flag = DB_VERSION_HIGHER_THAN_MAXIMUM;
+ zabbix_log(LOG_LEVEL_WARNING, "Unsupported DB! %s version is %lu which is higher than maximum of %lu",
+ database, (unsigned long)current_version, (unsigned long)max_version);
+ }
+ else
+ flag = DB_VERSION_SUPPORTED;
+
+ return flag;
+}
+
+/******************************************************************************
+ * *
+ * Function: zbx_db_version_json_create *
+ * *
+ * Purpose: prepare json for front-end with the DB current, minimum and *
+ * maximum versions and a flag that indicates if the version *
+ * satisfies the requirements *
* *
- * Purpose: returns DBMS version as integer: MMmmuu *
+ * Parameters: json - [IN/OUT] json data *
+ * database - [IN] name of DB (MySQL/ElasticDB) *
+ * friendly_current_version - [IN] string current version *
+ * friendly_min_version - [IN] string min version *
+ * friendly_max_version - [IN] string max version *
+ * flag - [IN] status if DB satisfies the *
+ * requirements *
+ * *
+ ******************************************************************************/
+void zbx_db_version_json_create(struct zbx_json *json, const char *database, const char *friendly_current_version,
+ const char *friendly_min_version, const char *friendly_max_version, int flag)
+{
+ zbx_json_addobject(json, NULL);
+ zbx_json_addstring(json, "database", database, ZBX_JSON_TYPE_STRING);
+
+ if (DB_VERSION_FAILED_TO_RETRIEVE != flag)
+ zbx_json_addstring(json, "current_version", friendly_current_version, ZBX_JSON_TYPE_STRING);
+
+ zbx_json_addstring(json, "min_version", friendly_min_version, ZBX_JSON_TYPE_STRING);
+ zbx_json_addstring(json, "max_version", friendly_max_version, ZBX_JSON_TYPE_STRING);
+ zbx_json_addint64(json, "flag", flag);
+ zbx_json_close(json);
+}
+
+/******************************************************************************
+ * *
+ * Function: zbx_dbms_version_get *
+ * *
+ * Purpose: For PostgreSQL, MySQL and MariaDB: *
+ * returns DBMS version as integer: MMmmuu *
* M = major version part *
* m = minor version part *
* u = patch version part *
* *
- * Example: 1.2.34 version will be returned as 10234 *
+ * Example: if the original DB version was 1.2.34 then 10234 gets returned *
+ * *
+ * Purpose: For OracleDB: *
+ * returns DBMS version as integer: MRruRRivUU *
+ * MR = major release version part *
+ * ru = release update version part *
+ * RR = release update version revision part *
+ * iv = increment version part *
+ * UU = unused, reserved for future use *
+ * *
+ * Example: if the OracleDB version was 18.1.0.0.7 then 1801000007 gets *
+ * returned *
* *
- * Return value: DBMS version or 0 if unknown *
+ * Return value: DBMS version or DBVERSION_UNDEFINED if unknown *
* *
******************************************************************************/
-int zbx_dbms_get_version(void)
+zbx_uint32_t zbx_dbms_version_get(void)
{
+#if defined(HAVE_MYSQL)
+ return ZBX_MYSQL_SVERSION;
+#elif defined(HAVE_POSTGRESQL)
return ZBX_PG_SVERSION;
+#elif defined(HAVE_ORACLE)
+ return ZBX_ORACLE_SVERSION;
+#else
+ return ZBX_DBVERSION_UNDEFINED;
+#endif
}
+#ifdef HAVE_MYSQL
+/******************************************************************************
+ * *
+ * Function: zbx_dbms_mariadb_used *
+ * *
+ * Purpose: returns flag if the mariadb was detected *
+ * *
+ * Return value: ON - mariadb detected *
+ * OFF - otherwise (it is unforked mysql) *
+ ******************************************************************************/
+int zbx_dbms_mariadb_used(void)
+{
+ return ZBX_MARIADB_SFORK;
+}
+#endif
+
+/***************************************************************************************************************
+ * *
+ * Function: zbx_dbms_version_extract *
+ * *
+ * Purpose: retrieves the DB version and makes sure it is stored in the numeric format, also fills the json *
+ * to report to front-end *
+ * *
+ * For PostgreSQL: *
+ * numeric version is available from the API *
+ * *
+ * For MySQL and MariaDB: *
+ * numeric version is available from the API, but also the additional processing is required *
+ * to determine if it is a MySQL or MariaDB and save this result as well *
+ * *
+ * For Oracle: *
+ * numeric version needs to be manually parsed from the string result *
+ * Oracle DB format is like 18.1.2.3.0 where *
+ * 18 - major release version *
+ * 1 - release update version *
+ * 2 - release update version revision *
+ * 3 - increment version *
+ * 0 - unused, reserved for future use *
+ * *
+ * Oracle Examples: *
+ * For "Oracle Database 18c Express Edition Release 1.0.0.0.0 - Production" => 100000000 *
+ * For "Oracle Database 18c Express Edition Release 18.2.0.0.7 - Production" => 1802000007 *
+ * For "Oracle Database 18c Express Edition Release 0.0.34.123.7 - Production" => DBVERSION_UNDEFINED *
+ * For "Oracle Database 18c Express Edition Release 1.0.3.x.7 - Production" => DBVERISON_UNDEFINED *
+ * For "<anything else>" => DBVERSION_UNDEFINED *
+ * *
+ **************************************************************************************************************/
+zbx_uint32_t zbx_dbms_version_extract(struct zbx_json *json)
+{
+#define RIGHT2(x) ((int)((zbx_uint32_t)(x) - ((zbx_uint32_t)((x)/100))*100))
+#if defined(HAVE_MYSQL)
+ int flag;
+ const char *info;
+ char *version_friendly;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+ ZBX_MYSQL_SVERSION = (zbx_uint32_t)mysql_get_server_version(conn);
+
+ if (NULL != (info = mysql_get_server_info(conn)) && NULL != strstr(info, "MariaDB"))
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "MariaDB fork detected");
+ ZBX_MARIADB_SFORK = ON;
+ }
+
+ version_friendly = zbx_dsprintf(NULL, "%d.%.2d.%.2d", RIGHT2(ZBX_MYSQL_SVERSION/10000),
+ RIGHT2(ZBX_MYSQL_SVERSION/100), RIGHT2(ZBX_MYSQL_SVERSION));
+
+ if (ON == ZBX_MARIADB_SFORK)
+ {
+ flag = zbx_db_version_check("MariaDB", ZBX_MYSQL_SVERSION, ZBX_MARIA_MIN_VERSION, ZBX_DBVERSION_UNDEFINED);
+ zbx_db_version_json_create(json, "MariaDB", version_friendly,
+ ZBX_MARIA_MIN_VERSION_FRIENDLY, ZBX_MARIA_MAX_VERSION_FRIENDLY, flag);
+ }
+ else
+ {
+ flag = zbx_db_version_check("MySQL", ZBX_MYSQL_SVERSION, ZBX_MYSQL_MIN_VERSION, ZBX_MYSQL_MAX_VERSION);
+ zbx_db_version_json_create(json, "MySQL", version_friendly,
+ ZBX_MYSQL_MIN_VERSION_FRIENDLY, ZBX_MYSQL_MAX_VERSION_FRIENDLY, flag);
+ }
+
+ zbx_free(version_friendly);
+#elif defined(HAVE_POSTGRESQL)
+ int flag;
+ char *version_friendly;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+ ZBX_PG_SVERSION = PQserverVersion(conn);
+ version_friendly = zbx_dsprintf(NULL, "%d.%d.%d", RIGHT2(ZBX_PG_SVERSION/10000),
+ RIGHT2(ZBX_PG_SVERSION/100), RIGHT2(ZBX_PG_SVERSION));
+ flag = zbx_db_version_check("PostgreSQL", ZBX_PG_SVERSION, ZBX_POSTGRESQL_MIN_VERSION,
+ ZBX_POSTGRESQL_MAX_VERSION);
+ zbx_db_version_json_create(json, "PostgreSQL", version_friendly,
+ ZBX_POSTGRESQL_MIN_VERSION_FRIENDLY, ZBX_POSTGRESQL_MAX_VERSION_FRIENDLY, flag);
+ zbx_free(version_friendly);
+#elif defined(HAVE_ORACLE)
+# ifdef HAVE_OCI_SERVER_RELEASE2
+ char *version_str = "Version ";
+ ub4 oci_ver = 0;
+# endif
+ char *start, *release_str = "Release ";
+ char version_friendly[MAX_STRING_LEN / 8];
+ int flag, major_release_version, release_update_version, release_update_version_revision,
+ increment_version, reserved_for_future_use, overall_status = SUCCEED;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+# ifdef HAVE_OCI_SERVER_RELEASE2
+ if (OCI_SUCCESS != OCIServerRelease2(oracle.svchp, oracle.errhp, (OraText *) version_friendly,
+ (ub4)sizeof(version_friendly), OCI_HTYPE_SVCCTX, &oci_ver, OCI_DEFAULT))
+# else
+ if (OCI_SUCCESS != OCIServerVersion(oracle.svchp, oracle.errhp, (OraText *) version_friendly,
+ (ub4)sizeof(version_friendly), OCI_HTYPE_SVCCTX))
+# endif
+ {
+ overall_status = FAIL;
+ goto out;
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "OracleDB version retrieved unparsed: %s", version_friendly);
+
+ if (
+# ifdef HAVE_OCI_SERVER_RELEASE2
+ NULL != (start = strstr(version_friendly, version_str)) ||
+# endif
+ NULL != (start = strstr(version_friendly, release_str)))
+ {
+ size_t next_start_index;
+
+ next_start_index = start - version_friendly + strlen(release_str); /* same length for version_str */
+
+ if (5 != sscanf(version_friendly + next_start_index, "%d.%d.%d.%d.%d", &major_release_version,
+ &release_update_version, &release_update_version_revision, &increment_version,
+ &reserved_for_future_use) || major_release_version >= 100 ||
+ major_release_version <= 0 || release_update_version >= 100 ||
+ release_update_version < 0 || release_update_version_revision >= 100 ||
+ release_update_version_revision < 0 || increment_version >= 100 ||
+ increment_version < 0)
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "Unexpected Oracle DB version format: %s", version_friendly);
+ overall_status = FAIL;
+ }
+ }
+ else
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "Cannot find Release keyword in Oracle DB version.");
+ overall_status = FAIL;
+ }
+out:
+ if (FAIL == overall_status)
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "Failed to detect OracleDB version");
+ ZBX_ORACLE_SVERSION = ZBX_DBVERSION_UNDEFINED;
+ }
+ else
+ {
+ ZBX_ORACLE_SVERSION = major_release_version * 100000000 + release_update_version * 1000000 +
+ release_update_version_revision * 10000 + increment_version * 100 +
+ reserved_for_future_use;
+# ifndef HAVE_OCI_SERVER_RELEASE2
+ if (18 <= major_release_version)
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "Unable to determine the accurate Oracle DB version "
+ "(possibly there is a DB driver - DB version mismatch, "
+ "only the major Oracle DB version can be established): %s", version_friendly);
+ }
+# endif
+ }
+
+ flag = zbx_db_version_check("Oracle", ZBX_ORACLE_SVERSION, ZBX_ORACLE_MIN_VERSION, ZBX_ORACLE_MAX_VERSION);
+ zbx_db_version_json_create(json, "Oracle", version_friendly, ZBX_ORACLE_MIN_VERSION_FRIENDLY,
+ ZBX_ORACLE_MAX_VERSION_FRIENDLY, flag);
+#else
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+#endif
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s() version:%lu", __func__, (unsigned long)zbx_dbms_version_get());
+
+ return zbx_dbms_version_get();
+}
+
+#if defined(HAVE_POSTGRESQL)
/******************************************************************************
* *
* Function: zbx_tsdb_get_version *
diff --git a/src/libs/zbxdbhigh/db.c b/src/libs/zbxdbhigh/db.c
index 9b2b1fe7c17..7b4bdc7ab36 100644
--- a/src/libs/zbxdbhigh/db.c
+++ b/src/libs/zbxdbhigh/db.c
@@ -851,18 +851,65 @@ zbx_uint64_t DBget_maxid_num(const char *tablename, int num)
/******************************************************************************
* *
+ * Function: DBextract_version *
+ * *
+ * Purpose: connects to DB and tries to detect DB version *
+ * *
+ ******************************************************************************/
+zbx_uint32_t DBextract_version(struct zbx_json *json)
+{
+ zbx_uint32_t ret;
+
+ DBconnect(ZBX_DB_CONNECT_NORMAL);
+ ret = zbx_dbms_version_extract(json);
+ DBclose();
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Function: DBflush_version_requirements *
+ * *
+ * Purpose: writes a json entry in DB with the result for the front-end *
+ * *
+ * Parameters: version - [IN] entry of DB versions *
+ * *
+ ******************************************************************************/
+void DBflush_version_requirements(const char *version)
+{
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ DBconnect(ZBX_DB_CONNECT_NORMAL);
+
+ if (ZBX_DB_OK > DBexecute("update config set dbversion_status='%s'", version))
+ zabbix_log(LOG_LEVEL_CRIT, "Failed to set dbversion_status");
+
+ DBclose();
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+}
+
+/******************************************************************************
+ * *
* Function: DBcheck_capabilities *
* *
* Purpose: checks DBMS for optional features and exit if is not suitable *
* *
+ * Parameters: db_version - [IN] version of DB *
+ * *
+ * Return value: SUCCEED - if optional features were checked successfully *
+ * FAIL - otherwise *
+ * *
******************************************************************************/
-void DBcheck_capabilities(void)
+int DBcheck_capabilities(zbx_uint32_t db_version)
{
+ int ret = SUCCEED;
#ifdef HAVE_POSTGRESQL
#define MIN_POSTGRESQL_VERSION_WITH_TIMESCALEDB 100002
#define MIN_TIMESCALEDB_VERSION 10500
- int postgresql_version, timescaledb_version;
+ int timescaledb_version;
DB_RESULT result;
DB_ROW row;
@@ -880,22 +927,20 @@ void DBcheck_capabilities(void)
if (0 != zbx_strcmp_null(row[0], ZBX_CONFIG_DB_EXTENSION_TIMESCALE))
goto clean;
+ ret = FAIL; /* In case of major upgrade, db_extension may be missing */
+
/* Timescale compression feature is available in PostgreSQL 10.2 and TimescaleDB 1.5.0 */
- if (MIN_POSTGRESQL_VERSION_WITH_TIMESCALEDB > (postgresql_version = zbx_dbms_get_version()))
+ if (MIN_POSTGRESQL_VERSION_WITH_TIMESCALEDB > db_version)
{
- zabbix_log(LOG_LEVEL_CRIT, "PostgreSQL version %d is not supported with TimescaleDB, minimum is %d",
- postgresql_version, MIN_POSTGRESQL_VERSION_WITH_TIMESCALEDB);
- DBfree_result(result);
- DBclose();
- exit(EXIT_FAILURE);
+ zabbix_log(LOG_LEVEL_CRIT, "PostgreSQL version %lu is not supported with TimescaleDB, minimum is %d",
+ (unsigned long)db_version, MIN_POSTGRESQL_VERSION_WITH_TIMESCALEDB);
+ goto clean;
}
if (0 == (timescaledb_version = zbx_tsdb_get_version()))
{
zabbix_log(LOG_LEVEL_CRIT, "Cannot determine TimescaleDB version");
- DBfree_result(result);
- DBclose();
- exit(EXIT_FAILURE);
+ goto clean;
}
zabbix_log(LOG_LEVEL_INFORMATION, "TimescaleDB version: %d", timescaledb_version);
@@ -904,15 +949,18 @@ void DBcheck_capabilities(void)
{
zabbix_log(LOG_LEVEL_CRIT, "TimescaleDB version %d is not supported, minimum is %d",
timescaledb_version, MIN_TIMESCALEDB_VERSION);
- DBfree_result(result);
- DBclose();
- exit(EXIT_FAILURE);
+ goto clean;
}
+
+ ret = SUCCEED;
clean:
DBfree_result(result);
out:
DBclose();
+#else
+ ZBX_UNUSED(db_version);
#endif
+ return ret;
}
#define MAX_EXPRESSIONS 950
diff --git a/src/libs/zbxdbupgrade/dbupgrade_5030.c b/src/libs/zbxdbupgrade/dbupgrade_5030.c
index 58642d87a83..cbc421eb2fa 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_5030.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_5030.c
@@ -4654,6 +4654,13 @@ static int DBpatch_5030163(void)
return DBadd_field("config", &field);
}
+static int DBpatch_5030164(void)
+{
+ const ZBX_FIELD field = {"dbversion_status", "", NULL, NULL, 1024, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0};
+
+ return DBadd_field("config", &field);
+}
+
/* trigger function conversion to new syntax */
#define ZBX_DBPATCH_FUNCTION_UPDATE_NAME 0x01
@@ -5632,7 +5639,7 @@ static int dbpatch_convert_trigger(zbx_dbpatch_trigger_t *trigger, zbx_vector_pt
return SUCCEED;
}
-static int DBpatch_5030164(void)
+static int DBpatch_5030165(void)
{
int i, ret = SUCCEED;
DB_ROW row;
@@ -5776,7 +5783,7 @@ static int DBpatch_5030164(void)
return ret;
}
-static int DBpatch_5030165(void)
+static int DBpatch_5030166(void)
{
if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
return SUCCEED;
@@ -5966,7 +5973,7 @@ static int dbpatch_convert_expression_macro(const char *expression, const zbx_st
return SUCCEED;
}
-static int DBpatch_5030166(void)
+static int DBpatch_5030167(void)
{
DB_ROW row;
DB_RESULT result;
@@ -6160,7 +6167,7 @@ static char *dbpatch_formula_to_expression(zbx_uint64_t itemid, const char *form
return exp;
}
-static int DBpatch_5030167(void)
+static int DBpatch_5030168(void)
{
DB_ROW row;
DB_RESULT result;
@@ -6370,7 +6377,7 @@ static int dbpatch_aggregate2formula(const char *itemid, const AGENT_REQUEST *re
return SUCCEED;
}
-static int DBpatch_5030168(void)
+static int DBpatch_5030169(void)
{
DB_ROW row;
DB_RESULT result;
@@ -6429,7 +6436,7 @@ static int DBpatch_5030168(void)
return ret;
}
-static int DBpatch_5030169(void)
+static int DBpatch_5030170(void)
{
#ifdef HAVE_MYSQL
return DBcreate_index("items", "items_8", "key_(1024)", 0);
@@ -6614,5 +6621,6 @@ DBPATCH_ADD(5030166, 0, 1)
DBPATCH_ADD(5030167, 0, 1)
DBPATCH_ADD(5030168, 0, 1)
DBPATCH_ADD(5030169, 0, 1)
+DBPATCH_ADD(5030170, 0, 1)
DBPATCH_END()
diff --git a/src/libs/zbxhistory/history.c b/src/libs/zbxhistory/history.c
index 54bc95ba1a9..3afcdabd790 100644
--- a/src/libs/zbxhistory/history.c
+++ b/src/libs/zbxhistory/history.c
@@ -456,3 +456,16 @@ void zbx_history_value2variant(const history_value_t *value, unsigned char value
}
}
+/******************************************************************************
+ * *
+ * Function: zbx_history_check_version *
+ * *
+ * Purpose: relays the version retrieval logic to the history implementation *
+ * functions *
+ * *
+ ******************************************************************************/
+void zbx_history_check_version(struct zbx_json *json)
+{
+ if (NULL != CONFIG_HISTORY_STORAGE_URL)
+ zbx_elastic_version_extract(json);
+}
diff --git a/src/libs/zbxhistory/history.h b/src/libs/zbxhistory/history.h
index e086fa455db..710b9575d70 100644
--- a/src/libs/zbxhistory/history.h
+++ b/src/libs/zbxhistory/history.h
@@ -20,6 +20,8 @@
#ifndef ZABBIX_HISTORY_H
#define ZABBIX_HISTORY_H
+#include "zbxjson.h"
+
#define ZBX_HISTORY_IFACE_SQL 0
#define ZBX_HISTORY_IFACE_ELASTIC 1
@@ -48,5 +50,7 @@ int zbx_history_sql_init(zbx_history_iface_t *hist, unsigned char value_type, ch
/* elastic hist */
int zbx_history_elastic_init(zbx_history_iface_t *hist, unsigned char value_type, char **error);
+void zbx_elastic_version_extract(struct zbx_json *json);
+zbx_uint32_t zbx_elastic_version_get(void);
#endif
diff --git a/src/libs/zbxhistory/history_elastic.c b/src/libs/zbxhistory/history_elastic.c
index 313de56b563..c55e0a97a69 100644
--- a/src/libs/zbxhistory/history_elastic.c
+++ b/src/libs/zbxhistory/history_elastic.c
@@ -19,7 +19,6 @@
#include "common.h"
#include "log.h"
-#include "zbxjson.h"
#include "zbxalgo.h"
#include "dbcache.h"
#include "zbxhistory.h"
@@ -34,12 +33,13 @@
#define ZBX_IDX_JSON_ALLOCATE 256
#define ZBX_JSON_ALLOCATE 2048
-
const char *value_type_str[] = {"dbl", "str", "log", "uint", "text"};
extern char *CONFIG_HISTORY_STORAGE_URL;
extern int CONFIG_HISTORY_STORAGE_PIPELINES;
+static zbx_uint32_t ZBX_ELASTIC_SVERSION = ZBX_DBVERSION_UNDEFINED;
+
typedef struct
{
char *base_url;
@@ -479,7 +479,7 @@ try_again:
{
int fds;
CURLMcode code;
- char *error;
+ char *error;
zbx_curlpage_t *curl_page;
if (CURLM_OK != (code = curl_multi_perform(writer.handle, &running)))
@@ -1015,15 +1015,134 @@ int zbx_history_elastic_init(zbx_history_iface_t *hist, unsigned char value_type
return SUCCEED;
}
-#else
+/************************************************************************************
+ * *
+ * Function: zbx_elastic_version_extract *
+ * *
+ * Purpose: queries elastic search version and extracts the numeric version from *
+ * the response string *
+ * *
+ ************************************************************************************/
+void zbx_elastic_version_extract(struct zbx_json *json)
+{
+#define RIGHT2(x) ((int)((zbx_uint32_t)(x) - ((zbx_uint32_t)((x)/100))*100))
+ zbx_httppage_t page;
+ struct zbx_json_parse jp, jp_values, jp_sub;
+ struct curl_slist *curl_headers;
+ CURLcode err;
+ CURLoption opt;
+ CURL *handle;
+ size_t version_len = 0;
+ char *version_friendly = NULL, errbuf[CURL_ERROR_SIZE];
+ int flag, major_num, minor_num, increment_num, ret = FAIL;
+ zbx_uint32_t version;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ memset(&page, 0, sizeof(zbx_httppage_t));
+
+ if (0 != curl_global_init(CURL_GLOBAL_ALL))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot initialize cURL library");
+ goto out;
+ }
+
+ if (NULL == (handle = curl_easy_init()))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot initialize cURL session");
+ goto out;
+ }
+
+ curl_headers = curl_slist_append(NULL, "Content-Type: application/json");
+
+ if (CURLE_OK != (err = curl_easy_setopt(handle, opt = CURLOPT_URL, CONFIG_HISTORY_STORAGE_URL)) ||
+ CURLE_OK != (err = curl_easy_setopt(handle, opt = CURLOPT_WRITEFUNCTION, curl_write_cb)) ||
+ CURLE_OK != (err = curl_easy_setopt(handle, opt = CURLOPT_WRITEDATA, &page)) ||
+ CURLE_OK != (err = curl_easy_setopt(handle, opt = CURLOPT_HTTPHEADER, curl_headers)) ||
+ CURLE_OK != (err = curl_easy_setopt(handle, opt = CURLOPT_FAILONERROR, 1L)) ||
+ CURLE_OK != (err = curl_easy_setopt(handle, opt = CURLOPT_ERRORBUFFER, errbuf)))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot set cURL option %d: [%s]", (int)opt, curl_easy_strerror(err));
+ goto clean;
+ }
+
+ *errbuf = '\0';
+
+ if (CURLE_OK != (err = curl_easy_perform(handle)))
+ {
+ elastic_log_error(handle, err, errbuf);
+ goto clean;
+
+ }
+ if (SUCCEED != zbx_json_open(page.data, &jp) ||
+ SUCCEED != zbx_json_brackets_open(jp.start, &jp_values) ||
+ SUCCEED != zbx_json_brackets_by_name(&jp_values, "version", &jp_sub) ||
+ SUCCEED != zbx_json_value_by_name_dyn(&jp_sub, "number", &version_friendly, &version_len, NULL))
+ {
+ goto clean;
+ }
+
+ ret = SUCCEED;
+clean:
+ curl_slist_free_all(curl_headers);
+ curl_easy_cleanup(handle);
+out:
+ if (FAIL == ret)
+ {
+ zabbix_log(LOG_LEVEL_CRIT, "Failed to extract ElasticDB version");
+ version = ZBX_DBVERSION_UNDEFINED;
+ }
+ else
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "ElasticDB version retrieved unparsed: %s", version_friendly);
+
+ if (3 != sscanf(version_friendly, "%d.%d.%d", &major_num, &minor_num, &increment_num) ||
+ major_num >= 100 || major_num <= 0 || minor_num >= 100 || minor_num < 0 ||
+ increment_num >= 100 || increment_num < 0)
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "Failed to detect ElasticDB version from the "
+ "following query result: %s", version_friendly);
+ version = ZBX_DBVERSION_UNDEFINED;
+ }
+ else
+ {
+ version = major_num * 10000 + minor_num * 100 + increment_num;
+ }
+ }
+
+ flag = zbx_db_version_check("ElasticDB", version, ZBX_ELASTIC_MIN_VERSION, ZBX_DBVERSION_UNDEFINED);
+ zbx_db_version_json_create(json, "ElasticDB", version_friendly, ZBX_ELASTIC_MIN_VERSION_FRIENDLY, "", flag);
+ ZBX_ELASTIC_SVERSION = version;
+ zbx_free(version_friendly);
+ zbx_free(page.data);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s version:%lu", __func__, zbx_result_string(ret),
+ (unsigned long)version);
+}
+
+zbx_uint32_t zbx_elastic_version_get(void)
+{
+ return ZBX_ELASTIC_SVERSION;
+}
+#else
int zbx_history_elastic_init(zbx_history_iface_t *hist, unsigned char value_type, char **error)
{
ZBX_UNUSED(hist);
ZBX_UNUSED(value_type);
*error = zbx_strdup(*error, "cURL library support >= 7.28.0 is required for Elasticsearch history backend");
+
return FAIL;
}
+void zbx_elastic_version_extract(struct zbx_json *json)
+{
+ ZBX_UNUSED(json);
+}
+
+zbx_uint32_t zbx_elastic_version_get(void)
+{
+ return ZBX_DBVERSION_UNDEFINED;
+}
#endif
diff --git a/src/libs/zbxjson/json.c b/src/libs/zbxjson/json.c
index 7f73a05c0aa..5b0e4a6860e 100644
--- a/src/libs/zbxjson/json.c
+++ b/src/libs/zbxjson/json.c
@@ -875,11 +875,11 @@ static const char *zbx_json_copy_string(const char *p, char *out, size_t size)
while ('\0' != *p)
{
+ unsigned int nbytes, i;
+ unsigned char uc[4]; /* decoded Unicode character takes 1-4 bytes in UTF-8 */
+
switch (*p)
{
- unsigned int nbytes, i;
- unsigned char uc[4]; /* decoded Unicode character takes 1-4 bytes in UTF-8 */
-
case '\\':
++p;
if (0 == (nbytes = zbx_json_decode_character(&p, uc)))
diff --git a/src/libs/zbxtrends/cache.c b/src/libs/zbxtrends/cache.c
index 797eb56dfc8..f44f37fad79 100644
--- a/src/libs/zbxtrends/cache.c
+++ b/src/libs/zbxtrends/cache.c
@@ -90,7 +90,7 @@ static void tfc_free_slot(zbx_tfc_slot_t *slot)
cache->free_head = index;
}
-static zbx_tfc_slot_t *tfc_alloc_slot()
+static zbx_tfc_slot_t *tfc_alloc_slot(void)
{
zbx_uint32_t index;
@@ -289,7 +289,7 @@ static void tfc_free_data(zbx_tfc_data_t *data)
* Purpose: ensure there is a free slot available *
* *
******************************************************************************/
-static void tfc_reserve_slot()
+static void tfc_reserve_slot(void)
{
if (UINT32_MAX == cache->free_head && cache->slots_num == cache->free_slot)
{
diff --git a/src/zabbix_server/events.c b/src/zabbix_server/events.c
index 469c7e33939..67e599fa174 100644
--- a/src/zabbix_server/events.c
+++ b/src/zabbix_server/events.c
@@ -1829,6 +1829,7 @@ void zbx_export_events(void)
zbx_json_addint64(&json, ZBX_PROTO_TAG_VALUE, event->value);
zbx_json_adduint64(&json, ZBX_PROTO_TAG_EVENTID, event->eventid);
zbx_json_addstring(&json, ZBX_PROTO_TAG_NAME, event->name, ZBX_JSON_TYPE_STRING);
+ zbx_json_addint64(&json, ZBX_PROTO_TAG_SEVERITY, event->severity);
db_trigger_get_hosts(&hosts, &event->trigger);
diff --git a/src/zabbix_server/server.c b/src/zabbix_server/server.c
index f6b8b348f06..acf3b21a482 100644
--- a/src/zabbix_server/server.c
+++ b/src/zabbix_server/server.c
@@ -1058,6 +1058,23 @@ static void zbx_main_sigusr_handler(int flags)
}
+static void zbx_check_db(void)
+{
+ struct zbx_json db_ver;
+
+ zbx_json_initarray(&db_ver, ZBX_JSON_STAT_BUF_LEN);
+
+ if (SUCCEED != DBcheck_capabilities(DBextract_version(&db_ver)) || SUCCEED != DBcheck_version())
+ {
+ zbx_json_free(&db_ver);
+ exit(EXIT_FAILURE);
+ }
+
+ zbx_history_check_version(&db_ver);
+ DBflush_version_requirements(db_ver.buffer);
+ zbx_json_free(&db_ver);
+}
+
int MAIN_ZABBIX_ENTRY(int flags)
{
zbx_socket_t listen_sock;
@@ -1252,10 +1269,8 @@ int MAIN_ZABBIX_ENTRY(int flags)
exit(EXIT_FAILURE);
}
- DBcheck_capabilities();
+ zbx_check_db();
- if (SUCCEED != DBcheck_version())
- exit(EXIT_FAILURE);
DBcheck_character_set();
if (SUCCEED == DBcheck_double_type())