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:
authorDmitrijs Goloscapovs <dmitrijs.goloscapovs@zabbix.com>2022-11-07 15:02:25 +0300
committerDmitrijs Goloscapovs <dmitrijs.goloscapovs@zabbix.com>2022-11-07 15:02:25 +0300
commit0d725d08d1cd8287463c7a1ac9aae94dfd718b93 (patch)
tree0c497ca03967acb3223f573cec21241e12455dd5 /src
parent45aa479dacdba3c14093b05fcf97394f967ee118 (diff)
parenta7403cf21480121349e1e56e4ce33e5fc52fe016 (diff)
........S. [ZBX-21616] resolved conflict
Diffstat (limited to 'src')
-rw-r--r--src/go/go.mod61
-rw-r--r--src/go/go.sum219
-rw-r--r--src/go/internal/agent/scheduler/manager.go1
-rw-r--r--src/go/pkg/tls/tls.go47
-rw-r--r--src/go/pkg/version/version.go6
-rw-r--r--src/go/pkg/zbxlib/checks.go15
-rw-r--r--src/go/pkg/zbxlib/eventlog_windows.go13
-rw-r--r--src/go/pkg/zbxlib/expressions.go12
-rw-r--r--src/go/pkg/zbxlib/globals_windows.go3
-rw-r--r--src/go/pkg/zbxlib/log.go5
-rw-r--r--src/go/pkg/zbxlib/logfile.go16
-rw-r--r--src/go/pkg/zbxlib/nextcheck.go5
-rw-r--r--src/go/plugins/external/broker.go14
-rw-r--r--src/go/plugins/net/tcp/tcp_netstat.go4
-rw-r--r--src/go/plugins/net/udp/udp_netstat.go3
-rw-r--r--src/go/plugins/proc/proc_linux.go1
-rw-r--r--src/go/plugins/proc/procfs_linux.go3
-rw-r--r--src/go/plugins/system/cpu/cpu_linux.go3
-rw-r--r--src/go/plugins/vfs/file/encoding.go7
-rw-r--r--src/libs/zbxalgo/prediction.c2
-rw-r--r--src/libs/zbxcommon/components_strings_representations.c2
-rw-r--r--src/libs/zbxcommon/misc.c336
-rw-r--r--src/libs/zbxcrypto/crypto.c20
-rw-r--r--src/libs/zbxcrypto/hmac.c1
-rw-r--r--src/libs/zbxdb/db.c6
-rw-r--r--src/libs/zbxdbcache/dbconfig.c2598
-rw-r--r--src/libs/zbxdbcache/dbconfig.h175
-rw-r--r--src/libs/zbxdbcache/dbconfig_dump.c237
-rw-r--r--src/libs/zbxdbcache/dbconfig_maintenance.c6
-rw-r--r--src/libs/zbxdbcache/dbsync.c293
-rw-r--r--src/libs/zbxdbcache/dbsync.h10
-rw-r--r--src/libs/zbxdbcache/user_macro.c248
-rw-r--r--src/libs/zbxdbcache/user_macro.h15
-rw-r--r--src/libs/zbxdbcache/valuecache.c142
-rw-r--r--src/libs/zbxdbcache/valuecache.h9
-rw-r--r--src/libs/zbxdbhigh/graph_linking.c12
-rw-r--r--src/libs/zbxdbhigh/host.c48
-rw-r--r--src/libs/zbxdbhigh/proxy.c1910
-rw-r--r--src/libs/zbxdbhigh/template_item.c17
-rw-r--r--src/libs/zbxdbhigh/trigger_linking.c10
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_2010.c8
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_2030.c7
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_2050.c10
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_3010.c12
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_3030.c2
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_3050.c8
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_4030.c2
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_5010.c1
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_5030.c14
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_5050.c1
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_6010.c2
-rw-r--r--src/libs/zbxdbupgrade/dbupgrade_6030.c353
-rw-r--r--src/libs/zbxembed/global.c1
-rw-r--r--src/libs/zbxeval/execute.c2
-rw-r--r--src/libs/zbxeval/parse.c4
-rw-r--r--src/libs/zbxexpr/Makefile.am3
-rw-r--r--src/libs/zbxexpr/expr.c877
-rw-r--r--src/libs/zbxexpr/function.c555
-rw-r--r--src/libs/zbxexpr/host.c150
-rw-r--r--src/libs/zbxexpr/macro.c360
-rw-r--r--src/libs/zbxexpr/token.c10
-rw-r--r--src/libs/zbxlog/log.c4
-rw-r--r--src/libs/zbxmedia/email.c171
-rw-r--r--src/libs/zbxmodules/modules.c2
-rw-r--r--src/libs/zbxmutexs/mutexs.c2
-rw-r--r--src/libs/zbxnum/num.c42
-rw-r--r--src/libs/zbxparam/param.c2
-rw-r--r--src/libs/zbxrtc/rtc_client.c4
-rw-r--r--src/libs/zbxself/selfmon.c27
-rw-r--r--src/libs/zbxserver/anomalystl.c6
-rw-r--r--src/libs/zbxserver/calc_checks_eval.c16
-rw-r--r--src/libs/zbxserver/evalfunc.c2
-rw-r--r--src/libs/zbxserver/expression.c6
-rw-r--r--src/libs/zbxserver/zabbix_stats.c20
-rw-r--r--src/libs/zbxshmem/memalloc.c4
-rw-r--r--src/libs/zbxsysinfo/agent/agent.c4
-rw-r--r--src/libs/zbxsysinfo/aix/cpu.c5
-rw-r--r--src/libs/zbxsysinfo/aix/diskio.c5
-rw-r--r--src/libs/zbxsysinfo/aix/diskspace.c4
-rw-r--r--src/libs/zbxsysinfo/aix/hostname.c1
-rw-r--r--src/libs/zbxsysinfo/aix/inodes.c2
-rw-r--r--src/libs/zbxsysinfo/aix/net.c4
-rw-r--r--src/libs/zbxsysinfo/aix/proc.c4
-rw-r--r--src/libs/zbxsysinfo/aix/software.c2
-rw-r--r--src/libs/zbxsysinfo/aix/system.c2
-rw-r--r--src/libs/zbxsysinfo/aix/uptime.c4
-rw-r--r--src/libs/zbxsysinfo/alias/alias.c5
-rw-r--r--src/libs/zbxsysinfo/common/dir.c1
-rw-r--r--src/libs/zbxsysinfo/common/dns.c1
-rw-r--r--src/libs/zbxsysinfo/common/zabbix_stats.c2
-rw-r--r--src/libs/zbxsysinfo/common/zbxsysinfo_common.c2
-rw-r--r--src/libs/zbxsysinfo/freebsd/diskio.c6
-rw-r--r--src/libs/zbxsysinfo/freebsd/hostname.c1
-rw-r--r--src/libs/zbxsysinfo/freebsd/inodes.c3
-rw-r--r--src/libs/zbxsysinfo/freebsd/proc.c43
-rw-r--r--src/libs/zbxsysinfo/hpux/diskio.c2
-rw-r--r--src/libs/zbxsysinfo/hpux/hostname.c1
-rw-r--r--src/libs/zbxsysinfo/linux/diskio.c6
-rw-r--r--src/libs/zbxsysinfo/linux/hostname.c1
-rw-r--r--src/libs/zbxsysinfo/linux/inodes.c1
-rw-r--r--src/libs/zbxsysinfo/linux/memory.c4
-rw-r--r--src/libs/zbxsysinfo/netbsd/diskio.c2
-rw-r--r--src/libs/zbxsysinfo/netbsd/hostname.c1
-rw-r--r--src/libs/zbxsysinfo/netbsd/inodes.c1
-rw-r--r--src/libs/zbxsysinfo/openbsd/diskio.c2
-rw-r--r--src/libs/zbxsysinfo/openbsd/hostname.c1
-rw-r--r--src/libs/zbxsysinfo/osf/diskio.c2
-rw-r--r--src/libs/zbxsysinfo/osf/diskspace.c1
-rw-r--r--src/libs/zbxsysinfo/osf/hostname.c1
-rw-r--r--src/libs/zbxsysinfo/osf/inodes.c1
-rw-r--r--src/libs/zbxsysinfo/osf/memory.c12
-rw-r--r--src/libs/zbxsysinfo/osf/swap.c12
-rw-r--r--src/libs/zbxsysinfo/osx/diskio.c2
-rw-r--r--src/libs/zbxsysinfo/osx/hostname.c1
-rw-r--r--src/libs/zbxsysinfo/solaris/Makefile.am2
-rw-r--r--src/libs/zbxsysinfo/solaris/boottime.c1
-rw-r--r--src/libs/zbxsysinfo/solaris/cpu.c1
-rw-r--r--src/libs/zbxsysinfo/solaris/diskio.c10
-rw-r--r--src/libs/zbxsysinfo/solaris/hostname.c1
-rw-r--r--src/libs/zbxsysinfo/solaris/inodes.c1
-rw-r--r--src/libs/zbxsysinfo/solaris/net.c1
-rw-r--r--src/libs/zbxsysinfo/solaris/zbx_sysinfo_kstat.c41
-rw-r--r--src/libs/zbxsysinfo/solaris/zbx_sysinfo_kstat.h (renamed from src/zabbix_server/trapper/proxyconfig.h)16
-rw-r--r--src/libs/zbxsysinfo/sysinfo.c159
-rw-r--r--src/libs/zbxsysinfo/sysinfo.h45
-rw-r--r--src/libs/zbxsysinfo/unknown/diskio.c2
-rw-r--r--src/libs/zbxsysinfo/win32/diskio.c2
-rw-r--r--src/libs/zbxthreads/threads.c13
-rw-r--r--src/libs/zbxversion/version.c53
-rw-r--r--src/libs/zbxwin32/fatal.c6
-rw-r--r--src/libs/zbxwin32/service.c13
-rw-r--r--src/zabbix_agent/active.c18
-rw-r--r--src/zabbix_agent/diskdevices.c2
-rw-r--r--src/zabbix_agent/eventlog.c6
-rw-r--r--src/zabbix_agent/listener.c8
-rw-r--r--src/zabbix_agent/logfiles/logfiles.c6
-rw-r--r--src/zabbix_agent/zabbix_agentd.c33
-rw-r--r--src/zabbix_agent/zbxconf.c19
-rw-r--r--src/zabbix_java/src/com/zabbix/gateway/GeneralInformation.java4
-rw-r--r--src/zabbix_proxy/Makefile.am6
-rw-r--r--src/zabbix_proxy/datasender/datasender.c10
-rw-r--r--src/zabbix_proxy/heart/Makefile.am7
-rw-r--r--src/zabbix_proxy/heart/heart.c165
-rw-r--r--src/zabbix_proxy/housekeeper/housekeeper.c2
-rw-r--r--src/zabbix_proxy/proxy.c81
-rw-r--r--src/zabbix_proxy/proxyconfig/Makefile.am2
-rw-r--r--src/zabbix_proxy/proxyconfig/proxyconfig.c129
-rw-r--r--src/zabbix_proxy/proxyconfigwrite/Makefile.am9
-rw-r--r--src/zabbix_proxy/proxyconfigwrite/proxyconfig_write.c2133
-rw-r--r--src/zabbix_proxy/proxyconfigwrite/proxyconfig_write.h (renamed from src/zabbix_proxy/heart/heart.h)18
-rw-r--r--src/zabbix_proxy/stats/zabbix_stats.h3
-rw-r--r--src/zabbix_proxy/stats/zabbix_stats_proxy.c35
-rw-r--r--src/zabbix_proxy/taskmanager/server_tasks.c10
-rw-r--r--src/zabbix_proxy/taskmanager/taskmanager.c26
-rw-r--r--src/zabbix_proxy/taskmanager/taskmanager.h2
-rw-r--r--src/zabbix_server/Makefile.am4
-rw-r--r--src/zabbix_server/actions.c243
-rw-r--r--src/zabbix_server/alerter/alert_manager.c6
-rw-r--r--src/zabbix_server/alerter/alert_syncer.c2
-rw-r--r--src/zabbix_server/alerter/alerter.c8
-rw-r--r--src/zabbix_server/availability/avail_manager.c6
-rw-r--r--src/zabbix_server/dbconfig/Makefile.am2
-rw-r--r--src/zabbix_server/dbconfig/dbconfig.c27
-rw-r--r--src/zabbix_server/dbsyncer/dbsyncer.c2
-rw-r--r--src/zabbix_server/discoverer/discoverer.c148
-rw-r--r--src/zabbix_server/escalator/escalator.c16
-rw-r--r--src/zabbix_server/events.c40
-rw-r--r--src/zabbix_server/ha/ha.h17
-rw-r--r--src/zabbix_server/ha/ha_manager.c100
-rw-r--r--src/zabbix_server/housekeeper/housekeeper.c4
-rw-r--r--src/zabbix_server/housekeeper/trigger_housekeeper.c2
-rw-r--r--src/zabbix_server/httppoller/httppoller.c59
-rw-r--r--src/zabbix_server/httppoller/httptest.c217
-rw-r--r--src/zabbix_server/httppoller/httptest.h4
-rw-r--r--src/zabbix_server/ipmi/ipmi_manager.c10
-rw-r--r--src/zabbix_server/ipmi/ipmi_poller.c6
-rw-r--r--src/zabbix_server/lld/lld.c39
-rw-r--r--src/zabbix_server/lld/lld_item.c4
-rw-r--r--src/zabbix_server/lld/lld_manager.c6
-rw-r--r--src/zabbix_server/lld/lld_worker.c6
-rw-r--r--src/zabbix_server/odbc/odbc.c9
-rw-r--r--src/zabbix_server/operations.c4
-rw-r--r--src/zabbix_server/pinger/pinger.c25
-rw-r--r--src/zabbix_server/poller/checks_agent.c2
-rw-r--r--src/zabbix_server/poller/checks_db.c6
-rw-r--r--src/zabbix_server/poller/checks_external.c8
-rw-r--r--src/zabbix_server/poller/checks_internal.c23
-rw-r--r--src/zabbix_server/poller/checks_internal.h3
-rw-r--r--src/zabbix_server/poller/checks_internal_server.c75
-rw-r--r--src/zabbix_server/poller/checks_java.c2
-rw-r--r--src/zabbix_server/poller/checks_simple.c8
-rw-r--r--src/zabbix_server/poller/checks_simple_vmware.c6
-rw-r--r--src/zabbix_server/poller/checks_snmp.c54
-rw-r--r--src/zabbix_server/poller/checks_ssh.c6
-rw-r--r--src/zabbix_server/poller/checks_telnet.c6
-rw-r--r--src/zabbix_server/poller/poller.c30
-rw-r--r--src/zabbix_server/poller/poller.h7
-rw-r--r--src/zabbix_server/postinit.c6
-rw-r--r--src/zabbix_server/preprocessor/preproc_manager.c28
-rw-r--r--src/zabbix_server/preprocessor/preproc_worker.c6
-rw-r--r--src/zabbix_server/preprocessor/preprocessing.c4
-rw-r--r--src/zabbix_server/proxyconfigread/Makefile.am9
-rw-r--r--src/zabbix_server/proxyconfigread/proxyconfig_read.c1201
-rw-r--r--src/zabbix_server/proxyconfigread/proxyconfig_read.h36
-rw-r--r--src/zabbix_server/proxypoller/Makefile.am1
-rw-r--r--src/zabbix_server/proxypoller/proxypoller.c109
-rw-r--r--src/zabbix_server/reporter/report_manager.c7
-rw-r--r--src/zabbix_server/reporter/report_writer.c6
-rw-r--r--src/zabbix_server/scripts/scripts.c10
-rw-r--r--src/zabbix_server/selfmon/selfmon.c4
-rw-r--r--src/zabbix_server/server.c91
-rw-r--r--src/zabbix_server/service/service_actions.c12
-rw-r--r--src/zabbix_server/service/service_manager.c35
-rw-r--r--src/zabbix_server/snmptrapper/snmptrapper.c16
-rw-r--r--src/zabbix_server/stats/zabbix_stats.h3
-rw-r--r--src/zabbix_server/stats/zabbix_stats_server.c23
-rw-r--r--src/zabbix_server/taskmanager/proxy_tasks.c16
-rw-r--r--src/zabbix_server/taskmanager/taskmanager.c102
-rw-r--r--src/zabbix_server/timer/timer.c2
-rw-r--r--src/zabbix_server/trapper/Makefile.am6
-rw-r--r--src/zabbix_server/trapper/active.c32
-rw-r--r--src/zabbix_server/trapper/proxyconfig.c165
-rw-r--r--src/zabbix_server/trapper/proxydata.c39
-rw-r--r--src/zabbix_server/trapper/proxydata.h4
-rw-r--r--src/zabbix_server/trapper/trapper.c243
-rw-r--r--src/zabbix_server/trapper/trapper.h2
-rw-r--r--src/zabbix_server/trapper/trapper_auth.c1
-rw-r--r--src/zabbix_server/trapper/trapper_item_test.c13
-rw-r--r--src/zabbix_server/trapper/trapper_item_test.h6
-rw-r--r--src/zabbix_server/trapper/trapper_proxy.c38
-rw-r--r--src/zabbix_server/trapper/trapper_request.h3
-rw-r--r--src/zabbix_server/trapper/trapper_server.c12
-rw-r--r--src/zabbix_server/vmware/vmware_manager.c6
233 files changed, 10517 insertions, 5513 deletions
diff --git a/src/go/go.mod b/src/go/go.mod
index a49e83baa4d..e1592e57866 100644
--- a/src/go/go.mod
+++ b/src/go/go.mod
@@ -1,33 +1,60 @@
module zabbix.com
-go 1.16
+go 1.18
require (
- git.zabbix.com/ap/plugin-support v0.0.0-20220608100211-35b8bffd7ad0
+ git.zabbix.com/ap/plugin-support v1.1.0
github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69
github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5
- github.com/chromedp/cdproto v0.0.0-20210104223854-2cc87dae3ee3
- github.com/chromedp/chromedp v0.6.0
+ github.com/chromedp/cdproto v0.0.0-20220827030233-358ed4af73cf
+ github.com/chromedp/chromedp v0.8.5
github.com/dustin/gomemcached v0.0.0-20160817010731-a2284a01c143
- github.com/eclipse/paho.mqtt.golang v1.2.0
- github.com/fsnotify/fsnotify v1.4.9
+ github.com/eclipse/paho.mqtt.golang v1.4.1
+ github.com/fsnotify/fsnotify v1.5.4
github.com/go-ldap/ldap v3.0.3+incompatible
- github.com/go-ole/go-ole v1.2.4
- github.com/go-sql-driver/mysql v1.5.0
+ github.com/go-ole/go-ole v1.2.6
+ github.com/go-sql-driver/mysql v1.6.0
github.com/goburrow/modbus v0.1.0
- github.com/goburrow/serial v0.1.0 // indirect
github.com/godbus/dbus v4.1.0+incompatible
- github.com/godror/godror v0.20.1
- github.com/jackc/pgx/v4 v4.8.2-0.20200910143026-040df1ccef85
- github.com/mattn/go-sqlite3 v1.14.8
- github.com/mediocregopher/radix/v3 v3.5.0
- github.com/memcachier/mc/v3 v3.0.1
- github.com/miekg/dns v1.1.43
+ github.com/godror/godror v0.34.0
+ github.com/jackc/pgx/v4 v4.17.2
+ github.com/mattn/go-sqlite3 v1.14.15
+ github.com/mediocregopher/radix/v3 v3.8.1
+ github.com/memcachier/mc/v3 v3.0.3
+ github.com/miekg/dns v1.1.50
github.com/natefinch/npipe v0.0.0-20160621034901-c1b8fa8bdcce
github.com/omeid/go-yarn v0.0.1
+ golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64
+)
+
+require (
+ github.com/chromedp/sysutil v1.0.0 // indirect
+ github.com/go-logfmt/logfmt v0.5.1 // indirect
+ github.com/go-logr/logr v1.2.3 // indirect
+ github.com/goburrow/serial v0.1.0 // indirect
+ github.com/gobwas/httphead v0.1.0 // indirect
+ github.com/gobwas/pool v0.2.1 // indirect
+ github.com/gobwas/ws v1.1.0 // indirect
+ github.com/godror/knownpb v0.1.0 // indirect
+ github.com/gorilla/websocket v1.4.2 // indirect
+ github.com/jackc/chunkreader/v2 v2.0.1 // indirect
+ github.com/jackc/pgconn v1.13.0 // indirect
+ github.com/jackc/pgio v1.0.0 // indirect
+ github.com/jackc/pgpassfile v1.0.0 // indirect
+ github.com/jackc/pgproto3/v2 v2.3.1 // indirect
+ github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
+ github.com/jackc/pgtype v1.12.0 // indirect
+ github.com/jackc/puddle v1.3.0 // indirect
+ github.com/josharian/intern v1.0.0 // indirect
+ github.com/mailru/easyjson v0.7.7 // indirect
github.com/pkg/errors v0.9.1 // indirect
- golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5
+ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect
+ golang.org/x/mod v0.4.2 // indirect
+ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
+ golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 // indirect
+ golang.org/x/text v0.3.7 // indirect
+ golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
+ google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
- gopkg.in/yaml.v2 v2.2.8 // indirect
)
diff --git a/src/go/go.sum b/src/go/go.sum
index 52f19406c56..e204247a5fe 100644
--- a/src/go/go.sum
+++ b/src/go/go.sum
@@ -1,26 +1,16 @@
-git.zabbix.com/ap/plugin-support v0.0.0-20220524072909-7233a93fe116 h1:IGbQPDh/U7UHSM0M4h2k/wdRjyO3zG8uq4Dx+gej4y8=
-git.zabbix.com/ap/plugin-support v0.0.0-20220524072909-7233a93fe116/go.mod h1:R3QzQWgpxlA+ddJNkOhsPTcGOVtrR69WS0hXIsnBurY=
-git.zabbix.com/ap/plugin-support v0.0.0-20220524082638-7fd18350f78d h1:fv+sfiIPe6U8X0T+vrpI4bBpo5kzYnp9qxNwA30Ay/U=
-git.zabbix.com/ap/plugin-support v0.0.0-20220524082638-7fd18350f78d/go.mod h1:R3QzQWgpxlA+ddJNkOhsPTcGOVtrR69WS0hXIsnBurY=
-git.zabbix.com/ap/plugin-support v0.0.0-20220525103006-9363aae69d10 h1:zRmgkxzcYbFXMmHgLQ0i3FIOUhqLKK6uCTF/Fdlbl00=
-git.zabbix.com/ap/plugin-support v0.0.0-20220525103006-9363aae69d10/go.mod h1:R3QzQWgpxlA+ddJNkOhsPTcGOVtrR69WS0hXIsnBurY=
-git.zabbix.com/ap/plugin-support v0.0.0-20220530082632-bd6f3ae15c88 h1:a/w3gm8CKYRkw7gRu6+ufdCAadmWjnh4LNHqQRG3Nu4=
-git.zabbix.com/ap/plugin-support v0.0.0-20220530082632-bd6f3ae15c88/go.mod h1:R3QzQWgpxlA+ddJNkOhsPTcGOVtrR69WS0hXIsnBurY=
-git.zabbix.com/ap/plugin-support v0.0.0-20220601115430-7e21b812be52 h1:dgk5oJtySHzjkkzfELzM4tkAQbjJO9krfj0GJQMXdS4=
-git.zabbix.com/ap/plugin-support v0.0.0-20220601115430-7e21b812be52/go.mod h1:R3QzQWgpxlA+ddJNkOhsPTcGOVtrR69WS0hXIsnBurY=
-git.zabbix.com/ap/plugin-support v0.0.0-20220608100211-35b8bffd7ad0 h1:VZuQnO95vu+83jsQaY+HGDzx+SoTf8inEZFkZhPvZtM=
-git.zabbix.com/ap/plugin-support v0.0.0-20220608100211-35b8bffd7ad0/go.mod h1:R3QzQWgpxlA+ddJNkOhsPTcGOVtrR69WS0hXIsnBurY=
-git.zabbix.com/ap/plugin-support v0.0.2 h1:ce5LDuqEK4yYrD0g2BNWrSlnr33AVB3QT4G3wmjhDts=
-git.zabbix.com/ap/plugin-support v0.0.2/go.mod h1:R3QzQWgpxlA+ddJNkOhsPTcGOVtrR69WS0hXIsnBurY=
+git.zabbix.com/ap/plugin-support v1.1.0 h1:t2a2ijsup3KSm0fXkPr9mnQw9xPskZ0PzWnQwGVjxzw=
+git.zabbix.com/ap/plugin-support v1.1.0/go.mod h1:R3QzQWgpxlA+ddJNkOhsPTcGOVtrR69WS0hXIsnBurY=
github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69 h1:+tu3HOoMXB7RXEINRVIpxJCT+KdYiI7LAEAUrOw3dIU=
github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69/go.mod h1:L1AbZdiDllfyYH5l5OkAaZtk7VkWe89bPJFmnDBNHxg=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
+github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5 h1:BjkPE3785EwPhhyuFkbINB+2a1xATwk8SNDWnJiD41g=
github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5/go.mod h1:jtAfVaU/2cu1+wdSRPWE2c1N2qeAA3K4RH9pYgqwets=
-github.com/chromedp/cdproto v0.0.0-20210104223854-2cc87dae3ee3 h1:XeGYLuu3Yu3/2/FLDXyObe6lBYtUFDTJgjjNPcfcU40=
-github.com/chromedp/cdproto v0.0.0-20210104223854-2cc87dae3ee3/go.mod h1:55pim6Ht4LJKdVLlyFJV/g++HsEA1hQxPbB5JyNdZC0=
-github.com/chromedp/chromedp v0.6.0 h1:jjzHzXW5pNdKt1D9cEDAKZM/yZ2EwL/hLyGbCUFldBI=
-github.com/chromedp/chromedp v0.6.0/go.mod h1:Yay7TUDCNOQBK8EJDUon6AUaQI12VEBOuULcGtY4uDY=
+github.com/chromedp/cdproto v0.0.0-20220827030233-358ed4af73cf h1:e0oJZmGJidTRZ0FvWXNhdj9OaOMN30Yf+T3K2Tf3L+s=
+github.com/chromedp/cdproto v0.0.0-20220827030233-358ed4af73cf/go.mod h1:5Y4sD/eXpwrChIuxhSr/G20n9CdbCmoerOHnuAf0Zr0=
+github.com/chromedp/chromedp v0.8.5 h1:HAVg54yQFcn7sg5reVjXtoI1eQaFxhjAjflHACicUFw=
+github.com/chromedp/chromedp v0.8.5/go.mod h1:xal2XY5Di7m/bzlGwtoYpmgIOfDqCakOIVg5OfdkPZ4=
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
@@ -33,18 +23,22 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/gomemcached v0.0.0-20160817010731-a2284a01c143 h1:K9CFK8HRZWzmoIWbpA7u0XYLggCyfa/N77eVaq/nUiA=
github.com/dustin/gomemcached v0.0.0-20160817010731-a2284a01c143/go.mod h1:BLhrehfVmtABJWBZTJV8HyPWCSZoiMzjjcZ3+vHHhPI=
-github.com/eclipse/paho.mqtt.golang v1.2.0 h1:1F8mhG9+aO5/xpdtFkW4SxOJB67ukuDC3t2y2qayIX0=
-github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
-github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
-github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/eclipse/paho.mqtt.golang v1.4.1 h1:tUSpviiL5G3P9SZZJPC4ZULZJsxQKXxfENpMvdbAXAI=
+github.com/eclipse/paho.mqtt.golang v1.4.1/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA=
+github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
+github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
+github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-ldap/ldap v3.0.3+incompatible h1:HTeSZO8hWMS1Rgb2Ziku6b8a7qRIZZMHjsvuZyatzwk=
github.com/go-ldap/ldap v3.0.3+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
-github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
-github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
-github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
-github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
-github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
+github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
+github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
+github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
+github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
+github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
+github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/goburrow/modbus v0.1.0 h1:DejRZY73nEM6+bt5JSP6IsFolJ9dVcqxsYbpLbeW/ro=
github.com/goburrow/modbus v0.1.0/go.mod h1:Kx552D5rLIS8E7TyUwQ/UdHEqvX5T8tyiGBTlzMcZBg=
@@ -54,18 +48,22 @@ github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
-github.com/gobwas/ws v1.0.4 h1:5eXU1CZhpQdq5kXbKb+sECH5Ia5KiO6CYzIzdlVx6Bs=
-github.com/gobwas/ws v1.0.4/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
+github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
+github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
github.com/godbus/dbus v4.1.0+incompatible h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4=
github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
-github.com/godror/godror v0.20.1 h1:s/ehD65nfVzWR2MrZGChDkLvVPlIVxbt+Jpzfwkl1c8=
-github.com/godror/godror v0.20.1/go.mod h1:YlPoIf962ZZKPM5Xqa8NxmGgck39pi51tqAs+K3IaFM=
-github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
-github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
-github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
-github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/godror/godror v0.34.0 h1:/D40cxuWY3PtMa1oIcfXqqInlts5anEL3vj6IkTW8Q8=
+github.com/godror/godror v0.34.0/go.mod h1:9QtjJWw+r1v9zh93Qx+hSOfYRVgj11a/7TUnU/00Wbc=
+github.com/godror/knownpb v0.1.0 h1:dJPK8s/I3PQzGGaGcUStL2zIaaICNzKKAK8BzP1uLio=
+github.com/godror/knownpb v0.1.0/go.mod h1:4nRFbQo1dDuwKnblRXDxrfCFYeT4hjg3GjMqef58eRE=
+github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
+github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
+github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
@@ -73,51 +71,47 @@ github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgO
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
-github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk=
-github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
-github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
-github.com/jackc/pgconn v1.6.5-0.20200905181414-0d4f029683fc h1:9ThyBXKdyBFN2Y1NSCPGCA0kdWCNpd9u4SKWwtr6GfU=
-github.com/jackc/pgconn v1.6.5-0.20200905181414-0d4f029683fc/go.mod h1:gm9GeeZiC+Ja7JV4fB/MNDeaOqsCrzFiZlLVhAompxk=
+github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
+github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
+github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
+github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys=
+github.com/jackc/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI=
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
-github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
+github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
+github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc=
+github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
-github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
-github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
-github.com/jackc/pgproto3/v2 v2.0.4 h1:RHkX5ZUD9bl/kn0f9dYUWs1N7Nwvo1wwUYvKiR26Zco=
-github.com/jackc/pgproto3/v2 v2.0.4/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
-github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
+github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y=
+github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
-github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0=
-github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po=
-github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ=
-github.com/jackc/pgtype v1.4.3-0.20200905161353-e7d2b057a716 h1:DrP52jA32liWkjCF/g3rYC1QjnRh6kvyXaZSevAtlqE=
-github.com/jackc/pgtype v1.4.3-0.20200905161353-e7d2b057a716/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig=
+github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
+github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w=
+github.com/jackc/pgtype v1.12.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
-github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA=
-github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o=
-github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg=
-github.com/jackc/pgx/v4 v4.8.2-0.20200910143026-040df1ccef85 h1:G5gbS1Q6cq7/Q1Z1CUqU9IKWfar2R1P6CE0zkKClEG0=
-github.com/jackc/pgx/v4 v4.8.2-0.20200910143026-040df1ccef85/go.mod h1:OWJpVJk5U9XXEiYHeQ+5NtRt82Y5c8gvIZj96kl27Ow=
+github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
+github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E=
+github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw=
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
-github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
-github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
-github.com/jackc/puddle v1.1.2-0.20200821025810-91d0159cc97a h1:ec2LCBkfN1pOq0PhLRH/QitjSXr9s2dnh0gOFyohxHM=
-github.com/jackc/puddle v1.1.2-0.20200821025810-91d0159cc97a/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0=
+github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@@ -127,33 +121,33 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
-github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
-github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
+github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
+github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
-github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU=
-github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
-github.com/mediocregopher/radix/v3 v3.5.0 h1:8QHQmNh2ne9aFxTD3z63u/bkPPiOtknHoz80oP8EA/E=
-github.com/mediocregopher/radix/v3 v3.5.0/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
-github.com/memcachier/mc/v3 v3.0.1 h1:Os/fUl/8c+hc1qWgjv5hNK0JI6GxKUOuehzB/UmjLP0=
-github.com/memcachier/mc/v3 v3.0.1/go.mod h1:GzjocBahcXPxt2cmqzknrgqCOmMxiSzhVKPOe90Tpug=
-github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
-github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
+github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
+github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
+github.com/mediocregopher/radix/v3 v3.8.1 h1:rOkHflVuulFKlwsLY01/M2cM2tWCjDoETcMqKbAWu1M=
+github.com/mediocregopher/radix/v3 v3.8.1/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
+github.com/memcachier/mc/v3 v3.0.3 h1:qii+lDiPKi36O4Xg+HVKwHu6Oq+Gt17b+uEiA0Drwv4=
+github.com/memcachier/mc/v3 v3.0.3/go.mod h1:GzjocBahcXPxt2cmqzknrgqCOmMxiSzhVKPOe90Tpug=
+github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
+github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/natefinch/npipe v0.0.0-20160621034901-c1b8fa8bdcce h1:TqjP/BTDrwN7zP9xyXVuLsMBXYMt6LLYi55PlrIcq8U=
github.com/natefinch/npipe v0.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:ifHPsLndGGzvgzcaXUvzmt6LxKT4pJ+uzEhtnMt+f7A=
+github.com/oklog/ulid/v2 v2.0.2 h1:r4fFzBm+bv0wNKNh5eXTwU7i85y5x+uwkxCUTNVQqLc=
github.com/omeid/go-yarn v0.0.1 h1:mUQExNwUrYn7tZRwQdsUuoQWHIujtjjpjb/PAtUj9dk=
github.com/omeid/go-yarn v0.0.1/go.mod h1:JYxmAvShSw7YmX/9vFsccpJE4o/KW111eUh3n/TQ5h8=
+github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -165,47 +159,65 @@ github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OK
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
-github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc h1:jUIKcSPO9MoMJBbEoyE/RJoE8vz7Mb8AjvifMMwSyvY=
-github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
+github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
+golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
+golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4=
+golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -213,20 +225,30 @@ golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 h1:y/woIyUBFbpQGKS0u1aHF/40WUDnek3fPOyD08H5Vng=
-golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 h1:UiNENfZ8gDvpiWw7IpOMQ27spWmThO1RwwdQVbJahJM=
+golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
@@ -234,6 +256,10 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0=
+golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -241,6 +267,9 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
+google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -248,8 +277,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
-gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
-gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
diff --git a/src/go/internal/agent/scheduler/manager.go b/src/go/internal/agent/scheduler/manager.go
index fa0c32abc0a..14e96f4d012 100644
--- a/src/go/internal/agent/scheduler/manager.go
+++ b/src/go/internal/agent/scheduler/manager.go
@@ -527,6 +527,7 @@ func (m *Manager) init() {
if metric.Plugin.IsExternal() {
ext := metric.Plugin.(*external.Plugin)
+ metric.Plugin.SetCapacity(1)
log.Infof("using plugin '%s' (%s) providing following interfaces: %s", metric.Plugin.Name(),
ext.Path, interfaces)
} else {
diff --git a/src/go/pkg/tls/tls.go b/src/go/pkg/tls/tls.go
index 4a73e81456c..be240db2e34 100644
--- a/src/go/pkg/tls/tls.go
+++ b/src/go/pkg/tls/tls.go
@@ -961,6 +961,7 @@ func SupportedErrMsg() string {
}
func init() {
+ log.Tracef("Calling C function \"tls_init()\"")
supported = C.tls_init() != -1
if !supported {
@@ -970,8 +971,10 @@ func init() {
func describeCiphersuites(context unsafe.Pointer) (desc string) {
var cDesc *C.char
+ log.Tracef("Calling C function \"tls_describe_ciphersuites()\"")
C.tls_describe_ciphersuites(C.SSL_CTX_LP(context), &cDesc)
desc = C.GoString(cDesc)
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cDesc))
return
}
@@ -987,8 +990,10 @@ type tlsConn struct {
func (c *tlsConn) Error() (err error) {
var cBuf *C.char
var errmsg string
+ log.Tracef("Calling C function \"tls_error()\"")
if c.tls != nil && 0 != C.tls_error((*C.tls_t)(c.tls), &cBuf) {
errmsg = C.GoString(cBuf)
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cBuf))
} else {
errmsg = "unknown openssl error"
@@ -997,12 +1002,14 @@ func (c *tlsConn) Error() (err error) {
}
func (c *tlsConn) ready() bool {
+ log.Tracef("Calling C function \"tls_ready()\"")
return C.tls_ready((*C.tls_t)(c.tls)) == 1
}
// Note, don't use flushTLS() and recvTLS() concurrently
func (c *tlsConn) flushTLS() (err error) {
for {
+ log.Tracef("Calling C function \"tls_recv()\"")
if cn := C.tls_recv((*C.tls_t)(c.tls), (*C.char)(unsafe.Pointer(&c.buf[0])), C.int(len(c.buf))); cn > 0 {
if c.shiftDeadline {
if err = c.conn.SetWriteDeadline(time.Now().Add(c.timeout)); err != nil {
@@ -1030,6 +1037,7 @@ func (c *tlsConn) recvTLS() (err error) {
if n, err = c.conn.Read(c.buf); err != nil {
return
}
+ log.Tracef("Calling C function \"tls_send()\"")
C.tls_send((*C.tls_t)(c.tls), (*C.char)(unsafe.Pointer(&c.buf[0])), C.int(n))
return
}
@@ -1055,9 +1063,11 @@ func (c *tlsConn) SetWriteDeadline(t time.Time) error {
}
func (c *tlsConn) Close() (err error) {
+ log.Tracef("Calling C function \"tls_close()\"")
cr := C.tls_close((*C.tls_t)(c.tls))
c.conn.Close()
+ log.Tracef("Calling C function \"tls_free()\"")
C.tls_free((*C.tls_t)(c.tls))
c.tls = nil
@@ -1072,12 +1082,15 @@ func (c *tlsConn) verifyIssuerSubject(cfg *Config) (err error) {
var cSubject, cIssuer *C.char
if cfg.ServerCertIssuer != "" {
cIssuer = C.CString(cfg.ServerCertIssuer)
+ log.Tracef("Calling C function \"free()\"")
defer C.free(unsafe.Pointer(cSubject))
}
if cfg.ServerCertSubject != "" {
cSubject = C.CString(cfg.ServerCertSubject)
+ log.Tracef("Calling C function \"free()\"")
defer C.free(unsafe.Pointer(cSubject))
}
+ log.Tracef("Calling C function \"tls_validate_issuer_and_subject()\"")
if 0 != C.tls_validate_issuer_and_subject((*C.tls_t)(c.tls), cIssuer, cSubject) {
return c.Error()
}
@@ -1087,8 +1100,10 @@ func (c *tlsConn) verifyIssuerSubject(cfg *Config) (err error) {
func (c *tlsConn) String() (desc string) {
var cDesc *C.char
+ log.Tracef("Calling C function \"tls_description()\"")
C.tls_description((*C.tls_t)(c.tls), &cDesc)
desc = C.GoString(cDesc)
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cDesc))
return
}
@@ -1099,10 +1114,13 @@ type Client struct {
}
func (c *Client) checkConnection() (err error) {
+ log.Tracef("Calling C function \"tls_connected()\"")
if C.tls_connected((*C.tls_t)(c.tls)) == C.int(1) {
return
}
+ log.Tracef("Calling C function \"tls_connected()\"")
for C.tls_connected((*C.tls_t)(c.tls)) != C.int(1) {
+ log.Tracef("Calling C function \"tls_handshake()\"")
cRet := C.tls_handshake((*C.tls_t)(c.tls))
if cRet == 0 {
break
@@ -1125,6 +1143,7 @@ func (c *Client) Write(b []byte) (n int, err error) {
if err = c.checkConnection(); err != nil {
return
}
+ log.Tracef("Calling C function \"tls_write()\"")
cRet := C.tls_write((*C.tls_t)(c.tls), (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
if cRet <= 0 {
return 0, c.Error()
@@ -1140,6 +1159,7 @@ func (c *Client) Read(b []byte) (n int, err error) {
if err = c.checkConnection(); err != nil {
return
}
+ log.Tracef("Calling C function \"tls_read()\"")
cRet := C.tls_read((*C.tls_t)(c.tls), (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
if cRet > 0 {
return int(cRet), nil
@@ -1169,7 +1189,9 @@ func NewClient(nc net.Conn, cfg *Config, timeout time.Duration, shiftDeadline bo
cSecret = C.CString(cfg.PSKKey)
defer func() {
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cUser))
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cSecret))
}()
context = pskContext
@@ -1179,11 +1201,13 @@ func NewClient(nc net.Conn, cfg *Config, timeout time.Duration, shiftDeadline bo
hostname := url.Host()
if nil == net.ParseIP(hostname) {
cHostname = C.CString(hostname)
+ log.Tracef("Calling C function \"free()\"")
defer C.free(unsafe.Pointer(cHostname))
}
}
// for TLS we overwrite the timeoutMode and force it to move on every read or write
+ log.Tracef("Calling C function \"tls_new_client()\"")
c := &Client{
tlsConn: tlsConn{
conn: nc,
@@ -1193,6 +1217,7 @@ func NewClient(nc net.Conn, cfg *Config, timeout time.Duration, shiftDeadline bo
shiftDeadline: shiftDeadline,
},
}
+ log.Tracef("Calling C function \"tls_free()\"")
runtime.SetFinalizer(c, func(c *Client) { C.tls_free((*C.tls_t)(c.tls)) })
if !c.ready() {
@@ -1218,10 +1243,12 @@ type Server struct {
}
func (s *Server) checkConnection() (err error) {
+ log.Tracef("Calling C function \"tls_connected()\"")
if C.tls_connected((*C.tls_t)(s.tls)) == C.int(1) {
return
}
for {
+ log.Tracef("Calling C function \"tls_accept()\"")
cRet := C.tls_accept((*C.tls_t)(s.tls))
if cRet == 0 {
break
@@ -1244,6 +1271,7 @@ func (s *Server) Write(b []byte) (n int, err error) {
if err = s.checkConnection(); err != nil {
return
}
+ log.Tracef("Calling C function \"tls_write()\"")
cRet := C.tls_write((*C.tls_t)(s.tls), (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
if cRet <= 0 {
return 0, s.Error()
@@ -1257,6 +1285,7 @@ func (s *Server) Read(b []byte) (n int, err error) {
if err = s.checkConnection(); err != nil {
return
}
+ log.Tracef("Calling C function \"tls_read()\"")
cRet := C.tls_read((*C.tls_t)(s.tls), (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
if cRet > 0 {
return int(cRet), nil
@@ -1281,7 +1310,9 @@ func NewServer(nc net.Conn, cfg *Config, b []byte, timeout time.Duration, shiftD
cSecret = C.CString(cfg.PSKKey)
defer func() {
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cUser))
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cSecret))
}()
}
@@ -1292,6 +1323,7 @@ func NewServer(nc net.Conn, cfg *Config, b []byte, timeout time.Duration, shiftD
}
// for TLS we overwrite the timeoutMode and force it to move on every read or write
+ log.Tracef("Calling C function \"tls_new_server()\"")
s := &Server{
tlsConn: tlsConn{
conn: nc,
@@ -1301,12 +1333,14 @@ func NewServer(nc net.Conn, cfg *Config, b []byte, timeout time.Duration, shiftD
shiftDeadline: shiftDeadline,
},
}
+ log.Tracef("Calling C function \"tls_free()\"")
runtime.SetFinalizer(s, func(s *Server) { C.tls_free((*C.tls_t)(s.tls)) })
if !s.ready() {
return nil, s.Error()
}
+ log.Tracef("Calling C function \"tls_send()\"")
C.tls_send((*C.tls_t)(s.tls), (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
if err = s.checkConnection(); err != nil {
@@ -1345,11 +1379,13 @@ type Config struct {
}
func CopyrightMessage() (message string) {
+ log.Tracef("Calling C function \"tls_version()\"")
version := C.tls_version()
if version == nil {
return ""
}
+ log.Tracef("Calling C function \"tls_version_static()\"")
return fmt.Sprintf("\n\nThis product includes software developed by the OpenSSL Project\n"+
"for use in the OpenSSL Toolkit (http://www.openssl.org/).\n\n"+
"Compiled with %s\nRunning with %s\n", C.GoString(C.tls_version_static()), C.GoString(version))
@@ -1360,9 +1396,11 @@ func Init(config *Config) (err error) {
return errors.New(SupportedErrMsg())
}
if pskContext != nil {
+ log.Tracef("Calling C function \"tls_free_context()\"")
C.tls_free_context(C.SSL_CTX_LP(pskContext))
}
if defaultContext != nil {
+ log.Tracef("Calling C function \"tls_free_context()\"")
C.tls_free_context(C.SSL_CTX_LP(defaultContext))
}
@@ -1371,28 +1409,37 @@ func Init(config *Config) (err error) {
cCaFile = C.CString(config.CAFile)
cCertFile = C.CString(config.CertFile)
cKeyFile = C.CString(config.KeyFile)
+ log.Tracef("Calling C function \"free()\"")
defer C.free(unsafe.Pointer(cCaFile))
+ log.Tracef("Calling C function \"free()\"")
defer C.free(unsafe.Pointer(cCertFile))
+ log.Tracef("Calling C function \"free()\"")
defer C.free(unsafe.Pointer(cKeyFile))
if config.CRLFile != "" {
cCrlFile = C.CString(config.CRLFile)
+ log.Tracef("Calling C function \"free()\"")
defer C.free(unsafe.Pointer(cCrlFile))
}
}
+ log.Tracef("Calling C function \"tls_new_context()\"")
if defaultContext = unsafe.Pointer(C.tls_new_context(cCaFile, cCrlFile, cCertFile, cKeyFile, &cErr)); defaultContext == nil {
err = fmt.Errorf("cannot initialize default TLS context: %s", C.GoString(cErr))
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cErr))
return
}
+ log.Tracef("Calling C function \"tls_new_context()\"")
if pskContext = unsafe.Pointer(C.tls_new_context(cNULL, cNULL, cNULL, cNULL, &cErr)); pskContext == nil {
err = fmt.Errorf("cannot initialize PSK TLS context: %s", C.GoString(cErr))
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cErr))
return
}
+ log.Tracef("Calling C function \"tls_version()\"")
log.Infof("OpenSSL library (%s) initialized", C.GoString(C.tls_version()))
log.Debugf("default context ciphersuites:%s", describeCiphersuites(defaultContext))
log.Debugf("psk context ciphersuites:%s", describeCiphersuites(pskContext))
diff --git a/src/go/pkg/version/version.go b/src/go/pkg/version/version.go
index c89f10d27e5..67eb292ae04 100644
--- a/src/go/pkg/version/version.go
+++ b/src/go/pkg/version/version.go
@@ -26,15 +26,15 @@ import (
)
const (
- ZABBIX_REVDATE = "14 September 2022"
+ ZABBIX_REVDATE = "29 September 2022"
ZABBIX_VERSION_MAJOR = 6
ZABBIX_VERSION_MINOR = 4
ZABBIX_VERSION_PATCH = 0
- ZABBIX_VERSION_RC = "alpha2"
+ ZABBIX_VERSION_RC = "beta2"
ZABBIX_VERSION_RC_NUM = "{ZABBIX_RC_NUM}"
ZABBIX_VERSION_REVISION = "{ZABBIX_REVISION}"
copyrightMessage = "Copyright (C) 2022 Zabbix SIA\n" +
- "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>.\n" +
+ "License GPLv2+: GNU GPL version 2 or later <https://www.gnu.org/licenses/>.\n" +
"This is free software: you are free to change and redistribute it according to\n" +
"the license. There is NO WARRANTY, to the extent permitted by law."
)
diff --git a/src/go/pkg/zbxlib/checks.go b/src/go/pkg/zbxlib/checks.go
index aceaf810546..d24a96c876e 100644
--- a/src/go/pkg/zbxlib/checks.go
+++ b/src/go/pkg/zbxlib/checks.go
@@ -36,9 +36,9 @@ static int execute_check(const char *key, zbx_agent_check_t check_func, char **v
AGENT_RESULT result;
AGENT_REQUEST request;
- init_request(&request);
- init_result(&result);
- if (SUCCEED != parse_item_key(key, &request))
+ zbx_init_agent_request(&request);
+ zbx_init_agent_result(&result);
+ if (SUCCEED != zbx_parse_item_key(key, &request))
{
*value = zbx_strdup(NULL, "Invalid item key format.");
goto out;
@@ -59,8 +59,8 @@ static int execute_check(const char *key, zbx_agent_check_t check_func, char **v
ret = SUCCEED;
out:
- free_result(&result);
- free_request(&request);
+ zbx_free_agent_result(&result);
+ zbx_free_agent_request(&request);
return ret;
}
@@ -72,6 +72,7 @@ import (
"unsafe"
"zabbix.com/pkg/itemutil"
+ "git.zabbix.com/ap/plugin-support/log"
)
func ExecuteCheck(key string, params []string) (result *string, err error) {
@@ -83,17 +84,21 @@ func ExecuteCheck(key string, params []string) (result *string, err error) {
var cvalue, cerrmsg *C.char
ckey := C.CString(itemutil.MakeKey(key, params))
+ log.Tracef("Calling C function \"execute_check()\"")
if C.execute_check(ckey, C.zbx_agent_check_t(cfunc), &cvalue, &cerrmsg) == Succeed {
if cvalue != nil {
value := C.GoString(cvalue)
result = &value
}
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cvalue))
} else {
err = errors.New(C.GoString(cerrmsg))
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cerrmsg))
}
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(ckey))
return
}
diff --git a/src/go/pkg/zbxlib/eventlog_windows.go b/src/go/pkg/zbxlib/eventlog_windows.go
index dadf1a31b6d..bc22fac410f 100644
--- a/src/go/pkg/zbxlib/eventlog_windows.go
+++ b/src/go/pkg/zbxlib/eventlog_windows.go
@@ -148,6 +148,8 @@ import (
"unsafe"
"zabbix.com/internal/agent"
"zabbix.com/pkg/tls"
+
+ "git.zabbix.com/ap/plugin-support/log"
)
type EventLogItem struct {
@@ -169,13 +171,16 @@ type EventLogResult struct {
}
func ProcessEventLogCheck(data unsafe.Pointer, item *EventLogItem, refresh int, cblob unsafe.Pointer) {
+ log.Tracef("Calling C function \"metric_set_refresh()\"")
C.metric_set_refresh(C.ZBX_ACTIVE_METRIC_LP(data), C.int(refresh))
var clastLogsizeSent, clastLogsizeLast C.zbx_uint64_t
var cstate, cmtime C.int
+ log.Tracef("Calling C function \"metric_get_meta()\"")
C.metric_get_meta(C.ZBX_ACTIVE_METRIC_LP(data), &clastLogsizeSent, &cmtime)
clastLogsizeLast = clastLogsizeSent
+ log.Tracef("Calling C function \"new_eventlog_result()\"")
result := C.new_eventlog_result(C.int(item.Output.PersistSlotsAvailable()))
var tlsConfig *tls.Config
@@ -193,6 +198,7 @@ func ProcessEventLogCheck(data unsafe.Pointer, item *EventLogItem, refresh int,
return
}
if (nil != tlsConfig) {
+ log.Tracef("Calling C function \"zbx_config_tls_init_for_agent2()\"")
C.zbx_config_tls_init_for_agent2(&ctlsConfig, (C.uint)(tlsConfig.Accept), (C.uint)(tlsConfig.Connect),
(C.CString)(tlsConfig.PSKIdentity), (C.CString)(tlsConfig.PSKKey),
(C.CString)(tlsConfig.CAFile), (C.CString)(tlsConfig.CRLFile), (C.CString)(tlsConfig.CertFile),
@@ -202,6 +208,7 @@ func ProcessEventLogCheck(data unsafe.Pointer, item *EventLogItem, refresh int,
}
var cerrmsg *C.char
+ log.Tracef("Calling C function \"process_eventlog_check()\"")
ret := C.process_eventlog_check(nil, C.zbx_vector_ptr_lp_t(unsafe.Pointer(result)),
C.zbx_vector_ptr_lp_t(cblob), C.ZBX_ACTIVE_METRIC_LP(data),
C.zbx_process_value_func_t(C.process_eventlog_value_cb), &clastLogsizeSent, ctlsConfig_p, &cerrmsg)
@@ -214,6 +221,7 @@ func ProcessEventLogCheck(data unsafe.Pointer, item *EventLogItem, refresh int,
if logTs.Before(item.LastTs) {
logTs = item.LastTs
}
+ log.Tracef("Calling C function \"get_eventlog_value()\"")
for i := 0; C.get_eventlog_value(result, C.int(i), &cvalue, &csource, &clogeventid, &cseverity, &ctimestamp, &cstate,
&clastlogsize) != C.FAIL; i++ {
@@ -249,16 +257,19 @@ func ProcessEventLogCheck(data unsafe.Pointer, item *EventLogItem, refresh int,
item.Results = append(item.Results, &r)
logTs = logTs.Add(time.Nanosecond)
}
+ log.Tracef("Calling C function \"free_eventlog_result()\"")
C.free_eventlog_result(result)
item.LastTs = logTs
if ret == C.FAIL {
+ log.Tracef("Calling C function \"metric_set_unsupported()\"")
C.metric_set_unsupported(C.ZBX_ACTIVE_METRIC_LP(data))
var err error
if cerrmsg != nil {
err = errors.New(C.GoString(cerrmsg))
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cerrmsg))
} else {
err = errors.New("Unknown error.")
@@ -269,9 +280,11 @@ func ProcessEventLogCheck(data unsafe.Pointer, item *EventLogItem, refresh int,
}
item.Results = append(item.Results, result)
} else {
+ log.Tracef("Calling C function \"metric_set_supported()\"")
ret := C.metric_set_supported(C.ZBX_ACTIVE_METRIC_LP(data), clastLogsizeSent, 0, clastLogsizeLast, 0)
if ret == Succeed {
+ log.Tracef("Calling C function \"metric_get_meta()\"")
C.metric_get_meta(C.ZBX_ACTIVE_METRIC_LP(data), &clastLogsizeLast, &cmtime)
result := EventLogResult{
Ts: time.Now(),
diff --git a/src/go/pkg/zbxlib/expressions.go b/src/go/pkg/zbxlib/expressions.go
index da079ee6877..d89a5c65e7a 100644
--- a/src/go/pkg/zbxlib/expressions.go
+++ b/src/go/pkg/zbxlib/expressions.go
@@ -48,21 +48,28 @@ import "C"
import (
"errors"
"unsafe"
+
+ "git.zabbix.com/ap/plugin-support/log"
)
func NewGlobalRegexp() (grxp unsafe.Pointer) {
+ log.Tracef("Calling C function \"new_global_regexp()\"")
return unsafe.Pointer(C.new_global_regexp())
}
func DestroyGlobalRegexp(grxp unsafe.Pointer) {
+ log.Tracef("Calling C function \"free_global_regexp()\"")
C.free_global_regexp(C.zbx_vector_ptr_lp_t(grxp))
}
func AddGlobalRegexp(grxp unsafe.Pointer, name, body string, expr_type int, delim byte, mode int) {
cname := C.CString(name)
cbody := C.CString(body)
+ log.Tracef("Calling C function \"add_regexp_ex()\"")
C.add_regexp_ex(C.zbx_vector_ptr_lp_t(grxp), cname, cbody, C.int(expr_type), C.char(delim), C.int(mode))
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cname))
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cbody))
}
@@ -77,9 +84,11 @@ func MatchGlobalRegexp(
var ctemplate, coutput *C.char
if output_template != nil {
ctemplate = C.CString(*output_template)
+ log.Tracef("Calling C function \"free()\"")
defer C.free(unsafe.Pointer(ctemplate))
}
+ log.Tracef("Calling C function \"regexp_sub_ex()\"")
ret := C.regexp_sub_ex(C.zbx_vector_ptr_lp_t(grxp), cvalue, cpattern, C.int(mode), ctemplate, &coutput)
switch ret {
case C.ZBX_REGEXP_MATCH:
@@ -93,9 +102,12 @@ func MatchGlobalRegexp(
err = errors.New("invalid global regular expression")
}
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cvalue))
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cpattern))
if coutput != nil {
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(coutput))
}
return
diff --git a/src/go/pkg/zbxlib/globals_windows.go b/src/go/pkg/zbxlib/globals_windows.go
index fdd88b66736..126123dc817 100644
--- a/src/go/pkg/zbxlib/globals_windows.go
+++ b/src/go/pkg/zbxlib/globals_windows.go
@@ -37,6 +37,9 @@ package zbxlib
#cgo LDFLAGS: ${SRCDIR}/../../../../build/mingw/output/file.o
#cgo LDFLAGS: ${SRCDIR}/../../../../build/mingw/output/time.o
#cgo LDFLAGS: ${SRCDIR}/../../../../build/mingw/output/expr.o
+#cgo LDFLAGS: ${SRCDIR}/../../../../build/mingw/output/function.o
+#cgo LDFLAGS: ${SRCDIR}/../../../../build/mingw/output/host.o
+#cgo LDFLAGS: ${SRCDIR}/../../../../build/mingw/output/macro.o
#cgo LDFLAGS: ${SRCDIR}/../../../../build/mingw/output/token.o
#cgo LDFLAGS: ${SRCDIR}/../../../../build/mingw/output/fatal.o
#cgo LDFLAGS: ${SRCDIR}/../../../../build/mingw/output/disk.o
diff --git a/src/go/pkg/zbxlib/log.go b/src/go/pkg/zbxlib/log.go
index 342e33440b6..e07268e7ff0 100644
--- a/src/go/pkg/zbxlib/log.go
+++ b/src/go/pkg/zbxlib/log.go
@@ -75,10 +75,15 @@ int zbx_redirect_stdio(const char *filename)
*/
import "C"
+import (
+ "git.zabbix.com/ap/plugin-support/log"
+)
+
func SetLogLevel(level int) {
C.zbx_log_level = C.int(level)
}
func init() {
+ log.Tracef("Calling C function \"getpid()\"")
C.zbx_agent_pid = C.getpid()
}
diff --git a/src/go/pkg/zbxlib/logfile.go b/src/go/pkg/zbxlib/logfile.go
index 584330b4d6c..ce137831313 100644
--- a/src/go/pkg/zbxlib/logfile.go
+++ b/src/go/pkg/zbxlib/logfile.go
@@ -252,6 +252,7 @@ import (
"zabbix.com/pkg/itemutil"
"zabbix.com/internal/agent"
"zabbix.com/pkg/tls"
+ "git.zabbix.com/ap/plugin-support/log"
)
const (
@@ -312,22 +313,27 @@ func NewActiveMetric(key string, params []string, lastLogsize uint64, mtime int3
}
ckey := C.CString(itemutil.MakeKey(key, params))
+ log.Tracef("Calling C function \"new_metric()\"")
return unsafe.Pointer(C.new_metric(ckey, C.zbx_uint64_t(lastLogsize), C.int(mtime), C.int(flags))), nil
}
func FreeActiveMetric(data unsafe.Pointer) {
+ log.Tracef("Calling C function \"metric_free()\"")
C.metric_free(C.ZBX_ACTIVE_METRIC_LP(data))
}
func ProcessLogCheck(data unsafe.Pointer, item *LogItem, refresh int, cblob unsafe.Pointer) {
+ log.Tracef("Calling C function \"metric_set_refresh()\"")
C.metric_set_refresh(C.ZBX_ACTIVE_METRIC_LP(data), C.int(refresh))
var clastLogsizeSent, clastLogsizeLast C.zbx_uint64_t
var cmtimeSent, cmtimeLast C.int
+ log.Tracef("Calling C function \"metric_get_meta()\"")
C.metric_get_meta(C.ZBX_ACTIVE_METRIC_LP(data), &clastLogsizeSent, &cmtimeSent)
clastLogsizeLast = clastLogsizeSent
cmtimeLast = cmtimeSent
+ log.Tracef("Calling C function \"new_log_result()\"")
result := C.new_log_result(C.int(item.Output.PersistSlotsAvailable()))
var tlsConfig *tls.Config
@@ -345,6 +351,7 @@ func ProcessLogCheck(data unsafe.Pointer, item *LogItem, refresh int, cblob unsa
return
}
if (nil != tlsConfig) {
+ log.Tracef("Calling C function \"zbx_config_tls_init_for_agent2()\"")
C.zbx_config_tls_init_for_agent2(&ctlsConfig, (C.uint)(tlsConfig.Accept), (C.uint)(tlsConfig.Connect),
(C.CString)(tlsConfig.PSKIdentity), (C.CString)(tlsConfig.PSKKey),
(C.CString)(tlsConfig.CAFile), (C.CString)(tlsConfig.CRLFile), (C.CString)(tlsConfig.CertFile),
@@ -354,11 +361,14 @@ func ProcessLogCheck(data unsafe.Pointer, item *LogItem, refresh int, cblob unsa
}
var cerrmsg *C.char
+ log.Tracef("Calling C function \"new_prep_vec()\"")
cprepVec := C.new_prep_vec() // In Agent2 it is always empty vector. Not used but required for linking.
+ log.Tracef("Calling C function \"process_log_check()\"")
ret := C.process_log_check(nil, C.zbx_vector_ptr_lp_t(unsafe.Pointer(result)), C.zbx_vector_ptr_lp_t(cblob),
C.ZBX_ACTIVE_METRIC_LP(data), C.zbx_process_value_func_t(C.process_value_cb), &clastLogsizeSent,
&cmtimeSent, &cerrmsg, cprepVec, ctlsConfig_p)
+ log.Tracef("Calling C function \"free_prep_vec()\"")
C.free_prep_vec(cprepVec)
// add cached results
@@ -369,6 +379,7 @@ func ProcessLogCheck(data unsafe.Pointer, item *LogItem, refresh int, cblob unsa
if logTs.Before(item.LastTs) {
logTs = item.LastTs
}
+ log.Tracef("Calling C function \"get_log_value()\"")
for i := 0; C.get_log_value(result, C.int(i), &cvalue, &cstate, &clastlogsize, &cmtime) != C.FAIL; i++ {
var value string
var err error
@@ -389,16 +400,19 @@ func ProcessLogCheck(data unsafe.Pointer, item *LogItem, refresh int, cblob unsa
item.Results = append(item.Results, r)
logTs = logTs.Add(time.Nanosecond)
}
+ log.Tracef("Calling C function \"free_log_result()\"")
C.free_log_result(result)
item.LastTs = logTs
if ret == C.FAIL {
+ log.Tracef("Calling C function \"metric_set_unsupported()\"")
C.metric_set_unsupported(C.ZBX_ACTIVE_METRIC_LP(data))
var err error
if cerrmsg != nil {
err = errors.New(C.GoString(cerrmsg))
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cerrmsg))
} else {
err = errors.New("Unknown error.")
@@ -409,10 +423,12 @@ func ProcessLogCheck(data unsafe.Pointer, item *LogItem, refresh int, cblob unsa
}
item.Results = append(item.Results, result)
} else {
+ log.Tracef("Calling C function \"metric_set_supported()\"")
ret := C.metric_set_supported(C.ZBX_ACTIVE_METRIC_LP(data), clastLogsizeSent, cmtimeSent, clastLogsizeLast,
cmtimeLast)
if ret == Succeed {
+ log.Tracef("Calling C function \"metric_get_meta()\"")
C.metric_get_meta(C.ZBX_ACTIVE_METRIC_LP(data), &clastLogsizeLast, &cmtimeLast)
result := &LogResult{
Ts: time.Now(),
diff --git a/src/go/pkg/zbxlib/nextcheck.go b/src/go/pkg/zbxlib/nextcheck.go
index dc02e09ebc0..ca239f940a8 100644
--- a/src/go/pkg/zbxlib/nextcheck.go
+++ b/src/go/pkg/zbxlib/nextcheck.go
@@ -33,6 +33,8 @@ import (
"errors"
"time"
"unsafe"
+
+ "git.zabbix.com/ap/plugin-support/log"
)
func GetNextcheck(itemid uint64, delay string, from time.Time) (nextcheck time.Time, scheduling bool, err error) {
@@ -41,11 +43,13 @@ func GetNextcheck(itemid uint64, delay string, from time.Time) (nextcheck time.T
cdelay := C.CString(delay)
now := from.Unix()
+ log.Tracef("Calling C function \"zbx_get_agent_item_nextcheck()\"")
ret := C.zbx_get_agent_item_nextcheck(C.zbx_uint64_t(itemid), cdelay, C.int(now),
&cnextcheck, &cscheduling, &cerr)
if ret != Succeed {
err = errors.New(C.GoString(cerr))
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cerr))
} else {
nextcheck = time.Unix(int64(cnextcheck), 0)
@@ -53,6 +57,7 @@ func GetNextcheck(itemid uint64, delay string, from time.Time) (nextcheck time.T
scheduling = true
}
}
+ log.Tracef("Calling C function \"free()\"")
C.free(unsafe.Pointer(cdelay))
return
diff --git a/src/go/plugins/external/broker.go b/src/go/plugins/external/broker.go
index df6310968e2..11fb36628db 100644
--- a/src/go/plugins/external/broker.go
+++ b/src/go/plugins/external/broker.go
@@ -85,7 +85,19 @@ func (b *pluginBroker) handleConnection() {
for {
t, data, err := comms.Read(b.conn)
if err != nil {
- return
+ if errors.Is(err, net.ErrClosed) {
+ log.Tracef("closed connection to loaded %s plugin", b.pluginName)
+
+ return
+ }
+
+ log.Errf(
+ "failed to read response for plugin %s, %s",
+ b.pluginName,
+ err.Error(),
+ )
+
+ continue
}
var id uint32
diff --git a/src/go/plugins/net/tcp/tcp_netstat.go b/src/go/plugins/net/tcp/tcp_netstat.go
index 0621389666a..aeb4e107b97 100644
--- a/src/go/plugins/net/tcp/tcp_netstat.go
+++ b/src/go/plugins/net/tcp/tcp_netstat.go
@@ -25,6 +25,7 @@ package tcpudp
import (
"errors"
"net"
+ "os"
"strconv"
"github.com/cakturk/go-netstat/netstat"
@@ -178,7 +179,8 @@ func netStatTcpCount(laddres net.IP, lNet *net.IPNet, lport int, raddres net.IP,
count++
return false
})
- if err != nil {
+
+ if err != nil && !errors.Is(err, os.ErrNotExist) {
return 0, err
}
diff --git a/src/go/plugins/net/udp/udp_netstat.go b/src/go/plugins/net/udp/udp_netstat.go
index 558ad767222..43611b92c6b 100644
--- a/src/go/plugins/net/udp/udp_netstat.go
+++ b/src/go/plugins/net/udp/udp_netstat.go
@@ -24,6 +24,7 @@ package udp
import (
"errors"
+ "os"
"net"
"strconv"
@@ -157,7 +158,7 @@ func netStatUdpCount(laddres net.IP, lNet *net.IPNet, lport int, raddres net.IP,
return true
})
- if err != nil {
+ if err != nil && !errors.Is(err, os.ErrNotExist) {
return 0, err
}
diff --git a/src/go/plugins/proc/proc_linux.go b/src/go/plugins/proc/proc_linux.go
index 46929372dd4..9692ea47476 100644
--- a/src/go/plugins/proc/proc_linux.go
+++ b/src/go/plugins/proc/proc_linux.go
@@ -476,6 +476,7 @@ func (p *Plugin) Export(key string, params []string, ctx plugin.ContextProvider)
ticks *= 1e12
ticks /= uint64(tail.timestamp.Sub(head.timestamp))
+ log.Tracef("Calling C function \"sysconf()\"")
return math.Round(float64(ticks)/float64(C.sysconf(C._SC_CLK_TCK))) / 10, nil
}
stats := &cpuUtilStats{accessed: now, history: make([]cpuUtilData, maxHistory)}
diff --git a/src/go/plugins/proc/procfs_linux.go b/src/go/plugins/proc/procfs_linux.go
index 021988cd394..6983fb7ed05 100644
--- a/src/go/plugins/proc/procfs_linux.go
+++ b/src/go/plugins/proc/procfs_linux.go
@@ -38,6 +38,7 @@ import (
"syscall"
"zabbix.com/pkg/procfs"
+ "git.zabbix.com/ap/plugin-support/log"
)
type processUserInfo struct {
@@ -182,7 +183,9 @@ func getProcessCpuTimes(pid string, proc *procStatus) () {
return
}
+ log.Tracef("Calling C function \"sysconf()\"")
proc.CpuTimeUser = float64(stat.utime) / float64(C.sysconf(C._SC_CLK_TCK))
+ log.Tracef("Calling C function \"sysconf()\"")
proc.CpuTimeSystem = float64(stat.stime) / float64(C.sysconf(C._SC_CLK_TCK))
proc.PageFaults = stat.pageFaults
}
diff --git a/src/go/plugins/system/cpu/cpu_linux.go b/src/go/plugins/system/cpu/cpu_linux.go
index 188db3ea6a7..9c96e7d4295 100644
--- a/src/go/plugins/system/cpu/cpu_linux.go
+++ b/src/go/plugins/system/cpu/cpu_linux.go
@@ -32,6 +32,7 @@ import (
"strings"
"git.zabbix.com/ap/plugin-support/plugin"
+ "git.zabbix.com/ap/plugin-support/log"
)
// Plugin -
@@ -132,10 +133,12 @@ func (p *Plugin) addCpu(index int) {
}
func numCPUConf() int {
+ log.Tracef("Calling C function \"sysconf()\"")
return int(C.sysconf(C._SC_NPROCESSORS_CONF))
}
func numCPUOnline() int {
+ log.Tracef("Calling C function \"sysconf()\"")
return int(C.sysconf(C._SC_NPROCESSORS_ONLN))
}
diff --git a/src/go/plugins/vfs/file/encoding.go b/src/go/plugins/vfs/file/encoding.go
index 455765a180c..795d16ce3b9 100644
--- a/src/go/plugins/vfs/file/encoding.go
+++ b/src/go/plugins/vfs/file/encoding.go
@@ -31,6 +31,8 @@ import "C"
import (
"syscall"
"unsafe"
+
+ "git.zabbix.com/ap/plugin-support/log"
)
func decode(encoder string, inbuf []byte) (outbuf []byte) {
@@ -48,10 +50,13 @@ func decode(encoder string, inbuf []byte) (outbuf []byte) {
}
tocode := C.CString("UTF-8")
+ log.Tracef("Calling C function \"free()\"")
defer C.free(unsafe.Pointer(tocode))
fromcode := C.CString(encoder)
+ log.Tracef("Calling C function \"free()\"")
defer C.free(unsafe.Pointer(fromcode))
+ log.Tracef("Calling C function \"iconv_open()\"")
cd, err := C.iconv_open(tocode, fromcode)
if err != nil {
@@ -65,6 +70,7 @@ func decode(encoder string, inbuf []byte) (outbuf []byte) {
for {
inptr := (*C.char)(unsafe.Pointer(&inbuf[len(inbuf)-int(inbytes)]))
outptr := (*C.char)(unsafe.Pointer(&outbuf[len(outbuf)-int(outbytes)]))
+ log.Tracef("Calling C function \"call_iconv()\"")
_, err := C.call_iconv(cd, inptr, &inbytes, outptr, &outbytes)
if err == nil || err.(syscall.Errno) != syscall.E2BIG {
break
@@ -75,6 +81,7 @@ func decode(encoder string, inbuf []byte) (outbuf []byte) {
outbuf = tmp
}
outbuf = outbuf[:len(outbuf)-int(outbytes)]
+ log.Tracef("Calling C function \"iconv_close()\"")
C.iconv_close(cd)
if len(outbuf) > 3 && 0xef == outbuf[0] && 0xbb == outbuf[1] && 0xbf == outbuf[2] {
outbuf = outbuf[3:]
diff --git a/src/libs/zbxalgo/prediction.c b/src/libs/zbxalgo/prediction.c
index af6e60bfd91..6b2ab0bfbe6 100644
--- a/src/libs/zbxalgo/prediction.c
+++ b/src/libs/zbxalgo/prediction.c
@@ -1150,7 +1150,7 @@ out:
double zbx_timeleft(double *t, double *x, int n, double now, double threshold, zbx_fit_t fit, unsigned k)
{
zbx_matrix_t *coefficients = NULL;
- double current, result;
+ double current, result = -1.0;
int res;
if (1 == n)
diff --git a/src/libs/zbxcommon/components_strings_representations.c b/src/libs/zbxcommon/components_strings_representations.c
index 7f84c5819f6..dbae20d087f 100644
--- a/src/libs/zbxcommon/components_strings_representations.c
+++ b/src/libs/zbxcommon/components_strings_representations.c
@@ -67,8 +67,6 @@ const char *get_process_type_string(unsigned char proc_type)
return "data sender";
case ZBX_PROCESS_TYPE_CONFSYNCER:
return "configuration syncer";
- case ZBX_PROCESS_TYPE_HEARTBEAT:
- return "heartbeat sender";
case ZBX_PROCESS_TYPE_SELFMON:
return "self-monitoring";
case ZBX_PROCESS_TYPE_VMWARE:
diff --git a/src/libs/zbxcommon/misc.c b/src/libs/zbxcommon/misc.c
index 0b3d9ac2c90..b4b40971cda 100644
--- a/src/libs/zbxcommon/misc.c
+++ b/src/libs/zbxcommon/misc.c
@@ -281,7 +281,7 @@ void zbx_usage(void)
static const char copyright_message[] =
"Copyright (C) 2022 Zabbix SIA\n"
- "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>.\n"
+ "License GPLv2+: GNU GPL version 2 or later <https://www.gnu.org/licenses/>.\n"
"This is free software: you are free to change and redistribute it according to\n"
"the license. There is NO WARRANTY, to the extent permitted by law.";
@@ -497,340 +497,6 @@ void uint64_array_remove(zbx_uint64_t *values, int *num, const zbx_uint64_t *rm_
/******************************************************************************
* *
- * Return value: SUCCEED - the char is allowed in the host name *
- * FAIL - otherwise *
- * *
- * Comments: in host name allowed characters: '0-9a-zA-Z. _-' *
- * !!! Don't forget to sync the code with PHP !!! *
- * *
- ******************************************************************************/
-int is_hostname_char(unsigned char c)
-{
- if (0 != isalnum(c))
- return SUCCEED;
-
- if (c == '.' || c == ' ' || c == '_' || c == '-')
- return SUCCEED;
-
- return FAIL;
-}
-
-/******************************************************************************
- * *
- * Return value: SUCCEED - the char is allowed in the item key *
- * FAIL - otherwise *
- * *
- * Comments: in key allowed characters: '0-9a-zA-Z._-' *
- * !!! Don't forget to sync the code with PHP !!! *
- * *
- ******************************************************************************/
-int is_key_char(unsigned char c)
-{
- if (0 != isalnum(c))
- return SUCCEED;
-
- if (c == '.' || c == '_' || c == '-')
- return SUCCEED;
-
- return FAIL;
-}
-
-/******************************************************************************
- * *
- * Return value: SUCCEED - the char is allowed in the trigger function *
- * FAIL - otherwise *
- * *
- * Comments: in trigger function allowed characters: 'a-z' *
- * !!! Don't forget to sync the code with PHP !!! *
- * *
- ******************************************************************************/
-int is_function_char(unsigned char c)
-{
- if (0 != islower(c))
- return SUCCEED;
-
- return FAIL;
-}
-
-/******************************************************************************
- * *
- * Return value: SUCCEED - the char is allowed in the macro name *
- * FAIL - otherwise *
- * *
- * Comments: allowed characters in macro names: '0-9A-Z._' *
- * !!! Don't forget to sync the code with PHP !!! *
- * *
- ******************************************************************************/
-int is_macro_char(unsigned char c)
-{
- if (0 != isupper(c))
- return SUCCEED;
-
- if ('.' == c || '_' == c)
- return SUCCEED;
-
- if (0 != isdigit(c))
- return SUCCEED;
-
- return FAIL;
-}
-
-/******************************************************************************
- * *
- * Purpose: checks if the name is a valid discovery macro *
- * *
- * Return value: SUCCEED - the name is a valid discovery macro *
- * FAIL - otherwise *
- * *
- ******************************************************************************/
-int is_discovery_macro(const char *name)
-{
- if ('{' != *name++ || '#' != *name++)
- return FAIL;
-
- do
- {
- if (SUCCEED != is_macro_char(*name++))
- return FAIL;
-
- } while ('}' != *name);
-
- if ('\0' != name[1])
- return FAIL;
-
- return SUCCEED;
-}
-
-/******************************************************************************
- * *
- * Purpose: advances pointer to first invalid character in string *
- * ensuring that everything before it is a valid key *
- * *
- * e.g., system.run[cat /etc/passwd | awk -F: '{ print $1 }'] *
- * *
- * Parameters: exp - [IN/OUT] pointer to the first char of key *
- * *
- * e.g., {host:system.run[cat /etc/passwd | awk -F: '{ print $1 }'].last(0)} *
- * ^ *
- * Return value: returns FAIL only if no key is present (length 0), *
- * or the whole string is invalid. SUCCEED otherwise. *
- * *
- * Comments: the pointer is advanced to the first invalid character even if *
- * FAIL is returned (meaning there is a syntax error in item key). *
- * If necessary, the caller must keep a copy of pointer original *
- * value. *
- * *
- ******************************************************************************/
-int parse_key(const char **exp)
-{
- const char *s;
-
- for (s = *exp; SUCCEED == is_key_char(*s); s++)
- ;
-
- if (*exp == s) /* the key is empty */
- return FAIL;
-
- if ('[' == *s) /* for instance, net.tcp.port[,80] */
- {
- int state = 0; /* 0 - init, 1 - inside quoted param, 2 - inside unquoted param */
- int array = 0; /* array nest level */
-
- for (s++; '\0' != *s; s++)
- {
- switch (state)
- {
- /* init state */
- case 0:
- if (',' == *s)
- ;
- else if ('"' == *s)
- state = 1;
- else if ('[' == *s)
- {
- if (0 == array)
- array = 1;
- else
- goto fail; /* incorrect syntax: multi-level array */
- }
- else if (']' == *s && 0 != array)
- {
- array = 0;
- s++;
-
- while (' ' == *s) /* skip trailing spaces after closing ']' */
- s++;
-
- if (']' == *s)
- goto succeed;
-
- if (',' != *s)
- goto fail; /* incorrect syntax */
- }
- else if (']' == *s && 0 == array)
- goto succeed;
- else if (' ' != *s)
- state = 2;
- break;
- /* quoted */
- case 1:
- if ('"' == *s)
- {
- while (' ' == s[1]) /* skip trailing spaces after closing quotes */
- s++;
-
- if (0 == array && ']' == s[1])
- {
- s++;
- goto succeed;
- }
-
- if (',' != s[1] && !(0 != array && ']' == s[1]))
- {
- s++;
- goto fail; /* incorrect syntax */
- }
-
- state = 0;
- }
- else if ('\\' == *s && '"' == s[1])
- s++;
- break;
- /* unquoted */
- case 2:
- if (',' == *s || (']' == *s && 0 != array))
- {
- s--;
- state = 0;
- }
- else if (']' == *s && 0 == array)
- goto succeed;
- break;
- }
- }
-fail:
- *exp = s;
- return FAIL;
-succeed:
- s++;
- }
-
- *exp = s;
- return SUCCEED;
-}
-
-/******************************************************************************
- * *
- * Purpose: return hostname and key *
- * <hostname:>key *
- * *
- * Parameters: *
- * exp - pointer to the first char of hostname *
- * host:key[key params] *
- * ^ *
- * *
- * Return value: return SUCCEED or FAIL *
- * *
- ******************************************************************************/
-int parse_host_key(char *exp, char **host, char **key)
-{
- char *p, *s;
-
- if (NULL == exp || '\0' == *exp)
- return FAIL;
-
- for (p = exp, s = exp; '\0' != *p; p++) /* check for optional hostname */
- {
- if (':' == *p) /* hostname:vfs.fs.size[/,total]
- * --------^
- */
- {
- *p = '\0';
- *host = zbx_strdup(NULL, s);
- *p++ = ':';
-
- s = p;
- break;
- }
-
- if (SUCCEED != is_hostname_char(*p))
- break;
- }
-
- *key = zbx_strdup(NULL, s);
-
- return SUCCEED;
-}
-
-/******************************************************************************
- * *
- * Purpose: replace all not-allowed hostname characters in the string *
- * *
- * Parameters: host - the target C-style string *
- * *
- * Comments: the string must be null-terminated, otherwise not secure! *
- * *
- ******************************************************************************/
-void make_hostname(char *host)
-{
- char *c;
-
- assert(host);
-
- for (c = host; '\0' != *c; ++c)
- {
- if (FAIL == is_hostname_char(*c))
- *c = '_';
- }
-}
-
-/******************************************************************************
- * *
- * Purpose: check a byte stream for a valid hostname *
- * *
- * Parameters: hostname - pointer to the first char of hostname *
- * error - pointer to the error message (can be NULL) *
- * *
- * Return value: return SUCCEED if hostname is valid *
- * or FAIL if hostname contains invalid chars, is empty *
- * or is longer than ZBX_MAX_HOSTNAME_LEN *
- * *
- ******************************************************************************/
-int zbx_check_hostname(const char *hostname, char **error)
-{
- int len = 0;
-
- while ('\0' != hostname[len])
- {
- if (FAIL == is_hostname_char(hostname[len]))
- {
- if (NULL != error)
- *error = zbx_dsprintf(NULL, "name contains invalid character '%c'", hostname[len]);
- return FAIL;
- }
-
- len++;
- }
-
- if (0 == len)
- {
- if (NULL != error)
- *error = zbx_strdup(NULL, "name is empty");
- return FAIL;
- }
-
- if (ZBX_MAX_HOSTNAME_LEN < len)
- {
- if (NULL != error)
- *error = zbx_dsprintf(NULL, "name is too long (max %d characters)", ZBX_MAX_HOSTNAME_LEN);
- return FAIL;
- }
-
- return SUCCEED;
-}
-
-/******************************************************************************
- * *
* Return value: Interface type *
* *
* Comments: !!! Don't forget to sync the code with PHP !!! *
diff --git a/src/libs/zbxcrypto/crypto.c b/src/libs/zbxcrypto/crypto.c
index 79557356458..5b19652bf2b 100644
--- a/src/libs/zbxcrypto/crypto.c
+++ b/src/libs/zbxcrypto/crypto.c
@@ -19,7 +19,6 @@
#include "zbxcrypto.h"
-#include "zbxhash.h"
#include "zbxtime.h"
/******************************************************************************
@@ -112,7 +111,7 @@ int zbx_bin2hex(const unsigned char *bin, size_t bin_len, char *out, size_t o
* Return value: Hexadecimal token string, must be freed by caller *
* *
* Comments: if you change token creation algorithm do not forget to adjust *
- * zbx_get_token_len() function *
+ * ZBX_SESSION_TOKEN_SIZE macro *
* *
******************************************************************************/
char *zbx_create_token(zbx_uint64_t seed)
@@ -124,7 +123,7 @@ char *zbx_create_token(zbx_uint64_t seed)
int i;
char *token, *ptr;
- ptr = token = (char *)zbx_malloc(NULL, zbx_get_token_len() + 1);
+ ptr = token = (char *)zbx_malloc(NULL, ZBX_SESSION_TOKEN_SIZE + 1);
zbx_timespec(&ts);
@@ -146,21 +145,6 @@ char *zbx_create_token(zbx_uint64_t seed)
/******************************************************************************
* *
- * Return value: number of characters in a token created by *
- * zbx_create_token() *
- * *
- * Comments: terminating '\0' byte is not included in the result *
- * *
- ******************************************************************************/
-size_t zbx_get_token_len(void)
-{
-#define ZBX_DATA_SESSION_TOKEN_SIZE (ZBX_MD5_DIGEST_SIZE * 2)
- return ZBX_DATA_SESSION_TOKEN_SIZE;
-#undef ZBX_DATA_SESSION_TOKEN_SIZE
-}
-
-/******************************************************************************
- * *
* Purpose: calculate UUID version 4 as string of 32 symbols *
* *
* Parameters: seed - [IN] string for seed calculation *
diff --git a/src/libs/zbxcrypto/hmac.c b/src/libs/zbxcrypto/hmac.c
index d3345b49c2d..3efe6af39af 100644
--- a/src/libs/zbxcrypto/hmac.c
+++ b/src/libs/zbxcrypto/hmac.c
@@ -19,7 +19,6 @@
#include "zbxcrypto.h"
-#include "zbxhash.h"
#include "zbxcommon.h"
static void *hmac_hash_init(zbx_crypto_hash_t type)
diff --git a/src/libs/zbxdb/db.c b/src/libs/zbxdb/db.c
index 7915e32d6e4..42db53433c2 100644
--- a/src/libs/zbxdb/db.c
+++ b/src/libs/zbxdb/db.c
@@ -2744,7 +2744,7 @@ void zbx_dbms_version_info_extract(struct zbx_db_version_info_t *version_info)
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
ZBX_PG_SVERSION = (zbx_uint32_t)PQserverVersion(conn);
- major = (zbx_uint32_t)RIGHT2(ZBX_PG_SVERSION/10000);
+ major = ZBX_PG_SVERSION/10000;
version_info->database = "PostgreSQL";
@@ -2755,12 +2755,12 @@ void zbx_dbms_version_info_extract(struct zbx_db_version_info_t *version_info)
if (10 > major)
{
- version_info->friendly_current_version = zbx_dsprintf(NULL, "%u.%d.%d", (unsigned int)major,
+ version_info->friendly_current_version = zbx_dsprintf(NULL, "%" PRIu32 ".%d.%d", major,
RIGHT2(ZBX_PG_SVERSION/100), RIGHT2(ZBX_PG_SVERSION));
}
else
{
- version_info->friendly_current_version = zbx_dsprintf(NULL, "%u.%d", (unsigned int)major,
+ version_info->friendly_current_version = zbx_dsprintf(NULL, "%" PRIu32 ".%d", major,
RIGHT2(ZBX_PG_SVERSION));
}
diff --git a/src/libs/zbxdbcache/dbconfig.c b/src/libs/zbxdbcache/dbconfig.c
index 13f21a4d3b4..4bfdb8a6c65 100644
--- a/src/libs/zbxdbcache/dbconfig.c
+++ b/src/libs/zbxdbcache/dbconfig.c
@@ -76,8 +76,11 @@ int sync_in_progress = 0;
in_maintenance_without_data_collection(dc_host->maintenance_status, \
dc_host->maintenance_type, dc_item->type)
-ZBX_PTR_VECTOR_IMPL(cached_proxy, zbx_cached_proxy_t *)
+ZBX_PTR_VECTOR_IMPL(cached_proxy_ptr, zbx_cached_proxy_t *)
+ZBX_PTR_VECTOR_IMPL(dc_httptest_ptr, zbx_dc_httptest_t *)
+ZBX_PTR_VECTOR_IMPL(dc_host_ptr, ZBX_DC_HOST *)
ZBX_PTR_VECTOR_IMPL(dc_item_ptr, ZBX_DC_ITEM *)
+ZBX_VECTOR_IMPL(host_rev, zbx_host_rev_t)
/******************************************************************************
* *
@@ -108,8 +111,10 @@ static void dc_item_reset_triggers(ZBX_DC_ITEM *item, ZBX_DC_TRIGGER *trigger_ex
static char *dc_expand_user_macros_dyn(const char *text, const zbx_uint64_t *hostids, int hostids_num, int env);
static void dc_reschedule_items(const zbx_hashset_t *activated_hosts);
+static void dc_reschedule_httptests(zbx_hashset_t *activated_hosts);
-static int dc_host_update_revision(ZBX_DC_HOST *host, zbx_uint32_t revision);
+static int dc_host_update_revision(ZBX_DC_HOST *host, zbx_uint64_t revision);
+static int dc_item_update_revision(ZBX_DC_ITEM *item, zbx_uint64_t revision);
extern char *CONFIG_VAULTTOKEN;
extern char *CONFIG_VAULT;
@@ -156,6 +161,7 @@ static zbx_dc_um_handle_t *dc_um_handle = NULL;
* | Zabbix internal | zabbix[host,,items_unsupported] | *
* | Zabbix internal | zabbix[host,discovery,interfaces] | *
* | Zabbix internal | zabbix[host,,maintenance] | *
+ * | Zabbix internal | zabbix[proxy,discovery] | *
* | Zabbix internal | zabbix[proxy,<proxyname>,lastaccess] | *
* | Zabbix internal | zabbix[proxy,<proxyname>,delay] | *
* | Zabbix aggregate | * | *
@@ -179,13 +185,25 @@ int is_item_processed_by_server(unsigned char type, const char *key)
AGENT_REQUEST request;
char *arg1, *arg2, *arg3;
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED != parse_item_key(key, &request) || 3 != request.nparam)
+ if (SUCCEED != zbx_parse_item_key(key, &request) || 2 > request.nparam ||
+ 3 < request.nparam)
+ {
goto clean;
+ }
arg1 = get_rparam(&request, 0);
arg2 = get_rparam(&request, 1);
+
+ if (2 == request.nparam)
+ {
+ if (0 == strcmp(arg1, "proxy") && 0 == strcmp(arg2, "discovery"))
+ ret = SUCCEED;
+
+ goto clean;
+ }
+
arg3 = get_rparam(&request, 2);
if (0 == strcmp(arg1, "host"))
@@ -201,11 +219,13 @@ int is_item_processed_by_server(unsigned char type, const char *key)
else if (0 == strcmp(arg2, "discovery") && 0 == strcmp(arg3, "interfaces"))
ret = SUCCEED;
}
- else if (0 == strcmp(arg1, "proxy") &&
- (0 == strcmp(arg3, "lastaccess") || 0 == strcmp(arg3, "delay")))
+ else if (0 == strcmp(arg1, "proxy") && (0 == strcmp(arg3, "lastaccess") ||
+ 0 == strcmp(arg3, "delay")))
+ {
ret = SUCCEED;
+ }
clean:
- free_request(&request);
+ zbx_free_agent_request(&request);
}
break;
}
@@ -228,9 +248,9 @@ static unsigned char poller_by_item(unsigned char type, const char *key)
switch (type)
{
case ITEM_TYPE_SIMPLE:
- if (SUCCEED == cmp_key_id(key, SERVER_ICMPPING_KEY) ||
- SUCCEED == cmp_key_id(key, SERVER_ICMPPINGSEC_KEY) ||
- SUCCEED == cmp_key_id(key, SERVER_ICMPPINGLOSS_KEY))
+ if (SUCCEED == cmp_key_id(key, ZBX_SERVER_ICMPPING_KEY) ||
+ SUCCEED == cmp_key_id(key, ZBX_SERVER_ICMPPINGSEC_KEY) ||
+ SUCCEED == cmp_key_id(key, ZBX_SERVER_ICMPPINGLOSS_KEY))
{
if (0 == CONFIG_PINGER_FORKS)
break;
@@ -338,9 +358,9 @@ static zbx_uint64_t get_item_nextcheck_seed(zbx_uint64_t itemid, zbx_uint64_t in
if (ITEM_TYPE_SIMPLE == type)
{
- if (SUCCEED == cmp_key_id(key, SERVER_ICMPPING_KEY) ||
- SUCCEED == cmp_key_id(key, SERVER_ICMPPINGSEC_KEY) ||
- SUCCEED == cmp_key_id(key, SERVER_ICMPPINGLOSS_KEY))
+ if (SUCCEED == cmp_key_id(key, ZBX_SERVER_ICMPPING_KEY) ||
+ SUCCEED == cmp_key_id(key, ZBX_SERVER_ICMPPINGSEC_KEY) ||
+ SUCCEED == cmp_key_id(key, ZBX_SERVER_ICMPPINGLOSS_KEY))
{
return interfaceid;
}
@@ -569,12 +589,12 @@ static ZBX_DC_HOST *DCfind_proxy(const char *host)
static zbx_hash_t __config_strpool_hash(const void *data)
{
- return ZBX_DEFAULT_STRING_HASH_FUNC((char *)data + REFCOUNT_FIELD_SIZE);
+ return ZBX_DEFAULT_STRING_HASH_FUNC((const char *)data + REFCOUNT_FIELD_SIZE);
}
static int __config_strpool_compare(const void *d1, const void *d2)
{
- return strcmp((char *)d1 + REFCOUNT_FIELD_SIZE, (char *)d2 + REFCOUNT_FIELD_SIZE);
+ return strcmp((const char *)d1 + REFCOUNT_FIELD_SIZE, (const char *)d2 + REFCOUNT_FIELD_SIZE);
}
const char *dc_strpool_intern(const char *str)
@@ -703,21 +723,29 @@ static void DCupdate_proxy_queue(ZBX_DC_PROXY *proxy)
* value_raw - [IN] setting value to validate *
* *
******************************************************************************/
-static int set_hk_opt(int *value, int non_zero, int value_min, const char *value_raw)
+static int set_hk_opt(int *value, int non_zero, int value_min, const char *value_raw, zbx_uint64_t revision)
{
- if (SUCCEED != zbx_is_time_suffix(value_raw, value, ZBX_LENGTH_UNLIMITED))
+ int value_int;
+
+ if (SUCCEED != zbx_is_time_suffix(value_raw, &value_int, ZBX_LENGTH_UNLIMITED))
return FAIL;
- if (0 != non_zero && 0 == *value)
+ if (0 != non_zero && 0 == value_int)
return FAIL;
- if (0 != *value && (value_min > *value || ZBX_HK_PERIOD_MAX < *value))
+ if (0 != *value && (value_min > value_int || ZBX_HK_PERIOD_MAX < value_int))
return FAIL;
+ if (*value != value_int)
+ {
+ *value = value_int;
+ config->revision.config_table = revision;
+ }
+
return SUCCEED;
}
-static int DCsync_config(zbx_dbsync_t *sync, int *flags)
+static int DCsync_config(zbx_dbsync_t *sync, zbx_uint64_t revision, int *flags)
{
const ZBX_TABLE *config_table;
@@ -735,9 +763,10 @@ static int DCsync_config(zbx_dbsync_t *sync, int *flags)
const char *row[ARRSIZE(selected_fields)];
size_t i;
- int j, found = 1, ret;
+ int j, found = 1, ret, value_int;
+ unsigned char value_uchar;
char **db_row;
- zbx_uint64_t rowid;
+ zbx_uint64_t rowid, value_uint64;
unsigned char tag;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
@@ -748,6 +777,7 @@ static int DCsync_config(zbx_dbsync_t *sync, int *flags)
{
found = 0;
config->config = (ZBX_DC_CONFIG_TABLE *)__config_shmem_malloc_func(NULL, sizeof(ZBX_DC_CONFIG_TABLE));
+ memset(config->config, 0, sizeof(ZBX_DC_CONFIG_TABLE));
}
if (SUCCEED != (ret = zbx_dbsync_next(sync, &rowid, &db_row, &tag)))
@@ -771,24 +801,69 @@ static int DCsync_config(zbx_dbsync_t *sync, int *flags)
/* store the config data */
if (NULL != row[0])
- ZBX_STR2UINT64(config->config->discovery_groupid, row[0]);
+ ZBX_STR2UINT64(value_uint64, row[0]);
else
- config->config->discovery_groupid = ZBX_DISCOVERY_GROUPID_UNDEFINED;
+ value_uint64 = ZBX_DISCOVERY_GROUPID_UNDEFINED;
- ZBX_STR2UCHAR(config->config->snmptrap_logging, row[1]);
- config->config->default_inventory_mode = atoi(row[25]);
- dc_strpool_replace(found, (const char **)&config->config->db.extension, row[26]);
- ZBX_STR2UCHAR(config->config->autoreg_tls_accept, row[27]);
- ZBX_STR2UCHAR(config->config->db.history_compression_status, row[28]);
+ if (config->config->discovery_groupid != value_uint64)
+ {
+ config->config->discovery_groupid = value_uint64;
+ config->revision.config_table = revision;
+ }
- if (SUCCEED != zbx_is_time_suffix(row[29], &config->config->db.history_compress_older, ZBX_LENGTH_UNLIMITED))
+ ZBX_STR2UCHAR(value_uchar, row[1]);
+ if (config->config->snmptrap_logging != value_uchar)
+ {
+ config->config->snmptrap_logging = value_uchar;
+ config->revision.config_table = revision;
+ }
+
+ if (config->config->default_inventory_mode != (value_int = atoi(row[25])))
+ {
+ config->config->default_inventory_mode = value_int;
+ config->revision.config_table = revision;
+ }
+
+ if (NULL == config->config->db.extension || 0 != strcmp(config->config->db.extension, row[26]))
+ {
+ dc_strpool_replace(found, (const char **)&config->config->db.extension, row[26]);
+ config->revision.config_table = revision;
+ }
+
+ ZBX_STR2UCHAR(value_uchar, row[27]);
+ if (config->config->autoreg_tls_accept != value_uchar)
+ {
+ config->config->autoreg_tls_accept = value_uchar;
+ config->revision.config_table = revision;
+ }
+
+ ZBX_STR2UCHAR(value_uchar, row[28]);
+ if (config->config->db.history_compression_status != value_uchar)
+ {
+ config->config->db.history_compression_status = value_uchar;
+ config->revision.config_table = revision;
+ }
+
+ if (SUCCEED != zbx_is_time_suffix(row[29], &value_int, ZBX_LENGTH_UNLIMITED))
{
zabbix_log(LOG_LEVEL_WARNING, "invalid history compression age: %s", row[29]);
- config->config->db.history_compress_older = 0;
+ value_int = 0;
+ }
+
+ if (config->config->db.history_compress_older != value_int)
+ {
+ config->config->db.history_compress_older = value_int;
+ config->revision.config_table = revision;
}
for (j = 0; TRIGGER_SEVERITY_COUNT > j; j++)
- dc_strpool_replace(found, &config->config->severity_name[j], row[2 + j]);
+ {
+ if (NULL == config->config->severity_name[j] || 0 != strcmp(config->config->severity_name[j], row[2 + j]))
+ {
+ dc_strpool_replace(found, (const char **)&config->config->severity_name[j], row[2 + j]);
+ config->revision.config_table = revision;
+ }
+ }
/* instance id cannot be changed - update it only at first sync to avoid read locks later */
if (0 == found)
@@ -799,51 +874,89 @@ static int DCsync_config(zbx_dbsync_t *sync, int *flags)
#endif
/* read housekeeper configuration */
-
- if (ZBX_HK_OPTION_ENABLED == (config->config->hk.events_mode = atoi(row[8])) &&
- (SUCCEED != set_hk_opt(&config->config->hk.events_trigger, 1, SEC_PER_DAY, row[9]) ||
- SUCCEED != set_hk_opt(&config->config->hk.events_internal, 1, SEC_PER_DAY, row[10]) ||
- SUCCEED != set_hk_opt(&config->config->hk.events_discovery, 1, SEC_PER_DAY, row[11]) ||
- SUCCEED != set_hk_opt(&config->config->hk.events_autoreg, 1, SEC_PER_DAY, row[12]) ||
- SUCCEED != set_hk_opt(&config->config->hk.events_service, 1, SEC_PER_DAY, row[32])))
+ if (ZBX_HK_OPTION_ENABLED == (value_int = atoi(row[8])) &&
+ (SUCCEED != set_hk_opt(&config->config->hk.events_trigger, 1, SEC_PER_DAY, row[9], revision) ||
+ SUCCEED != set_hk_opt(&config->config->hk.events_internal, 1, SEC_PER_DAY, row[10], revision) ||
+ SUCCEED != set_hk_opt(&config->config->hk.events_discovery, 1, SEC_PER_DAY, row[11], revision) ||
+ SUCCEED != set_hk_opt(&config->config->hk.events_autoreg, 1, SEC_PER_DAY, row[12], revision) ||
+ SUCCEED != set_hk_opt(&config->config->hk.events_service, 1, SEC_PER_DAY, row[32], revision)))
{
zabbix_log(LOG_LEVEL_WARNING, "trigger, internal, network discovery and auto-registration data"
" housekeeping will be disabled due to invalid settings");
- config->config->hk.events_mode = ZBX_HK_OPTION_DISABLED;
+ value_int = ZBX_HK_OPTION_DISABLED;
+ }
+ if (config->config->hk.events_mode != value_int)
+ {
+ config->config->hk.events_mode = value_int;
+ config->revision.config_table = revision;
}
- if (ZBX_HK_OPTION_ENABLED == (config->config->hk.services_mode = atoi(row[13])) &&
- SUCCEED != set_hk_opt(&config->config->hk.services, 1, SEC_PER_DAY, row[14]))
+ if (ZBX_HK_OPTION_ENABLED == (value_int = atoi(row[13])) &&
+ SUCCEED != set_hk_opt(&config->config->hk.services, 1, SEC_PER_DAY, row[14], revision))
{
zabbix_log(LOG_LEVEL_WARNING, "IT services data housekeeping will be disabled due to invalid"
" settings");
- config->config->hk.services_mode = ZBX_HK_OPTION_DISABLED;
+ value_int = ZBX_HK_OPTION_DISABLED;
+ }
+ if (config->config->hk.services_mode != value_int)
+ {
+ config->config->hk.services_mode = value_int;
+ config->revision.config_table = revision;
}
- if (ZBX_HK_OPTION_ENABLED == (config->config->hk.audit_mode = atoi(row[15])) &&
- SUCCEED != set_hk_opt(&config->config->hk.audit, 1, SEC_PER_DAY, row[16]))
+ if (ZBX_HK_OPTION_ENABLED == (value_int = atoi(row[15])) &&
+ SUCCEED != set_hk_opt(&config->config->hk.audit, 1, SEC_PER_DAY, row[16], revision))
{
zabbix_log(LOG_LEVEL_WARNING, "audit data housekeeping will be disabled due to invalid"
" settings");
- config->config->hk.audit_mode = ZBX_HK_OPTION_DISABLED;
+ value_int = ZBX_HK_OPTION_DISABLED;
+ }
+ if (config->config->hk.audit_mode != value_int)
+ {
+ config->config->hk.audit_mode = value_int;
+ config->revision.config_table = revision;
}
- if (ZBX_HK_OPTION_ENABLED == (config->config->hk.sessions_mode = atoi(row[17])) &&
- SUCCEED != set_hk_opt(&config->config->hk.sessions, 1, SEC_PER_DAY, row[18]))
+ if (ZBX_HK_OPTION_ENABLED == (value_int = atoi(row[17])) &&
+ SUCCEED != set_hk_opt(&config->config->hk.sessions, 1, SEC_PER_DAY, row[18], revision))
{
zabbix_log(LOG_LEVEL_WARNING, "user sessions data housekeeping will be disabled due to invalid"
" settings");
- config->config->hk.sessions_mode = ZBX_HK_OPTION_DISABLED;
+ value_int = ZBX_HK_OPTION_DISABLED;
+ }
+ if (config->config->hk.sessions_mode != value_int)
+ {
+ config->config->hk.sessions_mode = value_int;
+ config->revision.config_table = revision;
}
- config->config->hk.history_mode = atoi(row[19]);
- if (ZBX_HK_OPTION_ENABLED == (config->config->hk.history_global = atoi(row[20])) &&
- SUCCEED != set_hk_opt(&config->config->hk.history, 0, ZBX_HK_HISTORY_MIN, row[21]))
+ if (config->config->hk.history_mode != (value_int = atoi(row[19])))
+ {
+ config->config->hk.history_mode = value_int;
+ config->revision.config_table = revision;
+ }
+
+ if (ZBX_HK_OPTION_ENABLED == (value_int = atoi(row[20])) &&
+ SUCCEED != set_hk_opt(&config->config->hk.history, 0, ZBX_HK_HISTORY_MIN, row[21], revision))
{
zabbix_log(LOG_LEVEL_WARNING, "history data housekeeping will be disabled and all items will"
" store their history due to invalid global override settings");
- config->config->hk.history_mode = ZBX_HK_MODE_DISABLED;
- config->config->hk.history = 1; /* just enough to make 0 == items[i].history condition fail */
+ if (ZBX_HK_MODE_DISABLED != config->config->hk.history_mode)
+ {
+ config->config->hk.history_mode = ZBX_HK_MODE_DISABLED;
+ config->revision.config_table = revision;
+ }
+
+ if (1 != config->config->hk.history)
+ {
+ config->config->hk.history = 1; /* just enough to make 0 == items[i].history condition fail */
+ config->revision.config_table = revision;
+ }
+ }
+ if (config->config->hk.history_global != value_int)
+ {
+ config->config->hk.history_global = value_int;
+ config->revision.config_table = revision;
}
#ifdef HAVE_POSTGRESQL
@@ -851,18 +964,40 @@ static int DCsync_config(zbx_dbsync_t *sync, int *flags)
ZBX_HK_OPTION_ENABLED == config->config->hk.history_global &&
0 == zbx_strcmp_null(config->config->db.extension, ZBX_DB_EXTENSION_TIMESCALEDB))
{
- config->config->hk.history_mode = ZBX_HK_MODE_PARTITION;
+ if (ZBX_HK_MODE_PARTITION != config->config->hk.history_mode)
+ {
+ config->config->hk.history_mode = ZBX_HK_MODE_PARTITION;
+ config->revision.config_table = revision;
+ }
}
#endif
- config->config->hk.trends_mode = atoi(row[22]);
- if (ZBX_HK_OPTION_ENABLED == (config->config->hk.trends_global = atoi(row[23])) &&
- SUCCEED != set_hk_opt(&config->config->hk.trends, 0, ZBX_HK_TRENDS_MIN, row[24]))
+ if (config->config->hk.trends_mode != (value_int = atoi(row[22])))
+ {
+ config->config->hk.trends_mode = value_int;
+ config->revision.config_table = revision;
+ }
+
+ if (ZBX_HK_OPTION_ENABLED == (value_int = atoi(row[23])) &&
+ SUCCEED != set_hk_opt(&config->config->hk.trends, 0, ZBX_HK_TRENDS_MIN, row[24], revision))
{
zabbix_log(LOG_LEVEL_WARNING, "trends data housekeeping will be disabled and all numeric items"
" will store their history due to invalid global override settings");
- config->config->hk.trends_mode = ZBX_HK_MODE_DISABLED;
- config->config->hk.trends = 1; /* just enough to make 0 == items[i].trends condition fail */
+ if (ZBX_HK_MODE_DISABLED != config->config->hk.trends_mode)
+ {
+ config->config->hk.trends_mode = ZBX_HK_MODE_DISABLED;
+ config->revision.config_table = revision;
+ }
+ if (1 != config->config->hk.trends)
+ {
+ config->config->hk.trends = 1; /* just enough to make 0 == items[i].trends condition fail */
+ config->revision.config_table = revision;
+ }
+ }
+ if (config->config->hk.trends_global != value_int)
+ {
+ config->config->hk.trends_global = value_int;
+ config->revision.config_table = revision;
}
#ifdef HAVE_POSTGRESQL
@@ -870,12 +1005,25 @@ static int DCsync_config(zbx_dbsync_t *sync, int *flags)
ZBX_HK_OPTION_ENABLED == config->config->hk.trends_global &&
0 == zbx_strcmp_null(config->config->db.extension, ZBX_DB_EXTENSION_TIMESCALEDB))
{
- config->config->hk.trends_mode = ZBX_HK_MODE_PARTITION;
+ if (ZBX_HK_MODE_PARTITION != config->config->hk.trends_mode)
+ {
+ config->config->hk.trends_mode = ZBX_HK_MODE_PARTITION;
+ config->revision.config_table = revision;
+ }
}
#endif
- dc_strpool_replace(found, &config->config->default_timezone, row[31]);
- config->config->auditlog_enabled = atoi(row[33]);
+ if (NULL == config->config->default_timezone || 0 != strcmp(config->config->default_timezone, row[31]))
+ {
+ dc_strpool_replace(found, (const char **)&config->config->default_timezone, row[31]);
+ config->revision.config_table = revision;
+ }
+
+ if (config->config->auditlog_enabled != (value_int = atoi(row[33])))
+ {
+ config->config->auditlog_enabled = value_int;
+ config->revision.config_table = revision;
+ }
if (SUCCEED == ret && SUCCEED == zbx_dbsync_next(sync, &rowid, &db_row, &tag)) /* table must have */
zabbix_log(LOG_LEVEL_ERR, "table 'config' has multiple records"); /* only one record */
@@ -908,7 +1056,7 @@ static time_t calculate_proxy_nextcheck(zbx_uint64_t hostid, unsigned int delay,
return nextcheck;
}
-static void DCsync_autoreg_config(zbx_dbsync_t *sync)
+static void DCsync_autoreg_config(zbx_dbsync_t *sync, zbx_uint64_t revision)
{
/* sync this function with zbx_dbsync_compare_autoreg_psk() */
char **db_row;
@@ -934,6 +1082,8 @@ static void DCsync_autoreg_config(zbx_dbsync_t *sync)
default:
THIS_SHOULD_NEVER_HAPPEN;
}
+
+ config->revision.autoreg_tls = revision;
}
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
@@ -987,38 +1137,78 @@ static void DCsync_proxy_remove(ZBX_DC_PROXY *proxy)
}
dc_strpool_release(proxy->proxy_address);
+ dc_strpool_release(proxy->version_str);
+
+ zbx_vector_dc_host_ptr_destroy(&proxy->hosts);
+ zbx_vector_host_rev_destroy(&proxy->removed_hosts);
+
zbx_hashset_remove_direct(&config->proxies, proxy);
}
-static void DCsync_hosts(zbx_dbsync_t *sync, zbx_uint32_t revision, zbx_vector_uint64_t *active_avail_diff,
- zbx_hashset_t *activated_hosts)
+static void dc_host_deregister_proxy(ZBX_DC_HOST *host, zbx_uint64_t proxy_hostid, zbx_uint64_t revision)
{
- char **row;
- zbx_uint64_t rowid;
- unsigned char tag;
+ ZBX_DC_PROXY *proxy;
+ int i;
+ zbx_host_rev_t rev;
- ZBX_DC_HOST *host;
- ZBX_DC_IPMIHOST *ipmihost;
+ if (NULL == (proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies, &proxy_hostid)))
+ return;
+
+ rev.hostid = host->hostid;
+ rev.revision = revision;
+ zbx_vector_host_rev_append(&proxy->removed_hosts, rev);
+
+ if (FAIL == (i = zbx_vector_dc_host_ptr_search(&proxy->hosts, host, ZBX_DEFAULT_PTR_COMPARE_FUNC)))
+ return;
+
+ zbx_vector_dc_host_ptr_remove_noorder(&proxy->hosts, i);
+ proxy->revision = revision;
+}
+
+static void dc_host_register_proxy(ZBX_DC_HOST *host, zbx_uint64_t proxy_hostid, zbx_uint64_t revision)
+{
ZBX_DC_PROXY *proxy;
- ZBX_DC_HOST_H *host_h, host_h_local, *host_p, host_p_local;
- int found;
- int update_index_h, update_index_p, ret;
- zbx_uint64_t hostid, proxy_hostid;
- unsigned char status;
- time_t now;
- signed char ipmi_authtype;
- unsigned char ipmi_privilege;
+ if (NULL == (proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies, &proxy_hostid)))
+ return;
+
+ zbx_vector_dc_host_ptr_append(&proxy->hosts, host);
+ proxy->revision = revision;
+}
+
+
+static void DCsync_hosts(zbx_dbsync_t *sync, zbx_uint64_t revision, zbx_vector_uint64_t *active_avail_diff,
+ zbx_hashset_t *activated_hosts)
+{
+ char **row;
+ zbx_uint64_t rowid;
+ unsigned char tag;
+
+ ZBX_DC_HOST *host;
+ ZBX_DC_IPMIHOST *ipmihost;
+ ZBX_DC_PROXY *proxy;
+ ZBX_DC_HOST_H *host_h, host_h_local, *host_p, host_p_local;
+
+ int i, found;
+ int update_index_h, update_index_p, ret;
+ zbx_uint64_t hostid, proxy_hostid;
+ unsigned char status;
+ time_t now;
+ signed char ipmi_authtype;
+ unsigned char ipmi_privilege;
+ zbx_vector_dc_host_ptr_t proxy_hosts;
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
- ZBX_DC_PSK *psk_i, psk_i_local;
- zbx_ptr_pair_t *psk_owner, psk_owner_local;
- zbx_hashset_t psk_owners;
+ ZBX_DC_PSK *psk_i, psk_i_local;
+ zbx_ptr_pair_t *psk_owner, psk_owner_local;
+ zbx_hashset_t psk_owners;
#endif
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
zbx_hashset_create(&psk_owners, 0, ZBX_DEFAULT_PTR_HASH_FUNC, ZBX_DEFAULT_PTR_COMPARE_FUNC);
#endif
+ zbx_vector_dc_host_ptr_create(&proxy_hosts);
+
now = time(NULL);
while (SUCCEED == (ret = zbx_dbsync_next(sync, &rowid, &row, &tag)))
@@ -1305,11 +1495,13 @@ done:
host->maintenance_type = (unsigned char)atoi(row[8]);
host->maintenance_from = atoi(row[9]);
host->data_expected_from = now;
- host->update_items = 0;
zbx_vector_ptr_create_ext(&host->interfaces_v, __config_shmem_malloc_func,
__config_shmem_realloc_func, __config_shmem_free_func);
- zbx_vector_dc_item_ptr_create_ext(&host->active_items, __config_shmem_malloc_func,
+
+ zbx_vector_dc_httptest_ptr_create_ext(&host->httptests, __config_shmem_malloc_func,
+ __config_shmem_realloc_func, __config_shmem_free_func);
+ zbx_vector_dc_item_ptr_create_ext(&host->items, __config_shmem_malloc_func,
__config_shmem_realloc_func, __config_shmem_free_func);
}
else
@@ -1337,7 +1529,6 @@ done:
if (0 != reset_availability)
{
- int i;
ZBX_DC_INTERFACE *interface;
for (i = 0; i < host->interfaces_v.values_num; i++)
@@ -1356,6 +1547,30 @@ done:
}
}
+ if (HOST_STATUS_MONITORED == status || HOST_STATUS_NOT_MONITORED == status)
+ {
+ if (0 != found && 0 != host->proxy_hostid && host->proxy_hostid != proxy_hostid)
+ {
+ dc_host_deregister_proxy(host, host->proxy_hostid, revision);
+ }
+
+ if (0 != proxy_hostid)
+ {
+ if (0 == found || host->proxy_hostid != proxy_hostid)
+ {
+ zbx_vector_dc_host_ptr_append(&proxy_hosts, host);
+ }
+ else
+ {
+ if (NULL != (proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies,
+ &proxy_hostid)))
+ {
+ proxy->revision = revision;
+ }
+ }
+ }
+ }
+
host->proxy_hostid = proxy_hostid;
/* update 'hosts_h' and 'hosts_p' indexes using new data, if not done already */
@@ -1409,13 +1624,22 @@ done:
if (0 == found)
{
proxy->location = ZBX_LOC_NOWHERE;
- proxy->version = 0;
+ proxy->revision = revision;
+
+ proxy->version_int = ZBX_COMPONENT_VERSION_UNDEFINED;
+ proxy->version_str = dc_strpool_intern(ZBX_VERSION_UNDEFINED_STR);
+ proxy->compatibility = ZBX_PROXY_VERSION_UNDEFINED;
proxy->lastaccess = atoi(row[12]);
proxy->last_cfg_error_time = 0;
proxy->proxy_delay = 0;
proxy->nodata_win.flags = ZBX_PROXY_SUPPRESS_DISABLE;
proxy->nodata_win.values_num = 0;
proxy->nodata_win.period_end = 0;
+
+ zbx_vector_dc_host_ptr_create_ext(&proxy->hosts, __config_shmem_malloc_func,
+ __config_shmem_realloc_func, __config_shmem_free_func);
+ zbx_vector_host_rev_create_ext(&proxy->removed_hosts, __config_shmem_malloc_func,
+ __config_shmem_realloc_func, __config_shmem_free_func);
}
proxy->auto_compress = atoi(row[16 + ZBX_HOST_TLS_OFFSET]);
@@ -1445,6 +1669,9 @@ done:
host->status = status;
}
+ for (i = 0; i < proxy_hosts.values_num; i++)
+ dc_host_register_proxy(proxy_hosts.values[i], proxy_hosts.values[i]->proxy_hostid, revision);
+
/* remove deleted hosts from buffer */
for (; SUCCEED == ret; ret = zbx_dbsync_next(sync, &rowid, &row, &tag))
{
@@ -1482,6 +1709,9 @@ done:
}
zbx_vector_uint64_append(active_avail_diff, host->hostid);
+
+ if (0 != host->proxy_hostid)
+ dc_host_deregister_proxy(host, host->proxy_hostid, revision);
}
else if (HOST_STATUS_PROXY_ACTIVE == host->status || HOST_STATUS_PROXY_PASSIVE == host->status)
{
@@ -1517,24 +1747,28 @@ done:
}
#endif
zbx_vector_ptr_destroy(&host->interfaces_v);
- zbx_vector_dc_item_ptr_destroy(&host->active_items);
+ zbx_vector_dc_item_ptr_destroy(&host->items);
zbx_hashset_remove_direct(&config->hosts, host);
+
+ zbx_vector_dc_httptest_ptr_destroy(&host->httptests);
}
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
zbx_hashset_destroy(&psk_owners);
#endif
+ zbx_vector_dc_host_ptr_destroy(&proxy_hosts);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
}
-static void DCsync_host_inventory(zbx_dbsync_t *sync)
+static void DCsync_host_inventory(zbx_dbsync_t *sync, zbx_uint64_t revision)
{
ZBX_DC_HOST_INVENTORY *host_inventory, *host_inventory_auto;
zbx_uint64_t rowid, hostid;
int found, ret, i;
char **row;
unsigned char tag;
+ ZBX_DC_HOST *dc_host;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
@@ -1576,6 +1810,9 @@ static void DCsync_host_inventory(zbx_dbsync_t *sync)
for (i = 0; i < HOST_INVENTORY_FIELD_COUNT; i++)
host_inventory_auto->values[i] = NULL;
}
+
+ if (NULL != (dc_host = (ZBX_DC_HOST *)zbx_hashset_search(&config->hosts, &hostid)))
+ dc_host_update_revision(dc_host, revision);
}
/* remove deleted host inventory from cache */
@@ -1587,6 +1824,9 @@ static void DCsync_host_inventory(zbx_dbsync_t *sync)
continue;
}
+ if (NULL != (dc_host = (ZBX_DC_HOST *)zbx_hashset_search(&config->hosts, &host_inventory->hostid)))
+ dc_host_update_revision(dc_host, revision);
+
for (i = 0; i < HOST_INVENTORY_FIELD_COUNT; i++)
dc_strpool_release(host_inventory->values[i]);
@@ -1674,7 +1914,7 @@ void DCsync_kvs_paths(const struct zbx_json_parse *jp_kvs_paths)
{
START_SYNC;
- config->revision++;
+ config->revision.config++;
for (j = 0; j < diff.values_num; j++)
{
@@ -1693,8 +1933,8 @@ void DCsync_kvs_paths(const struct zbx_json_parse *jp_kvs_paths)
dc_kv->value = NULL;
}
- config->um_cache = um_cache_set_value_to_macros(config->um_cache, config->revision,
- &dc_kv->macros, dc_kv->value);
+ config->um_cache = um_cache_set_value_to_macros(config->um_cache,
+ config->revision.config, &dc_kv->macros, dc_kv->value);
dc_kv->update = 0;
}
@@ -1862,7 +2102,7 @@ static void dc_interface_snmp_remove(zbx_uint64_t interfaceid)
return;
}
-static void DCsync_interfaces(zbx_dbsync_t *sync, zbx_uint32_t revision)
+static void DCsync_interfaces(zbx_dbsync_t *sync, zbx_uint64_t revision)
{
char **row;
zbx_uint64_t rowid;
@@ -2150,6 +2390,12 @@ static void dc_interface_snmpitems_remove(ZBX_DC_ITEM *item)
}
}
+static void dc_masteritem_free(ZBX_DC_MASTERITEM *masteritem)
+{
+ zbx_vector_uint64_pair_destroy(&masteritem->dep_itemids);
+ __config_shmem_free_func(masteritem);
+}
+
/******************************************************************************
* *
* Purpose: remove itemid from master item dependent itemid vector *
@@ -2161,10 +2407,14 @@ static void dc_interface_snmpitems_remove(ZBX_DC_ITEM *item)
static void dc_masteritem_remove_depitem(zbx_uint64_t master_itemid, zbx_uint64_t dep_itemid)
{
ZBX_DC_MASTERITEM *masteritem;
+ ZBX_DC_ITEM *item;
int index;
zbx_uint64_pair_t pair;
- if (NULL == (masteritem = (ZBX_DC_MASTERITEM *)zbx_hashset_search(&config->masteritems, &master_itemid)))
+ if (NULL == (item = (ZBX_DC_ITEM *)zbx_hashset_search(&config->items, &master_itemid)))
+ return;
+
+ if (NULL == (masteritem = item->master_item))
return;
pair.first = dep_itemid;
@@ -2178,8 +2428,8 @@ static void dc_masteritem_remove_depitem(zbx_uint64_t master_itemid, zbx_uint64_
if (0 == masteritem->dep_itemids.values_num)
{
- zbx_vector_uint64_pair_destroy(&masteritem->dep_itemids);
- zbx_hashset_remove_direct(&config->masteritems, masteritem);
+ dc_masteritem_free(item->master_item);
+ item->master_item = NULL;
}
}
@@ -2234,7 +2484,14 @@ static unsigned char *config_decode_serialized_expression(const char *src)
return dst;
}
-static void DCsync_items(zbx_dbsync_t *sync, zbx_uint32_t revision, int flags, zbx_synced_new_config_t synced)
+static void dc_preprocitem_free(ZBX_DC_PREPROCITEM *preprocitem)
+{
+ zbx_vector_ptr_destroy(&preprocitem->preproc_ops);
+ __config_shmem_free_func(preprocitem);
+}
+
+static void DCsync_items(zbx_dbsync_t *sync, zbx_uint64_t revision, int flags, zbx_synced_new_config_t synced,
+ zbx_vector_uint64_t *deleted_itemids)
{
char **row;
zbx_uint64_t rowid;
@@ -2256,8 +2513,6 @@ static void DCsync_items(zbx_dbsync_t *sync, zbx_uint32_t revision, int flags, z
ZBX_DC_JMXITEM *jmxitem;
ZBX_DC_CALCITEM *calcitem;
ZBX_DC_INTERFACE_ITEM *interface_snmpitem;
- ZBX_DC_MASTERITEM *master;
- ZBX_DC_PREPROCITEM *preprocitem;
ZBX_DC_HTTPITEM *httpitem;
ZBX_DC_SCRIPTITEM *scriptitem;
ZBX_DC_ITEM_HK *item_hk, item_hk_local;
@@ -2332,24 +2587,6 @@ static void DCsync_items(zbx_dbsync_t *sync, zbx_uint32_t revision, int flags, z
update_index = 1;
}
- if (0 == found || item->type != type)
- {
- if (1 == found)
- {
- if (ITEM_TYPE_ZABBIX_ACTIVE == item->type)
- {
- if (FAIL != (i = zbx_vector_dc_item_ptr_search(&host->active_items, item,
- ZBX_DEFAULT_PTR_COMPARE_FUNC)))
- {
- zbx_vector_dc_item_ptr_remove(&host->active_items, i);
- }
- }
- }
-
- if (ITEM_TYPE_ZABBIX_ACTIVE == type)
- zbx_vector_dc_item_ptr_append(&host->active_items, item);
- }
-
/* store new information in item structure */
item->hostid = hostid;
@@ -2389,6 +2626,11 @@ static void DCsync_items(zbx_dbsync_t *sync, zbx_uint32_t revision, int flags, z
zbx_vector_ptr_create_ext(&item->tags, __config_shmem_malloc_func, __config_shmem_realloc_func,
__config_shmem_free_func);
+
+ zbx_vector_dc_item_ptr_append(&host->items, item);
+
+ item->preproc_item = NULL;
+ item->master_item = NULL;
}
else
{
@@ -2842,31 +3084,36 @@ static void DCsync_items(zbx_dbsync_t *sync, zbx_uint32_t revision, int flags, z
depitem = (ZBX_DC_DEPENDENTITEM *)dep_items.values[i];
dc_masteritem_remove_depitem(depitem->last_master_itemid, depitem->itemid);
+
+ if (NULL == (item = (ZBX_DC_ITEM *)zbx_hashset_search(&config->items, &depitem->master_itemid)))
+ continue;
+
pair.first = depitem->itemid;
pair.second = depitem->flags;
- /* append item to dependent item vector of master item */
- if (NULL == (master = (ZBX_DC_MASTERITEM *)zbx_hashset_search(&config->masteritems,
- &depitem->master_itemid)))
+ if (NULL == item->master_item)
{
- ZBX_DC_MASTERITEM master_local;
+ item->master_item = (ZBX_DC_MASTERITEM *)__config_shmem_malloc_func(NULL,
+ sizeof(ZBX_DC_MASTERITEM));
- master_local.itemid = depitem->master_itemid;
- master = (ZBX_DC_MASTERITEM *)zbx_hashset_insert(&config->masteritems, &master_local,
- sizeof(master_local));
-
- zbx_vector_uint64_pair_create_ext(&master->dep_itemids, __config_shmem_malloc_func,
+ zbx_vector_uint64_pair_create_ext(&item->master_item->dep_itemids, __config_shmem_malloc_func,
__config_shmem_realloc_func, __config_shmem_free_func);
}
- zbx_vector_uint64_pair_append(&master->dep_itemids, pair);
+ zbx_vector_uint64_pair_append(&item->master_item->dep_itemids, pair);
}
zbx_vector_ptr_destroy(&dep_items);
+ if (NULL != deleted_itemids)
+ zbx_vector_uint64_reserve(deleted_itemids, sync->remove_num);
+
/* remove deleted items from cache */
for (; SUCCEED == ret; ret = zbx_dbsync_next(sync, &rowid, &row, &tag))
{
+ if (NULL != deleted_itemids)
+ zbx_vector_uint64_append(deleted_itemids, rowid);
+
if (NULL == (item = (ZBX_DC_ITEM *)zbx_hashset_search(&config->items, &rowid)))
continue;
@@ -2874,13 +3121,10 @@ static void DCsync_items(zbx_dbsync_t *sync, zbx_uint32_t revision, int flags, z
{
dc_host_update_revision(host, revision);
- if (ITEM_TYPE_ZABBIX_ACTIVE == item->type)
+ if (FAIL != (i = zbx_vector_dc_item_ptr_search(&host->items, item,
+ ZBX_DEFAULT_PTR_COMPARE_FUNC)))
{
- if (FAIL != (i = zbx_vector_dc_item_ptr_search(&host->active_items, item,
- ZBX_DEFAULT_PTR_COMPARE_FUNC)))
- {
- zbx_vector_dc_item_ptr_remove(&host->active_items, i);
- }
+ zbx_vector_dc_item_ptr_remove(&host->items, i);
}
}
@@ -3098,12 +3342,11 @@ static void DCsync_items(zbx_dbsync_t *sync, zbx_uint32_t revision, int flags, z
zbx_vector_ptr_destroy(&item->tags);
- if (NULL != (preprocitem = (ZBX_DC_PREPROCITEM *)zbx_hashset_search(&config->preprocitems,
- &item->itemid)))
- {
- zbx_vector_ptr_destroy(&preprocitem->preproc_ops);
- zbx_hashset_remove_direct(&config->preprocitems, preprocitem);
- }
+ if (NULL != item->preproc_item)
+ dc_preprocitem_free(item->preproc_item);
+
+ if (NULL != item->master_item)
+ dc_masteritem_free(item->master_item);
zbx_hashset_remove_direct(&config->items, item);
}
@@ -3221,7 +3464,7 @@ static void DCsync_prototype_items(zbx_dbsync_t *sync)
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
}
-static void DCsync_triggers(zbx_dbsync_t *sync, zbx_uint32_t revision)
+static void DCsync_triggers(zbx_dbsync_t *sync, zbx_uint64_t revision)
{
char **row;
zbx_uint64_t rowid;
@@ -3826,7 +4069,7 @@ static void dc_schedule_trigger_timers(zbx_hashset_t *trend_queue, int now)
}
}
-static void DCsync_functions(zbx_dbsync_t *sync, zbx_uint32_t revision)
+static void DCsync_functions(zbx_dbsync_t *sync, zbx_uint64_t revision)
{
char **row;
zbx_uint64_t rowid;
@@ -3931,7 +4174,7 @@ static ZBX_DC_REGEXP *dc_regexp_remove_expression(const char *regexp_name, zbx_u
* Parameters: result - [IN] the result of expressions database select *
* *
******************************************************************************/
-static void DCsync_expressions(zbx_dbsync_t *sync, zbx_uint32_t revision)
+static void DCsync_expressions(zbx_dbsync_t *sync, zbx_uint64_t revision)
{
char **row;
zbx_uint64_t rowid;
@@ -3978,6 +4221,8 @@ static void DCsync_expressions(zbx_dbsync_t *sync, zbx_uint32_t revision)
}
zbx_vector_uint64_append(&regexp->expressionids, expressionid);
+
+ config->revision.expression = revision;
}
/* remove regexps with no expressions related to it */
@@ -4015,7 +4260,7 @@ static void DCsync_expressions(zbx_dbsync_t *sync, zbx_uint32_t revision)
}
if (0 != sync->add_num || 0 != sync->update_num || 0 != sync->remove_num)
- config->expression_revision = revision;
+ config->revision.expression = revision;
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
}
@@ -4204,7 +4449,7 @@ static void DCsync_action_conditions(zbx_dbsync_t *sync)
zbx_vector_ptr_append(&action->conditions, condition);
}
- if (CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
zbx_vector_ptr_append(&actions, action);
}
@@ -4224,7 +4469,7 @@ static void DCsync_action_conditions(zbx_dbsync_t *sync)
{
zbx_vector_ptr_remove_noorder(&action->conditions, index);
- if (CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
zbx_vector_ptr_append(&actions, action);
}
}
@@ -4244,7 +4489,7 @@ static void DCsync_action_conditions(zbx_dbsync_t *sync)
{
action = (zbx_dc_action_t *)actions.values[i];
- if (CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
zbx_vector_ptr_sort(&action->conditions, dc_compare_action_conditions_by_type);
}
@@ -4511,7 +4756,7 @@ static void DCsync_corr_conditions(zbx_dbsync_t *sync)
zbx_vector_ptr_append(&correlation->conditions, condition);
/* sort the conditions later */
- if (CONDITION_EVAL_TYPE_AND_OR == correlation->evaltype)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == correlation->evaltype)
zbx_vector_ptr_append(&correlations, correlation);
}
@@ -4533,7 +4778,7 @@ static void DCsync_corr_conditions(zbx_dbsync_t *sync)
ZBX_DEFAULT_PTR_COMPARE_FUNC)))
{
/* sort the conditions later */
- if (CONDITION_EVAL_TYPE_AND_OR == correlation->evaltype)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == correlation->evaltype)
zbx_vector_ptr_append(&correlations, correlation);
zbx_vector_ptr_remove_noorder(&correlation->conditions, index);
@@ -5038,20 +5283,21 @@ static int dc_compare_preprocops_by_step(const void *d1, const void *d2)
* 3 - params *
* *
******************************************************************************/
-static void DCsync_item_preproc(zbx_dbsync_t *sync, int timestamp)
+static void DCsync_item_preproc(zbx_dbsync_t *sync, zbx_uint64_t revision)
{
- char **row;
- zbx_uint64_t rowid;
- unsigned char tag;
- zbx_uint64_t item_preprocid, itemid;
- int found, ret, i, index;
- ZBX_DC_PREPROCITEM *preprocitem = NULL;
- zbx_dc_preproc_op_t *op;
- zbx_vector_ptr_t items;
+ char **row;
+ zbx_uint64_t rowid;
+ unsigned char tag;
+ zbx_uint64_t item_preprocid, itemid;
+ int found, ret, i, index;
+ ZBX_DC_PREPROCITEM *preprocitem = NULL;
+ zbx_dc_preproc_op_t *op;
+ ZBX_DC_ITEM *item;
+ zbx_vector_dc_item_ptr_t items;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
- zbx_vector_ptr_create(&items);
+ zbx_vector_dc_item_ptr_create(&items);
while (SUCCEED == (ret = zbx_dbsync_next(sync, &rowid, &row, &tag)))
{
@@ -5061,25 +5307,19 @@ static void DCsync_item_preproc(zbx_dbsync_t *sync, int timestamp)
ZBX_STR2UINT64(itemid, row[1]);
- if (NULL == preprocitem || itemid != preprocitem->itemid)
- {
- if (NULL == (preprocitem = (ZBX_DC_PREPROCITEM *)zbx_hashset_search(&config->preprocitems,
- &itemid)))
- {
- ZBX_DC_PREPROCITEM preprocitem_local;
+ if (NULL == (item = (ZBX_DC_ITEM *)zbx_hashset_search(&config->items, &itemid)))
+ continue;
- preprocitem_local.itemid = itemid;
- preprocitem_local.update_time = timestamp;
+ if (NULL == (preprocitem = item->preproc_item))
+ {
+ preprocitem = (ZBX_DC_PREPROCITEM *)__config_shmem_malloc_func(NULL, sizeof(ZBX_DC_PREPROCITEM));
- zbx_vector_ptr_create_ext(&preprocitem_local.preproc_ops, __config_shmem_malloc_func,
- __config_shmem_realloc_func, __config_shmem_free_func);
+ zbx_vector_ptr_create_ext(&preprocitem->preproc_ops, __config_shmem_malloc_func,
+ __config_shmem_realloc_func, __config_shmem_free_func);
- preprocitem = (ZBX_DC_PREPROCITEM *)zbx_hashset_insert(&config->preprocitems,
- &preprocitem_local, sizeof(preprocitem_local));
- }
- else
- preprocitem->update_time = timestamp;
+ item->preproc_item = preprocitem;
}
+ zbx_vector_dc_item_ptr_append(&items, item);
ZBX_STR2UINT64(item_preprocid, row[0]);
@@ -5097,8 +5337,6 @@ static void DCsync_item_preproc(zbx_dbsync_t *sync, int timestamp)
op->itemid = itemid;
zbx_vector_ptr_append(&preprocitem->preproc_ops, op);
}
-
- zbx_vector_ptr_append(&items, preprocitem);
}
/* remove deleted item preprocessing operations */
@@ -5108,14 +5346,14 @@ static void DCsync_item_preproc(zbx_dbsync_t *sync, int timestamp)
if (NULL == (op = (zbx_dc_preproc_op_t *)zbx_hashset_search(&config->preprocops, &rowid)))
continue;
- if (NULL != (preprocitem = (ZBX_DC_PREPROCITEM *)zbx_hashset_search(&config->preprocitems,
- &op->itemid)))
+ if (NULL != (item = (ZBX_DC_ITEM *)zbx_hashset_search(&config->items, &op->itemid)) &&
+ NULL != (preprocitem = item->preproc_item))
{
if (FAIL != (index = zbx_vector_ptr_search(&preprocitem->preproc_ops, op,
ZBX_DEFAULT_PTR_COMPARE_FUNC)))
{
zbx_vector_ptr_remove_noorder(&preprocitem->preproc_ops, index);
- zbx_vector_ptr_append(&items, preprocitem);
+ zbx_vector_dc_item_ptr_append(&items, item);
}
}
@@ -5126,23 +5364,28 @@ static void DCsync_item_preproc(zbx_dbsync_t *sync, int timestamp)
/* sort item preprocessing operations by step */
- zbx_vector_ptr_sort(&items, ZBX_DEFAULT_PTR_COMPARE_FUNC);
- zbx_vector_ptr_uniq(&items, ZBX_DEFAULT_PTR_COMPARE_FUNC);
+ zbx_vector_dc_item_ptr_sort(&items, ZBX_DEFAULT_PTR_COMPARE_FUNC);
+ zbx_vector_dc_item_ptr_uniq(&items, ZBX_DEFAULT_PTR_COMPARE_FUNC);
for (i = 0; i < items.values_num; i++)
{
- preprocitem = (ZBX_DC_PREPROCITEM *)items.values[i];
+ item = items.values[i];
+
+ if (NULL == (preprocitem = item->preproc_item))
+ continue;
+
+ dc_item_update_revision(item, revision);
if (0 == preprocitem->preproc_ops.values_num)
{
- zbx_vector_ptr_destroy(&preprocitem->preproc_ops);
- zbx_hashset_remove_direct(&config->preprocitems, preprocitem);
+ dc_preprocitem_free(preprocitem);
+ item->preproc_item = NULL;
}
else
zbx_vector_ptr_sort(&preprocitem->preproc_ops, dc_compare_preprocops_by_step);
}
- zbx_vector_ptr_destroy(&items);
+ zbx_vector_dc_item_ptr_destroy(&items);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
}
@@ -5160,7 +5403,7 @@ static void DCsync_item_preproc(zbx_dbsync_t *sync, int timestamp)
* 3 - value *
* *
******************************************************************************/
-static void DCsync_itemscript_param(zbx_dbsync_t *sync)
+static void DCsync_itemscript_param(zbx_dbsync_t *sync, zbx_uint64_t revision)
{
char **row;
zbx_uint64_t rowid;
@@ -5170,6 +5413,7 @@ static void DCsync_itemscript_param(zbx_dbsync_t *sync)
ZBX_DC_SCRIPTITEM *scriptitem;
zbx_dc_scriptitem_param_t *scriptitem_params;
zbx_vector_ptr_t items;
+ ZBX_DC_ITEM *dc_item;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
@@ -5241,6 +5485,9 @@ static void DCsync_itemscript_param(zbx_dbsync_t *sync)
{
scriptitem = (ZBX_DC_SCRIPTITEM *)items.values[i];
+ if (NULL != (dc_item = (ZBX_DC_ITEM *)zbx_hashset_search(&config->items, &scriptitem->itemid)))
+ dc_item_update_revision(dc_item, revision);
+
if (0 == scriptitem->params.values_num)
{
zbx_vector_ptr_destroy(&scriptitem->params);
@@ -5257,21 +5504,6 @@ static void DCsync_itemscript_param(zbx_dbsync_t *sync)
/******************************************************************************
* *
- * Purpose: update host revision *
- * *
- ******************************************************************************/
-static int dc_host_update_revision(ZBX_DC_HOST *host, zbx_uint32_t revision)
-{
- if (host->revision == revision)
- return SUCCEED;
-
- host->revision = revision;
-
- return SUCCEED;
-}
-
-/******************************************************************************
- * *
* Purpose: Updates group hosts in configuration cache *
* *
* Parameters: sync - [IN] the db synchronization data *
@@ -5334,6 +5566,588 @@ static void DCsync_hostgroup_hosts(zbx_dbsync_t *sync)
/******************************************************************************
* *
+ * Purpose: calculate nextcheck timestamp *
+ * *
+ * Parameters: seend - [IN] the seed *
+ * delay - [IN] the delay in seconds *
+ * now - [IN] current timestamp *
+ * *
+ * Return value: nextcheck value *
+ * *
+ ******************************************************************************/
+static time_t dc_calculate_nextcheck(zbx_uint64_t seed, int delay, time_t now)
+{
+ time_t nextcheck;
+
+ if (0 == delay)
+ return ZBX_JAN_2038;
+
+ nextcheck = delay * (now / delay) + (unsigned int)(seed % (unsigned int)delay);
+
+ while (nextcheck <= now)
+ nextcheck += delay;
+
+ return nextcheck;
+}
+
+static void dc_drule_queue(zbx_dc_drule_t *drule)
+{
+ zbx_binary_heap_elem_t elem;
+
+ elem.key = drule->druleid;
+ elem.data = (const void *)drule;
+
+ if (ZBX_LOC_QUEUE != drule->location)
+ {
+ zbx_binary_heap_insert(&config->drule_queue, &elem);
+ drule->location = ZBX_LOC_QUEUE;
+ }
+ else
+ zbx_binary_heap_update_direct(&config->drule_queue, &elem);
+}
+
+static void dc_drule_dequeue(zbx_dc_drule_t *drule)
+{
+ if (ZBX_LOC_QUEUE == drule->location)
+ {
+ zbx_binary_heap_remove_direct(&config->drule_queue, drule->druleid);
+ drule->location = ZBX_LOC_NOWHERE;
+ }
+}
+
+static void dc_sync_drules(zbx_dbsync_t *sync, zbx_uint64_t revision)
+{
+ char **row, *delay_str;
+ zbx_uint64_t rowid, druleid, proxy_hostid;
+ unsigned char tag;
+ int found, ret, delay = 0;
+ ZBX_DC_PROXY *proxy;
+ zbx_dc_drule_t *drule;
+ time_t now;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ now = time(NULL);
+
+ while (SUCCEED == (ret = zbx_dbsync_next(sync, &rowid, &row, &tag)))
+ {
+ /* removed rows will be always added at the end */
+ if (ZBX_DBSYNC_ROW_REMOVE == tag)
+ break;
+
+ ZBX_STR2UINT64(druleid, row[0]);
+ ZBX_DBROW2UINT64(proxy_hostid, row[1]);
+
+ drule = (zbx_dc_drule_t *)DCfind_id(&config->drules, druleid, sizeof(zbx_dc_drule_t), &found);
+
+ ZBX_STR2UCHAR(drule->status, row[3]);
+
+ if (0 == found)
+ {
+ drule->location = ZBX_LOC_NOWHERE;
+ drule->nextcheck = 0;
+ }
+ else
+ {
+ if (0 != drule->proxy_hostid && proxy_hostid != drule->proxy_hostid &&
+ NULL != (proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies,
+ &drule->proxy_hostid)))
+ {
+ proxy->revision = revision;
+ }
+ }
+
+ drule->proxy_hostid = proxy_hostid;
+ if (0 != drule->proxy_hostid)
+ {
+ if (NULL != (proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies, &drule->proxy_hostid)))
+ proxy->revision = revision;
+ }
+
+ delay_str = dc_expand_user_macros_dyn(row[2], NULL, 0, ZBX_MACRO_ENV_NONSECURE);
+ if (SUCCEED != zbx_is_time_suffix(delay_str, &delay, ZBX_LENGTH_UNLIMITED))
+ delay = ZBX_DEFAULT_INTERVAL;
+ zbx_free(delay_str);
+
+ if (DRULE_STATUS_MONITORED == drule->status && 0 == drule->proxy_hostid)
+ {
+ int delay_new = 0;
+
+ if (0 == found && 0 < config->revision.config)
+ delay_new = delay > SEC_PER_MIN ? SEC_PER_MIN : delay;
+ else if (ZBX_LOC_NOWHERE == drule->location || delay != drule->delay)
+ delay_new = delay;
+
+ if (0 != delay_new)
+ {
+ drule->nextcheck = dc_calculate_nextcheck(drule->druleid, delay_new, now);
+ dc_drule_queue(drule);
+ }
+ }
+ else
+ dc_drule_dequeue(drule);
+
+ drule->delay = delay;
+ drule->revision = revision;
+ }
+
+ /* remove deleted discovery rules from cache and update proxy revision */
+ for (; SUCCEED == ret; ret = zbx_dbsync_next(sync, &rowid, &row, &tag))
+ {
+ if (NULL == (drule = (zbx_dc_drule_t *)zbx_hashset_search(&config->drules, &rowid)))
+ continue;
+
+ if (0 != drule->proxy_hostid)
+ {
+ if (NULL != (proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies, &drule->proxy_hostid)))
+ proxy->revision = revision;
+ }
+
+ dc_drule_dequeue(drule);
+ zbx_hashset_remove_direct(&config->drules, drule);
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+}
+
+static void dc_sync_dchecks(zbx_dbsync_t *sync, zbx_uint64_t revision)
+{
+ char **row;
+ zbx_uint64_t rowid, druleid, dcheckid;
+ unsigned char tag;
+ int found, ret;
+ ZBX_DC_PROXY *proxy;
+ zbx_dc_drule_t *drule;
+ zbx_dc_dcheck_t *dcheck;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ while (SUCCEED == (ret = zbx_dbsync_next(sync, &rowid, &row, &tag)))
+ {
+ /* removed rows will be always added at the end */
+ if (ZBX_DBSYNC_ROW_REMOVE == tag)
+ break;
+
+ ZBX_STR2UINT64(dcheckid, row[0]);
+ ZBX_STR2UINT64(druleid, row[1]);
+
+ if (NULL == (drule = (zbx_dc_drule_t *)zbx_hashset_search(&config->drules, &druleid)))
+ continue;
+
+ dcheck = (zbx_dc_dcheck_t *)DCfind_id(&config->dchecks, dcheckid, sizeof(zbx_dc_dcheck_t), &found);
+ dcheck->druleid = druleid;
+
+ if (drule->revision == revision)
+ continue;
+
+ drule->revision = revision;
+
+ if (NULL != (proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies, &drule->proxy_hostid)))
+ proxy->revision = revision;
+ }
+
+ /* remove deleted discovery checks from cache and update proxy revision */
+ for (; SUCCEED == ret; ret = zbx_dbsync_next(sync, &rowid, &row, &tag))
+ {
+ if (NULL == (dcheck = (zbx_dc_dcheck_t *)zbx_hashset_search(&config->dchecks, &rowid)))
+ continue;
+
+ if (NULL != (drule = (zbx_dc_drule_t *)zbx_hashset_search(&config->drules, &dcheck->druleid)) &&
+ 0 != drule->proxy_hostid && drule->revision != revision)
+ {
+ if (NULL != (proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies, &drule->proxy_hostid)))
+ proxy->revision = revision;
+
+ drule->revision = revision;
+ }
+
+ zbx_hashset_remove_direct(&config->dchecks, dcheck);
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: update host and its proxy revision *
+ * *
+ ******************************************************************************/
+static int dc_host_update_revision(ZBX_DC_HOST *host, zbx_uint64_t revision)
+{
+ ZBX_DC_PROXY *proxy;
+
+ if (host->revision == revision)
+ return SUCCEED;
+
+ host->revision = revision;
+
+ if (0 == host->proxy_hostid)
+ return SUCCEED;
+
+ if (NULL == (proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies, &host->proxy_hostid)))
+ return FAIL;
+
+ proxy->revision = revision;
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: update item, host and its proxy revision *
+ * *
+ ******************************************************************************/
+static int dc_item_update_revision(ZBX_DC_ITEM *item, zbx_uint64_t revision)
+{
+ ZBX_DC_HOST *host;
+
+ if (item->revision == revision)
+ return SUCCEED;
+
+ item->revision = revision;
+
+ if (NULL == (host = (ZBX_DC_HOST *)zbx_hashset_search(&config->hosts, &item->hostid)))
+ return FAIL;
+
+ dc_host_update_revision(host, revision);
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: update httptest and its parent object revision *
+ * *
+ ******************************************************************************/
+static int dc_httptest_update_revision(zbx_dc_httptest_t *httptest, zbx_uint64_t revision)
+{
+ ZBX_DC_HOST *host;
+
+ if (httptest->revision == revision)
+ return SUCCEED;
+
+ httptest->revision = revision;
+
+ if (NULL == (host = (ZBX_DC_HOST *)zbx_hashset_search(&config->hosts, &httptest->hostid)))
+ return FAIL;
+
+ dc_host_update_revision(host, revision);
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: update httptest step and its parent object revision *
+ * *
+ ******************************************************************************/
+static int dc_httpstep_update_revision(zbx_dc_httpstep_t *httpstep, zbx_uint64_t revision)
+{
+ zbx_dc_httptest_t *httptest;
+
+ if (httpstep->revision == revision)
+ return SUCCEED;
+
+ httpstep->revision = revision;
+
+ if (NULL == (httptest = (zbx_dc_httptest_t *)zbx_hashset_search(&config->httptests, &httpstep->httptestid)))
+ return FAIL;
+
+ return dc_httptest_update_revision(httptest, revision);
+}
+
+static void dc_httptest_queue(zbx_dc_httptest_t *httptest)
+{
+ zbx_binary_heap_elem_t elem;
+
+ elem.key = httptest->httptestid;
+ elem.data = (const void *)httptest;
+
+ if (ZBX_LOC_QUEUE != httptest->location)
+ {
+ zbx_binary_heap_insert(&config->httptest_queue, &elem);
+ httptest->location = ZBX_LOC_QUEUE;
+ }
+ else
+ zbx_binary_heap_update_direct(&config->httptest_queue, &elem);
+}
+
+static void dc_httptest_dequeue(zbx_dc_httptest_t *httptest)
+{
+ if (ZBX_LOC_QUEUE == httptest->location)
+ {
+ zbx_binary_heap_remove_direct(&config->httptest_queue, httptest->httptestid);
+ httptest->location = ZBX_LOC_NOWHERE;
+ }
+}
+
+/******************************************************************************
+ * *
+ * Purpose: update httpstep and its parent object revision *
+ * *
+ ******************************************************************************/
+static void dc_sync_httptests(zbx_dbsync_t *sync, zbx_uint64_t revision)
+{
+ char **row, *delay_str;
+ zbx_uint64_t rowid, httptestid, hostid;
+ unsigned char tag;
+ int found, ret, delay;
+ ZBX_DC_HOST *host;
+ zbx_dc_httptest_t *httptest;
+ time_t now;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ now = time(NULL);
+
+ while (SUCCEED == (ret = zbx_dbsync_next(sync, &rowid, &row, &tag)))
+ {
+ /* removed rows will be always added at the end */
+ if (ZBX_DBSYNC_ROW_REMOVE == tag)
+ break;
+
+ ZBX_STR2UINT64(hostid, row[1]);
+
+ if (NULL == (host = (ZBX_DC_HOST *)zbx_hashset_search(&config->hosts, &hostid)))
+ continue;
+
+ dc_host_update_revision(host, revision);
+
+ ZBX_STR2UINT64(httptestid, row[0]);
+
+ httptest = (zbx_dc_httptest_t *)DCfind_id(&config->httptests, httptestid, sizeof(zbx_dc_httptest_t),
+ &found);
+
+ ZBX_STR2UCHAR(httptest->status, row[3]);
+
+ if (0 == found)
+ {
+ httptest->location = ZBX_LOC_NOWHERE;
+ httptest->nextcheck = 0;
+ zbx_vector_dc_httptest_ptr_append(&host->httptests, httptest);
+ }
+
+ delay_str = dc_expand_user_macros_dyn(row[2], &hostid, 1, ZBX_MACRO_ENV_NONSECURE);
+ if (SUCCEED != zbx_is_time_suffix(delay_str, &delay, ZBX_LENGTH_UNLIMITED))
+ delay = ZBX_DEFAULT_INTERVAL;
+ zbx_free(delay_str);
+
+ if (HTTPTEST_STATUS_MONITORED == httptest->status && HOST_STATUS_MONITORED == host->status &&
+ 0 == host->proxy_hostid)
+ {
+ int delay_new = 0;
+
+ if (0 == found && 0 < config->revision.config)
+ delay_new = delay > SEC_PER_MIN ? SEC_PER_MIN : delay;
+ else if (ZBX_LOC_NOWHERE == httptest->location || delay != httptest->delay)
+ delay_new = delay;
+
+ if (0 != delay_new)
+ {
+ httptest->nextcheck = dc_calculate_nextcheck(httptest->httptestid, delay_new, now);
+ dc_httptest_queue(httptest);
+ }
+ }
+ else
+ dc_httptest_dequeue(httptest);
+
+ httptest->hostid = hostid;
+ httptest->delay = delay;
+ httptest->revision = revision;
+ }
+
+ /* remove deleted httptest rules from cache and update host revision */
+ for (; SUCCEED == ret; ret = zbx_dbsync_next(sync, &rowid, &row, &tag))
+ {
+ int index;
+
+ if (NULL == (httptest = (zbx_dc_httptest_t *)zbx_hashset_search(&config->httptests, &rowid)))
+ continue;
+
+ if (NULL != (host = (ZBX_DC_HOST *)zbx_hashset_search(&config->hosts, &httptest->hostid)))
+ {
+ dc_host_update_revision(host, revision);
+
+ if (FAIL != (index = zbx_vector_dc_httptest_ptr_search(&host->httptests, httptest,
+ ZBX_DEFAULT_PTR_COMPARE_FUNC)))
+ {
+ zbx_vector_dc_httptest_ptr_remove(&host->httptests, index);
+ }
+ }
+
+ dc_httptest_dequeue(httptest);
+ zbx_hashset_remove_direct(&config->httptests, httptest);
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+}
+
+static void dc_sync_httptest_fields(zbx_dbsync_t *sync, zbx_uint64_t revision)
+{
+ char **row;
+ zbx_uint64_t rowid, httptestid, httptest_fieldid;
+ unsigned char tag;
+ int found, ret;
+ zbx_dc_httptest_t *httptest;
+ zbx_dc_httptest_field_t *httptest_field;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ while (SUCCEED == (ret = zbx_dbsync_next(sync, &rowid, &row, &tag)))
+ {
+ /* removed rows will be always added at the end */
+ if (ZBX_DBSYNC_ROW_REMOVE == tag)
+ break;
+
+ ZBX_STR2UINT64(httptestid, row[1]);
+
+ if (NULL == (httptest = (zbx_dc_httptest_t *)zbx_hashset_search(&config->httptests, &httptestid)))
+ continue;
+
+ dc_httptest_update_revision(httptest, revision);
+
+ ZBX_STR2UINT64(httptest_fieldid, row[0]);
+
+ httptest_field = (zbx_dc_httptest_field_t *)DCfind_id(&config->httptest_fields, httptest_fieldid,
+ sizeof(zbx_dc_httptest_field_t), &found);
+
+ httptest_field->httptestid = httptestid;
+
+ }
+
+ /* remove deleted httptest fields from cache and update host revision */
+ for (; SUCCEED == ret; ret = zbx_dbsync_next(sync, &rowid, &row, &tag))
+ {
+ if (NULL == (httptest_field = (zbx_dc_httptest_field_t *)zbx_hashset_search(&config->httptest_fields,
+ &rowid)))
+ {
+ continue;
+ }
+
+ if (NULL != (httptest = (zbx_dc_httptest_t *)zbx_hashset_search(&config->httptests,
+ &httptest_field->httptestid)))
+ {
+ dc_httptest_update_revision(httptest, revision);
+ }
+
+ zbx_hashset_remove_direct(&config->httptest_fields, httptest_field);
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+}
+
+static void dc_sync_httpsteps(zbx_dbsync_t *sync, zbx_uint64_t revision)
+{
+ char **row;
+ zbx_uint64_t rowid, httptestid, httpstepid;
+ unsigned char tag;
+ int found, ret;
+ zbx_dc_httptest_t *httptest;
+ zbx_dc_httpstep_t *httpstep;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ while (SUCCEED == (ret = zbx_dbsync_next(sync, &rowid, &row, &tag)))
+ {
+ /* removed rows will be always added at the end */
+ if (ZBX_DBSYNC_ROW_REMOVE == tag)
+ break;
+
+ ZBX_STR2UINT64(httptestid, row[1]);
+
+ if (NULL == (httptest = (zbx_dc_httptest_t *)zbx_hashset_search(&config->httptests, &httptestid)))
+ continue;
+
+ dc_httptest_update_revision(httptest, revision);
+
+ httptest->revision = revision;
+
+ ZBX_STR2UINT64(httpstepid, row[0]);
+
+ httpstep = (zbx_dc_httpstep_t *)DCfind_id(&config->httpsteps, httpstepid,
+ sizeof(zbx_dc_httpstep_t), &found);
+
+ httpstep->httptestid = httptestid;
+ httpstep->revision = revision;
+ }
+
+ /* remove deleted httptest fields from cache and update host revision */
+ for (; SUCCEED == ret; ret = zbx_dbsync_next(sync, &rowid, &row, &tag))
+ {
+ if (NULL == (httpstep = (zbx_dc_httpstep_t *)zbx_hashset_search(&config->httpsteps,
+ &rowid)))
+ {
+ continue;
+ }
+
+ if (NULL != (httptest = (zbx_dc_httptest_t *)zbx_hashset_search(&config->httptests,
+ &httpstep->httptestid)))
+ {
+ dc_httptest_update_revision(httptest, revision);
+ }
+
+ zbx_hashset_remove_direct(&config->httpsteps, httpstep);
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+}
+
+static void dc_sync_httpstep_fields(zbx_dbsync_t *sync, zbx_uint64_t revision)
+{
+ char **row;
+ zbx_uint64_t rowid, httpstep_fieldid, httpstepid;
+ unsigned char tag;
+ int found, ret;
+ zbx_dc_httpstep_t *httpstep;
+ zbx_dc_httpstep_field_t *httpstep_field;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ while (SUCCEED == (ret = zbx_dbsync_next(sync, &rowid, &row, &tag)))
+ {
+ /* removed rows will be always added at the end */
+ if (ZBX_DBSYNC_ROW_REMOVE == tag)
+ break;
+
+ ZBX_STR2UINT64(httpstepid, row[1]);
+
+ if (NULL == (httpstep = (zbx_dc_httpstep_t *)zbx_hashset_search(&config->httpsteps, &httpstepid)))
+ continue;
+
+ dc_httpstep_update_revision(httpstep, revision);
+
+ ZBX_STR2UINT64(httpstep_fieldid, row[0]);
+
+ httpstep_field = (zbx_dc_httpstep_field_t *)DCfind_id(&config->httpstep_fields, httpstep_fieldid,
+ sizeof(zbx_dc_httpstep_field_t), &found);
+
+ httpstep_field->httpstepid = httpstep_fieldid;
+
+ }
+
+ /* remove deleted httpstep fields from cache and update host revision */
+ for (; SUCCEED == ret; ret = zbx_dbsync_next(sync, &rowid, &row, &tag))
+ {
+ if (NULL == (httpstep_field = (zbx_dc_httpstep_field_t *)zbx_hashset_search(&config->httpstep_fields,
+ &rowid)))
+ {
+ continue;
+ }
+
+ if (NULL != (httpstep = (zbx_dc_httpstep_t *)zbx_hashset_search(&config->httpsteps,
+ &httpstep_field->httpstepid)))
+ {
+ dc_httpstep_update_revision(httpstep, revision);
+ }
+
+ zbx_hashset_remove_direct(&config->httpstep_fields, httpstep_field);
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+}
+
+/******************************************************************************
+ * *
* Purpose: updates trigger topology after trigger dependency changes *
* *
******************************************************************************/
@@ -5423,8 +6237,8 @@ static void dc_trigger_add_itemids(ZBX_DC_TRIGGER *trigger, const zbx_vector_uin
* Purpose: reset item trigger links and remove corresponding itemids from *
* affected triggers *
* *
- * Parameters: item - the item to reset *
- * trigger - the trigger to exclude *
+ * Parameters: item - the item to reset *
+ * trigger_exclude - the trigger to exclude *
* *
******************************************************************************/
static void dc_item_reset_triggers(ZBX_DC_ITEM *item, ZBX_DC_TRIGGER *trigger_exclude)
@@ -5667,7 +6481,7 @@ static void zbx_dbsync_process_active_avail_diff(zbx_vector_uint64_t *diff)
* Purpose: Synchronize configuration data from database *
* *
******************************************************************************/
-void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
+void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced, zbx_vector_uint64_t *deleted_itemids)
{
static int sync_status = ZBX_DBSYNC_STATUS_UNKNOWN;
@@ -5679,7 +6493,8 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
correlation_sec, correlation_sec2, corr_condition_sec, corr_condition_sec2, corr_operation_sec,
corr_operation_sec2, hgroups_sec, hgroups_sec2, itempp_sec, itempp_sec2, itemscrp_sec,
itemscrp_sec2, total, total2, update_sec, maintenance_sec, maintenance_sec2, item_tag_sec,
- item_tag_sec2, um_cache_sec, queues_sec, changelog_sec;
+ item_tag_sec2, um_cache_sec, queues_sec, changelog_sec, drules_sec, drules_sec2, httptest_sec,
+ httptest_sec2;
zbx_dbsync_t config_sync, hosts_sync, hi_sync, htmpl_sync, gmacro_sync, hmacro_sync, if_sync, items_sync,
template_items_sync, prototype_items_sync, item_discovery_sync, triggers_sync, tdep_sync,
@@ -5687,7 +6502,8 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
item_tag_sync, host_tag_sync, correlation_sync, corr_condition_sync, corr_operation_sync,
hgroups_sync, itempp_sync, itemscrp_sync, maintenance_sync, maintenance_period_sync,
maintenance_tag_sync, maintenance_group_sync, maintenance_host_sync, hgroup_host_sync,
- autoreg_host_sync;
+ drules_sync, dchecks_sync, httptest_sync, httptest_field_sync, httpstep_sync,
+ httpstep_field_sync, autoreg_host_sync;
double autoreg_csec, autoreg_csec2, autoreg_host_csec, autoreg_host_csec2;
zbx_dbsync_t autoreg_config_sync;
@@ -5696,8 +6512,8 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
zbx_hashset_t trend_queue;
zbx_vector_uint64_t active_avail_diff;
- zbx_uint32_t new_revision = config->revision + 1;
zbx_hashset_t activated_hosts;
+ zbx_uint64_t new_revision = config->revision.config + 1;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
@@ -5717,6 +6533,7 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
/* global configuration must be synchronized directly with database */
zbx_dbsync_init(&config_sync, ZBX_DBSYNC_INIT);
+
zbx_dbsync_init(&autoreg_config_sync, mode);
zbx_dbsync_init(&autoreg_host_sync, mode);
zbx_dbsync_init(&hosts_sync, changelog_sync_mode);
@@ -5758,6 +6575,15 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
zbx_dbsync_init(&maintenance_group_sync, mode);
zbx_dbsync_init(&maintenance_host_sync, mode);
+ zbx_dbsync_init(&drules_sync, changelog_sync_mode);
+ zbx_dbsync_init(&dchecks_sync, changelog_sync_mode);
+
+ zbx_dbsync_init(&httptest_sync, changelog_sync_mode);
+ zbx_dbsync_init(&httptest_field_sync, changelog_sync_mode);
+ zbx_dbsync_init(&httpstep_sync, changelog_sync_mode);
+ zbx_dbsync_init(&httpstep_field_sync, changelog_sync_mode);
+
+
#ifdef HAVE_ORACLE
/* With Oracle fetch statements can fail before all data has been fetched. */
/* In such cache next sync will need to do full scan rather than just */
@@ -5784,11 +6610,12 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
/* sync global configuration settings */
START_SYNC;
sec = zbx_time();
- DCsync_config(&config_sync, &flags);
+ DCsync_config(&config_sync, new_revision, &flags);
csec2 = zbx_time() - sec;
+ /* must be done in the same cache locking with config sync */
sec = zbx_time();
- DCsync_autoreg_config(&autoreg_config_sync); /* must be done in the same cache locking with config sync */
+ DCsync_autoreg_config(&autoreg_config_sync, new_revision);
autoreg_csec2 = zbx_time() - sec;
sec = zbx_time();
@@ -5828,6 +6655,7 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
host_tag_sec2 = zbx_time() - sec;
FINISH_SYNC;
+
/* postpone configuration sync until macro secrets are received from Zabbix server */
if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER) && 0 != config->kvs_paths.values_num &&
ZBX_DBSYNC_INIT == mode)
@@ -5867,14 +6695,33 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
goto out;
maintenance_sec = zbx_time() - sec;
+ sec = zbx_time();
+ if (FAIL == zbx_dbsync_prepare_drules(&drules_sync))
+ goto out;
+ if (FAIL == zbx_dbsync_prepare_dchecks(&dchecks_sync))
+ goto out;
+ drules_sec = zbx_time() - sec;
+
+ sec = zbx_time();
+ if (FAIL == zbx_dbsync_prepare_httptests(&httptest_sync))
+ goto out;
+ if (FAIL == zbx_dbsync_prepare_httptest_fields(&httptest_field_sync))
+ goto out;
+ if (FAIL == zbx_dbsync_prepare_httpsteps(&httpstep_sync))
+ goto out;
+ if (FAIL == zbx_dbsync_prepare_httpstep_fields(&httpstep_field_sync))
+ goto out;
+ httptest_sec = zbx_time() - sec;
+
START_SYNC;
sec = zbx_time();
zbx_vector_uint64_create(&active_avail_diff);
DCsync_hosts(&hosts_sync, new_revision, &active_avail_diff, &activated_hosts);
+ zbx_dbsync_clear_user_macros();
hsec2 = zbx_time() - sec;
sec = zbx_time();
- DCsync_host_inventory(&hi_sync);
+ DCsync_host_inventory(&hi_sync, new_revision);
hisec2 = zbx_time() - sec;
sec = zbx_time();
@@ -5956,7 +6803,7 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
/* relies on hosts, proxies and interfaces, must be after DCsync_{hosts,interfaces}() */
sec = zbx_time();
- DCsync_items(&items_sync, new_revision, flags, synced);
+ DCsync_items(&items_sync, new_revision, flags, synced, deleted_itemids);
isec2 = zbx_time() - sec;
sec = zbx_time();
@@ -5973,12 +6820,12 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
/* relies on items, must be after DCsync_items() */
sec = zbx_time();
- DCsync_item_preproc(&itempp_sync, sec);
+ DCsync_item_preproc(&itempp_sync, new_revision);
itempp_sec2 = zbx_time() - sec;
/* relies on items, must be after DCsync_items() */
sec = zbx_time();
- DCsync_itemscript_param(&itemscrp_sync);
+ DCsync_itemscript_param(&itemscrp_sync, new_revision);
itemscrp_sec2 = zbx_time() - sec;
config->item_sync_ts = time(NULL);
@@ -6106,6 +6953,18 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
corr_operation_sec2 = zbx_time() - sec;
sec = zbx_time();
+ dc_sync_drules(&drules_sync, new_revision);
+ dc_sync_dchecks(&dchecks_sync, new_revision);
+ drules_sec2 = zbx_time() - sec;
+
+ sec = zbx_time();
+ dc_sync_httptests(&httptest_sync, new_revision);
+ dc_sync_httptest_fields(&httptest_field_sync, new_revision);
+ dc_sync_httpsteps(&httpstep_sync, new_revision);
+ dc_sync_httpstep_fields(&httpstep_field_sync, new_revision);
+ httptest_sec2 = zbx_time() - sec;
+
+ sec = zbx_time();
if (0 != hosts_sync.add_num + hosts_sync.update_num + hosts_sync.remove_num)
update_flags |= ZBX_DBSYNC_UPDATE_HOSTS;
@@ -6145,18 +7004,19 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
update_sec = zbx_time() - sec;
- config->revision = new_revision;
+ config->revision.config = new_revision;
if (SUCCEED == ZBX_CHECK_LOG_LEVEL(LOG_LEVEL_DEBUG))
{
total = csec + hsec + hisec + htsec + gmsec + hmsec + ifsec + idsec + isec + tisec + pisec + tsec +
dsec + fsec + expr_sec + action_sec + action_op_sec + action_condition_sec +
trigger_tag_sec + correlation_sec + corr_condition_sec + corr_operation_sec +
- hgroups_sec + itempp_sec + maintenance_sec + item_tag_sec;
+ hgroups_sec + itempp_sec + maintenance_sec + item_tag_sec + drules_sec + httptest_sec;
total2 = csec2 + hsec2 + hisec2 + ifsec2 + idsec2 + isec2 + tisec2 + pisec2 + tsec2 + dsec2 + fsec2 +
expr_sec2 + action_op_sec2 + action_sec2 + action_condition_sec2 + trigger_tag_sec2 +
correlation_sec2 + corr_condition_sec2 + corr_operation_sec2 + hgroups_sec2 +
- itempp_sec2 + maintenance_sec2 + item_tag_sec2 + update_sec + um_cache_sec;
+ itempp_sec2 + maintenance_sec2 + item_tag_sec2 + update_sec + um_cache_sec +
+ drules_sec2 + httptest_sec2;
zabbix_log(LOG_LEVEL_DEBUG, "%s() changelog : sql:" ZBX_FS_DBL " sec (%d records)",
__func__, changelog_sec, changelog_num);
@@ -6287,6 +7147,25 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
ZBX_FS_UI64 "/" ZBX_FS_UI64 "/" ZBX_FS_UI64 ").",
__func__, maintenance_sec, maintenance_sec2, maintenance_sync.add_num,
maintenance_sync.update_num, maintenance_sync.remove_num);
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() drules : sql:" ZBX_FS_DBL " sync:" ZBX_FS_DBL " sec ("
+ ZBX_FS_UI64 "/" ZBX_FS_UI64 "/" ZBX_FS_UI64 ").",
+ __func__, drules_sec, drules_sec2, drules_sync.add_num, drules_sync.update_num,
+ drules_sync.remove_num);
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() dchecks : (" ZBX_FS_UI64 "/" ZBX_FS_UI64 "/" ZBX_FS_UI64 ").",
+ __func__, dchecks_sync.add_num, dchecks_sync.update_num, dchecks_sync.remove_num);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() httptests : sql:" ZBX_FS_DBL " sync:" ZBX_FS_DBL " sec ("
+ ZBX_FS_UI64 "/" ZBX_FS_UI64 "/" ZBX_FS_UI64 ").",
+ __func__, httptest_sec, httptest_sec2, httptest_sync.add_num, httptest_sync.update_num,
+ httptest_sync.remove_num);
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() httptestfld : (" ZBX_FS_UI64 "/" ZBX_FS_UI64 "/" ZBX_FS_UI64 ").",
+ __func__, httptest_field_sync.add_num, httptest_field_sync.update_num,
+ httptest_field_sync.remove_num);
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() httpsteps : (" ZBX_FS_UI64 "/" ZBX_FS_UI64 "/" ZBX_FS_UI64 ").",
+ __func__, httpstep_sync.add_num, httpstep_sync.update_num, httpstep_sync.remove_num);
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() httpstepfld : (" ZBX_FS_UI64 "/" ZBX_FS_UI64 "/" ZBX_FS_UI64 ").",
+ __func__, httpstep_field_sync.add_num, httpstep_field_sync.update_num,
+ httpstep_field_sync.remove_num);
zabbix_log(LOG_LEVEL_DEBUG, "%s() macro cache: " ZBX_FS_DBL " sec.", __func__, um_cache_sec);
zabbix_log(LOG_LEVEL_DEBUG, "%s() reindex : " ZBX_FS_DBL " sec.", __func__, update_sec);
@@ -6336,8 +7215,6 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
zabbix_log(LOG_LEVEL_DEBUG, "%s() numitems : %d (%d slots)", __func__,
config->numitems.num_data, config->numitems.num_slots);
zabbix_log(LOG_LEVEL_DEBUG, "%s() preprocitems: %d (%d slots)", __func__,
- config->preprocitems.num_data, config->preprocitems.num_slots);
- zabbix_log(LOG_LEVEL_DEBUG, "%s() preprocops : %d (%d slots)", __func__,
config->preprocops.num_data, config->preprocops.num_slots);
zabbix_log(LOG_LEVEL_DEBUG, "%s() snmpitems : %d (%d slots)", __func__,
config->snmpitems.num_data, config->snmpitems.num_slots);
@@ -6399,6 +7276,20 @@ void DCsync_configuration(unsigned char mode, zbx_synced_new_config_t synced)
zabbix_log(LOG_LEVEL_DEBUG, "%s() maint time : %d (%d slots)", __func__,
config->maintenance_periods.num_data, config->maintenance_periods.num_slots);
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() drules : %d (%d slots)", __func__,
+ config->drules.num_data, config->drules.num_slots);
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() dchecks : %d (%d slots)", __func__,
+ config->dchecks.num_data, config->dchecks.num_slots);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() httptests : %d (%d slots)", __func__,
+ config->httptests.num_data, config->httptests.num_slots);
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() httptestfld: %d (%d slots)", __func__,
+ config->httptest_fields.num_data, config->httptest_fields.num_slots);
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() httpsteps : %d (%d slots)", __func__,
+ config->httpsteps.num_data, config->httpsteps.num_slots);
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() httpstepfld: %d (%d slots)", __func__,
+ config->httpstep_fields.num_data, config->httpstep_fields.num_slots);
+
for (i = 0; ZBX_POLLER_TYPE_COUNT > i; i++)
{
zabbix_log(LOG_LEVEL_DEBUG, "%s() queue[%d] : %d (%d allocated)", __func__,
@@ -6460,7 +7351,12 @@ out:
if (0 != (update_flags & (ZBX_DBSYNC_UPDATE_HOSTS | ZBX_DBSYNC_UPDATE_ITEMS | ZBX_DBSYNC_UPDATE_MACROS)))
{
sec = zbx_time();
+
dc_reschedule_items(&activated_hosts);
+
+ if (0 != activated_hosts.num_data)
+ dc_reschedule_httptests(&activated_hosts);
+
queues_sec = zbx_time() - sec;
zabbix_log(LOG_LEVEL_DEBUG, "%s() reschedule : " ZBX_FS_DBL " sec.", __func__, queues_sec);
}
@@ -6500,6 +7396,12 @@ clean:
zbx_dbsync_clear(&maintenance_group_sync);
zbx_dbsync_clear(&maintenance_host_sync);
zbx_dbsync_clear(&hgroup_host_sync);
+ zbx_dbsync_clear(&drules_sync);
+ zbx_dbsync_clear(&dchecks_sync);
+ zbx_dbsync_clear(&httptest_sync);
+ zbx_dbsync_clear(&httptest_field_sync);
+ zbx_dbsync_clear(&httpstep_sync);
+ zbx_dbsync_clear(&httpstep_field_sync);
if (ZBX_DBSYNC_INIT == mode)
zbx_hashset_destroy(&trend_queue);
@@ -6783,6 +7685,28 @@ static int __config_timer_compare(const void *d1, const void *d2)
return 0;
}
+static int __config_drule_compare(const void *d1, const void *d2)
+{
+ const zbx_binary_heap_elem_t *e1 = (const zbx_binary_heap_elem_t *)d1;
+ const zbx_binary_heap_elem_t *e2 = (const zbx_binary_heap_elem_t *)d2;
+
+ const zbx_dc_drule_t *r1 = (const zbx_dc_drule_t *)e1->data;
+ const zbx_dc_drule_t *r2 = (const zbx_dc_drule_t *)e2->data;
+
+ return (int)(r1->nextcheck - r2->nextcheck);
+}
+
+static int __config_httptest_compare(const void *d1, const void *d2)
+{
+ const zbx_binary_heap_elem_t *e1 = (const zbx_binary_heap_elem_t *)d1;
+ const zbx_binary_heap_elem_t *e2 = (const zbx_binary_heap_elem_t *)d2;
+
+ const zbx_dc_httptest_t *ht1 = (const zbx_dc_httptest_t *)e1->data;
+ const zbx_dc_httptest_t *ht2 = (const zbx_dc_httptest_t *)e2->data;
+
+ return (int)(ht1->nextcheck - ht2->nextcheck);
+}
+
static zbx_hash_t __config_session_hash(const void *data)
{
const zbx_session_t *session = (const zbx_session_t *)data;
@@ -6846,8 +7770,6 @@ int init_configuration_cache(char **error)
CREATE_HASHSET(config->simpleitems, 0);
CREATE_HASHSET(config->jmxitems, 0);
CREATE_HASHSET(config->calcitems, 0);
- CREATE_HASHSET(config->masteritems, 0);
- CREATE_HASHSET(config->preprocitems, 0);
CREATE_HASHSET(config->httpitems, 0);
CREATE_HASHSET(config->scriptitems, 0);
CREATE_HASHSET(config->itemscript_params, 0);
@@ -6954,6 +7876,27 @@ int init_configuration_cache(char **error)
__config_shmem_realloc_func,
__config_shmem_free_func);
+ zbx_binary_heap_create_ext(&config->drule_queue,
+ __config_drule_compare,
+ ZBX_BINARY_HEAP_OPTION_DIRECT,
+ __config_shmem_malloc_func,
+ __config_shmem_realloc_func,
+ __config_shmem_free_func);
+
+ zbx_binary_heap_create_ext(&config->httptest_queue,
+ __config_httptest_compare,
+ ZBX_BINARY_HEAP_OPTION_DIRECT,
+ __config_shmem_malloc_func,
+ __config_shmem_realloc_func,
+ __config_shmem_free_func);
+
+ CREATE_HASHSET(config->drules, 0);
+ CREATE_HASHSET(config->dchecks, 0);
+
+ CREATE_HASHSET(config->httptests, 0);
+ CREATE_HASHSET(config->httptest_fields, 0);
+ CREATE_HASHSET(config->httpsteps, 0);
+ CREATE_HASHSET(config->httpstep_fields, 0);
for (i = 0; i < ZBX_SESSION_TYPE_COUNT; i++)
CREATE_HASHSET_EXT(config->sessions[i], 0, __config_session_hash, __config_session_compare);
@@ -6961,6 +7904,7 @@ int init_configuration_cache(char **error)
config->status = (ZBX_DC_STATUS *)__config_shmem_malloc_func(NULL, sizeof(ZBX_DC_STATUS));
config->status->last_update = 0;
+ config->status->sync_ts = 0;
config->availability_diff_ts = 0;
config->sync_ts = 0;
@@ -6968,8 +7912,8 @@ int init_configuration_cache(char **error)
config->internal_actions = 0;
config->auto_registration_actions = 0;
- config->revision = 0;
- config->expression_revision = 0;
+
+ memset(&config->revision, 0, sizeof(config->revision));
config->um_cache = um_cache_create();
@@ -7245,7 +8189,7 @@ int DCcheck_proxy_permissions(const char *host, const zbx_socket_t *sock, zbx_ui
* *
******************************************************************************/
int DCcheck_host_permissions(const char *host, const zbx_socket_t *sock, zbx_uint64_t *hostid,
- zbx_uint32_t *revision, char **error)
+ zbx_uint64_t *revision, char **error)
{
const ZBX_DC_HOST *dc_host;
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
@@ -7290,14 +8234,14 @@ int DCcheck_host_permissions(const char *host, const zbx_socket_t *sock, zbx_uin
#endif
*hostid = dc_host->hostid;
- *revision = MAX(dc_host->revision, config->expression_revision);
+ *revision = MAX(dc_host->revision, config->revision.expression);
um_cache_get_host_revision(config->um_cache, ZBX_UM_CACHE_GLOBAL_MACRO_HOSTID, revision);
um_cache_get_host_revision(config->um_cache, *hostid, revision);
/* configuration is not yet fully synced */
- if (*revision > config->revision)
- *revision = config->revision;
+ if (*revision > config->revision.config)
+ *revision = config->revision.config;
UNLOCK_CACHE;
@@ -7677,7 +8621,7 @@ static void DCget_item(DC_ITEM *dst_item, const ZBX_DC_ITEM *src_item, unsigned
*dst_item->snmp_community_orig = '\0';
*dst_item->snmp_oid_orig = '\0';
*dst_item->snmpv3_securityname_orig = '\0';
- dst_item->snmpv3_securitylevel = ITEM_SNMPV3_SECURITYLEVEL_NOAUTHNOPRIV;
+ dst_item->snmpv3_securitylevel = ZBX_ITEM_SNMPV3_SECURITYLEVEL_NOAUTHNOPRIV;
*dst_item->snmpv3_authpassphrase_orig = '\0';
*dst_item->snmpv3_privpassphrase_orig = '\0';
dst_item->snmpv3_authprotocol = 0;
@@ -8179,11 +9123,19 @@ void DCconfig_get_items_by_itemids(DC_ITEM *items, const zbx_uint64_t *itemids,
int DCconfig_get_active_items_count_by_hostid(zbx_uint64_t hostid)
{
const ZBX_DC_HOST *dc_host;
- int num = 0;
+ int i, num = 0;
RDLOCK_CACHE;
+
if (NULL != (dc_host = (ZBX_DC_HOST *)zbx_hashset_search(&config->hosts, &hostid)))
- num = dc_host->active_items.values_num;
+ {
+ for (i = 0; i < dc_host->items.values_num; i++)
+ {
+ if (ITEM_TYPE_ZABBIX_ACTIVE == dc_host->items.values[i]->type)
+ num++;
+ }
+ }
+
UNLOCK_CACHE;
return num;
@@ -8192,33 +9144,39 @@ int DCconfig_get_active_items_count_by_hostid(zbx_uint64_t hostid)
void DCconfig_get_active_items_by_hostid(DC_ITEM *items, zbx_uint64_t hostid, int *errcodes, size_t num)
{
const ZBX_DC_HOST *dc_host;
- size_t i = 0;
+ size_t i, j = 0;
RDLOCK_CACHE;
if (NULL != (dc_host = (ZBX_DC_HOST *)zbx_hashset_search(&config->hosts, &hostid)) &&
- 0 != dc_host->active_items.values_num)
+ 0 != dc_host->items.values_num)
{
- DCget_host(&items[0].host, dc_host, ZBX_ITEM_GET_ALL);
-
- for (; i < MIN((size_t)dc_host->active_items.values_num, num); i++)
+ for (i = 0; i < (size_t)dc_host->items.values_num && j < num; i++)
{
const ZBX_DC_ITEM *dc_item;
- dc_item = dc_host->active_items.values[i];
+ dc_item = dc_host->items.values[i];
- if (0 != i)
- items[i].host = items[0].host;
+ if (ITEM_TYPE_ZABBIX_ACTIVE != dc_item->type)
+ continue;
- DCget_item(&items[i], dc_item, ZBX_ITEM_GET_DEFAULT);
- errcodes[i] = SUCCEED;
+ DCget_item(&items[j], dc_item, ZBX_ITEM_GET_DEFAULT);
+ errcodes[j++] = SUCCEED;
+ }
+
+ if (0 != j)
+ {
+ DCget_host(&items[0].host, dc_host, ZBX_ITEM_GET_ALL);
+
+ for (i = 1; i < j; i++)
+ items[i].host = items[0].host;
}
}
UNLOCK_CACHE;
- for (; i < num; i++)
- errcodes[i] = FAIL;
+ for (; j < num; j++)
+ errcodes[j] = FAIL;
}
/******************************************************************************
@@ -8324,60 +9282,185 @@ void DCconfig_get_items_by_itemids_partial(DC_ITEM *items, const zbx_uint64_t *i
zbx_dc_close_user_macros(um_handle);
}
+static void dc_preproc_dump(zbx_hashset_t *items)
+{
+ zbx_hashset_iter_t iter;
+ zbx_preproc_item_t *item;
+ int i;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ zbx_hashset_iter_reset(items, &iter);
+ while (NULL != (item = (zbx_preproc_item_t *)zbx_hashset_iter_next(&iter)))
+ {
+ zabbix_log(LOG_LEVEL_TRACE, "itemid:" ZBX_FS_UI64 " type:%u value_type:%u revision:" ZBX_FS_UI64,
+ item->itemid, item->type, item->value_type, item->preproc_revision);
+
+ zabbix_log(LOG_LEVEL_TRACE, " dependent items:");
+ for (i = 0; i < item->dep_itemids_num; i++)
+ {
+ zabbix_log(LOG_LEVEL_TRACE, " depitemid:" ZBX_FS_UI64 "," ZBX_FS_UI64,
+ item->dep_itemids[i].first, item->dep_itemids[i].second);
+ }
+
+ zabbix_log(LOG_LEVEL_TRACE, " preprocessing steps:");
+ for (i = 0; i < item->preproc_ops_num; i++)
+ {
+ zabbix_log(LOG_LEVEL_TRACE, " type:%u params:%s error_handler:%u error_handler_params:%s",
+ item->preproc_ops[i].type, ZBX_NULL2EMPTY_STR(item->preproc_ops[i].params),
+ item->preproc_ops[i].error_handler,
+ ZBX_NULL2EMPTY_STR(item->preproc_ops[i].error_handler_params));
+ }
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+}
+
+static void dc_preproc_free_ops(zbx_preproc_op_t *ops, int ops_num)
+{
+ int i;
+
+ for (i = 0; i < ops_num; i++)
+ {
+ zbx_free(ops[i].params);
+ zbx_free(ops[i].error_handler_params);
+ }
+ zbx_free(ops);
+}
+
/******************************************************************************
* *
- * Purpose: initialize new preprocessor item from configuration cache *
+ * Purpose: sync item preprocessing steps with preprocessing manager cache, *
+ * updating preprocessing revision if any changes were detected *
* *
- * Parameters: item - [OUT] the item to initialize *
- * itemid - [IN] the item identifier *
+ ******************************************************************************/
+static void dc_preproc_sync_preprocitem(zbx_preproc_item_t *item, const ZBX_DC_PREPROCITEM *preprocitem,
+ zbx_uint64_t revision)
+{
+ int i, ops_num = 0;
+ zbx_preproc_op_t *ops;
+
+ if (NULL == preprocitem)
+ {
+ dc_preproc_free_ops(item->preproc_ops, item->preproc_ops_num);
+ item->preproc_ops = NULL;
+ item->preproc_ops_num = 0;
+ return;
+ }
+
+ ops = (zbx_preproc_op_t *)zbx_malloc(NULL, sizeof(zbx_preproc_op_t) * preprocitem->preproc_ops.values_num);
+
+ for (i = 0; i < preprocitem->preproc_ops.values_num; i++)
+ {
+ zbx_dc_preproc_op_t *op = (zbx_dc_preproc_op_t *)preprocitem->preproc_ops.values[i];
+
+ ops[i].type = op->type;
+ ops[i].error_handler = op->error_handler;
+
+ ops[i].params = dc_expand_user_macros_dyn(op->params, &item->hostid, 1, ZBX_MACRO_ENV_NONSECURE);
+ ops[i].error_handler_params = zbx_strdup(NULL, op->error_handler_params);
+ }
+
+ if (preprocitem->preproc_ops.values_num == item->preproc_ops_num)
+ {
+ for (;ops_num < item->preproc_ops_num; ops_num++)
+ {
+ zbx_preproc_op_t *src = &ops[ops_num];
+ zbx_preproc_op_t *dst = &item->preproc_ops[ops_num];
+
+ if (src->type != dst->type)
+ break;
+
+ if (src->error_handler != dst->error_handler)
+ break;
+
+ if (0 != zbx_strcmp_null(src->params, dst->params))
+ break;
+
+ if (0 != zbx_strcmp_null(src->error_handler_params, dst->error_handler_params))
+ break;
+ }
+ }
+
+ if (ops_num != item->preproc_ops_num)
+ item->preproc_revision = revision;
+
+ dc_preproc_free_ops(item->preproc_ops, item->preproc_ops_num);
+
+ item->preproc_ops = ops;
+ item->preproc_ops_num = preprocitem->preproc_ops.values_num;
+}
+
+/******************************************************************************
* *
- * Return value: SUCCEED - the item was initialized successfully *
- * FAIL - item with the specified itemid is not cached or *
- * monitored *
+ * Purpose: sync mater-dependent item links *
* *
******************************************************************************/
-static int dc_preproc_item_init(zbx_preproc_item_t *item, zbx_uint64_t itemid)
+static void dc_preproc_sync_masteritem(zbx_preproc_item_t *item, const ZBX_DC_MASTERITEM *masteritem)
{
- const ZBX_DC_ITEM *dc_item;
- const ZBX_DC_HOST *dc_host;
+ if (NULL == masteritem)
+ {
+ zbx_free(item->dep_itemids);
+ item->dep_itemids_num = 0;
+ return;
+ }
- if (NULL == (dc_item = (const ZBX_DC_ITEM *)zbx_hashset_search(&config->items, &itemid)))
- return FAIL;
+ if (masteritem->dep_itemids.values_num > item->dep_itemids_num)
+ {
+ item->dep_itemids = (zbx_uint64_pair_t *)zbx_realloc(item->dep_itemids,
+ sizeof(zbx_uint64_pair_t) * masteritem->dep_itemids.values_num);
+ }
- if (ITEM_STATUS_ACTIVE != dc_item->status)
- return FAIL;
+ memcpy(item->dep_itemids, masteritem->dep_itemids.values,
+ sizeof(zbx_uint64_pair_t) * masteritem->dep_itemids.values_num);
- if (NULL == (dc_host = (const ZBX_DC_HOST *)zbx_hashset_search(&config->hosts, &dc_item->hostid)))
- return FAIL;
+ item->dep_itemids_num = masteritem->dep_itemids.values_num;
+}
- if (HOST_STATUS_MONITORED != dc_host->status)
- return FAIL;
+static void dc_preproc_sync_item(zbx_hashset_t *items, ZBX_DC_ITEM *dc_item, zbx_uint64_t revision)
+{
+ zbx_preproc_item_t *pp_item;
- switch (dc_item->type)
+ if (NULL == (pp_item = (zbx_preproc_item_t *)zbx_hashset_search(items, &dc_item->itemid)))
{
- case ITEM_TYPE_INTERNAL:
- case ITEM_TYPE_CALCULATED:
- case ITEM_TYPE_DEPENDENT:
- break;
- default:
- if (0 != dc_host->proxy_hostid)
- return FAIL;
+ zbx_preproc_item_t pp_item_local = {.itemid = dc_item->itemid};
+
+ pp_item = (zbx_preproc_item_t *)zbx_hashset_insert(items, &pp_item_local, sizeof(pp_item_local));
+ pp_item->hostid = dc_item->hostid;
+ pp_item->preproc_revision = revision;
}
- item->itemid = itemid;
- item->hostid = dc_item->hostid;
- item->type = dc_item->type;
- item->value_type = dc_item->value_type;
+ pp_item->type = dc_item->type;
+ pp_item->value_type = dc_item->value_type;
+ pp_item->revision = revision;
- item->dep_itemids = NULL;
- item->dep_itemids_num = 0;
+ dc_preproc_sync_masteritem(pp_item, dc_item->master_item);
+ dc_preproc_sync_preprocitem(pp_item, dc_item->preproc_item, revision);
+}
- item->preproc_ops = NULL;
- item->preproc_ops_num = 0;
- item->update_time = 0;
- item->macro_update = ZBX_PREPROC_MACRO_UPDATE_FALSE;
- return SUCCEED;
+static void dc_preproc_add_item_rec(ZBX_DC_ITEM *dc_item, zbx_vector_dc_item_ptr_t *items_sync)
+{
+ if (NULL != dc_item->master_item || NULL != dc_item->preproc_item || ITEM_TYPE_INTERNAL == dc_item->type)
+ zbx_vector_dc_item_ptr_append(items_sync, dc_item);
+
+ if (NULL != dc_item->master_item)
+ {
+ int i;
+
+ for (i = 0; i < dc_item->master_item->dep_itemids.values_num; i++)
+ {
+ ZBX_DC_ITEM *dep_item;
+
+ if (NULL == (dep_item = (ZBX_DC_ITEM *)zbx_hashset_search(&config->items,
+ &dc_item->master_item->dep_itemids.values[i].first)))
+ {
+ continue;
+ }
+
+ dc_preproc_add_item_rec(dep_item, items_sync);
+ }
+ }
}
/******************************************************************************
@@ -8391,196 +9474,101 @@ static int dc_preproc_item_init(zbx_preproc_item_t *item, zbx_uint64_t itemid)
* timestamp - [IN/OUT] timestamp of a last update *
* *
******************************************************************************/
-void DCconfig_get_preprocessable_items(zbx_hashset_t *items, int *timestamp)
+void DCconfig_get_preprocessable_items(zbx_hashset_t *items, zbx_uint64_t *revision)
{
- const ZBX_DC_PREPROCITEM *dc_preprocitem;
- const ZBX_DC_MASTERITEM *dc_masteritem;
- const ZBX_DC_ITEM *dc_item;
- const zbx_dc_preproc_op_t *dc_op;
- zbx_preproc_item_t *item, item_local;
+ ZBX_DC_HOST *dc_host;
+ zbx_preproc_item_t *pp_item;
zbx_hashset_iter_t iter;
- zbx_hashset_t ids;
- zbx_preproc_op_t *op;
int i;
- zbx_dc_um_handle_t *um_handle;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
-
- /* no changes */
- if (0 != *timestamp && *timestamp == config->item_sync_ts)
- goto out;
+ zbx_uint64_t global_revision = *revision;
+ zbx_vector_dc_item_ptr_t items_sync;
- zbx_hashset_create(&ids, MAX((size_t)items->num_data, 1000), ZBX_DEFAULT_UINT64_HASH_FUNC,
- ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+ if (config->revision.config == *revision)
+ return;
- *timestamp = config->item_sync_ts;
+ zbx_vector_dc_item_ptr_create(&items_sync);
+ zbx_vector_dc_item_ptr_reserve(&items_sync, 100);
RDLOCK_CACHE;
- zbx_hashset_iter_reset(&config->preprocitems, &iter);
- while (NULL != (dc_preprocitem = (const ZBX_DC_PREPROCITEM *)zbx_hashset_iter_next(&iter)))
+ if (SUCCEED != um_cache_get_host_revision(config->um_cache, 0, &global_revision))
+ global_revision = 0;
+
+ zbx_hashset_iter_reset(&config->hosts, &iter);
+ while (NULL != (dc_host = (ZBX_DC_HOST *)zbx_hashset_iter_next(&iter)))
{
- if (FAIL == dc_preproc_item_init(&item_local, dc_preprocitem->itemid))
+ if (HOST_STATUS_MONITORED != dc_host->status)
continue;
- if (NULL != (item = (zbx_preproc_item_t *)zbx_hashset_search(items, &item_local)))
+ for (i = 0; i < dc_host->items.values_num; i++)
{
- if (item->update_time == dc_preprocitem->update_time &&
- item->preproc_ops_num == dc_preprocitem->preproc_ops.values_num)
- {
- for (i = 0; i < dc_preprocitem->preproc_ops.values_num; i++)
- {
- dc_op = (const zbx_dc_preproc_op_t *)dc_preprocitem->preproc_ops.values[i];
- op = &item->preproc_ops[i];
-
- op->params_orig = zbx_strdup(NULL, dc_op->params);
- }
+ ZBX_DC_ITEM *dc_item = dc_host->items.values[i];
- item->dep_itemids_num = 0;
- zbx_free(item->dep_itemids);
-
- zbx_hashset_insert(&ids, &item->itemid, sizeof(item->itemid));
+ if (ITEM_STATUS_ACTIVE != dc_item->status || ITEM_TYPE_DEPENDENT == dc_item->type)
continue;
- }
- else
- zbx_hashset_remove_direct(items, item);
- }
-
- item = (zbx_preproc_item_t *)zbx_hashset_insert(items, &item_local, sizeof(item_local));
- item->preproc_ops_num = dc_preprocitem->preproc_ops.values_num;
- item->preproc_ops = (zbx_preproc_op_t *)zbx_malloc(NULL, sizeof(zbx_preproc_op_t) *
- item->preproc_ops_num);
- item->update_time = dc_preprocitem->update_time;
-
- for (i = 0; i < dc_preprocitem->preproc_ops.values_num; i++)
- {
- dc_op = (const zbx_dc_preproc_op_t *)dc_preprocitem->preproc_ops.values[i];
- op = &item->preproc_ops[i];
- op->type = dc_op->type;
- op->params = NULL;
- op->params_orig = zbx_strdup(NULL, dc_op->params);
- op->error_handler = dc_op->error_handler;
- op->error_handler_params = zbx_strdup(NULL, dc_op->error_handler_params);
- }
-
- zbx_hashset_insert(&ids, &item->itemid, sizeof(item->itemid));
- }
-
- zbx_hashset_iter_reset(&config->masteritems, &iter);
- while (NULL != (dc_masteritem = (const ZBX_DC_MASTERITEM *)zbx_hashset_iter_next(&iter)))
- {
- if (NULL == (item = (zbx_preproc_item_t *)zbx_hashset_search(items, &dc_masteritem->itemid)))
- {
- if (FAIL == dc_preproc_item_init(&item_local, dc_masteritem->itemid))
- continue;
-
- item = (zbx_preproc_item_t *)zbx_hashset_insert(items, &item_local, sizeof(item_local));
- }
- else
- {
- if (NULL == zbx_hashset_search(&ids, &item->itemid))
+ if (NULL == dc_item->preproc_item && NULL == dc_item->master_item &&
+ ITEM_TYPE_INTERNAL != dc_item->type)
{
- if (FAIL == dc_preproc_item_init(&item_local, dc_masteritem->itemid))
- continue;
-
- /* remove preprocessing and reset dep_itemids */
- zbx_hashset_remove_direct(items, item);
- item = (zbx_preproc_item_t *)zbx_hashset_insert(items, &item_local, sizeof(item_local));
+ continue;
}
- }
-
- zbx_hashset_insert(&ids, &item->itemid, sizeof(item->itemid));
-
- item->dep_itemids_num = 0;
- item->dep_itemids = (zbx_uint64_pair_t *)zbx_malloc(NULL, sizeof(zbx_uint64_pair_t) *
- dc_masteritem->dep_itemids.values_num);
- for (i = 0; i < dc_masteritem->dep_itemids.values_num; i++)
- {
- if (NULL == (dc_item = (ZBX_DC_ITEM *)zbx_hashset_search(&config->items,
- &dc_masteritem->dep_itemids.values[i].first)) ||
- ITEM_STATUS_ACTIVE != dc_item->status)
+ if (0 == dc_host->proxy_hostid ||
+ SUCCEED == is_item_processed_by_server(dc_item->type, dc_item->key))
{
- continue;
+ dc_preproc_add_item_rec(dc_item, &items_sync);
}
- item->dep_itemids[item->dep_itemids_num++] = dc_masteritem->dep_itemids.values[i];
}
- }
- zbx_hashset_iter_reset(&config->items, &iter);
- while (NULL != (dc_item = (const ZBX_DC_ITEM *)zbx_hashset_iter_next(&iter)))
- {
- if (ITEM_TYPE_INTERNAL != dc_item->type)
+ /* don't check host macro revision if the host does not have locally pre-processable items */
+ if (0 == items_sync.values_num)
continue;
- if (NULL == (item = zbx_hashset_search(items, &dc_item->itemid)))
+ if (*revision >= global_revision && *revision >= dc_host->revision)
{
- if (FAIL == dc_preproc_item_init(&item_local, dc_item->itemid))
- continue;
+ zbx_uint64_t macro_revision = *revision;
- item = zbx_hashset_insert(items, &item_local, sizeof(item_local));
- }
- else
- {
- if (NULL == zbx_hashset_search(&ids, &item->itemid))
+ if (SUCCEED == um_cache_get_host_revision(config->um_cache, dc_host->hostid, &macro_revision) &&
+ *revision >= macro_revision)
{
- if (FAIL == dc_preproc_item_init(&item_local, dc_item->itemid))
- continue;
+ for (i = 0; i < items_sync.values_num; i++)
+ {
+ if (NULL != (pp_item = (zbx_preproc_item_t *)zbx_hashset_search(items,
+ &items_sync.values[i]->itemid)))
+ {
+ pp_item->revision = config->revision.config;
+ }
- /* remove preprocessing and dependent */
- zbx_hashset_remove_direct(items, item);
- item = (zbx_preproc_item_t *)zbx_hashset_insert(items, &item_local, sizeof(item_local));
+ }
+ zbx_vector_dc_item_ptr_clear(&items_sync);
}
}
- zbx_hashset_insert(&ids, &item->itemid, sizeof(item->itemid));
+ for (i = 0; i < items_sync.values_num; i++)
+ dc_preproc_sync_item(items, items_sync.values[i], config->revision.config);
+
+ zbx_vector_dc_item_ptr_clear(&items_sync);
}
- UNLOCK_CACHE;
+ *revision = config->revision.config;
- zbx_hashset_iter_reset(items, &iter);
- while (NULL != (item = (zbx_preproc_item_t *)zbx_hashset_iter_next(&iter)))
- {
- if (NULL == zbx_hashset_search(&ids, &item->itemid))
- zbx_hashset_iter_remove(&iter);
- }
+ UNLOCK_CACHE;
- um_handle = zbx_dc_open_user_macros();
+ /* remove items without preprocessing */
zbx_hashset_iter_reset(items, &iter);
- while (NULL != (item = (zbx_preproc_item_t *)zbx_hashset_iter_next(&iter)))
+ while (NULL != (pp_item = (zbx_preproc_item_t *)zbx_hashset_iter_next(&iter)))
{
- for (i = 0; i < item->preproc_ops_num; i++)
- {
- (void)zbx_dc_expand_user_macros(um_handle, &item->preproc_ops[i].error_handler_params,
- &item->hostid, 1, NULL);
-
- if (NULL != strstr(item->preproc_ops[i].params_orig, "{$"))
- {
- (void)zbx_dc_expand_user_macros(um_handle, &item->preproc_ops[i].params_orig,
- &item->hostid, 1, NULL);
-
- if (NULL != item->preproc_ops[i].params &&
- 0 != strcmp(item->preproc_ops[i].params,
- item->preproc_ops[i].params_orig))
- {
- item->macro_update = ZBX_PREPROC_MACRO_UPDATE_TRUE;
- }
- }
-
- zbx_free(item->preproc_ops[i].params);
- item->preproc_ops[i].params = item->preproc_ops[i].params_orig;
- item->preproc_ops[i].params_orig = NULL;
- }
+ if (pp_item->revision == *revision)
+ continue;
+ zbx_hashset_iter_remove(&iter);
}
- zbx_dc_close_user_macros(um_handle);
+ zbx_vector_dc_item_ptr_destroy(&items_sync);
- zbx_hashset_destroy(&ids);
-out:
- zabbix_log(LOG_LEVEL_DEBUG, "End of %s() items:%d", __func__, items->num_data);
+ if (SUCCEED == ZBX_CHECK_LOG_LEVEL(LOG_LEVEL_TRACE))
+ dc_preproc_dump(items);
}
void DCconfig_get_hosts_by_itemids(DC_HOST *hosts, const zbx_uint64_t *itemids, int *errcodes, size_t num)
@@ -10739,11 +11727,16 @@ static void DCget_proxy(DC_PROXY *dst_proxy, const ZBX_DC_PROXY *src_proxy)
dst_proxy->proxy_data_nextcheck = src_proxy->proxy_data_nextcheck;
dst_proxy->proxy_tasks_nextcheck = src_proxy->proxy_tasks_nextcheck;
dst_proxy->last_cfg_error_time = src_proxy->last_cfg_error_time;
- dst_proxy->version = src_proxy->version;
+ zbx_strlcpy(dst_proxy->version_str, src_proxy->version_str, sizeof(dst_proxy->version_str));
+ dst_proxy->version_int = src_proxy->version_int;
+ dst_proxy->compatibility = src_proxy->compatibility;
dst_proxy->lastaccess = src_proxy->lastaccess;
dst_proxy->auto_compress = src_proxy->auto_compress;
dst_proxy->last_version_error_time = src_proxy->last_version_error_time;
+ dst_proxy->revision = src_proxy->revision;
+ dst_proxy->macro_revision = config->um_cache->revision;
+
if (NULL != (host = (const ZBX_DC_HOST *)zbx_hashset_search(&config->hosts, &src_proxy->hostid)))
{
zbx_strscpy(dst_proxy->host, host->host);
@@ -11113,56 +12106,7 @@ int DCget_item_queue(zbx_vector_ptr_t *queue, int from, int to)
/******************************************************************************
* *
- * Purpose: check that functionids in trigger (recovery) expression *
- * *
- * Parameters: expression - [IN] trigger (recovery) expression *
- * data - [IN] parsed and serialized expression *
- * *
- * Return value: SUCCEED - all functionids correspond to enabled items and *
- * enabled hosts *
- * FAIL - at least one item or host is disabled *
- * *
- ******************************************************************************/
-static int dc_trigger_items_hosts_enabled(const char *expression, const unsigned char *data)
-{
- zbx_uint64_t functionid;
- const ZBX_DC_ITEM *dc_item;
- const ZBX_DC_FUNCTION *dc_function;
- const ZBX_DC_HOST *dc_host;
- int i, ret = FAIL;
- zbx_vector_uint64_t functionids;
-
- zbx_vector_uint64_create(&functionids);
- zbx_get_serialized_expression_functionids(expression, data, &functionids);
-
- for (i = 0; i < functionids.values_num; i++)
- {
- functionid = functionids.values[i];
-
- if (NULL == (dc_function = (ZBX_DC_FUNCTION *)zbx_hashset_search(&config->functions, &functionid)))
- goto out;
-
- if (NULL == (dc_item = (ZBX_DC_ITEM *)zbx_hashset_search(&config->items, &dc_function->itemid)))
- goto out;
-
- if (ITEM_STATUS_ACTIVE != dc_item->status)
- goto out;
-
- if (NULL == (dc_host = (ZBX_DC_HOST *)zbx_hashset_search(&config->hosts, &dc_item->hostid)))
- goto out;
-
- if (HOST_STATUS_MONITORED != dc_host->status)
- goto out;
- }
-
- ret = SUCCEED;
-out:
- zbx_vector_uint64_destroy(&functionids);
-
- return ret;
-}
-
-/******************************************************************************
+ * Function: dc_status_update *
* *
* Purpose: check when status information stored in configuration cache was *
* updated last time and update it if necessary *
@@ -11197,10 +12141,17 @@ static void dc_status_update(void)
ZBX_DC_HOST *dc_host, *dc_proxy_host;
const ZBX_DC_ITEM *dc_item;
const ZBX_DC_TRIGGER *dc_trigger;
+ int reset;
if (0 != config->status->last_update && config->status->last_update + ZBX_STATUS_LIFETIME > time(NULL))
return;
+
+ if (config->status->sync_ts != config->sync_ts)
+ reset = SUCCEED;
+ else
+ reset = FAIL;
+
/* reset global counters */
config->status->hosts_monitored = 0;
@@ -11211,17 +12162,22 @@ static void dc_status_update(void)
config->status->triggers_enabled_ok = 0;
config->status->triggers_enabled_problem = 0;
config->status->triggers_disabled = 0;
- config->status->required_performance = 0.0;
- /* loop over proxies to reset per-proxy host and required performance counters */
+ if (SUCCEED == reset)
+ config->status->required_performance = 0.0;
- zbx_hashset_iter_reset(&config->proxies, &iter);
+ /* loop over proxies to reset per-proxy host and required performance counters */
- while (NULL != (dc_proxy = (ZBX_DC_PROXY *)zbx_hashset_iter_next(&iter)))
+ if (SUCCEED == reset)
{
- dc_proxy->hosts_monitored = 0;
- dc_proxy->hosts_not_monitored = 0;
- dc_proxy->required_performance = 0.0;
+ zbx_hashset_iter_reset(&config->proxies, &iter);
+
+ while (NULL != (dc_proxy = (ZBX_DC_PROXY *)zbx_hashset_iter_next(&iter)))
+ {
+ dc_proxy->hosts_monitored = 0;
+ dc_proxy->hosts_not_monitored = 0;
+ dc_proxy->required_performance = 0.0;
+ }
}
/* loop over hosts */
@@ -11243,25 +12199,33 @@ static void dc_status_update(void)
config->status->hosts_monitored++;
if (0 == dc_host->proxy_hostid)
break;
- if (NULL == (dc_proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies,
- &dc_host->proxy_hostid)))
+
+ if (SUCCEED == reset)
{
- break;
- }
+ if (NULL == (dc_proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies,
+ &dc_host->proxy_hostid)))
+ {
+ break;
+ }
- dc_proxy->hosts_monitored++;
+ dc_proxy->hosts_monitored++;
+ }
break;
case HOST_STATUS_NOT_MONITORED:
config->status->hosts_not_monitored++;
if (0 == dc_host->proxy_hostid)
break;
- if (NULL == (dc_proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies,
- &dc_host->proxy_hostid)))
+
+ if (SUCCEED == reset)
{
- break;
- }
+ if (NULL == (dc_proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies,
+ &dc_host->proxy_hostid)))
+ {
+ break;
+ }
- dc_proxy->hosts_not_monitored++;
+ dc_proxy->hosts_not_monitored++;
+ }
break;
}
}
@@ -11283,7 +12247,9 @@ static void dc_status_update(void)
if (0 != dc_host->proxy_hostid)
{
- dc_proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies, &dc_host->proxy_hostid);
+ if (SUCCEED == reset)
+ dc_proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies, &dc_host->proxy_hostid);
+
dc_proxy_host = (ZBX_DC_HOST *)zbx_hashset_search(&config->hosts, &dc_host->proxy_hostid);
}
@@ -11292,22 +12258,25 @@ static void dc_status_update(void)
case ITEM_STATUS_ACTIVE:
if (HOST_STATUS_MONITORED == dc_host->status)
{
- int delay;
- char *delay_s;
+ if (SUCCEED == reset)
+ {
+ int delay;
+ char *delay_s;
- delay_s = dc_expand_user_macros_dyn(dc_item->delay, &dc_item->hostid, 1,
- ZBX_MACRO_ENV_NONSECURE);
+ delay_s = dc_expand_user_macros_dyn(dc_item->delay, &dc_item->hostid, 1,
+ ZBX_MACRO_ENV_NONSECURE);
- if (SUCCEED == zbx_interval_preproc(delay_s, &delay, NULL, NULL) &&
- 0 != delay)
- {
- config->status->required_performance += 1.0 / delay;
+ if (SUCCEED == zbx_interval_preproc(delay_s, &delay, NULL, NULL) &&
+ 0 != delay)
+ {
+ config->status->required_performance += 1.0 / delay;
- if (NULL != dc_proxy)
- dc_proxy->required_performance += 1.0 / delay;
- }
+ if (NULL != dc_proxy)
+ dc_proxy->required_performance += 1.0 / delay;
+ }
- zbx_free(delay_s);
+ zbx_free(delay_s);
+ }
switch (dc_item->state)
{
@@ -11352,11 +12321,7 @@ static void dc_status_update(void)
switch (dc_trigger->status)
{
case TRIGGER_STATUS_ENABLED:
- if (SUCCEED == dc_trigger_items_hosts_enabled(dc_trigger->expression,
- dc_trigger->expression_bin) &&
- (TRIGGER_RECOVERY_MODE_RECOVERY_EXPRESSION !=
- dc_trigger->recovery_mode || SUCCEED == dc_trigger_items_hosts_enabled(
- dc_trigger->recovery_expression, dc_trigger->recovery_expression_bin)))
+ if (TRIGGER_FUNCTIONAL_TRUE == dc_trigger->functional)
{
switch (dc_trigger->value)
{
@@ -11381,6 +12346,7 @@ static void dc_status_update(void)
}
}
+ config->status->sync_ts = config->sync_ts;
config->status->last_update = time(NULL);
#undef ZBX_STATUS_LIFETIME
@@ -11970,6 +12936,8 @@ void zbx_config_clean(zbx_config_t *cfg)
********************************************************************************/
int DCreset_interfaces_availability(zbx_vector_availability_ptr_t *interfaces)
{
+#define ZBX_INTERFACE_MOVE_TOLERANCE_INTERVAL (10 * SEC_PER_MIN)
+
ZBX_DC_HOST *host;
ZBX_DC_INTERFACE *interface;
zbx_hashset_iter_t iter;
@@ -12004,7 +12972,7 @@ int DCreset_interfaces_availability(zbx_vector_availability_ptr_t *interfaces)
if (NULL != (proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies, &host->proxy_hostid)))
{
/* SEC_PER_MIN is a tolerance interval, it was chosen arbitrarily */
- if (ZBX_PROXY_HEARTBEAT_FREQUENCY_MAX + SEC_PER_MIN >= now - proxy->lastaccess)
+ if (ZBX_INTERFACE_MOVE_TOLERANCE_INTERVAL >= now - proxy->lastaccess)
continue;
}
@@ -12044,6 +13012,7 @@ int DCreset_interfaces_availability(zbx_vector_availability_ptr_t *interfaces)
zabbix_log(LOG_LEVEL_DEBUG, "End of %s() interfaces:%d", __func__, interfaces->values_num);
return 0 == interfaces->values_num ? FAIL : SUCCEED;
+#undef ZBX_INTERFACE_MOVE_TOLERANCE_INTERVAL
}
/*******************************************************************************
@@ -12372,17 +13341,20 @@ static char *dc_correlation_formula_dup(const zbx_dc_correlation_t *dc_correlati
const zbx_dc_corr_condition_t *dc_condition;
zbx_uint64_t last_id;
- if (CONDITION_EVAL_TYPE_EXPRESSION == dc_correlation->evaltype || 0 == dc_correlation->conditions.values_num)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION == dc_correlation->evaltype || 0 ==
+ dc_correlation->conditions.values_num)
+ {
return zbx_strdup(NULL, dc_correlation->formula);
+ }
dc_condition = (const zbx_dc_corr_condition_t *)dc_correlation->conditions.values[0];
switch (dc_correlation->evaltype)
{
- case CONDITION_EVAL_TYPE_OR:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_OR:
op = " or";
break;
- case CONDITION_EVAL_TYPE_AND:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_AND:
op = " and";
break;
}
@@ -12832,14 +13804,14 @@ int zbx_dc_update_passive_proxy_nextcheck(zbx_uint64_t proxyid)
* Purpose: retrieve proxyids for all cached proxies *
* *
******************************************************************************/
-void zbx_dc_get_all_proxies(zbx_vector_cached_proxy_t *proxies)
+void zbx_dc_get_all_proxies(zbx_vector_cached_proxy_ptr_t *proxies)
{
ZBX_DC_HOST_H *dc_host;
zbx_hashset_iter_t iter;
RDLOCK_CACHE;
- zbx_vector_cached_proxy_reserve(proxies, (size_t)config->hosts_p.num_data);
+ zbx_vector_cached_proxy_ptr_reserve(proxies, (size_t)config->hosts_p.num_data);
zbx_hashset_iter_reset(&config->hosts_p, &iter);
while (NULL != (dc_host = (ZBX_DC_HOST_H *)zbx_hashset_iter_next(&iter)))
@@ -12852,12 +13824,18 @@ void zbx_dc_get_all_proxies(zbx_vector_cached_proxy_t *proxies)
proxy->hostid = dc_host->host_ptr->hostid;
proxy->status = dc_host->host_ptr->status;
- zbx_vector_cached_proxy_append(proxies, proxy);
+ zbx_vector_cached_proxy_ptr_append(proxies, proxy);
}
UNLOCK_CACHE;
}
+void zbx_cached_proxy_free(zbx_cached_proxy_t *proxy)
+{
+ zbx_free(proxy->name);
+ zbx_free(proxy);
+}
+
int zbx_dc_get_proxy_name_type_by_id(zbx_uint64_t proxyid, int *status, char **name)
{
int ret = SUCCEED;
@@ -13225,7 +14203,7 @@ void zbx_dc_get_trigger_dependencies(const zbx_vector_uint64_t *triggerids, zbx_
* Purpose: reschedules items that are processed by the target daemon *
* *
* Parameter: itemids - [IN] the item identifiers *
- * nextcheck - [IN] the schedueld time *
+ * nextcheck - [IN] the scheduled time *
* proxy_hostids - [OUT] the proxy_hostids of the given itemids *
* (optional, can be NULL) *
* *
@@ -13344,8 +14322,7 @@ void zbx_dc_update_proxy(zbx_proxy_diff_t *diff)
{
int lost = 0; /* communication lost */
- if (0 != (diff->flags &
- (ZBX_FLAGS_PROXY_DIFF_UPDATE_HEARTBEAT | ZBX_FLAGS_PROXY_DIFF_UPDATE_CONFIG)))
+ if (0 != (diff->flags & ZBX_FLAGS_PROXY_DIFF_UPDATE_CONFIG))
{
int delay = diff->lastaccess - proxy->lastaccess;
@@ -13363,8 +14340,14 @@ void zbx_dc_update_proxy(zbx_proxy_diff_t *diff)
if (0 != (diff->flags & ZBX_FLAGS_PROXY_DIFF_UPDATE_VERSION))
{
- if (proxy->version != diff->version)
- proxy->version = diff->version;
+ if (0 != strcmp(proxy->version_str, diff->version_str))
+ dc_strpool_replace(1, &proxy->version_str, diff->version_str);
+
+ if (proxy->version_int != diff->version_int)
+ {
+ proxy->version_int = diff->version_int;
+ proxy->compatibility = diff->compatibility;
+ }
else
diff->flags &= (~ZBX_FLAGS_PROXY_DIFF_UPDATE_VERSION);
}
@@ -13467,7 +14450,7 @@ const char *zbx_dc_get_session_token(void)
/******************************************************************************
* *
- * Purpose: returns data session, creates a new session if none found *
+ * Purpose: return session, create a new session if none found *
* *
* Parameter: hostid - [IN] the host (proxy) identifier *
* token - [IN] the session token (not NULL) *
@@ -13513,6 +14496,56 @@ zbx_session_t *zbx_dc_get_or_create_session(zbx_uint64_t hostid, const char *tok
/******************************************************************************
* *
+ * Purpose: update session revision/lastaccess in cache or create new session *
+ * if necessary *
+ * *
+ * Parameter: hostid - [IN] the host (proxy) identifier *
+ * token - [IN] the session token (not NULL) *
+ * session_config_revision - [IN] the session configuration *
+ * revision *
+ * dc_revision - [OUT] - the cached configuration revision *
+ * *
+ * Return value: The number of created sessions *
+ * *
+ ******************************************************************************/
+int zbx_dc_register_config_session(zbx_uint64_t hostid, const char *token, zbx_uint64_t session_config_revision,
+ zbx_dc_revision_t *dc_revision)
+{
+ zbx_session_t *session, session_local;
+ time_t now;
+
+ now = time(NULL);
+ session_local.hostid = hostid;
+ session_local.token = token;
+
+ RDLOCK_CACHE;
+ if (NULL != (session = (zbx_session_t *)zbx_hashset_search(&config->sessions[ZBX_SESSION_TYPE_CONFIG],
+ &session_local)))
+ {
+ /* one session cannot be updated at the same time by different processes, */
+ /* so updating its properties without reallocating memory can be done with read lock */
+ session->last_id = session_config_revision;
+ session_local.lastaccess = now;
+ }
+ *dc_revision = config->revision;
+ UNLOCK_CACHE;
+
+ if (NULL != session)
+ return 0;
+
+ session_local.last_id = session_config_revision;
+ session_local.lastaccess = now;
+
+ WRLOCK_CACHE;
+ session_local.token = dc_strdup(token);
+ zbx_hashset_insert(&config->sessions[ZBX_SESSION_TYPE_CONFIG], &session_local, sizeof(session_local));
+ UNLOCK_CACHE;
+
+ return 1; /* a session was created */
+}
+
+/******************************************************************************
+ * *
* Purpose: removes data sessions not accessed for 25 hours *
* *
******************************************************************************/
@@ -13829,6 +14862,138 @@ int DCget_proxy_lastaccess_by_name(const char *name, int *lastaccess, char **err
/******************************************************************************
* *
+ * Purpose: get data of all proxies from configuration cache and pack into *
+ * JSON for LLD *
+ * *
+ * Parameter: data - [OUT] JSON with proxy data *
+ * error - [OUT] error message *
+ * *
+ * Return value: SUCCEED - interface data in JSON, 'data' is allocated *
+ * FAIL - proxy not found, 'error' message is allocated *
+ * *
+ * Comments: Allocates memory. *
+ * If there are no proxies, an empty JSON {"data":[]} is returned. *
+ * *
+ ******************************************************************************/
+int zbx_proxy_discovery_get(char **data, char **error)
+{
+ int i, ret = SUCCEED;
+ zbx_vector_cached_proxy_ptr_t proxies;
+ struct zbx_json json;
+
+ WRLOCK_CACHE;
+
+ dc_status_update();
+
+ UNLOCK_CACHE;
+
+ zbx_json_initarray(&json, ZBX_JSON_STAT_BUF_LEN);
+ zbx_vector_cached_proxy_ptr_create(&proxies);
+ zbx_dc_get_all_proxies(&proxies);
+
+ RDLOCK_CACHE;
+
+ for (i = 0; i < proxies.values_num; i++)
+ {
+ zbx_cached_proxy_t *proxy;
+ const ZBX_DC_HOST *dc_host;
+ const ZBX_DC_PROXY *dc_proxy;
+
+ proxy = proxies.values[i];
+
+ zbx_json_addobject(&json, NULL);
+
+ zbx_json_addstring(&json, "name", proxy->name, ZBX_JSON_TYPE_STRING);
+
+ if (HOST_STATUS_PROXY_PASSIVE == proxy->status)
+ zbx_json_addstring(&json, "passive", "true", ZBX_JSON_TYPE_INT);
+ else
+ zbx_json_addstring(&json, "passive", "false", ZBX_JSON_TYPE_INT);
+
+ dc_host = DCfind_proxy(proxy->name);
+
+ if (NULL == dc_host)
+ {
+ *error = zbx_dsprintf(*error, "Proxy \"%s\" not found in configuration cache.", proxy->name);
+ ret = FAIL;
+ goto clean;
+ }
+ else
+ {
+ unsigned int encryption;
+
+ if (HOST_STATUS_PROXY_PASSIVE == proxy->status)
+ encryption = dc_host->tls_connect;
+ else
+ encryption = dc_host->tls_accept;
+
+ if (0 < (encryption & ZBX_TCP_SEC_UNENCRYPTED))
+ zbx_json_addstring(&json, "unencrypted", "true", ZBX_JSON_TYPE_INT);
+ else
+ zbx_json_addstring(&json, "unencrypted", "false", ZBX_JSON_TYPE_INT);
+
+ if (0 < (encryption & ZBX_TCP_SEC_TLS_PSK))
+ zbx_json_addstring(&json, "psk", "true", ZBX_JSON_TYPE_INT);
+ else
+ zbx_json_addstring(&json, "psk", "false", ZBX_JSON_TYPE_INT);
+
+ if (0 < (encryption & ZBX_TCP_SEC_TLS_CERT))
+ zbx_json_addstring(&json, "cert", "true", ZBX_JSON_TYPE_INT);
+ else
+ zbx_json_addstring(&json, "cert", "false", ZBX_JSON_TYPE_INT);
+
+ zbx_json_adduint64(&json, "items", dc_host->items_active_normal +
+ dc_host->items_active_notsupported);
+
+ if (NULL != (dc_proxy = (const ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies,
+ &dc_host->hostid)))
+ {
+ if (1 == dc_proxy->auto_compress)
+ zbx_json_addstring(&json, "compression", "true", ZBX_JSON_TYPE_INT);
+ else
+ zbx_json_addstring(&json, "compression", "false", ZBX_JSON_TYPE_INT);
+
+ zbx_json_addstring(&json, "version", dc_proxy->version_str, ZBX_JSON_TYPE_STRING);
+
+ zbx_json_adduint64(&json, "compatibility", dc_proxy->compatibility);
+
+ if (0 < dc_proxy->lastaccess)
+ zbx_json_addint64(&json, "last_seen", time(NULL) - dc_proxy->lastaccess);
+ else
+ zbx_json_addint64(&json, "last_seen", -1);
+
+ zbx_json_adduint64(&json, "hosts", dc_proxy->hosts_monitored);
+
+ zbx_json_addfloat(&json, "requiredperformance", dc_proxy->required_performance);
+ }
+ else
+ {
+ *error = zbx_dsprintf(*error, "Proxy \"%s\" not found in configuration cache.",
+ proxy->name);
+ ret = FAIL;
+ goto clean;
+ }
+ }
+ zbx_json_close(&json);
+ }
+clean:
+ UNLOCK_CACHE;
+
+ if (SUCCEED == ret)
+ {
+ zbx_json_close(&json);
+ *data = zbx_strdup(NULL, json.buffer);
+ }
+
+ zbx_json_free(&json);
+ zbx_vector_cached_proxy_ptr_clear_ext(&proxies, zbx_cached_proxy_free);
+ zbx_vector_cached_proxy_ptr_destroy(&proxies);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
* Purpose: returns server/proxy instance id *
* *
* Return value: the instance id *
@@ -14321,7 +15486,396 @@ static void dc_reschedule_items(const zbx_hashset_t *activated_hosts)
zbx_vector_item_delay_destroy(&items);
}
+/******************************************************************************
+ * *
+ * Purpose: reschedule httptests on hosts that were re-enabled or unassigned *
+ * from proxy *
+ * *
+ * Comments: Cache is not locked for read access because this function is *
+ * called from configuration syncer and nobody else can add/remove *
+ * objects or change their configuration. *
+ * *
+ ******************************************************************************/
+static void dc_reschedule_httptests(zbx_hashset_t *activated_hosts)
+{
+ zbx_vector_dc_httptest_ptr_t httptests;
+ zbx_hashset_iter_t iter;
+ int i;
+ zbx_uint64_t *phostid;
+ ZBX_DC_HOST *host;
+ time_t now;
+
+ zbx_vector_dc_httptest_ptr_create(&httptests);
+
+ now = time(NULL);
+
+ zbx_hashset_iter_reset(activated_hosts, &iter);
+ while (NULL != (phostid = (zbx_uint64_t *)zbx_hashset_iter_next(&iter)))
+ {
+ if (NULL == (host = (ZBX_DC_HOST *)zbx_hashset_search(&config->hosts, phostid)))
+ continue;
+
+ for (i = 0; i < host->httptests.values_num; i++)
+ {
+ if (ZBX_LOC_NOWHERE != host->httptests.values[i]->location)
+ continue;
+
+ zbx_vector_dc_httptest_ptr_append(&httptests, host->httptests.values[i]);
+ }
+ }
+
+ if (0 != httptests.values_num)
+ {
+ WRLOCK_CACHE;
+
+ for (i = 0; i < httptests.values_num; i++)
+ {
+ zbx_dc_httptest_t *httptest = httptests.values[i];
+
+ httptest->nextcheck = dc_calculate_nextcheck(httptest->httptestid, httptest->delay, now);
+ dc_httptest_queue(httptest);
+ }
+
+ UNLOCK_CACHE;
+ }
+
+ zbx_vector_dc_httptest_ptr_destroy(&httptests);
+}
+
+
+/******************************************************************************
+ * *
+ * Purpose: get next drule to be processed *
+ * *
+ * Parameter: now - [IN] the current timestamp *
+ * druleid - [OUT] the id of drule to be processed *
+ * nextcheck - [OUT] the timestamp of next drule to be processed, *
+ * if there is no rule to be processed now and *
+ * the queue is not empty. 0 otherwise *
+ * *
+ * Return value: SUCCEED - the drule id was returned successfully *
+ * FAIL - no drules are scheduled at current time *
+ * *
+ ******************************************************************************/
+int zbx_dc_drule_next(time_t now, zbx_uint64_t *druleid, time_t *nextcheck)
+{
+ zbx_binary_heap_elem_t *elem;
+ zbx_dc_drule_t *drule;
+ int ret = FAIL;
+
+ *nextcheck = 0;
+
+ WRLOCK_CACHE;
+
+ if (FAIL == zbx_binary_heap_empty(&config->drule_queue))
+ {
+ elem = zbx_binary_heap_find_min(&config->drule_queue);
+ drule = (zbx_dc_drule_t *)elem->data;
+
+ if (drule->nextcheck <= now)
+ {
+ zbx_binary_heap_remove_min(&config->drule_queue);
+ *druleid = drule->druleid;
+ drule->location = ZBX_LOC_POLLER;
+ ret = SUCCEED;
+ }
+ else
+ *nextcheck = drule->nextcheck;
+ }
+
+ UNLOCK_CACHE;
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: queue drule to be processed according to the delay *
+ * *
+ * Parameter: now - [IN] the current timestamp *
+ * druleid - [IN] the id of drule to be queued *
+ * delay - [IN] the number of seconds between drule processing *
+ * *
+ ******************************************************************************/
+void zbx_dc_drule_queue(time_t now, zbx_uint64_t druleid, int delay)
+{
+ zbx_dc_drule_t *drule;
+
+ WRLOCK_CACHE;
+
+ if (NULL != (drule = (zbx_dc_drule_t *)zbx_hashset_search(&config->drules, &druleid)))
+ {
+ drule->delay = delay;
+ drule->nextcheck = dc_calculate_nextcheck(drule->druleid, drule->delay, now);
+ dc_drule_queue(drule);
+ }
+
+ UNLOCK_CACHE;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: get next httptest to be processed *
+ * *
+ * Parameter: now - [IN] the current timestamp *
+ * httptestid - [OUT] the id of httptest to be processed *
+ * nextcheck - [OUT] the timestamp of next httptest to be *
+ * processed, if there is no httptest to be *
+ * processed now and the queue is not empty. *
+ * 0 - otherwise *
+ * *
+ * Return value: SUCCEED - the httptest id was returned successfully *
+ * FAIL - no httptests are scheduled at current time *
+ * *
+ ******************************************************************************/
+int zbx_dc_httptest_next(time_t now, zbx_uint64_t *httptestid, time_t *nextcheck)
+{
+ zbx_binary_heap_elem_t *elem;
+ zbx_dc_httptest_t *httptest;
+ int ret = FAIL;
+ ZBX_DC_HOST *dc_host;
+
+ *nextcheck = 0;
+
+ WRLOCK_CACHE;
+
+ while (FAIL == zbx_binary_heap_empty(&config->httptest_queue))
+ {
+ elem = zbx_binary_heap_find_min(&config->httptest_queue);
+ httptest = (zbx_dc_httptest_t *)elem->data;
+
+ if (httptest->nextcheck <= now)
+ {
+ zbx_binary_heap_remove_min(&config->httptest_queue);
+ httptest->location = ZBX_LOC_NOWHERE;
+
+ if (NULL == (dc_host = (ZBX_DC_HOST *)zbx_hashset_search(&config->hosts, &httptest->hostid)))
+ continue;
+
+ if (HOST_STATUS_MONITORED != dc_host->status || 0 != dc_host->proxy_hostid)
+ continue;
+
+ if (HOST_MAINTENANCE_STATUS_ON == dc_host->maintenance_status &&
+ MAINTENANCE_TYPE_NODATA == dc_host->maintenance_type)
+ {
+ httptest->nextcheck = dc_calculate_nextcheck(httptest->httptestid, httptest->delay, now);
+ dc_httptest_queue(httptest);
+
+ continue;
+ }
+
+ httptest->location = ZBX_LOC_POLLER;
+ *httptestid = httptest->httptestid;
+
+ ret = SUCCEED;
+ }
+ else
+ *nextcheck = httptest->nextcheck;
+
+ break;
+ }
+
+ UNLOCK_CACHE;
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: queue httptest to be processed according to the delay *
+ * *
+ * Parameter: now - [IN] the current timestamp *
+ * httptestid - [IN] the id of httptest to be queued *
+ * delay - [IN] the number of seconds between httptest *
+ * processing *
+ * *
+ ******************************************************************************/
+void zbx_dc_httptest_queue(time_t now, zbx_uint64_t httptestid, int delay)
+{
+ zbx_dc_httptest_t *httptest;
+
+ WRLOCK_CACHE;
+
+ if (NULL != (httptest = (zbx_dc_httptest_t *)zbx_hashset_search(&config->httptests, &httptestid)))
+ {
+ httptest->delay = delay;
+ httptest->nextcheck = dc_calculate_nextcheck(httptest->httptestid, httptest->delay, now);
+ dc_httptest_queue(httptest);
+ }
+
+ UNLOCK_CACHE;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: get the configuration revision received from server *
+ * *
+ * Comments: The revision is accessed without locking because no other process*
+ * can access it at the same time. *
+ * *
+ ******************************************************************************/
+zbx_uint64_t zbx_dc_get_received_revision(void)
+{
+ return config->revision.upstream;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: cache the configuration revision received from server *
+ * *
+ * Comments: The revision is updated without locking because no other process *
+ * can access it at the same time. *
+ * *
+ ******************************************************************************/
+void zbx_dc_update_received_revision(zbx_uint64_t revision)
+{
+ config->revision.upstream = revision;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: get hosts/httptests for proxy configuration update *
+ * *
+ * Parameters: proxy_hostid - [IN] *
+ * revision - [IN] the current proxy configuration revision*
+ * hostids - [OUT] the monitored hosts *
+ * updated_hostids - [OUT] the hosts updated since specified *
+ * configuration revision, sorted *
+ * removed_hostids - [OUT] the hosts removed since specified *
+ * configuration revision, sorted *
+ * httptestids - [OUT] the web scenarios monitored by proxy *
+ * *
+ ******************************************************************************/
+void zbx_dc_get_proxy_config_updates(zbx_uint64_t proxy_hostid, zbx_uint64_t revision, zbx_vector_uint64_t *hostids,
+ zbx_vector_uint64_t *updated_hostids, zbx_vector_uint64_t *removed_hostids,
+ zbx_vector_uint64_t *httptestids)
+{
+ ZBX_DC_PROXY *proxy;
+
+ RDLOCK_CACHE;
+
+ if (NULL != (proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&config->proxies, &proxy_hostid)))
+ {
+ int i, j;
+
+ zbx_vector_uint64_reserve(hostids, (size_t)proxy->hosts.values_num);
+
+ for (i = 0; i < proxy->hosts.values_num; i++)
+ {
+ ZBX_DC_HOST *host = proxy->hosts.values[i];
+
+ zbx_vector_uint64_append(hostids, host->hostid);
+
+ if (host->revision > revision)
+ {
+ zbx_vector_uint64_append(updated_hostids, host->hostid);
+
+ for (j = 0; j < host->httptests.values_num; j++)
+ zbx_vector_uint64_append(httptestids, host->httptests.values[j]->httptestid);
+ }
+ }
+
+ /* skip when full sync */
+ if (0 != revision)
+ {
+ for (i = 0; i < proxy->removed_hosts.values_num; )
+ {
+ if (proxy->removed_hosts.values[i].revision > revision)
+ {
+ zbx_vector_uint64_append(removed_hostids, proxy->removed_hosts.values[i].hostid);
+
+ /* this operation can be done with read lock: */
+ /* - removal from vector does not allocate/free memory */
+ /* - two configuration requests for the same proxy cannot be */
+ /* processed at the same time */
+ /* - configuration syncer uses write lock to update */
+ /* removed hosts on proxy */
+ zbx_vector_host_rev_remove_noorder(&proxy->removed_hosts, i);
+ }
+ else
+ i++;
+ }
+ }
+ }
+
+ UNLOCK_CACHE;
+
+ zbx_vector_uint64_sort(hostids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+ zbx_vector_uint64_sort(updated_hostids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+ zbx_vector_uint64_sort(removed_hostids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+ zbx_vector_uint64_sort(httptestids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+}
+
+void zbx_dc_get_macro_updates(const zbx_vector_uint64_t *hostids, const zbx_vector_uint64_t *updated_hostids,
+ zbx_uint64_t revision, zbx_vector_uint64_t *macro_hostids, int *global,
+ zbx_vector_uint64_t *del_macro_hostids)
+{
+ zbx_vector_uint64_t hostids_tmp, globalids;
+ zbx_uint64_t globalhostid = 0;
+
+ /* force full sync for updated hosts (in the case host was assigned to proxy) */
+ /* and revision based sync for the monitored hosts (except updated hosts that */
+ /* were already synced) */
+
+ zbx_vector_uint64_create(&hostids_tmp);
+ if (0 != hostids->values_num)
+ {
+ zbx_vector_uint64_append_array(&hostids_tmp, hostids->values, hostids->values_num);
+ zbx_vector_uint64_setdiff(&hostids_tmp, updated_hostids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+ }
+
+ zbx_vector_uint64_create(&globalids);
+
+ RDLOCK_CACHE;
+
+ /* check revision of global macro 'host' (hostid 0) */
+ um_cache_get_macro_updates(config->um_cache, &globalhostid, 1, revision, &globalids, del_macro_hostids);
+
+ if (0 != hostids_tmp.values_num)
+ {
+ um_cache_get_macro_updates(config->um_cache, hostids_tmp.values, hostids_tmp.values_num, revision,
+ macro_hostids, del_macro_hostids);
+ }
+
+ if (0 != updated_hostids->values_num)
+ {
+ um_cache_get_macro_updates(config->um_cache, updated_hostids->values, updated_hostids->values_num, 0,
+ macro_hostids, del_macro_hostids);
+ }
+
+ UNLOCK_CACHE;
+
+ *global = (0 < globalids.values_num ? SUCCEED : FAIL);
+
+ if (0 != macro_hostids->values_num)
+ zbx_vector_uint64_sort(macro_hostids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
+ if (0 != del_macro_hostids->values_num)
+ zbx_vector_uint64_sort(del_macro_hostids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
+ zbx_vector_uint64_destroy(&globalids);
+ zbx_vector_uint64_destroy(&hostids_tmp);
+}
+
+void zbx_dc_get_unused_macro_templates(zbx_hashset_t *templates, const zbx_vector_uint64_t *hostids,
+ zbx_vector_uint64_t *templateids)
+{
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ RDLOCK_CACHE;
+
+ um_cache_get_unused_templates(config->um_cache, templates, hostids, templateids);
+
+ UNLOCK_CACHE;
+
+ if (0 != templateids->values_num)
+ zbx_vector_uint64_sort(templateids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s() templateids_num:%d", __func__, templateids->values_num);
+}
+
#ifdef HAVE_TESTS
# include "../../../tests/libs/zbxdbcache/dc_item_poller_type_update_test.c"
# include "../../../tests/libs/zbxdbcache/dc_function_calculate_nextcheck_test.c"
#endif
+
diff --git a/src/libs/zbxdbcache/dbconfig.h b/src/libs/zbxdbcache/dbconfig.h
index bc1d60585c2..b9d3e5a77e2 100644
--- a/src/libs/zbxdbcache/dbconfig.h
+++ b/src/libs/zbxdbcache/dbconfig.h
@@ -24,6 +24,7 @@
#include "zbxalgo.h"
#include "dbcache.h"
#include "user_macro.h"
+#include "zbxversion.h"
#define ZBX_MAINTENANCE_IDLE 0
#define ZBX_MAINTENANCE_RUNNING 1
@@ -41,8 +42,8 @@ typedef struct
const unsigned char *expression_bin;
const unsigned char *recovery_expression_bin;
int lastchange;
- zbx_uint32_t revision;
- zbx_uint32_t timer_revision;
+ zbx_uint64_t revision;
+ zbx_uint64_t timer_revision;
unsigned char topoindex;
unsigned char priority;
unsigned char type;
@@ -84,14 +85,26 @@ typedef struct
zbx_uint64_t itemid;
const char *function;
const char *parameter;
- zbx_uint32_t revision;
- zbx_uint32_t timer_revision;
+ zbx_uint64_t revision;
+ zbx_uint64_t timer_revision;
unsigned char type;
}
ZBX_DC_FUNCTION;
typedef struct
{
+ zbx_vector_uint64_pair_t dep_itemids;
+}
+ZBX_DC_MASTERITEM;
+
+typedef struct
+{
+ zbx_vector_ptr_t preproc_ops;
+}
+ZBX_DC_PREPROCITEM;
+
+typedef struct
+{
zbx_uint64_t itemid;
zbx_uint64_t hostid;
zbx_uint64_t interfaceid;
@@ -107,7 +120,7 @@ typedef struct
int nextcheck;
int mtime;
int data_expected_from;
- zbx_uint32_t revision;
+ zbx_uint64_t revision;
unsigned char type;
unsigned char value_type;
unsigned char poller_type;
@@ -120,6 +133,8 @@ typedef struct
unsigned char queue_priority;
unsigned char update_triggers;
zbx_uint64_t templateid;
+ ZBX_DC_PREPROCITEM *preproc_item;
+ ZBX_DC_MASTERITEM *master_item;
zbx_vector_ptr_t tags;
}
@@ -259,21 +274,6 @@ ZBX_DC_CALCITEM;
typedef struct
{
- zbx_uint64_t itemid;
- zbx_vector_uint64_pair_t dep_itemids;
-}
-ZBX_DC_MASTERITEM;
-
-typedef struct
-{
- zbx_uint64_t itemid;
- int update_time;
- zbx_vector_ptr_t preproc_ops;
-}
-ZBX_DC_PREPROCITEM;
-
-typedef struct
-{
zbx_uint64_t itemid;
const char *timeout;
const char *url;
@@ -321,6 +321,42 @@ ZBX_PTR_VECTOR_DECL(dc_item_ptr, ZBX_DC_ITEM *)
typedef struct
{
+ zbx_uint64_t httptestid;
+ zbx_uint64_t hostid;
+ time_t nextcheck;
+ int delay;
+ unsigned char status;
+ unsigned char location;
+ zbx_uint64_t revision;
+}
+zbx_dc_httptest_t;
+
+typedef struct
+{
+ zbx_uint64_t httptest_fieldid;
+ zbx_uint64_t httptestid;
+}
+zbx_dc_httptest_field_t;
+
+typedef struct
+{
+ zbx_uint64_t httpstepid;
+ zbx_uint64_t httptestid;
+ zbx_uint64_t revision;
+}
+zbx_dc_httpstep_t;
+
+typedef struct
+{
+ zbx_uint64_t httpstep_fieldid;
+ zbx_uint64_t httpstepid;
+}
+zbx_dc_httpstep_field_t;
+
+ZBX_PTR_VECTOR_DECL(dc_httptest_ptr, zbx_dc_httptest_t *)
+
+typedef struct
+{
zbx_uint64_t hostid;
zbx_uint64_t proxy_hostid;
zbx_uint64_t items_active_normal; /* On enabled hosts these two fields store number of enabled */
@@ -335,15 +371,12 @@ typedef struct
const char *name;
int maintenance_from;
int data_expected_from;
- zbx_uint32_t revision;
+ zbx_uint64_t revision;
unsigned char maintenance_status;
unsigned char maintenance_type;
unsigned char status;
- /* flag to force update for all items */
- unsigned char update_items;
-
/* 'tls_connect' and 'tls_accept' must be respected even if encryption support is not compiled in */
unsigned char tls_connect;
unsigned char tls_accept;
@@ -355,10 +388,14 @@ typedef struct
zbx_vector_ptr_t interfaces_v; /* for quick finding of all host interfaces in */
/* 'config->interfaces' hashset */
- zbx_vector_dc_item_ptr_t active_items;
+
+ zbx_vector_dc_httptest_ptr_t httptests;
+ zbx_vector_dc_item_ptr_t items;
}
ZBX_DC_HOST;
+ZBX_PTR_VECTOR_DECL(dc_host_ptr, ZBX_DC_HOST *)
+
typedef struct
{
const char *host;
@@ -388,24 +425,39 @@ ZBX_DC_HOST_H;
typedef struct
{
- zbx_uint64_t hostid;
- zbx_uint64_t hosts_monitored; /* number of enabled hosts assigned to proxy */
- zbx_uint64_t hosts_not_monitored; /* number of disabled hosts assigned to proxy */
- double required_performance;
- int proxy_config_nextcheck;
- int proxy_data_nextcheck;
- int proxy_tasks_nextcheck;
- int nextcheck;
- int lastaccess;
- int proxy_delay;
- zbx_proxy_suppress_t nodata_win;
- int last_cfg_error_time; /* time when passive proxy misconfiguration error was seen */
- /* or 0 if no error */
- int version;
- unsigned char location;
- unsigned char auto_compress;
- const char *proxy_address;
- int last_version_error_time;
+ zbx_uint64_t hostid;
+ zbx_uint64_t revision;
+}
+zbx_host_rev_t;
+
+ZBX_VECTOR_DECL(host_rev, zbx_host_rev_t)
+
+typedef struct
+{
+ zbx_uint64_t hostid;
+ zbx_uint64_t hosts_monitored; /* number of enabled hosts assigned to proxy */
+ zbx_uint64_t hosts_not_monitored; /* number of disabled hosts assigned to proxy */
+ double required_performance;
+ int proxy_config_nextcheck;
+ int proxy_data_nextcheck;
+ int proxy_tasks_nextcheck;
+ int nextcheck;
+ int lastaccess;
+ int proxy_delay;
+ zbx_proxy_suppress_t nodata_win;
+ int last_cfg_error_time; /* time when passive proxy misconfiguration error was seen */
+ /* or 0 if no error */
+ const char *version_str;
+ int version_int;
+ zbx_proxy_compatibility_t compatibility;
+ unsigned char location;
+ unsigned char auto_compress;
+ const char *proxy_address;
+ int last_version_error_time;
+ zbx_uint64_t revision;
+
+ zbx_vector_dc_host_ptr_t hosts;
+ zbx_vector_host_rev_t removed_hosts;
}
ZBX_DC_PROXY;
@@ -550,6 +602,7 @@ typedef struct
/* disabled then trigger is counted as disabled) */
double required_performance; /* required performance of server (values per second) */
time_t last_update;
+ int sync_ts;
}
ZBX_DC_STATUS;
@@ -771,6 +824,25 @@ zbx_dc_macro_kv_t;
typedef struct
{
+ zbx_uint64_t druleid;
+ zbx_uint64_t proxy_hostid;
+ time_t nextcheck;
+ int delay;
+ unsigned char status;
+ unsigned char location;
+ zbx_uint64_t revision;
+}
+zbx_dc_drule_t;
+
+typedef struct
+{
+ zbx_uint64_t dcheckid;
+ zbx_uint64_t druleid;
+}
+zbx_dc_dcheck_t;
+
+typedef struct
+{
/* timestamp of the last host availability diff sent to sever, used only by proxies */
int availability_diff_ts;
int proxy_lastaccess_ts;
@@ -780,8 +852,7 @@ typedef struct
unsigned int internal_actions; /* number of enabled internal actions */
unsigned int auto_registration_actions; /* number of enabled auto resistration actions */
- zbx_uint32_t revision;
- zbx_uint32_t expression_revision;
+ zbx_dc_revision_t revision;
/* maintenance processing management */
unsigned char maintenance_update; /* flag to trigger maintenance update by timers */
@@ -808,8 +879,6 @@ typedef struct
zbx_hashset_t simpleitems;
zbx_hashset_t jmxitems;
zbx_hashset_t calcitems;
- zbx_hashset_t masteritems;
- zbx_hashset_t preprocitems;
zbx_hashset_t httpitems;
zbx_hashset_t scriptitems;
zbx_hashset_t functions;
@@ -858,10 +927,19 @@ typedef struct
zbx_hashset_t psks; /* for keeping PSK-identity and PSK pairs and for searching */
/* by PSK identity */
#endif
+ zbx_hashset_t data_sessions;
+ zbx_hashset_t drules;
+ zbx_hashset_t dchecks;
+ zbx_hashset_t httptests;
+ zbx_hashset_t httptest_fields;
+ zbx_hashset_t httpsteps;
+ zbx_hashset_t httpstep_fields;
zbx_hashset_t sessions[ZBX_SESSION_TYPE_COUNT];
zbx_binary_heap_t queues[ZBX_POLLER_TYPE_COUNT];
zbx_binary_heap_t pqueue;
zbx_binary_heap_t trigger_queue;
+ zbx_binary_heap_t drule_queue;
+ zbx_binary_heap_t httptest_queue; /* web scenario queue */
ZBX_DC_CONFIG_TABLE *config;
ZBX_DC_STATUS *status;
zbx_hashset_t strpool;
@@ -927,8 +1005,7 @@ char *dc_expand_user_macros(const char *text, const zbx_uint64_t *hostids, int h
#define ZBX_TRIGGER_TIMER_FUNCTION_TREND 0x0004
#define ZBX_TRIGGER_TIMER_FUNCTION (ZBX_TRIGGER_TIMER_FUNCTION_TIME | ZBX_TRIGGER_TIMER_FUNCTION_TREND)
-
-zbx_um_cache_t *um_cache_sync(zbx_um_cache_t *cache, zbx_uint32_t revision, zbx_dbsync_t *gmacros,
+zbx_um_cache_t *um_cache_sync(zbx_um_cache_t *cache, zbx_uint64_t revision, zbx_dbsync_t *gmacros,
zbx_dbsync_t *hmacros, zbx_dbsync_t *htmpls);
#endif
diff --git a/src/libs/zbxdbcache/dbconfig_dump.c b/src/libs/zbxdbcache/dbconfig_dump.c
index d7847bd10b2..95f1876ade7 100644
--- a/src/libs/zbxdbcache/dbconfig_dump.c
+++ b/src/libs/zbxdbcache/dbconfig_dump.c
@@ -33,6 +33,7 @@ static void DCdump_config(void)
if (NULL == config->config)
goto out;
+ zabbix_log(LOG_LEVEL_TRACE, "revision:" ZBX_FS_UI64, config->revision.config_table);
zabbix_log(LOG_LEVEL_TRACE, "discovery_groupid:" ZBX_FS_UI64, config->config->discovery_groupid);
zabbix_log(LOG_LEVEL_TRACE, "snmptrap_logging:%hhu", config->config->snmptrap_logging);
zabbix_log(LOG_LEVEL_TRACE, "default_inventory_mode:%d", config->config->default_inventory_mode);
@@ -99,7 +100,7 @@ static void DCdump_hosts(void)
int j;
host = (ZBX_DC_HOST *)index.values[i];
- zabbix_log(LOG_LEVEL_TRACE, "hostid:" ZBX_FS_UI64 " host:'%s' name:'%s' status:%u revision:%u",
+ zabbix_log(LOG_LEVEL_TRACE, "hostid:" ZBX_FS_UI64 " host:'%s' name:'%s' status:%u revision:" ZBX_FS_UI64,
host->hostid, host->host, host->name, host->status, host->revision);
zabbix_log(LOG_LEVEL_TRACE, " proxy_hostid:" ZBX_FS_UI64, host->proxy_hostid);
@@ -128,12 +129,16 @@ static void DCdump_hosts(void)
zabbix_log(LOG_LEVEL_TRACE, " interfaceid:" ZBX_FS_UI64, interface->interfaceid);
}
- for (j = 0; j < host->active_items.values_num; j++)
+ zabbix_log(LOG_LEVEL_TRACE, " httptests:");
+ for (j = 0; j < host->httptests.values_num; j++)
{
- ZBX_DC_ITEM *item = host->active_items.values[j];
-
- zabbix_log(LOG_LEVEL_TRACE, " itemid:" ZBX_FS_UI64, item->itemid);
+ zabbix_log(LOG_LEVEL_TRACE, " httptestid:" ZBX_FS_UI64,
+ host->httptests.values[j]->httptestid);
}
+
+ zabbix_log(LOG_LEVEL_TRACE, " items:");
+ for (j = 0; j < host->items.values_num; j++)
+ zabbix_log(LOG_LEVEL_TRACE, " itemid:" ZBX_FS_UI64, host->items.values[j]->itemid);
}
zbx_vector_ptr_destroy(&index);
@@ -204,7 +209,7 @@ static void DCdump_proxies(void)
ZBX_DC_PROXY *proxy;
zbx_hashset_iter_t iter;
zbx_vector_ptr_t index;
- int i;
+ int i, j;
zabbix_log(LOG_LEVEL_TRACE, "In %s()", __func__);
@@ -219,10 +224,20 @@ static void DCdump_proxies(void)
for (i = 0; i < index.values_num; i++)
{
proxy = (ZBX_DC_PROXY *)index.values[i];
- zabbix_log(LOG_LEVEL_TRACE, "hostid:" ZBX_FS_UI64 " location:%u", proxy->hostid, proxy->location);
+ zabbix_log(LOG_LEVEL_TRACE, "hostid:" ZBX_FS_UI64 " location:%u revision:" ZBX_FS_UI64, proxy->hostid,
+ proxy->location, proxy->revision);
zabbix_log(LOG_LEVEL_TRACE, " proxy_address:'%s'", proxy->proxy_address);
zabbix_log(LOG_LEVEL_TRACE, " compress:%d", proxy->auto_compress);
zabbix_log(LOG_LEVEL_TRACE, " lastaccess:%d", proxy->lastaccess);
+
+ zabbix_log(LOG_LEVEL_TRACE, " hosts:%d", proxy->hosts.values_num);
+ for (j = 0; j < proxy->hosts.values_num; j++)
+ zabbix_log(LOG_LEVEL_TRACE, " hostid:" ZBX_FS_UI64, proxy->hosts.values[j]->hostid);
+
+ zabbix_log(LOG_LEVEL_TRACE, " removed hosts:%d", proxy->removed_hosts.values_num);
+ for (j = 0; j < proxy->removed_hosts.values_num; j++)
+ zabbix_log(LOG_LEVEL_TRACE, " hostid:" ZBX_FS_UI64 " revision:" ZBX_FS_UI64,
+ proxy->removed_hosts.values[j].hostid, proxy->removed_hosts.values[j].revision);
}
zbx_vector_ptr_destroy(&index);
@@ -503,7 +518,6 @@ static void DCdump_preprocitem(const ZBX_DC_PREPROCITEM *preprocitem)
int i;
zabbix_log(LOG_LEVEL_TRACE, " preprocessing:");
- zabbix_log(LOG_LEVEL_TRACE, " update_time:%d", preprocitem->update_time);
for (i = 0; i < preprocitem->preproc_ops.values_num; i++)
{
@@ -567,8 +581,6 @@ static void DCdump_items(void)
{&config->simpleitems, (zbx_dc_dump_func_t)DCdump_simpleitem},
{&config->jmxitems, (zbx_dc_dump_func_t)DCdump_jmxitem},
{&config->calcitems, (zbx_dc_dump_func_t)DCdump_calcitem},
- {&config->masteritems, (zbx_dc_dump_func_t)DCdump_masteritem},
- {&config->preprocitems, (zbx_dc_dump_func_t)DCdump_preprocitem},
{&config->httpitems, (zbx_dc_dump_func_t)DCdump_httpitem},
{&config->scriptitems, (zbx_dc_dump_func_t)DCdump_scriptitem},
};
@@ -586,7 +598,7 @@ static void DCdump_items(void)
for (i = 0; i < index.values_num; i++)
{
item = (ZBX_DC_ITEM *)index.values[i];
- zabbix_log(LOG_LEVEL_TRACE, "itemid:" ZBX_FS_UI64 " hostid:" ZBX_FS_UI64 " key:'%s' revision:%u",
+ zabbix_log(LOG_LEVEL_TRACE, "itemid:" ZBX_FS_UI64 " hostid:" ZBX_FS_UI64 " key:'%s' revision:" ZBX_FS_UI64,
item->itemid, item->hostid, item->key, item->revision);
zabbix_log(LOG_LEVEL_TRACE, " type:%u value_type:%u", item->type, item->value_type);
zabbix_log(LOG_LEVEL_TRACE, " interfaceid:" ZBX_FS_UI64, item->interfaceid);
@@ -607,6 +619,12 @@ static void DCdump_items(void)
trace_items[j].dump_func(ptr);
}
+ if (NULL != item->master_item)
+ DCdump_masteritem(item->master_item);
+
+ if (NULL != item->preproc_item)
+ DCdump_preprocitem(item->preproc_item);
+
if (0 != item->tags.values_num)
DCdump_item_tags(item);
@@ -715,41 +733,6 @@ static void DCdump_item_discovery(void)
zabbix_log(LOG_LEVEL_TRACE, "End of %s()", __func__);
}
-static void DCdump_master_items(void)
-{
- ZBX_DC_MASTERITEM *master_item;
- zbx_hashset_iter_t iter;
- int i, j;
- zbx_vector_ptr_t index;
-
- zabbix_log(LOG_LEVEL_TRACE, "In %s()", __func__);
-
- zbx_vector_ptr_create(&index);
- zbx_hashset_iter_reset(&config->masteritems, &iter);
-
- while (NULL != (master_item = (ZBX_DC_MASTERITEM *)zbx_hashset_iter_next(&iter)))
- zbx_vector_ptr_append(&index, master_item);
-
- zbx_vector_ptr_sort(&index, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
-
- for (i = 0; i < index.values_num; i++)
- {
- master_item = (ZBX_DC_MASTERITEM *)index.values[i];
- zabbix_log(LOG_LEVEL_TRACE, "master itemid:" ZBX_FS_UI64, master_item->itemid);
-
- for (j = 0; j < master_item->dep_itemids.values_num; j++)
- {
- zabbix_log(LOG_LEVEL_TRACE, " itemid:" ZBX_FS_UI64 " flags:" ZBX_FS_UI64,
- master_item->dep_itemids.values[j].first,
- master_item->dep_itemids.values[j].second);
- }
- }
-
- zbx_vector_ptr_destroy(&index);
-
- zabbix_log(LOG_LEVEL_TRACE, "End of %s()", __func__);
-}
-
static void DCdump_prototype_items(void)
{
ZBX_DC_PROTOTYPE_ITEM *proto_item;
@@ -800,7 +783,7 @@ static void DCdump_functions(void)
{
function = (ZBX_DC_FUNCTION *)index.values[i];
zabbix_log(LOG_LEVEL_DEBUG, "functionid:" ZBX_FS_UI64 " triggerid:" ZBX_FS_UI64 " itemid:"
- ZBX_FS_UI64 " function:'%s' parameter:'%s' type:%u timer_revision:%u",
+ ZBX_FS_UI64 " function:'%s' parameter:'%s' type:%u timer_revision:" ZBX_FS_UI64,
function->functionid, function->triggerid, function->itemid, function->function,
function->parameter, function->type, function->timer_revision);
@@ -937,7 +920,7 @@ static void DCdump_expressions(void)
zabbix_log(LOG_LEVEL_TRACE, "In %s()", __func__);
- zabbix_log(LOG_LEVEL_TRACE, "expression_revision:%u", config->expression_revision);
+ zabbix_log(LOG_LEVEL_TRACE, "expression_revision:" ZBX_FS_UI64, config->revision.expression);
zbx_vector_ptr_create(&index);
zbx_hashset_iter_reset(&config->expressions, &iter);
@@ -1315,9 +1298,155 @@ static void DCdump_maintenances(void)
zabbix_log(LOG_LEVEL_TRACE, "End of %s()", __func__);
}
+/* stringpool dumping is disabled by default to avoid leaking secret macro data */
+#ifdef HAVE_TESTS
+static int strpool_compare(const void *v1, const void *v2)
+{
+ const char *s1 = *(const char * const *)v1 + sizeof(zbx_uint32_t);
+ const char *s2 = *(const char * const *)v2 + sizeof(zbx_uint32_t);
+
+ return strcmp(s1, s2);
+}
+
+static void DCdump_strpool()
+{
+ zbx_hashset_iter_t iter;
+ zbx_vector_ptr_t records;
+ char *record;
+ int i;
+
+ zabbix_log(LOG_LEVEL_TRACE, "In %s()", __func__);
+
+ zbx_vector_ptr_create(&records);
+ zbx_hashset_iter_reset(&config->strpool, &iter);
+
+ while (NULL != (record = (char *)zbx_hashset_iter_next(&iter)))
+ zbx_vector_ptr_append(&records, record);
+
+ zbx_vector_ptr_sort(&records, strpool_compare);
+
+ for (i = 0; i < records.values_num; i++)
+ {
+ zabbix_log(LOG_LEVEL_TRACE, " %s: %u", (char *)records.values[i] + sizeof(zbx_uint32_t),
+ *(zbx_uint32_t *)records.values[i]);
+ }
+
+ zbx_vector_ptr_destroy(&records);
+}
+#endif
+
+static void DCdump_drules(void)
+{
+ zbx_hashset_iter_t iter;
+ zbx_dc_drule_t *drule;
+
+ zabbix_log(LOG_LEVEL_TRACE, "In %s()", __func__);
+
+ zbx_hashset_iter_reset(&config->drules, &iter);
+ while (NULL != (drule = (zbx_dc_drule_t *)zbx_hashset_iter_next(&iter)))
+ {
+ zabbix_log(LOG_LEVEL_TRACE, "druleid:" ZBX_FS_UI64 " proxy_hostid:" ZBX_FS_UI64 " revision:" ZBX_FS_UI64,
+ drule->druleid, drule->proxy_hostid, drule->revision);
+ zabbix_log(LOG_LEVEL_TRACE, " status:%u delay:%d location:%d nextcheck:%ld",
+ drule->status, drule->delay, drule->location, (long int)drule->nextcheck);
+ }
+
+ zabbix_log(LOG_LEVEL_TRACE, "End of %s()", __func__);
+}
+
+static void DCdump_dchecks(void)
+{
+ zbx_hashset_iter_t iter;
+ zbx_dc_dcheck_t *dcheck;
+
+ zabbix_log(LOG_LEVEL_TRACE, "In %s()", __func__);
+
+ zbx_hashset_iter_reset(&config->dchecks, &iter);
+ while (NULL != (dcheck = (zbx_dc_dcheck_t *)zbx_hashset_iter_next(&iter)))
+ {
+ zabbix_log(LOG_LEVEL_TRACE, "dcheckid:" ZBX_FS_UI64 " druleid:" ZBX_FS_UI64,
+ dcheck->dcheckid, dcheck->druleid);
+ }
+
+ zabbix_log(LOG_LEVEL_TRACE, "End of %s()", __func__);
+}
+
+static void DCdump_httptests(void)
+{
+ zbx_hashset_iter_t iter;
+ zbx_dc_httptest_t *httptest;
+
+ zabbix_log(LOG_LEVEL_TRACE, "In %s()", __func__);
+
+ zbx_hashset_iter_reset(&config->httptests, &iter);
+ while (NULL != (httptest = (zbx_dc_httptest_t *)zbx_hashset_iter_next(&iter)))
+ {
+ zabbix_log(LOG_LEVEL_TRACE, "httptestid:" ZBX_FS_UI64 " hostid:" ZBX_FS_UI64 " revision:" ZBX_FS_UI64,
+ httptest->httptestid, httptest->hostid, httptest->revision);
+ zabbix_log(LOG_LEVEL_TRACE, " status:%u delay:%d location:%d nextcheck:%ld",
+ httptest->status, httptest->delay, httptest->location, (long int)httptest->nextcheck);
+ }
+
+ zabbix_log(LOG_LEVEL_TRACE, "End of %s()", __func__);
+}
+
+static void DCdump_httptest_fields(void)
+{
+ zbx_hashset_iter_t iter;
+ zbx_dc_httptest_field_t *httptest_field;
+
+ zabbix_log(LOG_LEVEL_TRACE, "In %s()", __func__);
+
+ zbx_hashset_iter_reset(&config->httptest_fields, &iter);
+ while (NULL != (httptest_field = (zbx_dc_httptest_field_t *)zbx_hashset_iter_next(&iter)))
+ {
+ zabbix_log(LOG_LEVEL_TRACE, "httptest_fieldid:" ZBX_FS_UI64 " httptestid:" ZBX_FS_UI64,
+ httptest_field->httptest_fieldid, httptest_field->httptestid);
+ }
+
+ zabbix_log(LOG_LEVEL_TRACE, "End of %s()", __func__);
+}
+
+static void DCdump_httpsteps(void)
+{
+ zbx_hashset_iter_t iter;
+ zbx_dc_httpstep_t *httpstep;
+
+ zabbix_log(LOG_LEVEL_TRACE, "In %s()", __func__);
+
+ zbx_hashset_iter_reset(&config->httpsteps, &iter);
+ while (NULL != (httpstep = (zbx_dc_httpstep_t *)zbx_hashset_iter_next(&iter)))
+ {
+ zabbix_log(LOG_LEVEL_TRACE, "httpstepid:" ZBX_FS_UI64 " httptestid:" ZBX_FS_UI64,
+ httpstep->httpstepid, httpstep->httptestid);
+ }
+
+ zabbix_log(LOG_LEVEL_TRACE, "End of %s()", __func__);
+}
+
+static void DCdump_httpstep_fields(void)
+{
+ zbx_hashset_iter_t iter;
+ zbx_dc_httpstep_field_t *httpstep_field;
+
+ zabbix_log(LOG_LEVEL_TRACE, "In %s()", __func__);
+
+ zbx_hashset_iter_reset(&config->httpstep_fields, &iter);
+ while (NULL != (httpstep_field = (zbx_dc_httpstep_field_t *)zbx_hashset_iter_next(&iter)))
+ {
+ zabbix_log(LOG_LEVEL_TRACE, "httpstep_fieldid:" ZBX_FS_UI64 " httpstepid:" ZBX_FS_UI64,
+ httpstep_field->httpstep_fieldid, httpstep_field->httpstepid);
+ }
+
+ zabbix_log(LOG_LEVEL_TRACE, "End of %s()", __func__);
+}
+
void DCdump_configuration(void)
{
- zabbix_log(LOG_LEVEL_TRACE, "=== Configuration cache contents (revision:%u) ===", config->revision);
+ zabbix_log(LOG_LEVEL_TRACE, "=== Configuration cache contents (revision:" ZBX_FS_UI64 ") ===",
+ config->revision.config);
+
+ zabbix_log(LOG_LEVEL_TRACE, " autoreg_tls_revision:" ZBX_FS_UI64, config->revision.autoreg_tls);
DCdump_config();
DCdump_hosts();
@@ -1332,7 +1461,6 @@ void DCdump_configuration(void)
DCdump_item_discovery();
DCdump_interface_snmpitems();
DCdump_template_items();
- DCdump_master_items();
DCdump_prototype_items();
DCdump_triggers();
DCdump_trigdeps();
@@ -1343,5 +1471,14 @@ void DCdump_configuration(void)
DCdump_host_groups();
DCdump_host_group_index();
DCdump_maintenances();
+ DCdump_drules();
+ DCdump_dchecks();
+ DCdump_httptests();
+ DCdump_httptest_fields();
+ DCdump_httpsteps();
+ DCdump_httpstep_fields();
DCdump_autoreg_hosts();
+#ifdef HAVE_TESTS
+ DCdump_strpool();
+#endif
}
diff --git a/src/libs/zbxdbcache/dbconfig_maintenance.c b/src/libs/zbxdbcache/dbconfig_maintenance.c
index 19ec3fd7265..e7094673ed0 100644
--- a/src/libs/zbxdbcache/dbconfig_maintenance.c
+++ b/src/libs/zbxdbcache/dbconfig_maintenance.c
@@ -1368,9 +1368,9 @@ static int dc_maintenance_match_tags(const zbx_dc_maintenance_t *maintenance, co
{
switch (maintenance->tags_evaltype)
{
- case MAINTENANCE_TAG_EVAL_TYPE_AND_OR:
+ case ZBX_MAINTENANCE_TAG_EVAL_TYPE_AND_OR:
/* break; is not missing here */
- case MAINTENANCE_TAG_EVAL_TYPE_OR:
+ case ZBX_MAINTENANCE_TAG_EVAL_TYPE_OR:
if (0 == maintenance->tags.values_num)
return SUCCEED;
@@ -1382,7 +1382,7 @@ static int dc_maintenance_match_tags(const zbx_dc_maintenance_t *maintenance, co
return FAIL;
}
- if (MAINTENANCE_TAG_EVAL_TYPE_AND_OR == maintenance->tags_evaltype)
+ if (ZBX_MAINTENANCE_TAG_EVAL_TYPE_AND_OR == maintenance->tags_evaltype)
return dc_maintenance_match_tags_andor(maintenance, tags);
else
return dc_maintenance_match_tags_or(maintenance, tags);
diff --git a/src/libs/zbxdbcache/dbsync.c b/src/libs/zbxdbcache/dbsync.c
index a973e21259e..e3e61718a5a 100644
--- a/src/libs/zbxdbcache/dbsync.c
+++ b/src/libs/zbxdbcache/dbsync.c
@@ -34,9 +34,16 @@
#define ZBX_DBSYNC_OBJ_TRIGGER_TAG 6
#define ZBX_DBSYNC_OBJ_FUNCTION 7
#define ZBX_DBSYNC_OBJ_ITEM_PREPROC 8
-
+#define ZBX_DBSYNC_OBJ_DRULE 9
+#define ZBX_DBSYNC_OBJ_DCHECK 10
+#define ZBX_DBSYNC_OBJ_HTTPTEST 11
+#define ZBX_DBSYNC_OBJ_HTTPTEST_FIELD 12
+#define ZBX_DBSYNC_OBJ_HTTPTESTITEM 13
+#define ZBX_DBSYNC_OBJ_HTTPSTEP 14
+#define ZBX_DBSYNC_OBJ_HTTPSTEP_FIELD 15
+#define ZBX_DBSYNC_OBJ_HTTPSTEP_ITEM 16
/* number of dbsync objects - keep in sync with above defines */
-#define ZBX_DBSYNC_OBJ_COUNT 8
+#define ZBX_DBSYNC_OBJ_COUNT 16
#define ZBX_DBSYNC_JOURNAL(X) (X - 1)
@@ -511,8 +518,8 @@ int zbx_dbsync_env_prepare(unsigned char mode)
static void dbsync_env_flush_journal(zbx_dbsync_journal_t *journal)
{
- zbx_vector_uint64_t objectids;
- int i, j, objects_num;
+ zbx_hashset_t objectids;
+ int i, j, objects_num;
if (0 == journal->changelog.values_num)
return;
@@ -522,8 +529,8 @@ static void dbsync_env_flush_journal(zbx_dbsync_journal_t *journal)
for (i = 0; i < journal->syncs.values_num; i++)
objects_num += journal->syncs.values[i]->rows.values_num;
- zbx_vector_uint64_create(&objectids);
- zbx_vector_uint64_reserve(&objectids, (size_t)objects_num);
+ zbx_hashset_create(&objectids, (size_t)objects_num, ZBX_DEFAULT_UINT64_HASH_FUNC,
+ ZBX_DEFAULT_UINT64_COMPARE_FUNC);
for (j = 0; j < journal->syncs.values_num; j++)
{
@@ -531,29 +538,26 @@ static void dbsync_env_flush_journal(zbx_dbsync_journal_t *journal)
{
zbx_dbsync_row_t *row = (zbx_dbsync_row_t *)journal->syncs.values[j]->rows.values[i];
- zbx_vector_uint64_append(&objectids, row->rowid);
+ zbx_hashset_insert(&objectids, &row->rowid, sizeof(row->rowid));
}
}
- if (0 != journal->inserts.values_num)
- zbx_vector_uint64_append_array(&objectids, journal->inserts.values, journal->inserts.values_num);
-
- if (0 != journal->updates.values_num)
- zbx_vector_uint64_append_array(&objectids, journal->updates.values, journal->updates.values_num);
+ for (i = 0; i < journal->inserts.values_num; i++)
+ zbx_hashset_insert(&objectids, &journal->inserts.values[i], sizeof(journal->inserts.values[i]));
- zbx_vector_uint64_sort(&objectids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+ for (i = 0; i < journal->updates.values_num; i++)
+ zbx_hashset_insert(&objectids, &journal->updates.values[i], sizeof(journal->updates.values[i]));
for (i = 0; i < journal->changelog.values_num; i++)
{
- if (FAIL != zbx_vector_uint64_bsearch(&objectids, journal->changelog.values[i].objectid,
- ZBX_DEFAULT_UINT64_COMPARE_FUNC))
+ if (NULL != zbx_hashset_search(&objectids, &journal->changelog.values[i].objectid))
{
zbx_hashset_insert(&dbsync_env.changelog, &journal->changelog.values[i].changelog,
sizeof(zbx_dbsync_changelog_t));
}
}
- zbx_vector_uint64_destroy(&objectids);
+ zbx_hashset_destroy(&objectids);
}
void zbx_dbsync_env_flush_changelog(void)
@@ -592,7 +596,7 @@ int zbx_dbsync_env_changelog_num(void)
* *
******************************************************************************/
static int dbsync_get_rows(zbx_dbsync_t *sync, char **sql, size_t *sql_alloc, size_t *sql_offset,
- const char *field, zbx_vector_uint64_t *ids, unsigned char tag)
+ const char *field, const char *order_field, zbx_vector_uint64_t *ids, unsigned char tag)
{
DB_ROW dbrow;
DB_RESULT result;
@@ -609,6 +613,8 @@ static int dbsync_get_rows(zbx_dbsync_t *sync, char **sql, size_t *sql_alloc, si
{
batch_size = MIN(ZBX_DBSYNC_BATCH_SIZE, ids->values + ids->values_num - batch);
DBadd_condition_alloc(sql, sql_alloc, sql_offset, field, batch, batch_size);
+ if (NULL != order_field)
+ zbx_snprintf_alloc(sql, sql_alloc, sql_offset, " order by %s", order_field);
if (NULL == (result = DBselect("%s", *sql)))
return FAIL;
@@ -640,7 +646,7 @@ static int dbsync_get_rows(zbx_dbsync_t *sync, char **sql, size_t *sql_alloc, si
* *
******************************************************************************/
static int dbsync_read_journal(zbx_dbsync_t *sync, char **sql, size_t *sql_alloc, size_t *sql_offset,
- const char *field, const char *keyword, zbx_dbsync_journal_t *journal)
+ const char *field, const char *keyword, const char *order_field, zbx_dbsync_journal_t *journal)
{
int i, inserts_num, updates_num;
@@ -656,8 +662,8 @@ static int dbsync_read_journal(zbx_dbsync_t *sync, char **sql, size_t *sql_alloc
if (0 != journal->inserts.values_num)
{
- if (FAIL == dbsync_get_rows(sync, sql, sql_alloc, sql_offset, field, &journal->inserts,
- ZBX_DBSYNC_ROW_ADD))
+ if (FAIL == dbsync_get_rows(sync, sql, sql_alloc, sql_offset, field, order_field,
+ &journal->inserts, ZBX_DBSYNC_ROW_ADD))
{
return FAIL;
}
@@ -665,8 +671,8 @@ static int dbsync_read_journal(zbx_dbsync_t *sync, char **sql, size_t *sql_alloc
if (0 != journal->updates.values_num)
{
- if (FAIL == dbsync_get_rows(sync, sql, sql_alloc, sql_offset, field, &journal->updates,
- ZBX_DBSYNC_ROW_UPDATE))
+ if (FAIL == dbsync_get_rows(sync, sql, sql_alloc, sql_offset, field, order_field,
+ &journal->updates, ZBX_DBSYNC_ROW_UPDATE))
{
return FAIL;
}
@@ -925,11 +931,7 @@ int zbx_dbsync_compare_autoreg_psk(zbx_dbsync_t *sync)
{
unsigned char tag = ZBX_DBSYNC_ROW_NONE;
- if ('\0' == dbsync_env.cache->autoreg_psk_identity[0]) /* no autoregistration PSK in cache */
- {
- tag = ZBX_DBSYNC_ROW_ADD;
- }
- else if (FAIL == dbsync_compare_str(dbrow[0], dbsync_env.cache->autoreg_psk_identity) ||
+ if (FAIL == dbsync_compare_str(dbrow[0], dbsync_env.cache->autoreg_psk_identity) ||
FAIL == dbsync_compare_str(dbrow[1], dbsync_env.cache->autoreg_psk))
{
tag = ZBX_DBSYNC_ROW_UPDATE;
@@ -1035,7 +1037,8 @@ int zbx_dbsync_compare_hosts(zbx_dbsync_t *sync)
goto out;
}
- ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "h.hostid", "and",
+ /* sort by h.proxy_hostid to ensure that proxies are synced before hosts assigned to them */
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "h.hostid", "and", NULL,
&dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_HOST)]);
out:
zbx_free(sql);
@@ -1730,7 +1733,7 @@ int zbx_dbsync_compare_items(zbx_dbsync_t *sync)
goto out;
}
- ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "i.itemid", "and",
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "i.itemid", "and", NULL,
&dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_ITEM)]);
out:
zbx_free(sql);
@@ -1918,7 +1921,7 @@ int zbx_dbsync_compare_prototype_items(zbx_dbsync_t *sync)
goto out;
}
- ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "i.itemid", "and",
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "i.itemid", "and", NULL,
&dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_ITEM)]);
out:
zbx_free(sql);
@@ -2030,7 +2033,7 @@ int zbx_dbsync_compare_triggers(zbx_dbsync_t *sync)
goto out;
}
- ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "triggerid", "where",
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "triggerid", "where", NULL,
&dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_TRIGGER)]);
out:
zbx_free(sql);
@@ -2169,7 +2172,7 @@ int zbx_dbsync_compare_functions(zbx_dbsync_t *sync)
goto out;
}
- ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "functionid", "where",
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "functionid", "where", NULL,
&dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_FUNCTION)]);
out:
zbx_free(sql);
@@ -2598,7 +2601,7 @@ int zbx_dbsync_compare_trigger_tags(zbx_dbsync_t *sync)
goto out;
}
- ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "triggertagid", "where",
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "triggertagid", "where", NULL,
&dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_TRIGGER_TAG)]);
out:
zbx_free(sql);
@@ -2633,7 +2636,7 @@ int zbx_dbsync_compare_item_tags(zbx_dbsync_t *sync)
goto out;
}
- ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "itemtagid", "where",
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "itemtagid", "where", NULL,
&dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_ITEM_TAG)]);
out:
zbx_free(sql);
@@ -2668,7 +2671,7 @@ int zbx_dbsync_compare_host_tags(zbx_dbsync_t *sync)
goto out;
}
- ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "hosttagid", "where",
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "hosttagid", "where", NULL,
&dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_HOST_TAG)]);
out:
zbx_free(sql);
@@ -3114,7 +3117,7 @@ int zbx_dbsync_compare_item_preprocs(zbx_dbsync_t *sync)
goto out;
}
- ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "item_preprocid", "where",
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "item_preprocid", "where", NULL,
&dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_ITEM_PREPROC)]);
out:
zbx_free(sql);
@@ -3763,3 +3766,221 @@ int zbx_dbsync_compare_host_group_hosts(zbx_dbsync_t *sync)
return SUCCEED;
}
+
+/******************************************************************************
+ * *
+ * Purpose: prepare dbsync object for drules table *
+ * *
+ * Parameter: sync - [OUT] the changeset *
+ * *
+ * Return value: SUCCEED - the changeset was successfully calculated *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+int zbx_dbsync_prepare_drules(zbx_dbsync_t *sync)
+{
+ char *sql = NULL;
+ size_t sql_alloc = 0, sql_offset = 0;
+ int ret = SUCCEED;
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select druleid,proxy_hostid,delay,status from drules");
+
+ dbsync_prepare(sync, 4, NULL);
+
+ if (ZBX_DBSYNC_INIT == sync->mode)
+ {
+ if (NULL == (sync->dbresult = DBselect("%s", sql)))
+ ret = FAIL;
+ goto out;
+ }
+
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "druleid", "where", NULL,
+ &dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_DRULE)]);
+out:
+ zbx_free(sql);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: prepare dbsync object for dchecks tabkle *
+ * *
+ * Parameter: sync - [OUT] the changeset *
+ * *
+ * Return value: SUCCEED - the changeset was successfully calculated *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+int zbx_dbsync_prepare_dchecks(zbx_dbsync_t *sync)
+{
+ char *sql = NULL;
+ size_t sql_alloc = 0, sql_offset = 0;
+ int ret = SUCCEED;
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select dcheckid,druleid from dchecks");
+
+ dbsync_prepare(sync, 2, NULL);
+
+ if (ZBX_DBSYNC_INIT == sync->mode)
+ {
+ if (NULL == (sync->dbresult = DBselect("%s", sql)))
+ ret = FAIL;
+ goto out;
+ }
+
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "dcheckid", "where", NULL,
+ &dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_DCHECK)]);
+out:
+ zbx_free(sql);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: prepare dbsync object for httptest table *
+ * *
+ * Parameter: sync - [OUT] the changeset *
+ * *
+ * Return value: SUCCEED - the changeset was successfully calculated *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+int zbx_dbsync_prepare_httptests(zbx_dbsync_t *sync)
+{
+ char *sql = NULL;
+ size_t sql_alloc = 0, sql_offset = 0;
+ int ret = SUCCEED;
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select httptestid,hostid,delay,status from httptest");
+
+ dbsync_prepare(sync, 4, NULL);
+
+ if (ZBX_DBSYNC_INIT == sync->mode)
+ {
+ if (NULL == (sync->dbresult = DBselect("%s", sql)))
+ ret = FAIL;
+ goto out;
+ }
+
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "httptestid", "where", NULL,
+ &dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_HTTPTEST)]);
+out:
+ zbx_free(sql);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: prepare dbsync object for httptest_field table *
+ * *
+ * Parameter: sync - [OUT] the changeset *
+ * *
+ * Return value: SUCCEED - the changeset was successfully calculated *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+int zbx_dbsync_prepare_httptest_fields(zbx_dbsync_t *sync)
+{
+ char *sql = NULL;
+ size_t sql_alloc = 0, sql_offset = 0;
+ int ret = SUCCEED;
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select httptest_fieldid,httptestid from httptest_field");
+
+ dbsync_prepare(sync, 2, NULL);
+
+ if (ZBX_DBSYNC_INIT == sync->mode)
+ {
+ if (NULL == (sync->dbresult = DBselect("%s", sql)))
+ ret = FAIL;
+ goto out;
+ }
+
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "httptest_fieldid", "where", NULL,
+ &dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_HTTPTEST_FIELD)]);
+out:
+ zbx_free(sql);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: prepare dbsync object for httpstep table *
+ * *
+ * Parameter: sync - [OUT] the changeset *
+ * *
+ * Return value: SUCCEED - the changeset was successfully calculated *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+int zbx_dbsync_prepare_httpsteps(zbx_dbsync_t *sync)
+{
+ char *sql = NULL;
+ size_t sql_alloc = 0, sql_offset = 0;
+ int ret = SUCCEED;
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select httpstepid,httptestid from httpstep");
+ dbsync_prepare(sync, 2, NULL);
+
+ if (ZBX_DBSYNC_INIT == sync->mode)
+ {
+ if (NULL == (sync->dbresult = DBselect("%s", sql)))
+ ret = FAIL;
+ goto out;
+ }
+
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "httpstepid", "where", NULL,
+ &dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_HTTPSTEP)]);
+out:
+ zbx_free(sql);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: prepare dbsync object for httpstep_field table *
+ * *
+ * Parameter: sync - [OUT] the changeset *
+ * *
+ * Return value: SUCCEED - the changeset was successfully calculated *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+int zbx_dbsync_prepare_httpstep_fields(zbx_dbsync_t *sync)
+{
+ char *sql = NULL;
+ size_t sql_alloc = 0, sql_offset = 0;
+ int ret = SUCCEED;
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select httpstep_fieldid,httpstepid from httpstep_field");
+ dbsync_prepare(sync, 2, NULL);
+
+ if (ZBX_DBSYNC_INIT == sync->mode)
+ {
+ if (NULL == (sync->dbresult = DBselect("%s", sql)))
+ ret = FAIL;
+ goto out;
+ }
+
+ ret = dbsync_read_journal(sync, &sql, &sql_alloc, &sql_offset, "httpstep_fieldid", "where", NULL,
+ &dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_HTTPSTEP_FIELD)]);
+out:
+ zbx_free(sql);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: remove deleted hosts/templates from user macro cache *
+ * *
+ ******************************************************************************/
+void zbx_dbsync_clear_user_macros(void)
+{
+ um_cache_remove_hosts(config->um_cache, &dbsync_env.journals[ZBX_DBSYNC_JOURNAL(ZBX_DBSYNC_OBJ_HOST)].deletes);
+}
diff --git a/src/libs/zbxdbcache/dbsync.h b/src/libs/zbxdbcache/dbsync.h
index a1fd8d529ca..d92abd060cb 100644
--- a/src/libs/zbxdbcache/dbsync.h
+++ b/src/libs/zbxdbcache/dbsync.h
@@ -154,4 +154,14 @@ int zbx_dbsync_compare_maintenance_groups(zbx_dbsync_t *sync);
int zbx_dbsync_compare_maintenance_hosts(zbx_dbsync_t *sync);
int zbx_dbsync_compare_host_group_hosts(zbx_dbsync_t *sync);
+int zbx_dbsync_prepare_drules(zbx_dbsync_t *sync);
+int zbx_dbsync_prepare_dchecks(zbx_dbsync_t *sync);
+
+int zbx_dbsync_prepare_httptests(zbx_dbsync_t *sync);
+int zbx_dbsync_prepare_httptest_fields(zbx_dbsync_t *sync);
+int zbx_dbsync_prepare_httpsteps(zbx_dbsync_t *sync);
+int zbx_dbsync_prepare_httpstep_fields(zbx_dbsync_t *sync);
+void zbx_dbsync_clear_user_macros(void);
+
+
#endif /* BUILD_SRC_LIBS_ZBXDBCACHE_DBSYNC_H_ */
diff --git a/src/libs/zbxdbcache/user_macro.c b/src/libs/zbxdbcache/user_macro.c
index ae2cc7a4e05..1a51243910e 100644
--- a/src/libs/zbxdbcache/user_macro.c
+++ b/src/libs/zbxdbcache/user_macro.c
@@ -36,6 +36,13 @@ ZBX_PTR_VECTOR_IMPL(um_host, zbx_um_host_t *)
extern char *CONFIG_VAULTDBPATH;
extern unsigned char program_type;
+typedef enum
+{
+ ZBX_UM_UPDATE_HOST,
+ ZBX_UM_UPDATE_MACRO
+}
+zbx_um_update_cause_t;
+
/*********************************************************************************
* *
* Purpose: create duplicate user macro cache *
@@ -76,7 +83,7 @@ static int um_macro_compare_by_name_context(const void *d1, const void *d2)
if (0 != (ret = strcmp(m1->name, m2->name)))
return ret;
- /* CONDITION_OPERATOR_EQUAL (0) has higher priority than CONDITION_OPERATOR_REGEXP (8) */
+ /* ZBX_CONDITION_OPERATOR_EQUAL (0) has higher priority than ZBX_CONDITION_OPERATOR_REGEXP (8) */
ZBX_RETURN_IF_NOT_EQUAL(m1->context_op, m2->context_op);
return zbx_strcmp_null(m1->context, m2->context);
@@ -132,7 +139,7 @@ zbx_um_cache_t *um_cache_create(void)
cache = (zbx_um_cache_t *)__config_shmem_malloc_func(NULL, sizeof(zbx_um_cache_t));
cache->refcount = 1;
cache->revision = 0;
- zbx_hashset_create_ext(&cache->hosts, 10, um_host_hash, um_host_compare,NULL,
+ zbx_hashset_create_ext(&cache->hosts, 10, um_host_hash, um_host_compare, NULL,
__config_shmem_malloc_func, __config_shmem_realloc_func, __config_shmem_free_func);
return cache;
@@ -235,6 +242,8 @@ static zbx_um_host_t *um_host_dup(zbx_um_host_t *host)
dup = (zbx_um_host_t *)__config_shmem_malloc_func(NULL, sizeof(zbx_um_host_t));
dup->hostid = host->hostid;
dup->refcount = 1;
+ dup->macro_revision = host->macro_revision;
+ dup->link_revision = host->link_revision;
zbx_vector_uint64_create_ext(&dup->templateids, __config_shmem_malloc_func, __config_shmem_realloc_func,
__config_shmem_free_func);
@@ -293,7 +302,8 @@ static zbx_um_host_t *um_cache_create_host(zbx_um_cache_t *cache, zbx_uint64_t h
host = (zbx_um_host_t *)__config_shmem_malloc_func(NULL, sizeof(zbx_um_host_t));
host->hostid = hostid;
host->refcount = 1;
- host->revision = cache->revision;
+ host->macro_revision = cache->revision;
+ host->link_revision = cache->revision;
zbx_vector_uint64_create_ext(&host->templateids, __config_shmem_malloc_func, __config_shmem_realloc_func,
__config_shmem_free_func);
zbx_vector_um_macro_create_ext(&host->macros, __config_shmem_malloc_func, __config_shmem_realloc_func,
@@ -311,7 +321,8 @@ static zbx_um_host_t *um_cache_create_host(zbx_um_cache_t *cache, zbx_uint64_t h
* Comments: If the host is used by other processes it will be duplicated. *
* *
*********************************************************************************/
-static zbx_um_host_t *um_cache_acquire_host(zbx_um_cache_t *cache, zbx_uint64_t hostid)
+static zbx_um_host_t *um_cache_acquire_host(zbx_um_cache_t *cache, zbx_uint64_t hostid,
+ zbx_um_update_cause_t cause)
{
zbx_uint64_t *phostid = &hostid;
zbx_um_host_t **phost;
@@ -326,9 +337,18 @@ static zbx_um_host_t *um_cache_acquire_host(zbx_um_cache_t *cache, zbx_uint64_t
/* hosts are acquired when there are changes to be made, */
/* meaning host revision must be updated */
- (*phost)->revision = cache->revision;
+ switch (cause)
+ {
+ case ZBX_UM_UPDATE_HOST:
+ (*phost)->link_revision = cache->revision;
+ break;
+ case ZBX_UM_UPDATE_MACRO:
+ (*phost)->macro_revision = cache->revision;
+ break;
+ }
return *phost;
+
}
return NULL;
@@ -419,6 +439,10 @@ static void um_macro_kv_remove(zbx_um_macro_t *macro, zbx_dc_macro_kv_t *mkv)
if (0 == mkv->kv->macros.values_num)
{
zbx_vector_uint64_pair_destroy(&mkv->kv->macros);
+ dc_strpool_release(mkv->kv->key);
+ if (NULL != mkv->kv->value)
+ dc_strpool_release(mkv->kv->value);
+
zbx_hashset_remove_direct(&mkv->kv_path->kvs, mkv->kv);
if (0 == mkv->kv_path->kvs.num_data)
dc_kvs_path_remove(mkv->kv_path);
@@ -646,7 +670,7 @@ static void um_cache_sync_macros(zbx_um_cache_t *cache, zbx_dbsync_t *sync, int
if (NULL != (pmacro = (zbx_um_macro_t **)zbx_hashset_search(user_macros, &pmacroid)))
{
- host = um_cache_acquire_host(cache, (*pmacro)->hostid);
+ host = um_cache_acquire_host(cache, (*pmacro)->hostid, ZBX_UM_UPDATE_MACRO);
if (SUCCEED == um_macro_is_locked(*pmacro))
{
@@ -671,7 +695,7 @@ static void um_cache_sync_macros(zbx_um_cache_t *cache, zbx_dbsync_t *sync, int
}
/* acquire new host */
- host = um_cache_acquire_host(cache, hostid);
+ host = um_cache_acquire_host(cache, hostid, ZBX_UM_UPDATE_MACRO);
}
dc_strpool_release((*pmacro)->name);
@@ -698,7 +722,7 @@ static void um_cache_sync_macros(zbx_um_cache_t *cache, zbx_dbsync_t *sync, int
macro->value = NULL;
pmacro = zbx_hashset_insert(user_macros, &macro, sizeof(macro));
- host = um_cache_acquire_host(cache, hostid);
+ host = um_cache_acquire_host(cache, hostid, ZBX_UM_UPDATE_MACRO);
}
(*pmacro)->hostid = hostid;
@@ -734,7 +758,7 @@ static void um_cache_sync_macros(zbx_um_cache_t *cache, zbx_dbsync_t *sync, int
if (ZBX_MACRO_VALUE_VAULT == (*pmacro)->type)
um_macro_deregister_kvs(*pmacro);
- if (NULL != (host = um_cache_acquire_host(cache, (*pmacro)->hostid)))
+ if (NULL != (host = um_cache_acquire_host(cache, (*pmacro)->hostid, ZBX_UM_UPDATE_MACRO)))
{
um_host_remove_macro(host, *pmacro);
zbx_vector_um_host_append(&hosts, host);
@@ -752,18 +776,10 @@ static void um_cache_sync_macros(zbx_um_cache_t *cache, zbx_dbsync_t *sync, int
{
if (0 == hosts.values[i]->macros.values_num)
{
- if (0 == hosts.values[i]->templateids.values_num)
- {
- zbx_hashset_remove(&cache->hosts, &hosts.values[i]);
- um_host_release(hosts.values[i]);
- }
- else
- {
- /* recreate empty-macros vector to release memory */
- zbx_vector_um_macro_destroy(&hosts.values[i]->macros);
- zbx_vector_um_macro_create_ext(&hosts.values[i]->macros, __config_shmem_malloc_func,
- __config_shmem_realloc_func, __config_shmem_free_func);
- }
+ /* recreate empty-macros vector to release memory */
+ zbx_vector_um_macro_destroy(&hosts.values[i]->macros);
+ zbx_vector_um_macro_create_ext(&hosts.values[i]->macros, __config_shmem_malloc_func,
+ __config_shmem_realloc_func, __config_shmem_free_func);
}
else
zbx_vector_um_macro_sort(&hosts.values[i]->macros, um_macro_compare_by_name_context);
@@ -793,7 +809,7 @@ static void um_cache_sync_hosts(zbx_um_cache_t *cache, zbx_dbsync_t *sync)
ZBX_STR2UINT64(hostid, row[0]);
- if (NULL == (host = um_cache_acquire_host(cache, hostid)))
+ if (NULL == (host = um_cache_acquire_host(cache, hostid, ZBX_UM_UPDATE_HOST)))
host = um_cache_create_host(cache, hostid);
ZBX_DBROW2UINT64(templateid, row[1]);
@@ -807,7 +823,7 @@ static void um_cache_sync_hosts(zbx_um_cache_t *cache, zbx_dbsync_t *sync)
ZBX_STR2UINT64(hostid, row[0]);
- if (NULL == (host = um_cache_acquire_host(cache, hostid)))
+ if (NULL == (host = um_cache_acquire_host(cache, hostid, ZBX_UM_UPDATE_HOST)))
continue;
ZBX_DBROW2UINT64(templateid, row[1]);
@@ -819,18 +835,9 @@ static void um_cache_sync_hosts(zbx_um_cache_t *cache, zbx_dbsync_t *sync)
zbx_vector_uint64_remove_noorder(&host->templateids, i);
if (0 == host->templateids.values_num)
{
- if (0 == host->macros.values_num)
- {
- zbx_hashset_remove(&cache->hosts, &host);
- um_host_release(host);
- }
- else
- {
- zbx_vector_uint64_destroy(&host->templateids);
- zbx_vector_uint64_create_ext(&host->templateids,
- __config_shmem_malloc_func, __config_shmem_realloc_func,
- __config_shmem_free_func);
- }
+ zbx_vector_uint64_destroy(&host->templateids);
+ zbx_vector_uint64_create_ext(&host->templateids, __config_shmem_malloc_func,
+ __config_shmem_realloc_func, __config_shmem_free_func);
}
break;
}
@@ -843,7 +850,7 @@ static void um_cache_sync_hosts(zbx_um_cache_t *cache, zbx_dbsync_t *sync)
* Purpose: sync user macro cache *
* *
*********************************************************************************/
-zbx_um_cache_t *um_cache_sync(zbx_um_cache_t *cache, zbx_uint32_t revision, zbx_dbsync_t *gmacros,
+zbx_um_cache_t *um_cache_sync(zbx_um_cache_t *cache, zbx_uint64_t revision, zbx_dbsync_t *gmacros,
zbx_dbsync_t *hmacros, zbx_dbsync_t *htmpls)
{
if (ZBX_DBSYNC_INIT != gmacros->mode && ZBX_DBSYNC_INIT != hmacros->mode && ZBX_DBSYNC_INIT != htmpls->mode &&
@@ -888,11 +895,11 @@ static int um_macro_match(const zbx_um_macro_t *macro, const char *name, const c
{
switch (macro->context_op)
{
- case CONDITION_OPERATOR_EQUAL:
+ case ZBX_CONDITION_OPERATOR_EQUAL:
if (0 == strcmp(macro->context, context))
return ZBX_UM_MATCH_FULL;
break;
- case CONDITION_OPERATOR_REGEXP:
+ case ZBX_CONDITION_OPERATOR_REGEXP:
if (NULL != zbx_regexp_match(context, macro->context, NULL))
return ZBX_UM_MATCH_FULL;
break;
@@ -1125,11 +1132,12 @@ void um_cache_resolve(const zbx_um_cache_t *cache, const zbx_uint64_t *hostids,
* Purpose: set value to the specified macros *
* *
* Parameters: cache - [IN] the user macro cache *
+ * revision - [IN] the configuration revision *
* host_macro_ids - [IN] a vector of hostid,macroid pairs *
* value - [IN] the new value (stored in string pool) *
* *
*********************************************************************************/
-zbx_um_cache_t *um_cache_set_value_to_macros(zbx_um_cache_t *cache, zbx_uint32_t revision,
+zbx_um_cache_t *um_cache_set_value_to_macros(zbx_um_cache_t *cache, zbx_uint64_t revision,
const zbx_vector_uint64_pair_t *host_macro_ids, const char *value)
{
int i;
@@ -1156,7 +1164,7 @@ zbx_um_cache_t *um_cache_set_value_to_macros(zbx_um_cache_t *cache, zbx_uint32_t
if (NULL == (pmacro = (zbx_um_macro_t **)zbx_hashset_search(user_macros, &pmacroid)))
continue;
- if (NULL == (host = um_cache_acquire_host(cache, (*pmacro)->hostid)))
+ if (NULL == (host = um_cache_acquire_host(cache, (*pmacro)->hostid, ZBX_UM_UPDATE_MACRO)))
continue;
if (SUCCEED == um_macro_is_locked(*pmacro))
@@ -1195,16 +1203,17 @@ void um_cache_dump(zbx_um_cache_t *cache)
zbx_vector_uint64_t ids;
int i;
- zabbix_log(LOG_LEVEL_TRACE, "In %s() hosts:%d refcount:%u revision:%u", __func__, cache->hosts.num_data,
- cache->refcount, cache->revision);
+ zabbix_log(LOG_LEVEL_TRACE, "In %s() hosts:%d refcount:%u revision:" ZBX_FS_UI64, __func__,
+ cache->hosts.num_data, cache->refcount, cache->revision);
zbx_vector_uint64_create(&ids);
zbx_hashset_iter_reset(&cache->hosts, &iter);
while (NULL != (phost = (zbx_um_host_t **)zbx_hashset_iter_next(&iter)))
{
- zabbix_log(LOG_LEVEL_TRACE, "hostid:" ZBX_FS_UI64 " refcount:%u revision:%u", (*phost)->hostid,
- (*phost)->refcount, (*phost)->revision);
+ zabbix_log(LOG_LEVEL_TRACE, "hostid:" ZBX_FS_UI64 " refcount:%u link_revision:" ZBX_FS_UI64
+ " macro_revision:" ZBX_FS_UI64, (*phost)->hostid,
+ (*phost)->refcount, (*phost)->link_revision, (*phost)->macro_revision);
zabbix_log(LOG_LEVEL_TRACE, " macros:");
@@ -1250,7 +1259,7 @@ void um_cache_dump(zbx_um_cache_t *cache)
zabbix_log(LOG_LEVEL_TRACE, "End of %s()", __func__);
}
-int um_cache_get_host_revision(const zbx_um_cache_t *cache, zbx_uint64_t hostid, zbx_uint32_t *revision)
+int um_cache_get_host_revision(const zbx_um_cache_t *cache, zbx_uint64_t hostid, zbx_uint64_t *revision)
{
const zbx_um_host_t * const *phost;
int i;
@@ -1259,11 +1268,156 @@ int um_cache_get_host_revision(const zbx_um_cache_t *cache, zbx_uint64_t hostid,
if (NULL == (phost = (const zbx_um_host_t * const *)zbx_hashset_search(&cache->hosts, &phostid)))
return FAIL;
- if ((*phost)->revision > *revision)
- *revision = (*phost)->revision;
+ if ((*phost)->macro_revision > *revision)
+ *revision = (*phost)->macro_revision;
for (i = 0; i < (*phost)->templateids.values_num; i++)
um_cache_get_host_revision(cache, (*phost)->templateids.values[i], revision);
return SUCCEED;
}
+
+static void um_cache_get_hosts(const zbx_um_cache_t *cache, const zbx_uint64_t *phostid, zbx_uint64_t revision,
+ zbx_vector_um_host_t *hosts)
+{
+ zbx_um_host_t **phost;
+ int i;
+
+ if (NULL == (phost = (zbx_um_host_t **)zbx_hashset_search(&cache->hosts, &phostid)))
+ return;
+
+ /* if host-template linking has changed, force macro update for all children */
+ if ((*phost)->link_revision > revision)
+ revision = 0;
+
+ if ((*phost)->macro_revision > revision || (*phost)->link_revision > revision)
+ zbx_vector_um_host_append(hosts, *phost);
+
+ for (i = 0; i < (*phost)->templateids.values_num; i++)
+ um_cache_get_hosts(cache, &(*phost)->templateids.values[i], revision, hosts);
+}
+
+/*********************************************************************************
+ * *
+ * Purpose: get identifiers of user macro host objects that were updated since *
+ * the specified revision *
+ * *
+ * Parameters: cache - [IN] the user macro cache *
+ * hostids - [IN] identifiers of the hosts to check *
+ * hostids_num - [IN] the number of hosts to check *
+ * revision - [IN] the revision *
+ * macro_hostids - [OUT] the identifiers of updated host objects *
+ * del_macro_hostids - [OUT] the identifiers of cleared host objects *
+ * (without macros or linked templates), *
+ * optional *
+ * *
+ *********************************************************************************/
+void um_cache_get_macro_updates(const zbx_um_cache_t *cache, const zbx_uint64_t *hostids, int hostids_num,
+ zbx_uint64_t revision, zbx_vector_uint64_t *macro_hostids, zbx_vector_uint64_t *del_macro_hostids)
+{
+ int i;
+ zbx_vector_um_host_t hosts;
+
+ zbx_vector_um_host_create(&hosts);
+
+ for (i = 0; i < hostids_num; i++)
+ um_cache_get_hosts(cache, &hostids[i], revision, &hosts);
+
+ if (0 != hosts.values_num)
+ {
+ zbx_vector_um_host_sort(&hosts, ZBX_DEFAULT_PTR_COMPARE_FUNC);
+ zbx_vector_um_host_uniq(&hosts, ZBX_DEFAULT_PTR_COMPARE_FUNC);
+
+ for (i = 0; i < hosts.values_num; i++)
+ {
+ if (0 != hosts.values[i]->macros.values_num || 0 != hosts.values[i]->templateids.values_num)
+ zbx_vector_uint64_append(macro_hostids, hosts.values[i]->hostid);
+ else
+ zbx_vector_uint64_append(del_macro_hostids, hosts.values[i]->hostid);
+ }
+ }
+
+ zbx_vector_um_host_destroy(&hosts);
+}
+
+/*********************************************************************************
+ * *
+ * Purpose: recursively remove templates linked to the hostid from unused_hosts *
+ * the specified revision *
+ * *
+ * Parameters: cache - [IN] the user macro cache *
+ * hostid - [IN] the parent hostid *
+ * templates - [IN/OUT] the leftover (not linked to hosts) *
+ * templates *
+ * *
+ *********************************************************************************/
+static void um_cache_check_used_templates(const zbx_um_cache_t *cache, zbx_uint64_t hostid,
+ zbx_hashset_t *templates)
+{
+ void *data;
+ zbx_um_host_t **phost;
+ zbx_uint64_t *phostid = &hostid;
+ int i;
+
+ if (NULL != (data = zbx_hashset_search(templates, &hostid)))
+ zbx_hashset_remove_direct(templates, data);
+
+ if (NULL == (phost = (zbx_um_host_t **)zbx_hashset_search(&cache->hosts, &phostid)))
+ return;
+
+ for (i = 0; i < (*phost)->templateids.values_num; i++)
+ um_cache_check_used_templates(cache, (*phost)->templateids.values[i], templates);
+}
+
+/*********************************************************************************
+ * *
+ * Purpose: get identifiers of templates not linked to the specified hosts *
+ * neither directly nor through other templates *
+ * *
+ * Parameters: cache - [IN] the user macro cache *
+ * templates - [IN] the database templates *
+ * hostids - [IN] the database hosts *
+ * templateids - [IN/OUT] the templates not linked to any host *
+ * neither directly nor through other *
+ * templates *
+ * *
+ *********************************************************************************/
+void um_cache_get_unused_templates(zbx_um_cache_t *cache, zbx_hashset_t *templates,
+ const zbx_vector_uint64_t *hostids, zbx_vector_uint64_t *templateids)
+{
+ zbx_hashset_iter_t iter;
+ int i;
+ zbx_uint64_t *phostid;
+
+ for (i = 0; i < hostids->values_num; i++)
+ um_cache_check_used_templates(cache, hostids->values[i], templates);
+
+ zbx_hashset_iter_reset(templates, &iter);
+ while (NULL != (phostid = (zbx_uint64_t *)zbx_hashset_iter_next(&iter)))
+ zbx_vector_uint64_append(templateids, *phostid);
+}
+
+/*********************************************************************************
+ * *
+ * Purpose: remove deleted hosts/templates from user macro cache *
+ * *
+ * Parameters: cache - [IN] the user macro cache *
+ * hostids - [IN] the deleted host/template identifiers *
+ * *
+ *********************************************************************************/
+void um_cache_remove_hosts(zbx_um_cache_t *cache, const zbx_vector_uint64_t *hostids)
+{
+ zbx_um_host_t **phost;
+ int i;
+
+ for (i = 0; i < hostids->values_num; i++)
+ {
+ zbx_uint64_t *phostid = &hostids->values[i];
+
+ if (NULL != (phost = (zbx_um_host_t **)zbx_hashset_search(&cache->hosts, &phostid)))
+ {
+ zbx_hashset_remove_direct(&cache->hosts, phost);
+ um_host_release(*phost);
+ }
+ }
+}
diff --git a/src/libs/zbxdbcache/user_macro.h b/src/libs/zbxdbcache/user_macro.h
index b3b288958a0..3ec3defaf07 100644
--- a/src/libs/zbxdbcache/user_macro.h
+++ b/src/libs/zbxdbcache/user_macro.h
@@ -46,7 +46,8 @@ typedef struct
zbx_vector_uint64_t templateids;
zbx_vector_um_macro_t macros;
zbx_uint32_t refcount;
- zbx_uint32_t revision;
+ zbx_uint64_t macro_revision;
+ zbx_uint64_t link_revision;
}
zbx_um_host_t;
@@ -56,7 +57,7 @@ typedef struct
{
zbx_hashset_t hosts;
zbx_uint32_t refcount;
- zbx_uint32_t revision;
+ zbx_uint64_t revision;
}
zbx_um_cache_t;
@@ -67,7 +68,7 @@ zbx_um_cache_t *um_cache_create(void);
void um_cache_release(zbx_um_cache_t *cache);
void um_macro_release(zbx_um_macro_t *macro);
-zbx_um_cache_t *um_cache_set_value_to_macros(zbx_um_cache_t *cache, zbx_uint32_t revision,
+zbx_um_cache_t *um_cache_set_value_to_macros(zbx_um_cache_t *cache, zbx_uint64_t revision,
const zbx_vector_uint64_pair_t *host_macro_ids, const char *value);
int um_macro_check_vault_location(const zbx_um_macro_t *macro, const char *location);
@@ -76,7 +77,13 @@ void um_cache_resolve_const(const zbx_um_cache_t *cache, const zbx_uint64_t *hos
const char *macro, int env, const char **value);
void um_cache_resolve(const zbx_um_cache_t *cache, const zbx_uint64_t *hostids, int hostids_num, const char *macro,
int env, char **value);
-int um_cache_get_host_revision(const zbx_um_cache_t *cache, zbx_uint64_t hostid, zbx_uint32_t *revision);
+int um_cache_get_host_revision(const zbx_um_cache_t *cache, zbx_uint64_t hostid, zbx_uint64_t *revision);
+void um_cache_get_macro_updates(const zbx_um_cache_t *cache, const zbx_uint64_t *hostids, int hostids_num,
+ zbx_uint64_t revision, zbx_vector_uint64_t *macro_hostids, zbx_vector_uint64_t *del_macro_hostids);
+
+void um_cache_get_unused_templates(zbx_um_cache_t *cache, zbx_hashset_t *templates,
+ const zbx_vector_uint64_t *hostids, zbx_vector_uint64_t *templateids);
+void um_cache_remove_hosts(zbx_um_cache_t *cache, const zbx_vector_uint64_t *hostids);
void um_cache_dump(zbx_um_cache_t *cache);
diff --git a/src/libs/zbxdbcache/valuecache.c b/src/libs/zbxdbcache/valuecache.c
index d2d2e0bb587..d6bbe498676 100644
--- a/src/libs/zbxdbcache/valuecache.c
+++ b/src/libs/zbxdbcache/valuecache.c
@@ -285,7 +285,7 @@ static void vc_history_record_vector_clean(zbx_vector_history_record_t *vector,
static size_t vch_item_free_cache(zbx_vc_item_t *item);
static size_t vch_item_free_chunk(zbx_vc_item_t *item, zbx_vc_chunk_t *chunk);
static int vch_item_add_values_at_tail(zbx_vc_item_t *item, const zbx_history_record_t *values, int values_num);
-static void vch_item_clean_cache(zbx_vc_item_t *item);
+static void vch_item_clean_cache(zbx_vc_item_t *item, int timestamp);
/*********************************************************************************
* *
@@ -541,12 +541,12 @@ static int vc_db_get_values(zbx_uint64_t itemid, int value_type, zbx_vector_hist
static zbx_hash_t vc_strpool_hash_func(const void *data)
{
- return ZBX_DEFAULT_STRING_HASH_FUNC((char *)data + REFCOUNT_FIELD_SIZE);
+ return ZBX_DEFAULT_STRING_HASH_FUNC((const char *)data + REFCOUNT_FIELD_SIZE);
}
static int vc_strpool_compare_func(const void *d1, const void *d2)
{
- return strcmp((char *)d1 + REFCOUNT_FIELD_SIZE, (char *)d2 + REFCOUNT_FIELD_SIZE);
+ return strcmp((const char *)d1 + REFCOUNT_FIELD_SIZE, (const char *)d2 + REFCOUNT_FIELD_SIZE);
}
/******************************************************************************
@@ -649,7 +649,7 @@ static void vc_update_statistics(zbx_vc_item_t *item, int hits, int misses, int
{
int hour;
- item->hits += hits;
+ item->hits += (zbx_uint64_t)hits;
item->last_accessed = now;
hour = item->last_accessed / SEC_PER_HOUR;
@@ -666,8 +666,8 @@ static void vc_update_statistics(zbx_vc_item_t *item, int hits, int misses, int
if (ZBX_VC_ENABLED == vc_state)
{
- vc_cache->hits += hits;
- vc_cache->misses += misses;
+ vc_cache->hits += (zbx_uint64_t)hits;
+ vc_cache->misses += (zbx_uint64_t)misses;
}
}
@@ -678,8 +678,8 @@ static void vc_update_statistics(zbx_vc_item_t *item, int hits, int misses, int
******************************************************************************/
static int vc_compare_items_by_total_values(const void *d1, const void *d2)
{
- zbx_vc_item_t *c1 = *(zbx_vc_item_t **)d1;
- zbx_vc_item_t *c2 = *(zbx_vc_item_t **)d2;
+ const zbx_vc_item_t *c1 = *(const zbx_vc_item_t * const *)d1;
+ const zbx_vc_item_t *c2 = *(const zbx_vc_item_t * const *)d2;
ZBX_RETURN_IF_NOT_EQUAL(c2->values_total, c1->values_total);
@@ -738,7 +738,7 @@ static void vc_warn_low_memory(void)
{
int now;
- now = time(NULL);
+ now = (int)time(NULL);
if (now - vc_cache->mode_time > ZBX_VC_LOW_MEMORY_RESET_PERIOD)
{
@@ -779,7 +779,7 @@ static size_t vc_release_unused_items(const zbx_vc_item_t *source_item)
if (NULL == vc_cache)
return freed;
- timestamp = time(NULL) - ZBX_VC_ITEM_EXPIRE_PERIOD;
+ timestamp = (int)time(NULL) - ZBX_VC_ITEM_EXPIRE_PERIOD;
zbx_hashset_iter_reset(&vc_cache->items, &iter);
@@ -797,25 +797,6 @@ static size_t vc_release_unused_items(const zbx_vc_item_t *source_item)
/******************************************************************************
* *
- * Purpose: release unused items from value cache *
- * *
- * Comments: If unused items are not cleared from value cache periodically *
- * then they will only be cleared when value cache is full, see *
- * vc_release_space(). *
- * *
- ******************************************************************************/
-void zbx_vc_housekeeping_value_cache(void)
-{
- if (ZBX_VC_DISABLED == vc_state)
- return;
-
- WRLOCK_CACHE;
- vc_release_unused_items(NULL);
- UNLOCK_CACHE;
-}
-
-/******************************************************************************
- * *
* Purpose: frees space in cache to store the specified number of bytes by *
* dropping the least accessed items *
* *
@@ -847,7 +828,7 @@ static void vc_release_space(zbx_vc_item_t *source_item, size_t space)
/* failed to free enough space by removing old items, entering low memory mode */
vc_cache->mode = ZBX_VC_MODE_LOWMEM;
- vc_cache->mode_time = time(NULL);
+ vc_cache->mode_time = (int)time(NULL);
vc_warn_low_memory();
@@ -1189,6 +1170,36 @@ static void vc_remove_item_by_id(zbx_uint64_t itemid)
vch_item_free_cache(item);
zbx_hashset_remove_direct(&vc_cache->items, item);
}
+
+/******************************************************************************
+ * *
+ * Purpose: removes items from cache and frees resources allocated for them *
+ * *
+ * Parameters: itemids - [IN] the item identifiers *
+ * *
+ * Comments: If unused items are not cleared from value cache periodically *
+ * then they will only be cleared when value cache is full, see *
+ * vc_release_space(). Cleared items can be cached again. *
+ * *
+ ******************************************************************************/
+void zbx_vc_remove_items_by_ids(zbx_vector_uint64_t *itemids)
+{
+ int i;
+
+ if (ZBX_VC_DISABLED == vc_state)
+ return;
+
+ if (0 == itemids->values_num)
+ return;
+
+ WRLOCK_CACHE;
+
+ for (i = 0; i < itemids->values_num; i++)
+ vc_remove_item_by_id(itemids->values[i]);
+
+ UNLOCK_CACHE;
+}
+
/******************************************************************************
* *
* Purpose: updates the timestamp from which the item is being cached *
@@ -1256,7 +1267,8 @@ static void vc_item_update_db_cached_from(zbx_vc_item_t *item, int timestamp)
******************************************************************************/
static void vch_item_update_range(zbx_vc_item_t *item, int range, int now)
{
- int hour, diff;
+ int diff, last_value_timestamp;
+ unsigned char hour;
if (VC_MIN_RANGE > range)
range = VC_MIN_RANGE;
@@ -1264,12 +1276,18 @@ static void vch_item_update_range(zbx_vc_item_t *item, int range, int now)
if (item->daily_range < range)
item->daily_range = range;
- hour = (now / SEC_PER_HOUR) & 0xff;
+ hour = (unsigned char)((now / SEC_PER_HOUR) & 0xff);
if (0 > (diff = hour - item->range_sync_hour))
diff += 0xff;
- if (item->active_range < item->daily_range || ZBX_VC_RANGE_SYNC_PERIOD < diff)
+ if (NULL != item->head)
+ last_value_timestamp = item->head->slots[item->head->last_value].timestamp.sec;
+ else
+ last_value_timestamp = now;
+
+ if (item->active_range < item->daily_range || (ZBX_VC_RANGE_SYNC_PERIOD < diff &&
+ (now - last_value_timestamp) / SEC_PER_HOUR < ZBX_VC_RANGE_SYNC_PERIOD))
{
item->active_range = item->daily_range;
item->daily_range = range;
@@ -1299,7 +1317,7 @@ static int vch_item_chunk_slot_count(zbx_vc_item_t *item, int values_new)
values = item->values_total + values_new;
- nslots = zbx_isqrt32(values);
+ nslots = (int)zbx_isqrt32((unsigned int)values);
if ((values + nslots - 1) / nslots + 1 > 32)
nslots = values / 32;
@@ -1330,9 +1348,9 @@ static int vch_item_chunk_slot_count(zbx_vc_item_t *item, int values_new)
static int vch_item_add_chunk(zbx_vc_item_t *item, int nslots, zbx_vc_chunk_t *insert_before)
{
zbx_vc_chunk_t *chunk;
- int chunk_size;
+ size_t chunk_size;
- chunk_size = sizeof(zbx_vc_chunk_t) + sizeof(zbx_history_record_t) * (nslots - 1);
+ chunk_size =sizeof(zbx_vc_chunk_t) + sizeof(zbx_history_record_t) * (size_t)(nslots - 1);
if (NULL == (chunk = (zbx_vc_chunk_t *)vc_item_malloc(item, chunk_size)))
return FAIL;
@@ -1562,7 +1580,7 @@ static int vch_item_copy_values_at_tail(zbx_vc_item_t *item, const zbx_history_r
break;
default:
memcpy(&item->tail->slots[item->tail->first_value - values_num], values,
- values_num * sizeof(zbx_history_record_t));
+ (size_t)values_num * sizeof(zbx_history_record_t));
item->tail->first_value -= values_num;
ret = SUCCEED;
}
@@ -1586,7 +1604,7 @@ static size_t vch_item_free_chunk(zbx_vc_item_t *item, zbx_vc_chunk_t *chunk)
{
size_t freed;
- freed = sizeof(zbx_vc_chunk_t) + (chunk->slots_num - 1) * sizeof(zbx_history_record_t);
+ freed = sizeof(zbx_vc_chunk_t) + (size_t)(chunk->slots_num - 1) * sizeof(zbx_history_record_t);
freed += vc_item_free_values(item, chunk->slots, chunk->first_value, chunk->last_value);
__vc_shmem_free_func(chunk);
@@ -1624,10 +1642,11 @@ static void vch_item_remove_chunk(zbx_vc_item_t *item, zbx_vc_chunk_t *chunk)
* Purpose: removes item history data that are outside (older) the maximum *
* request range *
* *
- * Parameters: item - [IN] the target item *
+ * Parameters: item - [IN] the target item *
+ * timestamp - [IN] last timestamp in active range *
* *
******************************************************************************/
-static void vch_item_clean_cache(zbx_vc_item_t *item)
+static void vch_item_clean_cache(zbx_vc_item_t *item, int timestamp)
{
zbx_vc_chunk_t *next;
@@ -1635,11 +1654,12 @@ static void vch_item_clean_cache(zbx_vc_item_t *item)
{
zbx_vc_chunk_t *tail = item->tail;
zbx_vc_chunk_t *chunk = tail;
- int timestamp;
- timestamp = time(NULL) - item->active_range;
+ timestamp -= item->active_range;
- /* try to remove chunks with all history values older than maximum request range */
+ /* Try to remove chunks with all history values older than maximum request range, maximum */
+ /* request range should be calculated from last received value with which active range */
+ /* was calculated to avoid dropping of chunks that might be still used in count request. */
while (NULL != chunk && chunk->slots[chunk->last_value].timestamp.sec < timestamp &&
chunk->slots[chunk->last_value].timestamp.sec !=
item->head->slots[item->head->last_value].timestamp.sec)
@@ -2128,7 +2148,7 @@ static void vch_item_get_values_by_time(const zbx_vc_item_t *item, zbx_vector_hi
/* range which might be greater than the current request range. */
if (0 != item->active_range || ZBX_ITEM_STATUS_CACHED_ALL != item->status)
{
- now = time(NULL);
+ now = (int)time(NULL);
/* add another second to include nanosecond shifts */
vc_cache_item_update(item->itemid, ZBX_VC_UPDATE_RANGE, seconds + now - ts->sec + 1, now);
}
@@ -2227,7 +2247,7 @@ out:
range_timestamp = values->values[values->values_num - 1].timestamp.sec - 1;
}
- now = time(NULL);
+ now = (int)time(NULL);
vc_cache_item_update(item->itemid, ZBX_VC_UPDATE_RANGE, now - range_timestamp, now);
}
@@ -2494,7 +2514,6 @@ int zbx_vc_add_values(zbx_vector_ptr_t *history, int *ret_flush)
zbx_vc_item_t *item;
int i;
ZBX_DC_HISTORY *h;
- time_t expire_timestamp;
if (SUCCEED != zbx_history_add_values(history, ret_flush))
return FAIL;
@@ -2502,8 +2521,6 @@ int zbx_vc_add_values(zbx_vector_ptr_t *history, int *ret_flush)
if (ZBX_VC_DISABLED == vc_state)
return SUCCEED;
- expire_timestamp = time(NULL) - ZBX_VC_ITEM_EXPIRE_PERIOD;
-
WRLOCK_CACHE;
for (i = 0; i < history->values_num; i++)
@@ -2514,6 +2531,12 @@ int zbx_vc_add_values(zbx_vector_ptr_t *history, int *ret_flush)
{
zbx_history_record_t record = {h->ts, h->value};
zbx_vc_chunk_t *head = item->head;
+ int last_value_timestamp;
+
+ if (NULL != head)
+ last_value_timestamp = head->slots[head->last_value].timestamp.sec;
+ else
+ last_value_timestamp = (int)time(NULL);
/* If the new value type does not match the item's type in cache remove it, */
/* so it's cached with the correct type from correct tables when accessed */
@@ -2521,8 +2544,7 @@ int zbx_vc_add_values(zbx_vector_ptr_t *history, int *ret_flush)
/* Also remove item if the value adding failed. In this case we */
/* won't have the latest data in cache - so the requests must go directly */
/* to the database. */
- if (item->value_type != h->value_type || item->last_accessed < expire_timestamp ||
- FAIL == vch_item_add_value_at_head(item, &record))
+ if (item->value_type != h->value_type || FAIL == vch_item_add_value_at_head(item, &record))
{
vc_remove_item(item);
continue;
@@ -2530,8 +2552,7 @@ int zbx_vc_add_values(zbx_vector_ptr_t *history, int *ret_flush)
/* try to remove old (unused) chunks if a new chunk was added */
if (head != item->head)
- vch_item_clean_cache(item);
-
+ vch_item_clean_cache(item, last_value_timestamp);
}
}
@@ -2563,8 +2584,8 @@ int zbx_vc_add_values(zbx_vector_ptr_t *history, int *ret_flush)
* seconds before <timestamp>. *
* *
******************************************************************************/
-int zbx_vc_get_values(zbx_uint64_t itemid, int value_type, zbx_vector_history_record_t *values, int seconds,
- int count, const zbx_timespec_t *ts)
+int zbx_vc_get_values(zbx_uint64_t itemid, unsigned char value_type, zbx_vector_history_record_t *values,
+ int seconds, int count, const zbx_timespec_t *ts)
{
zbx_vc_item_t *item, new_item;
int ret = FAIL, cache_used = 1;
@@ -2607,7 +2628,7 @@ out:
vc_remove_item_by_id(itemid);
if (SUCCEED == ret)
- vc_update_statistics(NULL, 0, values->values_num, time(NULL));
+ vc_update_statistics(NULL, 0, values->values_num, (int)time(NULL));
}
UNLOCK_CACHE;
@@ -2636,7 +2657,8 @@ out:
* function. *
* *
******************************************************************************/
-int zbx_vc_get_value(zbx_uint64_t itemid, int value_type, const zbx_timespec_t *ts, zbx_history_record_t *value)
+int zbx_vc_get_value(zbx_uint64_t itemid, unsigned char value_type, const zbx_timespec_t *ts,
+ zbx_history_record_t *value)
{
zbx_vector_history_record_t values;
int ret = FAIL;
@@ -2730,12 +2752,12 @@ void zbx_vc_get_diag_stats(zbx_uint64_t *items_num, zbx_uint64_t *values_num, in
RDLOCK_CACHE;
- *items_num = vc_cache->items.num_data;
+ *items_num = (zbx_uint64_t)vc_cache->items.num_data;
*mode = vc_cache->mode;
zbx_hashset_iter_reset(&vc_cache->items, &iter);
while (NULL != (item = (zbx_vc_item_t *)zbx_hashset_iter_next(&iter)))
- *values_num += item->values_total;
+ *values_num += (zbx_uint64_t)item->values_total;
UNLOCK_CACHE;
}
@@ -2774,7 +2796,7 @@ void zbx_vc_get_item_stats(zbx_vector_ptr_t *stats)
RDLOCK_CACHE;
- zbx_vector_ptr_reserve(stats, vc_cache->items.num_data);
+ zbx_vector_ptr_reserve(stats, (size_t)vc_cache->items.num_data);
zbx_hashset_iter_reset(&vc_cache->items, &iter);
while (NULL != (item = (zbx_vc_item_t *)zbx_hashset_iter_next(&iter)))
@@ -2805,7 +2827,7 @@ void zbx_vc_flush_stats(void)
zbx_vector_vc_itemupdate_sort(&vc_itemupdates, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
- now = time(NULL);
+ now = (int)time(NULL);
WRLOCK_CACHE;
diff --git a/src/libs/zbxdbcache/valuecache.h b/src/libs/zbxdbcache/valuecache.h
index 3b280e5a4df..d61e1b52d22 100644
--- a/src/libs/zbxdbcache/valuecache.h
+++ b/src/libs/zbxdbcache/valuecache.h
@@ -102,16 +102,17 @@ void zbx_vc_enable(void);
void zbx_vc_disable(void);
-int zbx_vc_get_values(zbx_uint64_t itemid, int value_type, zbx_vector_history_record_t *values, int seconds,
- int count, const zbx_timespec_t *ts);
+int zbx_vc_get_values(zbx_uint64_t itemid, unsigned char value_type, zbx_vector_history_record_t *values,
+ int seconds, int count, const zbx_timespec_t *ts);
-int zbx_vc_get_value(zbx_uint64_t itemid, int value_type, const zbx_timespec_t *ts, zbx_history_record_t *value);
+int zbx_vc_get_value(zbx_uint64_t itemid, unsigned char value_type, const zbx_timespec_t *ts,
+ zbx_history_record_t *value);
int zbx_vc_add_values(zbx_vector_ptr_t *history, int *ret_flush);
int zbx_vc_get_statistics(zbx_vc_stats_t *stats);
-void zbx_vc_housekeeping_value_cache(void);
+void zbx_vc_remove_items_by_ids(zbx_vector_uint64_t *itemids);
void zbx_vc_get_diag_stats(zbx_uint64_t *items_num, zbx_uint64_t *values_num, int *mode);
void zbx_vc_get_mem_stats(zbx_shmem_stats_t *mem);
diff --git a/src/libs/zbxdbhigh/graph_linking.c b/src/libs/zbxdbhigh/graph_linking.c
index 37809d4d2d1..133afb11433 100644
--- a/src/libs/zbxdbhigh/graph_linking.c
+++ b/src/libs/zbxdbhigh/graph_linking.c
@@ -1051,7 +1051,7 @@ static int update_graphs_items_updates(char **sql, size_t *sql_alloc, size_t *sq
d2 = ",";
zbx_audit_graph_update_json_update_gitem_update_drawtype(graphid,
- (int)graph_flags, host_items_entry->gitemid,
+ graph_flags, host_items_entry->gitemid,
host_items_entry->drawtype_orig,
host_items_entry->drawtype_new);
}
@@ -1063,7 +1063,7 @@ static int update_graphs_items_updates(char **sql, size_t *sql_alloc, size_t *sq
d2 = ",";
zbx_audit_graph_update_json_update_gitem_update_sortorder(graphid,
- (int)graph_flags, host_items_entry->gitemid,
+ graph_flags, host_items_entry->gitemid,
host_items_entry->sortorder_orig,
host_items_entry->sortorder_new);
}
@@ -1077,7 +1077,7 @@ static int update_graphs_items_updates(char **sql, size_t *sql_alloc, size_t *sq
zbx_free(color_esc);
d2 = ",";
- zbx_audit_graph_update_json_update_gitem_update_color(graphid, (int)graph_flags,
+ zbx_audit_graph_update_json_update_gitem_update_color(graphid, graph_flags,
host_items_entry->gitemid, host_items_entry->color_orig,
host_items_entry->color_new);
}
@@ -1089,7 +1089,7 @@ static int update_graphs_items_updates(char **sql, size_t *sql_alloc, size_t *sq
d2 = ",";
zbx_audit_graph_update_json_update_gitem_update_yaxisside(graphid,
- (int)graph_flags, host_items_entry->gitemid,
+ graph_flags, host_items_entry->gitemid,
host_items_entry->yaxisside_orig,
host_items_entry->yaxisside_new);
}
@@ -1101,7 +1101,7 @@ static int update_graphs_items_updates(char **sql, size_t *sql_alloc, size_t *sq
d2 = ",";
zbx_audit_graph_update_json_update_gitem_update_calc_fnc(graphid,
- (int)graph_flags, host_items_entry->gitemid,
+ graph_flags, host_items_entry->gitemid,
host_items_entry->calc_fnc_orig,
host_items_entry->calc_fnc_new);
}
@@ -1111,7 +1111,7 @@ static int update_graphs_items_updates(char **sql, size_t *sql_alloc, size_t *sq
zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%stype=%d", d2,
host_items_entry->type_new);
- zbx_audit_graph_update_json_update_gitem_update_type(graphid, (int)graph_flags,
+ zbx_audit_graph_update_json_update_gitem_update_type(graphid, graph_flags,
host_items_entry->gitemid, host_items_entry->type_orig,
host_items_entry->type_new);
}
diff --git a/src/libs/zbxdbhigh/host.c b/src/libs/zbxdbhigh/host.c
index a186bfe5065..f8b7f6b4596 100644
--- a/src/libs/zbxdbhigh/host.c
+++ b/src/libs/zbxdbhigh/host.c
@@ -1020,7 +1020,7 @@ void DBdelete_triggers(zbx_vector_uint64_t *triggerids)
}
for (i = 0; i < triggerids->values_num; i++)
- DBdelete_action_conditions(CONDITION_TYPE_TRIGGER, triggerids->values[i]);
+ DBdelete_action_conditions(ZBX_CONDITION_TYPE_TRIGGER, triggerids->values[i]);
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from trigger_tag where");
DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "triggerid", triggerids->values, triggerids->values_num);
@@ -1456,6 +1456,7 @@ static void DBdelete_httptests(const zbx_vector_uint64_t *httptestids)
char *sql = NULL;
size_t sql_alloc = 256, sql_offset = 0;
zbx_vector_uint64_t itemids;
+ zbx_vector_uint64_t httpstepids;
zabbix_log(LOG_LEVEL_DEBUG, "In %s() values_num:%d", __func__, httptestids->values_num);
@@ -1464,6 +1465,7 @@ static void DBdelete_httptests(const zbx_vector_uint64_t *httptestids)
sql = (char *)zbx_malloc(sql, sql_alloc);
zbx_vector_uint64_create(&itemids);
+ zbx_vector_uint64_create(&httpstepids);
/* httpstepitem, httptestitem */
sql_offset = 0;
@@ -1485,6 +1487,45 @@ static void DBdelete_httptests(const zbx_vector_uint64_t *httptestids)
if (FAIL == zbx_audit_DBselect_delete_for_item(sql, &itemids))
goto clean;
+
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select httpstepid from httpstep where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "httptestid",
+ httptestids->values, httptestids->values_num);
+ DBselect_uint64(sql, &httpstepids);
+
+ sql_offset = 0;
+ zbx_DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
+
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from httptest_field where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "httptestid",
+ httptestids->values, httptestids->values_num);
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
+
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from httptestitem where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "httptestid",
+ httptestids->values, httptestids->values_num);
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
+
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from httpstep_field where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "httpstepid",
+ httpstepids.values, httpstepids.values_num);
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
+
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from httpstepitem where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "httpstepid",
+ httpstepids.values, httpstepids.values_num);
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
+
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from httpstep where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "httpstepid",
+ httpstepids.values, httpstepids.values_num);
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
+
+ zbx_DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
+
+ DBexecute("%s", sql);
+
DBdelete_items(&itemids);
sql_offset = 0;
@@ -1493,6 +1534,7 @@ static void DBdelete_httptests(const zbx_vector_uint64_t *httptestids)
httptestids->values, httptestids->values_num);
DBexecute("%s", sql);
clean:
+ zbx_vector_uint64_destroy(&httpstepids);
zbx_vector_uint64_destroy(&itemids);
zbx_free(sql);
out:
@@ -5871,7 +5913,7 @@ void DBdelete_hosts(const zbx_vector_uint64_t *hostids, const zbx_vector_str_t *
/* delete action conditions */
for (i = 0; i < hostids->values_num; i++)
- DBdelete_action_conditions(CONDITION_TYPE_HOST, hostids->values[i]);
+ DBdelete_action_conditions(ZBX_CONDITION_TYPE_HOST, hostids->values[i]);
/* delete host tags */
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from host_tag where");
@@ -6375,7 +6417,7 @@ void DBdelete_groups(zbx_vector_uint64_t *groupids)
goto out;
for (i = 0; i < groupids->values_num; i++)
- DBdelete_action_conditions(CONDITION_TYPE_HOST_GROUP, groupids->values[i]);
+ DBdelete_action_conditions(ZBX_CONDITION_TYPE_HOST_GROUP, groupids->values[i]);
sql = (char *)zbx_malloc(sql, sql_alloc);
diff --git a/src/libs/zbxdbhigh/proxy.c b/src/libs/zbxdbhigh/proxy.c
index d7f2ba26752..984b40843f0 100644
--- a/src/libs/zbxdbhigh/proxy.c
+++ b/src/libs/zbxdbhigh/proxy.c
@@ -37,9 +37,10 @@
#include "zbxnum.h"
#include "zbxtime.h"
#include "zbxip.h"
+#include "version.h"
+#include "zbxversion.h"
extern char *CONFIG_SERVER;
-extern char *CONFIG_VAULTDBPATH;
/* the space reserved in json buffer to hold at least one record plus service data */
#define ZBX_DATA_JSON_RESERVED (ZBX_HISTORY_TEXT_VALUE_LEN * 4 + ZBX_KIBIBYTE * 4)
@@ -81,13 +82,6 @@ typedef struct
}
zbx_history_table_t;
-typedef struct
-{
- zbx_uint64_t id;
- size_t offset;
-}
-zbx_id_offset_t;
-
typedef int (*zbx_client_item_validator_t)(DC_ITEM *item, zbx_socket_t *sock, void *args, char **error);
typedef struct
@@ -127,13 +121,6 @@ static zbx_history_table_t areg = {
}
};
-typedef struct
-{
- char *path;
- zbx_hashset_t keys;
-}
-zbx_keys_path_t;
-
/******************************************************************************
* *
* Purpose: check proxy connection permissions (encryption configuration and *
@@ -330,7 +317,7 @@ static int zbx_host_check_permissions(const DC_HOST *host, const zbx_socket_t *s
* configured in passive mode or access denied) *
* *
******************************************************************************/
-int get_active_proxy_from_request(struct zbx_json_parse *jp, DC_PROXY *proxy, char **error)
+int get_active_proxy_from_request(const struct zbx_json_parse *jp, DC_PROXY *proxy, char **error)
{
char *ch_error, host[ZBX_HOSTNAME_BUF_LEN];
@@ -436,1666 +423,6 @@ int check_access_passive_proxy(zbx_socket_t *sock, int send_response, const char
/******************************************************************************
* *
- * Purpose: add database row to the proxy config json data *
- * *
- * Parameters: j - [OUT] the output json *
- * row - [IN] the database row to add *
- * table - [IN] the table configuration *
- * *
- ******************************************************************************/
-static void proxyconfig_add_row(struct zbx_json *j, const DB_ROW row, const ZBX_TABLE *table)
-{
- int fld = 0, i;
-
- zbx_json_addstring(j, NULL, row[fld++], ZBX_JSON_TYPE_INT);
-
- for (i = 0; 0 != table->fields[i].name; i++)
- {
- if (0 == (table->fields[i].flags & ZBX_PROXY))
- continue;
-
- switch (table->fields[i].type)
- {
- case ZBX_TYPE_INT:
- case ZBX_TYPE_UINT:
- case ZBX_TYPE_ID:
- if (SUCCEED != DBis_null(row[fld]))
- zbx_json_addstring(j, NULL, row[fld], ZBX_JSON_TYPE_INT);
- else
- zbx_json_addstring(j, NULL, NULL, ZBX_JSON_TYPE_NULL);
- break;
- default:
- zbx_json_addstring(j, NULL, row[fld], ZBX_JSON_TYPE_STRING);
- break;
- }
- fld++;
- }
-}
-
-typedef struct
-{
- zbx_uint64_t itemid;
- zbx_uint64_t master_itemid;
- char *buffer;
-}
-zbx_proxy_item_config_t;
-
-/******************************************************************************
- * *
- * Purpose: prepare items table proxy configuration data *
- * *
- ******************************************************************************/
-static int get_proxyconfig_table_items(zbx_uint64_t proxy_hostid, struct zbx_json *j, const ZBX_TABLE *table,
- zbx_hashset_t *itemids)
-{
- char *sql = NULL;
- size_t sql_alloc = 4 * ZBX_KIBIBYTE, sql_offset = 0;
- int f, fld, fld_type = -1, fld_key = -1, fld_master = -1, ret = SUCCEED;
- DB_RESULT result;
- DB_ROW row;
- zbx_hashset_t proxy_items;
- zbx_vector_ptr_t items;
- zbx_uint64_t itemid;
- zbx_hashset_iter_t iter;
- struct zbx_json json_array;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In %s() proxy_hostid:" ZBX_FS_UI64, __func__, proxy_hostid);
-
- zbx_json_addobject(j, table->table);
- zbx_json_addarray(j, "fields");
-
- sql = (char *)zbx_malloc(sql, sql_alloc);
-
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select t.%s", table->recid);
-
- zbx_json_addstring(j, NULL, table->recid, ZBX_JSON_TYPE_STRING);
-
- for (f = 0, fld = 1; 0 != table->fields[f].name; f++)
- {
- if (0 == (table->fields[f].flags & ZBX_PROXY))
- continue;
-
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ",t.");
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, table->fields[f].name);
-
- zbx_json_addstring(j, NULL, table->fields[f].name, ZBX_JSON_TYPE_STRING);
-
- if (0 == strcmp(table->fields[f].name, "type"))
- fld_type = fld;
- else if (0 == strcmp(table->fields[f].name, "key_"))
- fld_key = fld;
- else if (0 == strcmp(table->fields[f].name, "master_itemid"))
- fld_master = fld;
- fld++;
- }
-
- if (-1 == fld_type || -1 == fld_key || -1 == fld_master)
- {
- THIS_SHOULD_NEVER_HAPPEN;
- exit(EXIT_FAILURE);
- }
-
- zbx_json_close(j); /* fields */
-
- zbx_json_addarray(j, "data");
-
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
- " from items t,hosts r where t.hostid=r.hostid"
- " and r.proxy_hostid=" ZBX_FS_UI64
- " and r.status in (%d,%d)"
- " and t.flags<>%d"
- " and t.type in (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)"
- " order by t.%s",
- proxy_hostid,
- HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED,
- ZBX_FLAG_DISCOVERY_PROTOTYPE,
- ITEM_TYPE_ZABBIX, ITEM_TYPE_ZABBIX_ACTIVE, ITEM_TYPE_SNMP, ITEM_TYPE_IPMI, ITEM_TYPE_TRAPPER,
- ITEM_TYPE_SIMPLE, ITEM_TYPE_HTTPTEST, ITEM_TYPE_EXTERNAL, ITEM_TYPE_DB_MONITOR, ITEM_TYPE_SSH,
- ITEM_TYPE_TELNET, ITEM_TYPE_JMX, ITEM_TYPE_SNMPTRAP, ITEM_TYPE_INTERNAL,
- ITEM_TYPE_HTTPAGENT, ITEM_TYPE_DEPENDENT, ITEM_TYPE_SCRIPT,
- table->recid);
-
- if (NULL == (result = DBselect("%s", sql)))
- {
- ret = FAIL;
- goto skip_data;
- }
-
- zbx_hashset_create(&proxy_items, 1000, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
- zbx_json_initarray(&json_array, 256);
-
- while (NULL != (row = DBfetch(result)))
- {
- if (SUCCEED == is_item_processed_by_server(atoi(row[fld_type]), row[fld_key]))
- continue;
-
- if (SUCCEED != DBis_null(row[fld_master]))
- {
- zbx_proxy_item_config_t proxy_item_local, *proxy_item;
-
- ZBX_STR2UINT64(proxy_item_local.itemid, row[0]);
- ZBX_STR2UINT64(proxy_item_local.master_itemid, row[fld_master]);
- proxy_item = zbx_hashset_insert(&proxy_items, &proxy_item_local, sizeof(proxy_item_local));
-
- proxyconfig_add_row(&json_array, row, table);
-
- proxy_item->buffer = zbx_malloc(NULL, json_array.buffer_size + 1);
- memcpy(proxy_item->buffer, json_array.buffer, json_array.buffer_size + 1);
-
- zbx_json_cleanarray(&json_array);
- }
- else
- {
- ZBX_STR2UINT64(itemid, row[0]);
- zbx_hashset_insert(itemids, &itemid, sizeof(itemid));
-
- zbx_json_addarray(j, NULL);
- proxyconfig_add_row(j, row, table);
- zbx_json_close(j);
- }
- }
- DBfree_result(result);
- zbx_json_free(&json_array);
-
- /* flush cached dependent items */
-
- zbx_vector_ptr_create(&items);
- while (0 != proxy_items.num_data)
- {
- zbx_proxy_item_config_t *proxy_item;
- int i;
-
- zbx_hashset_iter_reset(&proxy_items, &iter);
- while (NULL != (proxy_item = (zbx_proxy_item_config_t *)zbx_hashset_iter_next(&iter)))
- {
- if (NULL == zbx_hashset_search(&proxy_items, &proxy_item->master_itemid))
- zbx_vector_ptr_append(&items, proxy_item);
- }
-
- if (0 == items.values_num)
- {
- THIS_SHOULD_NEVER_HAPPEN;
- exit(EXIT_FAILURE);
- }
-
- zbx_vector_ptr_sort(&items, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
- for (i = 0; i < items.values_num; i++)
- {
- proxy_item = (zbx_proxy_item_config_t *)items.values[i];
- if (NULL != zbx_hashset_search(itemids, &proxy_item->master_itemid))
- {
- zbx_hashset_insert(itemids, &proxy_item->itemid, sizeof(itemid));
- zbx_json_addraw(j, NULL, proxy_item->buffer);
- }
- zbx_free(proxy_item->buffer);
- zbx_hashset_remove_direct(&proxy_items, proxy_item);
- }
-
- zbx_vector_ptr_clear(&items);
- }
- zbx_vector_ptr_destroy(&items);
- zbx_hashset_destroy(&proxy_items);
-skip_data:
- zbx_free(sql);
-
- zbx_json_close(j); /* data */
- zbx_json_close(j); /* table->table */
-
- zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
-
- return ret;
-}
-
-/******************************************************************************
- * *
- * Purpose: prepare items table proxy configuration data *
- * *
- ******************************************************************************/
-static int get_proxyconfig_table_items_ext(zbx_uint64_t proxy_hostid, const zbx_hashset_t *itemids,
- struct zbx_json *j, const ZBX_TABLE *table)
-{
- char *sql = NULL;
- size_t sql_alloc = 4 * ZBX_KIBIBYTE, sql_offset = 0;
- int f, ret = SUCCEED, index = 1, itemid_index = 0;
- DB_RESULT result;
- DB_ROW row;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In %s() table:%s", __func__, table->table);
-
- zbx_json_addobject(j, table->table);
- zbx_json_addarray(j, "fields");
-
- sql = (char *)zbx_malloc(sql, sql_alloc);
-
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select t.%s", table->recid);
-
- zbx_json_addstring(j, NULL, table->recid, ZBX_JSON_TYPE_STRING);
-
- for (f = 0; 0 != table->fields[f].name; f++)
- {
- if (0 == (table->fields[f].flags & ZBX_PROXY))
- continue;
-
- /* either the table uses itemid as primary key, then it will be stored in the */
- /* first (0) column as record id, or it will have reference to items table */
- /* through itemid field */
- if (0 == strcmp(table->fields[f].name, "itemid"))
- itemid_index = index;
-
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ",t.");
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, table->fields[f].name);
- zbx_json_addstring(j, NULL, table->fields[f].name, ZBX_JSON_TYPE_STRING);
- index++;
- }
-
- zbx_json_close(j); /* fields */
-
- zbx_json_addarray(j, "data");
-
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
- " from %s t,items i,hosts h"
- " where t.itemid=i.itemid"
- " and i.hostid=h.hostid"
- " and h.proxy_hostid=" ZBX_FS_UI64,
- table->table, proxy_hostid);
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by t.");
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, table->recid);
-
- if (NULL == (result = DBselect("%s", sql)))
- {
- ret = FAIL;
- goto skip_data;
- }
-
- while (NULL != (row = DBfetch(result)))
- {
- zbx_uint64_t itemid;
-
- ZBX_STR2UINT64(itemid, row[itemid_index]);
- if (NULL != zbx_hashset_search((zbx_hashset_t *)itemids, &itemid))
- {
- zbx_json_addarray(j, NULL);
- proxyconfig_add_row(j, row, table);
- zbx_json_close(j);
- }
- }
- DBfree_result(result);
-skip_data:
- zbx_free(sql);
-
- zbx_json_close(j); /* data */
- zbx_json_close(j); /* table->table */
-
- zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
-
- return ret;
-}
-
-static int keys_path_compare(const void *d1, const void *d2)
-{
- const zbx_keys_path_t *ptr1 = *((const zbx_keys_path_t **)d1);
- const zbx_keys_path_t *ptr2 = *((const zbx_keys_path_t **)d2);
-
- return strcmp(ptr1->path, ptr2->path);
-}
-
-static zbx_hash_t keys_hash(const void *data)
-{
- return ZBX_DEFAULT_STRING_HASH_ALGO(*(const char **)data, strlen(*(const char **)data), ZBX_DEFAULT_HASH_SEED);
-}
-
-static int keys_compare(const void *d1, const void *d2)
-{
- return strcmp(*(const char **)d1, *(const char **)d2);
-}
-
-static void key_path_free(void *data)
-{
- zbx_hashset_iter_t iter;
- char **ptr;
- zbx_keys_path_t *keys_path = (zbx_keys_path_t *)data;
-
- zbx_hashset_iter_reset(&keys_path->keys, &iter);
- while (NULL != (ptr = (char **)zbx_hashset_iter_next(&iter)))
- zbx_free(*ptr);
- zbx_hashset_destroy(&keys_path->keys);
-
- zbx_free(keys_path->path);
- zbx_free(keys_path);
-}
-
-/******************************************************************************
- * *
- * Purpose: prepare proxy configuration data *
- * *
- ******************************************************************************/
-static int get_proxyconfig_table(zbx_uint64_t proxy_hostid, struct zbx_json *j, const ZBX_TABLE *table,
- const zbx_vector_uint64_t *hosts, const zbx_vector_uint64_t *httptests, zbx_vector_ptr_t *keys_paths)
-{
- char *sql = NULL;
- size_t sql_alloc = 4 * ZBX_KIBIBYTE, sql_offset = 0;
- int f, ret = SUCCEED, i, is_macro = 0;
- DB_RESULT result;
- DB_ROW row;
- int offset;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In %s() proxy_hostid:" ZBX_FS_UI64 " table:'%s'",
- __func__, proxy_hostid, table->table);
-
- if (0 == strcmp(table->table, "globalmacro"))
- {
- is_macro = 1;
- offset = 0;
- }
- else if (0 == strcmp(table->table, "hostmacro"))
- {
- is_macro = 1;
- offset = 1;
- }
-
- zbx_json_addobject(j, table->table);
- zbx_json_addarray(j, "fields");
-
- sql = (char *)zbx_malloc(sql, sql_alloc);
-
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select t.%s", table->recid);
-
- zbx_json_addstring(j, NULL, table->recid, ZBX_JSON_TYPE_STRING);
-
- for (f = 0; 0 != table->fields[f].name; f++)
- {
- if (0 == (table->fields[f].flags & ZBX_PROXY))
- continue;
-
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ",t.");
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, table->fields[f].name);
-
- zbx_json_addstring(j, NULL, table->fields[f].name, ZBX_JSON_TYPE_STRING);
- }
-
- zbx_json_close(j); /* fields */
-
- zbx_json_addarray(j, "data");
-
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " from %s t", table->table);
-
- if (SUCCEED == zbx_str_in_list("hosts,interface,host_inventory,hosts_templates,hostmacro", table->table, ','))
- {
- if (0 == hosts->values_num)
- goto skip_data;
-
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " where");
- DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "t.hostid", hosts->values, hosts->values_num);
- }
- else if (0 == strcmp(table->table, "interface_snmp"))
- {
- if (0 == hosts->values_num)
- goto skip_data;
-
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ",interface h where t.interfaceid=h.interfaceid and");
- DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "h.hostid", hosts->values, hosts->values_num);
- }
- else if (0 == strcmp(table->table, "drules"))
- {
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
- " where t.proxy_hostid=" ZBX_FS_UI64
- " and t.status=%d",
- proxy_hostid, DRULE_STATUS_MONITORED);
- }
- else if (0 == strcmp(table->table, "dchecks"))
- {
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
- ",drules r where t.druleid=r.druleid"
- " and r.proxy_hostid=" ZBX_FS_UI64
- " and r.status=%d",
- proxy_hostid, DRULE_STATUS_MONITORED);
- }
- else if (0 == strcmp(table->table, "hstgrp"))
- {
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ",config r where t.groupid=r.discovery_groupid");
- }
- else if (SUCCEED == zbx_str_in_list("httptest,httptest_field,httptestitem,httpstep", table->table, ','))
- {
- if (0 == httptests->values_num)
- goto skip_data;
-
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " where");
- DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "t.httptestid",
- httptests->values, httptests->values_num);
- }
- else if (SUCCEED == zbx_str_in_list("httpstepitem,httpstep_field", table->table, ','))
- {
- if (0 == httptests->values_num)
- goto skip_data;
-
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
- ",httpstep r where t.httpstepid=r.httpstepid"
- " and");
- DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "r.httptestid",
- httptests->values, httptests->values_num);
- }
-
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by t.");
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, table->recid);
-
- if (NULL == (result = DBselect("%s", sql)))
- {
- ret = FAIL;
- goto skip_data;
- }
-
- while (NULL != (row = DBfetch(result)))
- {
- zbx_json_addarray(j, NULL);
- proxyconfig_add_row(j, row, table);
- zbx_json_close(j);
- if (1 == is_macro)
- {
- zbx_keys_path_t *keys_path, keys_path_local;
- unsigned char type;
- char *path, *key;
-
- ZBX_STR2UCHAR(type, row[3 + offset]);
-
- if (ZBX_MACRO_VALUE_VAULT != type)
- continue;
-
- zbx_strsplit_last(row[2 + offset], ':', &path, &key);
-
- if (NULL == key)
- {
- zabbix_log(LOG_LEVEL_WARNING, "cannot parse macro \"%s\" value \"%s\"",
- row[1 + offset], row[2 + offset]);
- goto next;
- }
-
- if (NULL != CONFIG_VAULTDBPATH && 0 == strcasecmp(CONFIG_VAULTDBPATH, path) &&
- (0 == strcasecmp(key, ZBX_PROTO_TAG_PASSWORD)
- || 0 == strcasecmp(key, ZBX_PROTO_TAG_USERNAME)))
- {
- zabbix_log(LOG_LEVEL_WARNING, "cannot parse macro \"%s\" value \"%s\":"
- " database credentials should not be used with Vault macros",
- row[1 + offset], row[2 + offset]);
- goto next;
- }
-
- keys_path_local.path = path;
-
- if (FAIL == (i = zbx_vector_ptr_search(keys_paths, &keys_path_local, keys_path_compare)))
- {
- keys_path = zbx_malloc(NULL, sizeof(zbx_keys_path_t));
- keys_path->path = path;
-
- zbx_hashset_create(&keys_path->keys, 0, keys_hash, keys_compare);
- zbx_hashset_insert(&keys_path->keys, &key, sizeof(char **));
-
- zbx_vector_ptr_append(keys_paths, keys_path);
- path = key = NULL;
- }
- else
- {
- keys_path = (zbx_keys_path_t *)keys_paths->values[i];
- if (NULL == zbx_hashset_search(&keys_path->keys, &key))
- {
- zbx_hashset_insert(&keys_path->keys, &key, sizeof(char **));
- key = NULL;
- }
- }
-next:
- zbx_free(key);
- zbx_free(path);
- }
- }
- DBfree_result(result);
-skip_data:
- zbx_free(sql);
-
- zbx_json_close(j); /* data */
- zbx_json_close(j); /* table->table */
-
- zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
-
- return ret;
-}
-
-static void get_proxy_monitored_hosts(zbx_uint64_t proxy_hostid, zbx_vector_uint64_t *hosts)
-{
- DB_RESULT result;
- DB_ROW row;
- zbx_uint64_t hostid, *ids = NULL;
- int ids_alloc = 0, ids_num = 0;
- char *sql = NULL;
- size_t sql_alloc = 512, sql_offset;
-
- sql = (char *)zbx_malloc(sql, sql_alloc * sizeof(char));
-
- result = DBselect(
- "select hostid"
- " from hosts"
- " where proxy_hostid=" ZBX_FS_UI64
- " and status in (%d,%d)"
- " and flags<>%d",
- proxy_hostid, HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED, ZBX_FLAG_DISCOVERY_PROTOTYPE);
-
- while (NULL != (row = DBfetch(result)))
- {
- ZBX_STR2UINT64(hostid, row[0]);
-
- zbx_vector_uint64_append(hosts, hostid);
- uint64_array_add(&ids, &ids_alloc, &ids_num, hostid, 64);
- }
- DBfree_result(result);
-
- while (0 != ids_num)
- {
- sql_offset = 0;
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
- "select distinct templateid"
- " from hosts_templates"
- " where");
- DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", ids, ids_num);
-
- ids_num = 0;
-
- result = DBselect("%s", sql);
-
- while (NULL != (row = DBfetch(result)))
- {
- ZBX_STR2UINT64(hostid, row[0]);
-
- zbx_vector_uint64_append(hosts, hostid);
- uint64_array_add(&ids, &ids_alloc, &ids_num, hostid, 64);
- }
- DBfree_result(result);
- }
-
- zbx_free(ids);
- zbx_free(sql);
-
- zbx_vector_uint64_sort(hosts, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
-}
-
-static void get_proxy_monitored_httptests(zbx_uint64_t proxy_hostid, zbx_vector_uint64_t *httptests)
-{
- DB_RESULT result;
- DB_ROW row;
- zbx_uint64_t httptestid;
-
- result = DBselect(
- "select httptestid"
- " from httptest t,hosts h"
- " where t.hostid=h.hostid"
- " and t.status=%d"
- " and h.proxy_hostid=" ZBX_FS_UI64
- " and h.status=%d",
- HTTPTEST_STATUS_MONITORED, proxy_hostid, HOST_STATUS_MONITORED);
-
- while (NULL != (row = DBfetch(result)))
- {
- ZBX_STR2UINT64(httptestid, row[0]);
-
- zbx_vector_uint64_append(httptests, httptestid);
- }
- DBfree_result(result);
-
- zbx_vector_uint64_sort(httptests, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
-}
-
-static void get_macro_secrets(const zbx_vector_ptr_t *keys_paths, struct zbx_json *j)
-{
- int i;
- zbx_kvs_t kvs;
-
- zbx_kvs_create(&kvs, 100);
-
- zbx_json_addobject(j, "macro.secrets");
-
- for (i = 0; i < keys_paths->values_num; i++)
- {
- zbx_keys_path_t *keys_path;
- char *error = NULL, **ptr;
- zbx_hashset_iter_t iter;
-
- keys_path = (zbx_keys_path_t *)keys_paths->values[i];
- if (FAIL == zbx_vault_kvs_get(keys_path->path, &kvs, &error))
- {
- zabbix_log(LOG_LEVEL_WARNING, "cannot get secrets for path \"%s\": %s", keys_path->path, error);
- zbx_free(error);
- continue;
- }
-
- zbx_json_addobject(j, keys_path->path);
-
- zbx_hashset_iter_reset(&keys_path->keys, &iter);
- while (NULL != (ptr = (char **)zbx_hashset_iter_next(&iter)))
- {
- zbx_kv_t *kv, kv_local;
-
- kv_local.key = *ptr;
-
- if (NULL != (kv = zbx_kvs_search(&kvs, &kv_local)))
- zbx_json_addstring(j, kv->key, kv->value, ZBX_JSON_TYPE_STRING);
- }
- zbx_json_close(j);
-
- zbx_kvs_clear(&kvs);
- }
-
- zbx_json_close(j);
- zbx_kvs_destroy(&kvs);
-}
-
-/******************************************************************************
- * *
- * Purpose: prepare proxy configuration data *
- * *
- ******************************************************************************/
-int get_proxyconfig_data(zbx_uint64_t proxy_hostid, struct zbx_json *j, char **error)
-{
- static const char *proxytable[] =
- {
- "globalmacro",
- "hosts",
- "interface",
- "interface_snmp",
- "host_inventory",
- "hosts_templates",
- "hostmacro",
- "items",
- "item_rtdata",
- "item_preproc",
- "item_parameter",
- "drules",
- "dchecks",
- "regexps",
- "expressions",
- "hstgrp",
- "config",
- "httptest",
- "httptestitem",
- "httptest_field",
- "httpstep",
- "httpstepitem",
- "httpstep_field",
- "config_autoreg_tls",
- NULL
- };
-
- int i, ret = FAIL;
- const ZBX_TABLE *table;
- zbx_vector_uint64_t hosts, httptests;
- zbx_hashset_t itemids;
- zbx_vector_ptr_t keys_paths;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In %s() proxy_hostid:" ZBX_FS_UI64, __func__, proxy_hostid);
-
- zbx_hashset_create(&itemids, 1000, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
- zbx_vector_uint64_create(&hosts);
- zbx_vector_uint64_create(&httptests);
- zbx_vector_ptr_create(&keys_paths);
-
- DBbegin();
- get_proxy_monitored_hosts(proxy_hostid, &hosts);
- get_proxy_monitored_httptests(proxy_hostid, &httptests);
-
- for (i = 0; NULL != proxytable[i]; i++)
- {
- table = DBget_table(proxytable[i]);
-
- if (0 == strcmp(proxytable[i], "items"))
- {
- ret = get_proxyconfig_table_items(proxy_hostid, j, table, &itemids);
- }
- else if (0 == strcmp(proxytable[i], "item_preproc") || 0 == strcmp(proxytable[i], "item_rtdata") ||
- 0 == strcmp(proxytable[i], "item_parameter"))
- {
- if (0 != itemids.num_data)
- ret = get_proxyconfig_table_items_ext(proxy_hostid, &itemids, j, table);
- }
- else
- ret = get_proxyconfig_table(proxy_hostid, j, table, &hosts, &httptests, &keys_paths);
-
- if (SUCCEED != ret)
- {
- *error = zbx_dsprintf(*error, "failed to get data from table \"%s\"", table->table);
- goto out;
- }
- }
-
- get_macro_secrets(&keys_paths, j);
-
- ret = SUCCEED;
-out:
- DBcommit();
- zbx_vector_ptr_clear_ext(&keys_paths, key_path_free);
- zbx_vector_ptr_destroy(&keys_paths);
- zbx_vector_uint64_destroy(&httptests);
- zbx_vector_uint64_destroy(&hosts);
- zbx_hashset_destroy(&itemids);
-
- zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
-
- return ret;
-}
-
-/******************************************************************************
- * *
- * Purpose: A record is stored as a sequence of fields and flag bytes for *
- * handling NULL values. A field is stored as a null-terminated *
- * string to preserve field boundaries. If a field value can be NULL *
- * a flag byte is inserted after the field to distinguish between *
- * empty string and NULL value. The flag byte can be '\1' *
- * (not NULL value) or '\2' (NULL value). *
- * *
- * Examples of representation: *
- * \0\2 - the field can be NULL and it is NULL *
- * \0\1 - the field can be NULL but is empty string *
- * abc\0\1 - the field can be NULL but is a string "abc" *
- * \0 - the field can not be NULL and is empty string *
- * abc\0 - the field can not be NULL and is a string "abc" *
- * *
- ******************************************************************************/
-static void remember_record(const ZBX_FIELD **fields, int fields_count, char **recs, size_t *recs_alloc,
- size_t *recs_offset, DB_ROW row)
-{
- int f;
-
- for (f = 0; f < fields_count; f++)
- {
- if (0 != (fields[f]->flags & ZBX_NOTNULL))
- {
- zbx_strcpy_alloc(recs, recs_alloc, recs_offset, row[f]);
- *recs_offset += sizeof(char);
- }
- else if (SUCCEED != DBis_null(row[f]))
- {
- zbx_strcpy_alloc(recs, recs_alloc, recs_offset, row[f]);
- *recs_offset += sizeof(char);
- zbx_chrcpy_alloc(recs, recs_alloc, recs_offset, '\1');
- }
- else
- {
- zbx_strcpy_alloc(recs, recs_alloc, recs_offset, "");
- *recs_offset += sizeof(char);
- zbx_chrcpy_alloc(recs, recs_alloc, recs_offset, '\2');
- }
- }
-}
-
-static zbx_hash_t id_offset_hash_func(const void *data)
-{
- const zbx_id_offset_t *p = (zbx_id_offset_t *)data;
-
- return ZBX_DEFAULT_UINT64_HASH_ALGO(&p->id, sizeof(zbx_uint64_t), ZBX_DEFAULT_HASH_SEED);
-}
-
-static int id_offset_compare_func(const void *d1, const void *d2)
-{
- const zbx_id_offset_t *p1 = (zbx_id_offset_t *)d1, *p2 = (zbx_id_offset_t *)d2;
-
- return ZBX_DEFAULT_UINT64_COMPARE_FUNC(&p1->id, &p2->id);
-}
-
-/******************************************************************************
- * *
- * Purpose: find a number of the field *
- * *
- ******************************************************************************/
-static int find_field_by_name(const ZBX_FIELD **fields, int fields_count, const char *field_name)
-{
- int f;
-
- for (f = 0; f < fields_count; f++)
- {
- if (0 == strcmp(fields[f]->name, field_name))
- break;
- }
-
- return f;
-}
-
-/******************************************************************************
- * *
- * Purpose: This function compares a value from JSON record with the value *
- * of the n-th field of DB record. For description how DB record is *
- * stored in memory see comments in function remember_record(). *
- * *
- * Comparing deals with 4 cases: *
- * - JSON value is not NULL, DB value is not NULL *
- * - JSON value is not NULL, DB value is NULL *
- * - JSON value is NULL, DB value is NULL *
- * - JSON value is NULL, DB value is not NULL *
- * *
- ******************************************************************************/
-static int compare_nth_field(const ZBX_FIELD **fields, const char *rec_data, int n, const char *str, int is_null,
- int *last_n, size_t *last_pos)
-{
- int i = *last_n, null_in_db = 0;
- const char *p = rec_data + *last_pos, *field_start = NULL;
-
- do /* find starting position of the n-th field */
- {
- field_start = p;
- while ('\0' != *p++)
- ;
-
- null_in_db = 0;
-
- if (0 == (fields[i++]->flags & ZBX_NOTNULL)) /* field could be NULL */
- {
- if ('\2' == *p && (rec_data == p - 1 || '\0' == *(p - 2) || '\1' == *(p - 2) ||
- '\2' == *(p - 2))) /* field value is NULL */
- {
- null_in_db = 1;
- p++;
- }
- else if ('\1' == *p)
- {
- p++;
- }
- else
- {
- THIS_SHOULD_NEVER_HAPPEN;
- *last_n = 0;
- *last_pos = 0;
- return 1;
- }
- }
- }
- while (n >= i);
-
- *last_n = i; /* preserve number of field and its start position */
- *last_pos = (size_t)(p - rec_data); /* across calls to avoid searching from start */
-
- if (0 == is_null) /* value in JSON is not NULL */
- {
- if (0 == null_in_db)
- return strcmp(field_start, str);
- else
- return 1;
- }
- else
- {
- if ('\0' == *str)
- {
- if (1 == null_in_db)
- return 0; /* fields are "equal" - both contain NULL */
- else
- return 1;
- }
- else
- {
- THIS_SHOULD_NEVER_HAPPEN;
- *last_n = 0;
- *last_pos = 0;
- return 1;
- }
- }
-}
-
-/******************************************************************************
- * *
- * Purpose: update configuration table *
- * *
- * Parameters: ... *
- * del - [OUT] ids of the removed records that must be deleted *
- * from database *
- * *
- * Return value: SUCCEED - processed successfully *
- * FAIL - an error occurred *
- * *
- ******************************************************************************/
-static int process_proxyconfig_table(const ZBX_TABLE *table, struct zbx_json_parse *jp_obj,
- zbx_vector_uint64_t *del, char **error)
-{
- int f, fields_count, ret = FAIL, id_field_nr = 0, move_out = 0,
- move_field_nr = 0;
- const ZBX_FIELD *fields[ZBX_MAX_FIELDS];
- struct zbx_json_parse jp_data, jp_row;
- const char *p, *pf;
- zbx_uint64_t recid, *p_recid = NULL;
- zbx_vector_uint64_t ins, moves, availability_interfaceids;
- char *buf = NULL, *esc, *sql = NULL, *recs = NULL;
- size_t sql_alloc = 4 * ZBX_KIBIBYTE, sql_offset,
- recs_alloc = 20 * ZBX_KIBIBYTE, recs_offset = 0,
- buf_alloc = 0;
- DB_RESULT result;
- DB_ROW row;
- zbx_hashset_t h_id_offsets, h_del;
- zbx_hashset_iter_t iter;
- zbx_id_offset_t id_offset, *p_id_offset = NULL;
- zbx_db_insert_t db_insert;
- zbx_vector_ptr_t values;
- static zbx_vector_ptr_t skip_fields;
- static const ZBX_TABLE *table_items, *table_interface;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In %s() table:'%s'", __func__, table->table);
-
- /************************************************************************************/
- /* T1. RECEIVED JSON (jp_obj) DATA FORMAT */
- /************************************************************************************/
- /* Line | Data | Corresponding structure in DB */
- /* -----+-------------------------------------------+------------------------------ */
- /* 1 | { | */
- /* 2 | "hosts": { | first table */
- /* 3 | "fields": [ | list of table's columns */
- /* 4 | "hostid", | first column */
- /* 5 | "host", | second column */
- /* 6 | ... | ...columns */
- /* 7 | ], | */
- /* 8 | "data": [ | the table data */
- /* 9 | [ | first entry */
- /* 10 | 1, | value for first column */
- /* 11 | "zbx01", | value for second column */
- /* 12 | ... | ...values */
- /* 13 | ], | */
- /* 14 | [ | second entry */
- /* 15 | 2, | value for first column */
- /* 16 | "zbx02", | value for second column */
- /* 17 | ... | ...values */
- /* 18 | ], | */
- /* 19 | ... | ...entries */
- /* 20 | ] | */
- /* 21 | }, | */
- /* 22 | "items": { | second table */
- /* 23 | ... | ... */
- /* 24 | }, | */
- /* 25 | ... | ...tables */
- /* 26 | } | */
- /************************************************************************************/
-
- if (NULL == table_items)
- {
- table_items = DBget_table("item_rtdata");
-
- /* do not update existing lastlogsize and mtime fields */
- zbx_vector_ptr_create(&skip_fields);
- zbx_vector_ptr_append(&skip_fields, (void *)DBget_field(table_items, "lastlogsize"));
- zbx_vector_ptr_append(&skip_fields, (void *)DBget_field(table_items, "mtime"));
- zbx_vector_ptr_sort(&skip_fields, ZBX_DEFAULT_PTR_COMPARE_FUNC);
- }
-
- if (NULL == table_interface)
- table_interface = DBget_table("interface");
-
- /* get table columns (line 3 in T1) */
- if (FAIL == zbx_json_brackets_by_name(jp_obj, "fields", &jp_data))
- {
- *error = zbx_strdup(*error, zbx_json_strerror());
- goto out;
- }
-
- p = NULL;
- /* iterate column names (lines 4-6 in T1) */
- for (fields_count = 0; NULL != (p = zbx_json_next_value_dyn(&jp_data, p, &buf, &buf_alloc, NULL)); fields_count++)
- {
- if (NULL == (fields[fields_count] = DBget_field(table, buf)))
- {
- *error = zbx_dsprintf(*error, "invalid field name \"%s.%s\"", table->table, buf);
- goto out;
- }
-
- if (0 == (fields[fields_count]->flags & ZBX_PROXY) &&
- (0 != strcmp(table->recid, buf) || ZBX_TYPE_ID != fields[fields_count]->type))
- {
- *error = zbx_dsprintf(*error, "unexpected field \"%s.%s\"", table->table, buf);
- goto out;
- }
- }
-
- if (0 == fields_count)
- {
- *error = zbx_dsprintf(*error, "empty list of field names");
- goto out;
- }
-
- /* get the entries (line 8 in T1) */
- if (FAIL == zbx_json_brackets_by_name(jp_obj, ZBX_PROTO_TAG_DATA, &jp_data))
- {
- *error = zbx_strdup(*error, zbx_json_strerror());
- goto out;
- }
-
- /* all records will be stored in one large string */
- recs = (char *)zbx_malloc(recs, recs_alloc);
-
- /* hash set as index for fast access to records via IDs */
- zbx_hashset_create(&h_id_offsets, 10000, id_offset_hash_func, id_offset_compare_func);
-
- /* a hash set as a list for finding records to be deleted */
- zbx_hashset_create(&h_del, 10000, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
-
- sql = (char *)zbx_malloc(sql, sql_alloc);
-
- sql_offset = 0;
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select ");
-
- /* make a string with a list of fields for SELECT */
- for (f = 0; f < fields_count; f++)
- {
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, fields[f]->name);
- zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ',');
- }
-
- sql_offset--;
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " from ");
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, table->table);
-
- /* Find a number of the ID field. Usually the 1st field. */
- id_field_nr = find_field_by_name(fields, fields_count, table->recid);
-
- /* select all existing records */
- result = DBselect("%s", sql);
-
- while (NULL != (row = DBfetch(result)))
- {
- ZBX_STR2UINT64(recid, row[id_field_nr]);
-
- id_offset.id = recid;
- id_offset.offset = recs_offset;
-
- zbx_hashset_insert(&h_id_offsets, &id_offset, sizeof(id_offset));
- zbx_hashset_insert(&h_del, &recid, sizeof(recid));
-
- remember_record(fields, fields_count, &recs, &recs_alloc, &recs_offset, row);
- }
- DBfree_result(result);
-
- /* these tables have unique indices, need special preparation to avoid conflicts during inserts/updates */
- if (0 == strcmp("globalmacro", table->table))
- {
- move_out = 1;
- move_field_nr = find_field_by_name(fields, fields_count, "macro");
- }
- else if (0 == strcmp("hosts_templates", table->table))
- {
- move_out = 1;
- move_field_nr = find_field_by_name(fields, fields_count, "templateid");
- }
- else if (0 == strcmp("hostmacro", table->table))
- {
- move_out = 1;
- move_field_nr = find_field_by_name(fields, fields_count, "macro");
- }
- else if (0 == strcmp("items", table->table))
- {
- move_out = 1;
- move_field_nr = find_field_by_name(fields, fields_count, "key_");
- }
- else if (0 == strcmp("drules", table->table))
- {
- move_out = 1;
- move_field_nr = find_field_by_name(fields, fields_count, "name");
- }
- else if (0 == strcmp("regexps", table->table))
- {
- move_out = 1;
- move_field_nr = find_field_by_name(fields, fields_count, "name");
- }
- else if (0 == strcmp("httptest", table->table))
- {
- move_out = 1;
- move_field_nr = find_field_by_name(fields, fields_count, "name");
- }
-
- zbx_vector_uint64_create(&ins);
-
- if (1 == move_out)
- zbx_vector_uint64_create(&moves);
-
- zbx_vector_uint64_create(&availability_interfaceids);
-
- p = NULL;
- /* iterate the entries (lines 9, 14 and 19 in T1) */
- while (NULL != (p = zbx_json_next(&jp_data, p)))
- {
- if (FAIL == zbx_json_brackets_open(p, &jp_row) ||
- NULL == (pf = zbx_json_next_value_dyn(&jp_row, NULL, &buf, &buf_alloc, NULL)))
- {
- *error = zbx_strdup(*error, zbx_json_strerror());
- goto clean2;
- }
-
- /* check whether we need to update existing entry or insert a new one */
-
- ZBX_STR2UINT64(recid, buf);
-
- if (NULL != zbx_hashset_search(&h_del, &recid))
- {
- zbx_hashset_remove(&h_del, &recid);
-
- if (1 == move_out)
- {
- int last_n = 0;
- size_t last_pos = 0;
- zbx_json_type_t type;
-
- /* locate a copy of this record as found in database */
- id_offset.id = recid;
- if (NULL == (p_id_offset = (zbx_id_offset_t *)zbx_hashset_search(&h_id_offsets, &id_offset)))
- {
- THIS_SHOULD_NEVER_HAPPEN;
- goto clean2;
- }
-
- /* find the field requiring special preprocessing in JSON record */
- f = 1;
- while (NULL != (pf = zbx_json_next_value_dyn(&jp_row, pf, &buf, &buf_alloc, &type)))
- {
- /* parse values for the entry (lines 10-12 in T1) */
-
- if (fields_count == f)
- {
- *error = zbx_dsprintf(*error, "invalid number of fields \"%.*s\"",
- (int)(jp_row.end - jp_row.start + 1), jp_row.start);
- goto clean2;
- }
-
- if (move_field_nr == f)
- break;
- f++;
- }
-
- if (0 != compare_nth_field(fields, recs + p_id_offset->offset, move_field_nr, buf,
- (ZBX_JSON_TYPE_NULL == type), &last_n, &last_pos))
- {
- zbx_vector_uint64_append(&moves, recid);
- }
- }
- }
- else
- zbx_vector_uint64_append(&ins, recid);
- }
-
- /* copy IDs of records to be deleted from hash set to vector */
- zbx_hashset_iter_reset(&h_del, &iter);
- while (NULL != (p_recid = (uint64_t *)zbx_hashset_iter_next(&iter)))
- zbx_vector_uint64_append(del, *p_recid);
- zbx_vector_uint64_sort(del, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
-
- zbx_vector_uint64_sort(&ins, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
-
- if (1 == move_out)
- {
- /* special preprocessing for 'hosts_templates' table to eliminate conflicts */
- /* in the 'hostid, templateid' unique index */
- if (0 == strcmp("hosts_templates", table->table))
- {
- /* Making the 'hostid, templateid' combination unique to avoid collisions when new records */
- /* are inserted and existing ones are updated is a bit complex. Let's take a simpler approach */
- /* - delete affected old records and insert the new ones. */
- if (0 != moves.values_num)
- {
- zbx_vector_uint64_append_array(&ins, moves.values, moves.values_num);
- zbx_vector_uint64_sort(&ins, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
- zbx_vector_uint64_append_array(del, moves.values, moves.values_num);
- zbx_vector_uint64_sort(del, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
- }
-
- if (0 != del->values_num)
- {
- sql_offset = 0;
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "delete from %s where", table->table);
- DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, table->recid, del->values,
- del->values_num);
-
- if (ZBX_DB_OK > DBexecute("%s", sql))
- goto clean2;
-
- zbx_vector_uint64_clear(del);
- }
- }
- else
- {
- /* force index field update for removed records to avoid potential conflicts */
- if (0 != del->values_num)
- zbx_vector_uint64_append_array(&moves, del->values, del->values_num);
-
- /* special preprocessing for 'globalmacro', 'hostmacro', 'items', 'drules', 'regexps' and */
- /* 'httptest' tables to eliminate conflicts in the 'macro', 'hostid,macro', 'hostid,key_', */
- /* 'name', 'name' and 'hostid,name' unique indices */
- if (0 < moves.values_num)
- {
- sql_offset = 0;
-#ifdef HAVE_MYSQL
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
- "update %s set %s=concat('#',%s) where",
- table->table, fields[move_field_nr]->name, table->recid);
-#else
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update %s set %s='#'||%s where",
- table->table, fields[move_field_nr]->name, table->recid);
-#endif
- zbx_vector_uint64_sort(&moves, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
- DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, table->recid, moves.values,
- moves.values_num);
-
- if (ZBX_DB_OK > DBexecute("%s", sql))
- goto clean2;
- }
- }
- }
-
- /* apply insert operations */
-
- if (0 != ins.values_num)
- {
- zbx_vector_ptr_create(&values);
- zbx_db_insert_prepare_dyn(&db_insert, table, fields, fields_count);
-
- p = NULL;
- /* iterate the entries (lines 9, 14 and 19 in T1) */
- while (NULL != (p = zbx_json_next(&jp_data, p)))
- {
- zbx_json_type_t type;
- zbx_db_value_t *value;
-
- if (FAIL == zbx_json_brackets_open(p, &jp_row))
- {
- *error = zbx_dsprintf(*error, "invalid data format: %s", zbx_json_strerror());
- goto clean;
- }
-
- pf = zbx_json_next_value_dyn(&jp_row, NULL, &buf, &buf_alloc, NULL);
-
- /* check whether we need to insert a new entry or update an existing one */
- ZBX_STR2UINT64(recid, buf);
- if (FAIL == zbx_vector_uint64_bsearch(&ins, recid, ZBX_DEFAULT_UINT64_COMPARE_FUNC))
- continue;
-
- /* add the id field */
- value = (zbx_db_value_t *)zbx_malloc(NULL, sizeof(zbx_db_value_t));
- value->ui64 = recid;
- zbx_vector_ptr_append(&values, value);
-
- /* add the rest of fields */
- for (f = 1; NULL != (pf = zbx_json_next_value_dyn(&jp_row, pf, &buf, &buf_alloc, &type));
- f++)
- {
- if (f == fields_count)
- {
- *error = zbx_dsprintf(*error, "invalid number of fields \"%.*s\"",
- (int)(jp_row.end - jp_row.start + 1), jp_row.start);
- goto clean;
- }
-
- if (ZBX_JSON_TYPE_NULL == type && 0 != (fields[f]->flags & ZBX_NOTNULL))
- {
- *error = zbx_dsprintf(*error, "column \"%s.%s\" cannot be null",
- table->table, fields[f]->name);
- goto clean;
- }
-
- value = (zbx_db_value_t *)zbx_malloc(NULL, sizeof(zbx_db_value_t));
-
- switch (fields[f]->type)
- {
- case ZBX_TYPE_INT:
- value->i32 = atoi(buf);
- break;
- case ZBX_TYPE_UINT:
- ZBX_STR2UINT64(value->ui64, buf);
- break;
- case ZBX_TYPE_ID:
- if (ZBX_JSON_TYPE_NULL != type)
- ZBX_STR2UINT64(value->ui64, buf);
- else
- value->ui64 = 0;
- break;
- case ZBX_TYPE_FLOAT:
- value->dbl = atof(buf);
- break;
- case ZBX_TYPE_CHAR:
- case ZBX_TYPE_TEXT:
- case ZBX_TYPE_SHORTTEXT:
- case ZBX_TYPE_LONGTEXT:
- value->str = zbx_strdup(NULL, buf);
- break;
- default:
- *error = zbx_dsprintf(*error, "unsupported field type %d in \"%s.%s\"",
- (int)fields[f]->type, table->table, fields[f]->name);
- zbx_free(value);
- goto clean;
-
- }
-
- zbx_vector_ptr_append(&values, value);
- }
-
- zbx_db_insert_add_values_dyn(&db_insert, (const zbx_db_value_t **)values.values,
- values.values_num);
-
- for (f = 0; f < fields_count; f++)
- {
- switch (fields[f]->type)
- {
- case ZBX_TYPE_CHAR:
- case ZBX_TYPE_TEXT:
- case ZBX_TYPE_SHORTTEXT:
- case ZBX_TYPE_LONGTEXT:
- value = (zbx_db_value_t *)values.values[f];
- zbx_free(value->str);
- }
- }
- zbx_vector_ptr_clear_ext(&values, zbx_ptr_free);
-
- if (f != fields_count)
- {
- *error = zbx_dsprintf(*error, "invalid number of fields \"%.*s\"",
- (int)(jp_row.end - jp_row.start + 1), jp_row.start);
- goto clean;
- }
- }
-
- if (FAIL == zbx_db_insert_execute(&db_insert))
- goto clean;
- }
-
- /* apply update operations */
-
- sql_offset = 0;
- zbx_DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
-
- p = NULL;
- /* iterate the entries (lines 9, 14 and 19 in T1) */
- while (NULL != (p = zbx_json_next(&jp_data, p)))
- {
- int rec_differ = 0; /* how many fields differ */
- int last_n = 0;
- size_t tmp_offset = sql_offset, last_pos = 0;
- zbx_json_type_t type;
-
- if (FAIL == zbx_json_brackets_open(p, &jp_row))
- {
- *error = zbx_dsprintf(*error, "invalid data format: %s", zbx_json_strerror());
- goto clean;
- }
-
- pf = zbx_json_next_value_dyn(&jp_row, NULL, &buf, &buf_alloc, NULL);
-
- /* check whether we need to insert a new entry or update an existing one */
- ZBX_STR2UINT64(recid, buf);
- if (FAIL != zbx_vector_uint64_bsearch(&ins, recid, ZBX_DEFAULT_UINT64_COMPARE_FUNC))
- continue;
-
- if (1 == fields_count) /* only primary key given, no update needed */
- continue;
-
- /* locate a copy of this record as found in database */
- id_offset.id = recid;
- if (NULL == (p_id_offset = (zbx_id_offset_t *)zbx_hashset_search(&h_id_offsets, &id_offset)))
- {
- THIS_SHOULD_NEVER_HAPPEN;
- goto clean;
- }
-
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update %s set ", table->table);
-
- for (f = 1; NULL != (pf = zbx_json_next_value_dyn(&jp_row, pf, &buf, &buf_alloc, &type));
- f++)
- {
- /* parse values for the entry (lines 10-12 in T1) */
-
- if (f == fields_count)
- {
- *error = zbx_dsprintf(*error, "invalid number of fields \"%.*s\"",
- (int)(jp_row.end - jp_row.start + 1), jp_row.start);
- goto clean;
- }
-
- if (ZBX_JSON_TYPE_NULL == type && 0 != (fields[f]->flags & ZBX_NOTNULL))
- {
- *error = zbx_dsprintf(*error, "column \"%s.%s\" cannot be null",
- table->table, fields[f]->name);
- goto clean;
- }
-
- /* do not update existing lastlogsize and mtime fields */
- if (FAIL != zbx_vector_ptr_bsearch(&skip_fields, fields[f],
- ZBX_DEFAULT_PTR_COMPARE_FUNC))
- {
- continue;
- }
-
- if (0 == compare_nth_field(fields, recs + p_id_offset->offset, f, buf,
- (ZBX_JSON_TYPE_NULL == type), &last_n, &last_pos))
- {
- continue;
- }
-
- if (table == table_interface && 0 == strcmp(fields[f]->name, "available"))
- {
- /* host availability on server differs from local (proxy) availability - */
- /* reset availability timestamp to re-send availability data to server */
- zbx_vector_uint64_append(&availability_interfaceids, recid);
- continue;
- }
-
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%s=", fields[f]->name);
- rec_differ++;
-
- if (ZBX_JSON_TYPE_NULL == type)
- {
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "null,");
- continue;
- }
-
- switch (fields[f]->type)
- {
- case ZBX_TYPE_INT:
- case ZBX_TYPE_UINT:
- case ZBX_TYPE_ID:
- case ZBX_TYPE_FLOAT:
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%s,", buf);
- break;
- default:
- esc = DBdyn_escape_string(buf);
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "'%s',", esc);
- zbx_free(esc);
- }
- }
-
- if (f != fields_count)
- {
- *error = zbx_dsprintf(*error, "invalid number of fields \"%.*s\"",
- (int)(jp_row.end - jp_row.start + 1), jp_row.start);
- goto clean;
- }
-
- sql_offset--;
-
- if (0 != rec_differ)
- {
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where %s=" ZBX_FS_UI64 ";\n",
- table->recid, recid);
-
- if (SUCCEED != DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset))
- goto clean;
- }
- else
- {
- sql_offset = tmp_offset; /* discard this update, all fields are the same */
- *(sql + sql_offset) = '\0';
- }
- }
-
- if (16 < sql_offset) /* in ORACLE always present begin..end; */
- {
- zbx_DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
-
- if (ZBX_DB_OK > DBexecute("%s", sql))
- goto clean;
- }
-
- /* delete operations are performed by the caller using the returned del vector */
-
- if (0 != availability_interfaceids.values_num)
- {
- zbx_vector_uint64_sort(&availability_interfaceids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
- zbx_vector_uint64_uniq(&availability_interfaceids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
- DCtouch_interfaces_availability(&availability_interfaceids);
- }
-
- ret = SUCCEED;
-clean:
- if (0 != ins.values_num)
- {
- zbx_db_insert_clean(&db_insert);
- zbx_vector_ptr_destroy(&values);
- }
-clean2:
- zbx_hashset_destroy(&h_id_offsets);
- zbx_hashset_destroy(&h_del);
- zbx_vector_uint64_destroy(&availability_interfaceids);
- zbx_vector_uint64_destroy(&ins);
- if (1 == move_out)
- zbx_vector_uint64_destroy(&moves);
- zbx_free(sql);
- zbx_free(recs);
-out:
- zbx_free(buf);
-
- zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
-
- return ret;
-}
-
-/******************************************************************************
- * *
- * Purpose: update configuration *
- * *
- ******************************************************************************/
-int process_proxyconfig(struct zbx_json_parse *jp_data, struct zbx_json_parse *jp_kvs_paths)
-{
- typedef struct
- {
- const ZBX_TABLE *table;
- zbx_vector_uint64_t ids;
- }
- table_ids_t;
-
- char buf[ZBX_TABLENAME_LEN_MAX];
- const char *p = NULL;
- struct zbx_json_parse jp_obj;
- char *error = NULL;
- int i, ret = SUCCEED;
-
- table_ids_t *table_ids;
- zbx_vector_ptr_t tables_proxy;
- const ZBX_TABLE *table;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
-
- zbx_vector_ptr_create(&tables_proxy);
-
- DBbegin();
-
- /* iterate the tables (lines 2, 22 and 25 in T1) */
- while (NULL != (p = zbx_json_pair_next(jp_data, p, buf, sizeof(buf))) && SUCCEED == ret)
- {
- if (FAIL == zbx_json_brackets_open(p, &jp_obj))
- {
- error = zbx_strdup(error, zbx_json_strerror());
- ret = FAIL;
- break;
- }
-
- if (0 == strcmp(buf, "macro.secrets"))
- {
- *jp_kvs_paths = jp_obj;
- continue;
- }
-
- if (NULL == (table = DBget_table(buf)))
- {
- error = zbx_dsprintf(error, "invalid table name \"%s\"", buf);
- ret = FAIL;
- break;
- }
-
- table_ids = (table_ids_t *)zbx_malloc(NULL, sizeof(table_ids_t));
- table_ids->table = table;
- zbx_vector_uint64_create(&table_ids->ids);
- zbx_vector_ptr_append(&tables_proxy, table_ids);
-
- ret = process_proxyconfig_table(table, &jp_obj, &table_ids->ids, &error);
- }
-
- if (SUCCEED == ret)
- {
- char *sql = NULL;
- size_t sql_alloc = 512, sql_offset = 0;
-
- sql = (char *)zbx_malloc(sql, sql_alloc * sizeof(char));
-
- zbx_DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
-
- for (i = tables_proxy.values_num - 1; 0 <= i; i--)
- {
- table_ids = (table_ids_t *)tables_proxy.values[i];
-
- if (0 == table_ids->ids.values_num)
- continue;
-
- if (0 == strcmp(table_ids->table->table, "items"))
- {
- /* special case for item preprocessing - remove before removing items */
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from item_preproc where");
- DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, table_ids->table->recid,
- table_ids->ids.values, table_ids->ids.values_num);
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
-
- /* reset master_itemid to avoid recursive removal of dependent items */
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
- "update items set master_itemid=null where");
- DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", table_ids->ids.values,
- table_ids->ids.values_num);
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and master_itemid is not null;\n");
- }
-
- zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "delete from %s where",
- table_ids->table->table);
- DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, table_ids->table->recid,
- table_ids->ids.values, table_ids->ids.values_num);
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
-
- DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
- }
-
- if (sql_offset > 16) /* in ORACLE always present begin..end; */
- {
- zbx_DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
-
- if (ZBX_DB_OK > DBexecute("%s", sql))
- ret = FAIL;
- }
-
- zbx_free(sql);
- }
-
- for (i = 0; i < tables_proxy.values_num; i++)
- {
- table_ids = (table_ids_t *)tables_proxy.values[i];
-
- zbx_vector_uint64_destroy(&table_ids->ids);
- zbx_free(table_ids);
- }
- zbx_vector_ptr_destroy(&tables_proxy);
-
- if (SUCCEED != (ret = DBend(ret)))
- {
- zabbix_log(LOG_LEVEL_ERR, "failed to update local proxy configuration copy: %s",
- (NULL == error ? "database error" : error));
- }
-
- zbx_free(error);
-
- zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
-
- return ret;
-}
-
-/******************************************************************************
- * *
* Return value: SUCCEED - processed successfully *
* FAIL - no interface availability has been changed *
* *
@@ -2434,7 +761,6 @@ zbx_history_data_t;
static int proxy_get_history_data(zbx_uint64_t lastid, zbx_history_data_t **data, size_t *data_alloc,
char **string_buffer, size_t *string_buffer_alloc, int *more)
{
-
DB_RESULT result;
DB_ROW row;
char *sql = NULL;
@@ -2972,7 +1298,7 @@ static int process_history_data_value(DC_ITEM *item, zbx_agent_value_t *value, i
{
AGENT_RESULT result;
- init_result(&result);
+ zbx_init_agent_result(&result);
if (NULL != value->value)
{
@@ -3006,11 +1332,11 @@ static int process_history_data_value(DC_ITEM *item, zbx_agent_value_t *value, i
SET_LOG_RESULT(&result, log);
}
else
- set_result_type(&result, ITEM_VALUE_TYPE_TEXT, value->value);
+ zbx_set_agent_result_type(&result, ITEM_VALUE_TYPE_TEXT, value->value);
}
if (0 != value->meta)
- set_result_meta(&result, value->lastlogsize, value->mtime);
+ zbx_set_agent_result_meta(&result, value->lastlogsize, value->mtime);
if (0 != ZBX_ISSET_VALUE(&result) || 0 != ZBX_ISSET_META(&result))
{
@@ -3018,7 +1344,7 @@ static int process_history_data_value(DC_ITEM *item, zbx_agent_value_t *value, i
process_item_value(item, &result, &value->ts, h_num, NULL);
}
- free_result(&result);
+ zbx_free_agent_result(&result);
}
return SUCCEED;
@@ -3857,7 +2183,7 @@ static int process_client_history_data(zbx_socket_t *sock, struct zbx_json_parse
{
size_t token_len;
- if (zbx_get_token_len() != (token_len = strlen(token)))
+ if (ZBX_SESSION_TOKEN_SIZE != (token_len = strlen(token)))
{
*info = zbx_dsprintf(*info, "invalid session token length %d", (int)token_len);
ret = FAIL;
@@ -3866,12 +2192,12 @@ static int process_client_history_data(zbx_socket_t *sock, struct zbx_json_parse
}
if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_VERSION, tmp, sizeof(tmp), NULL) ||
- FAIL == (version = zbx_get_component_version(tmp)))
+ FAIL == (version = zbx_get_component_version_without_patch(tmp)))
{
- version = ZBX_COMPONENT_VERSION(4, 2);
+ version = ZBX_COMPONENT_VERSION(4, 2, 0);
}
- if (ZBX_COMPONENT_VERSION(4, 4) <= version &&
+ if (ZBX_COMPONENT_VERSION(4, 4, 0) <= version &&
SUCCEED == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOST, tmp, sizeof(tmp), NULL))
{
zbx_session_t *session;
@@ -4353,7 +2679,6 @@ static int process_autoregistration_contents(struct zbx_json_parse *jp_data, zbx
unsigned short port;
size_t host_metadata_alloc = 1; /* for at least NUL-terminating string */
zbx_vector_ptr_t autoreg_hosts;
- zbx_conn_flags_t flags = ZBX_CONN_DEFAULT;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
@@ -4369,7 +2694,8 @@ static int process_autoregistration_contents(struct zbx_json_parse *jp_data, zbx
while (NULL != (p = zbx_json_next(jp_data, p)))
{
- unsigned int connection_type;
+ unsigned int connection_type;
+ zbx_conn_flags_t flags = ZBX_CONN_DEFAULT;
if (FAIL == (ret = zbx_json_brackets_open(p, &jp_row)))
break;
@@ -4527,23 +2853,50 @@ int proxy_get_history_count(void)
* Parameters: *
* jp - [IN] JSON with the proxy version *
* *
- * Return value: The protocol version. *
- * SUCCEED - proxy version was successfully extracted *
- * FAIL - otherwise *
+ * Return value: The protocol version in textual representation, for example, *
+ * "6.4.0alpha1", *
+ * actual proxy version - if proxy version was successfully extracted *
+ * undefined version - otherwise *
+ * *
+ * Comments: allocates memory *
* *
******************************************************************************/
-int zbx_get_proxy_protocol_version(struct zbx_json_parse *jp)
+char *zbx_get_proxy_protocol_version_str(const struct zbx_json_parse *jp)
{
char value[MAX_STRING_LEN];
- int version;
- if (NULL != jp && SUCCEED == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_VERSION, value, sizeof(value), NULL) &&
- FAIL != (version = zbx_get_component_version(value)))
+ if (NULL != jp && SUCCEED == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_VERSION, value, sizeof(value), NULL))
+ return strdup(value);
+
+ return strdup(ZBX_VERSION_UNDEFINED_STR);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: converts protocol version fom textual to numeric representation *
+ * for version comparison. The function truncates release candidate *
+ * part of the version. *
+ * *
+ * Parameters: *
+ * version_str - [IN] proxy version, for example "6.4.0alpha1". *
+ * *
+ * Return value: The protocol version in numeric representation, for example, *
+ * 060400 *
+ * actual proxy version - if proxy version was successfully extracted *
+ * proxy version 3.2 - otherwise *
+ * *
+ ******************************************************************************/
+int zbx_get_proxy_protocol_version_int(const char *version_str)
+{
+ int version_int;
+
+ if (0 != strcmp(ZBX_VERSION_UNDEFINED_STR, version_str) &&
+ FAIL != (version_int = zbx_get_component_version(version_str)))
{
- return version;
+ return version_int;
}
- else
- return ZBX_COMPONENT_VERSION(3, 2);
+
+ return ZBX_COMPONENT_VERSION(3, 2, 0);
}
/******************************************************************************
@@ -4728,7 +3081,7 @@ int process_proxy_data(const DC_PROXY *proxy, struct zbx_json_parse *jp, zbx_tim
{
size_t token_len;
- if (zbx_get_token_len() != (token_len = strlen(value)))
+ if (ZBX_SESSION_TOKEN_SIZE != (token_len = strlen(value)))
{
*error = zbx_dsprintf(*error, "invalid session token length %d", (int)token_len);
ret = FAIL;
@@ -4912,40 +3265,112 @@ static void zbx_db_flush_proxy_lastaccess(void)
/******************************************************************************
* *
+ * Purpose: updates proxy version and compatibility with server in database *
+ * *
+ * Parameters: proxy - [IN] the proxy to update version for *
+ * diff - [IN] indicates changes to the proxy *
+ * *
+ ******************************************************************************/
+static void db_update_proxy_version(DC_PROXY *proxy, zbx_proxy_diff_t *diff)
+{
+ if (0 != (diff->flags & ZBX_FLAGS_PROXY_DIFF_UPDATE_VERSION))
+ {
+ if (0 != proxy->version_int)
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "proxy \"%s\" protocol version updated from %u.%u to %u.%u",
+ proxy->host,
+ ZBX_COMPONENT_VERSION_MAJOR(proxy->version_int),
+ ZBX_COMPONENT_VERSION_MINOR(proxy->version_int),
+ ZBX_COMPONENT_VERSION_MAJOR(diff->version_int),
+ ZBX_COMPONENT_VERSION_MINOR(diff->version_int));
+ }
+
+ if (ZBX_DB_OK > DBexecute(
+ "update host_rtdata"
+ " set version=%u,compatibility=%u"
+ " where hostid=" ZBX_FS_UI64,
+ ZBX_COMPONENT_VERSION_TO_DEC_FORMAT(diff->version_int), diff->compatibility,
+ diff->hostid))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "Failed to update proxy version and compatibility with server for"
+ " proxy '%s'.", proxy->host);
+ }
+ }
+}
+
+/******************************************************************************
+ * *
+ * Purpose: gets proxy version compatibility with server version *
+ * *
+ * Parameters: proxy_version - [IN] proxy_version *
+ * *
+ * Return value: proxy version compatibility with server version *
+ * *
+ ******************************************************************************/
+static zbx_proxy_compatibility_t zbx_get_proxy_compatibility(int proxy_version)
+{
+#define SERVER_VERSION ZBX_COMPONENT_VERSION(ZABBIX_VERSION_MAJOR, ZABBIX_VERSION_MINOR, 0)
+
+ if (0 == proxy_version)
+ return ZBX_PROXY_VERSION_UNDEFINED;
+
+ proxy_version = ZBX_COMPONENT_VERSION_WITHOUT_PATCH(proxy_version);
+
+ if (SERVER_VERSION == proxy_version)
+ return ZBX_PROXY_VERSION_CURRENT;
+
+ if (SERVER_VERSION < proxy_version)
+ return ZBX_PROXY_VERSION_UNSUPPORTED;
+#if (ZABBIX_VERSION_MINOR == 0)
+ if (ZABBIX_VERSION_MAJOR == 1 + ZBX_COMPONENT_VERSION_MAJOR(proxy_version))
+ return ZBX_PROXY_VERSION_STATUS_OUTDATED;
+#elif (ZABBIX_VERSION_MINOR > 0)
+ if (ZABBIX_VERSION_MAJOR == ZBX_COMPONENT_VERSION_MAJOR(proxy_version))
+ return ZBX_PROXY_VERSION_OUTDATED;
+#endif
+ return ZBX_PROXY_VERSION_UNSUPPORTED;
+
+#undef SERVER_VERSION
+}
+
+/******************************************************************************
+ * *
* Purpose: updates proxy runtime properties in cache and database. *
* *
- * Parameters: proxy - [IN/OUT] the proxy *
- * version - [IN] the proxy version *
- * lastaccess - [IN] the last proxy access time *
- * compress - [IN] 1 if proxy is using data compression, *
- * 0 otherwise *
- * flags_add - [IN] additional flags for update proxy *
+ * Parameters: proxy - [IN/OUT] the proxy *
+ * version_str - [IN] the proxy version as string *
+ * version_int - [IN] the proxy version in numeric representation *
+ * lastaccess - [IN] the last proxy access time *
+ * compress - [IN] 1 if proxy is using data compression, *
+ * 0 otherwise *
+ * flags_add - [IN] additional flags for update proxy *
* *
* Comments: The proxy parameter properties are also updated. *
* *
******************************************************************************/
-void zbx_update_proxy_data(DC_PROXY *proxy, int version, int lastaccess, int compress, zbx_uint64_t flags_add)
+void zbx_update_proxy_data(DC_PROXY *proxy, char *version_str, int version_int, int lastaccess, int compress,
+ zbx_uint64_t flags_add)
{
- zbx_proxy_diff_t diff;
+ zbx_proxy_diff_t diff;
+ zbx_proxy_compatibility_t compatibility;
+
+ compatibility = zbx_get_proxy_compatibility(version_int);
diff.hostid = proxy->hostid;
diff.flags = ZBX_FLAGS_PROXY_DIFF_UPDATE | flags_add;
- diff.version = version;
+ diff.version_str = version_str;
+ diff.version_int = version_int;
+ diff.compatibility = compatibility;
diff.lastaccess = lastaccess;
diff.compress = compress;
zbx_dc_update_proxy(&diff);
- if (0 != (diff.flags & ZBX_FLAGS_PROXY_DIFF_UPDATE_VERSION) && 0 != proxy->version)
- {
- zabbix_log(LOG_LEVEL_DEBUG, "proxy \"%s\" protocol version updated from %d.%d to %d.%d", proxy->host,
- ZBX_COMPONENT_VERSION_MAJOR(proxy->version),
- ZBX_COMPONENT_VERSION_MINOR(proxy->version),
- ZBX_COMPONENT_VERSION_MAJOR(diff.version),
- ZBX_COMPONENT_VERSION_MINOR(diff.version));
- }
+ db_update_proxy_version(proxy, &diff);
- proxy->version = version;
+ zbx_strlcpy(proxy->version_str, version_str, sizeof(proxy->version_str));
+ proxy->version_int = version_int;
+ proxy->compatibility = compatibility;
proxy->auto_compress = compress;
proxy->lastaccess = lastaccess;
@@ -4986,15 +3411,14 @@ static void zbx_update_proxy_lasterror(DC_PROXY *proxy)
******************************************************************************/
int zbx_check_protocol_version(DC_PROXY *proxy, int version)
{
- int server_version;
- int ret = SUCCEED;
- int now;
- int print_log = 0;
+ zbx_proxy_compatibility_t compatibility;
+
+ compatibility = zbx_get_proxy_compatibility(version);
/* warn if another proxy version is used and proceed with compatibility rules*/
- if ((server_version = ZBX_COMPONENT_VERSION(ZABBIX_VERSION_MAJOR, ZABBIX_VERSION_MINOR)) != version)
+ if (ZBX_PROXY_VERSION_CURRENT != compatibility)
{
- now = (int)time(NULL);
+ int now = zbx_time(), print_log = 0;
if (proxy->last_version_error_time <= now)
{
@@ -5003,36 +3427,30 @@ int zbx_check_protocol_version(DC_PROXY *proxy, int version)
zbx_update_proxy_lasterror(proxy);
}
- /* don't accept pre 4.2 data */
- if (ZBX_COMPONENT_VERSION(4, 2) > version)
+ if (ZBX_PROXY_VERSION_UNSUPPORTED == compatibility)
{
if (1 == print_log)
{
- zabbix_log(LOG_LEVEL_WARNING, "cannot process proxy \"%s\":"
- " protocol version %d.%d is not supported anymore",
- proxy->host, ZBX_COMPONENT_VERSION_MAJOR(version),
- ZBX_COMPONENT_VERSION_MINOR(version));
+ zabbix_log(LOG_LEVEL_WARNING, "Proxy \"%s\" version %u.%u.%u is not supported by server"
+ " version %d.%d.%d.", proxy->host,
+ ZBX_COMPONENT_VERSION_MAJOR(version),
+ ZBX_COMPONENT_VERSION_MINOR(version),
+ ZBX_COMPONENT_VERSION_PATCH(version), ZABBIX_VERSION_MAJOR,
+ ZABBIX_VERSION_MINOR, ZABBIX_VERSION_PATCH);
}
- ret = FAIL;
- goto out;
- }
-
- if (1 == print_log)
- {
- zabbix_log(LOG_LEVEL_WARNING, "proxy \"%s\" protocol version %d.%d differs from server version"
- " %d.%d", proxy->host, ZBX_COMPONENT_VERSION_MAJOR(version),
- ZBX_COMPONENT_VERSION_MINOR(version),
- ZABBIX_VERSION_MAJOR, ZABBIX_VERSION_MINOR);
+ return FAIL;
}
-
- if (version > server_version)
+ else if (ZBX_PROXY_VERSION_OUTDATED == compatibility && 1 == print_log)
{
- if (1 == print_log)
- zabbix_log(LOG_LEVEL_WARNING, "cannot accept proxy data");
- ret = FAIL;
+ zabbix_log(LOG_LEVEL_WARNING, "Proxy \"%s\" version %u.%u.%u is outdated, only data collection"
+ " and remote execution is available with server version %d.%d.%d.", proxy->host,
+ ZBX_COMPONENT_VERSION_MAJOR(version), ZBX_COMPONENT_VERSION_MINOR(version),
+ ZBX_COMPONENT_VERSION_PATCH(version), ZABBIX_VERSION_MAJOR,
+ ZABBIX_VERSION_MINOR, ZABBIX_VERSION_PATCH);
}
-
+ else if (ZBX_PROXY_VERSION_UNDEFINED == compatibility)
+ return FAIL;
}
-out:
- return ret;
+
+ return SUCCEED;
}
diff --git a/src/libs/zbxdbhigh/template_item.c b/src/libs/zbxdbhigh/template_item.c
index b93519cd3fe..9500bb99dbb 100644
--- a/src/libs/zbxdbhigh/template_item.c
+++ b/src/libs/zbxdbhigh/template_item.c
@@ -722,8 +722,11 @@ static void update_template_lld_rule_formulas(zbx_vector_ptr_t *items, zbx_vecto
{
zbx_template_item_t *item = (zbx_template_item_t *)items->values[i];
- if (0 == (ZBX_FLAG_DISCOVERY_RULE & item->flags) || CONDITION_EVAL_TYPE_EXPRESSION != item->evaltype)
+ if (0 == (ZBX_FLAG_DISCOVERY_RULE & item->flags) || ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION !=
+ item->evaltype)
+ {
continue;
+ }
index = zbx_vector_ptr_bsearch(rules, &item->templateid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
@@ -1676,7 +1679,7 @@ static void copy_template_item_tags(const zbx_vector_ptr_t *items)
for (j = 0; j < item->item_tags.values_num; j++)
{
- tag = (zbx_db_tag_t *)item->item_tags.values[j];
+ tag = item->item_tags.values[j];
if (0 != (tag->flags & ZBX_FLAG_DB_TAG_REMOVE))
{
@@ -1715,7 +1718,8 @@ static void copy_template_item_tags(const zbx_vector_ptr_t *items)
{
const char *d = "";
- tag = (zbx_db_tag_t *)item->item_tags.values[j];
+ tag = item->item_tags.values[j];
+
if (0 == tag->tagid)
{
zbx_db_insert_add_values(&db_insert, new_tagid, item->itemid, tag->tag, tag->value);
@@ -1828,7 +1832,7 @@ static void copy_template_item_script_params(const zbx_vector_ptr_t *items)
for (j = 0; j < item->item_params.values_num; j++)
{
- param = (zbx_item_param_t *)item->item_params.values[j];
+ param = item->item_params.values[j];
if (0 != (param->flags & ZBX_FLAG_ITEM_PARAM_DELETE))
{
@@ -1868,7 +1872,8 @@ static void copy_template_item_script_params(const zbx_vector_ptr_t *items)
{
const char *d = "";
- param = (zbx_item_param_t *)item->item_params.values[j];
+ param = item->item_params.values[j];
+
if (0 == param->item_parameterid)
{
zbx_db_insert_add_values(&db_insert, item_parameter_id, item->itemid, param->name,
@@ -2292,7 +2297,7 @@ static void save_template_lld_overrides(zbx_vector_ptr_t *overrides, zbx_hashset
override_conditionid, (int)override_condition->operator, override_condition->macro,
override_condition->value);
- if (CONDITION_EVAL_TYPE_EXPRESSION == override->evaltype)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION == override->evaltype)
{
update_template_lld_formula(&override->formula,
override_condition->override_conditionid, override_conditionid);
diff --git a/src/libs/zbxdbhigh/trigger_linking.c b/src/libs/zbxdbhigh/trigger_linking.c
index 6ce54f44676..b82a1ba1457 100644
--- a/src/libs/zbxdbhigh/trigger_linking.c
+++ b/src/libs/zbxdbhigh/trigger_linking.c
@@ -1209,8 +1209,8 @@ static int get_funcs_for_insert(zbx_uint64_t hostid, zbx_vector_uint64_t *insert
zbx_vector_uint64_append(&(found->itemids), itemid);
zbx_vector_str_append(&(found->functionids), zbx_strdup(NULL, row[1]));
zbx_vector_str_append(&(found->itemkeys), zbx_strdup(NULL, row[4]));
- zbx_vector_str_append(&(found->names), DBdyn_escape_string(row[2]));
- zbx_vector_str_append(&(found->parameters), DBdyn_escape_string(row[3]));
+ zbx_vector_str_append(&(found->names), zbx_strdup(NULL, row[2]));
+ zbx_vector_str_append(&(found->parameters), zbx_strdup(NULL, row[3]));
}
else
{
@@ -1225,8 +1225,8 @@ static int get_funcs_for_insert(zbx_uint64_t hostid, zbx_vector_uint64_t *insert
zbx_vector_uint64_append(&(local_temp_t.itemids), itemid);
zbx_vector_str_append(&(local_temp_t.functionids), zbx_strdup(NULL, row[1]));
zbx_vector_str_append(&(local_temp_t.itemkeys), zbx_strdup(NULL, row[4]));
- zbx_vector_str_append(&(local_temp_t.names), DBdyn_escape_string(row[2]));
- zbx_vector_str_append(&(local_temp_t.parameters), DBdyn_escape_string(row[3]));
+ zbx_vector_str_append(&(local_temp_t.names),zbx_strdup(NULL, row[2]));
+ zbx_vector_str_append(&(local_temp_t.parameters), zbx_strdup(NULL, row[3]));
local_temp_t.triggerid = temp_t.triggerid;
@@ -1280,7 +1280,7 @@ static int execute_triggers_inserts(zbx_vector_trigger_copies_insert_t *trigger_
zbx_db_insert_add_values(&db_insert, triggerid, trigger_copy_template->description,
(int)trigger_copy_template->priority, (int)trigger_copy_template->status,
trigger_copy_template->comments, trigger_copy_template->url,
- (int)trigger_copy_template->type, (int)TRIGGER_VALUE_OK, (int)TRIGGER_STATE_NORMAL,
+ (int)trigger_copy_template->type, TRIGGER_VALUE_OK, TRIGGER_STATE_NORMAL,
trigger_copy_template->templateid, (int)trigger_copy_template->flags,
(int)trigger_copy_template->recovery_mode, (int)trigger_copy_template->correlation_mode,
trigger_copy_template->correlation_tag, (int)trigger_copy_template->manual_close,
diff --git a/src/libs/zbxdbupgrade/dbupgrade_2010.c b/src/libs/zbxdbupgrade/dbupgrade_2010.c
index c893cf5f9a7..66abf788163 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_2010.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_2010.c
@@ -945,14 +945,14 @@ static int DBpatch_2010101(void)
if (1 != zbx_num_param(param))
{
- if (FAIL == (ret = quote_key_param(&param, 0)))
+ if (FAIL == (ret = zbx_quote_key_param(&param, 0)))
{
error_message = zbx_dsprintf(error_message, "unique description"
" \"%s\" contains invalid symbols and cannot be quoted", param);
}
}
- if (SUCCEED == ret && FAIL == (ret = quote_key_param(&dsn, 0)))
+ if (SUCCEED == ret && FAIL == (ret = zbx_quote_key_param(&dsn, 0)))
{
error_message = zbx_dsprintf(error_message, "data source name"
" \"%s\" contains invalid symbols and cannot be quoted", dsn);
@@ -1685,7 +1685,7 @@ static int DBpatch_2010195_replace_key_param_cb(const char *data, int key_type,
param = zbx_strdup(NULL, data);
- unquote_key_param(param);
+ zbx_unquote_key_param(param);
if ('\0' == *param)
{
@@ -1697,7 +1697,7 @@ static int DBpatch_2010195_replace_key_param_cb(const char *data, int key_type,
zbx_free(param);
- if (FAIL == (ret = quote_key_param(new_param, quoted)))
+ if (FAIL == (ret = zbx_quote_key_param(new_param, quoted)))
zbx_free(new_param);
return ret;
diff --git a/src/libs/zbxdbupgrade/dbupgrade_2030.c b/src/libs/zbxdbupgrade/dbupgrade_2030.c
index 787cbe5f9a4..bfeb5e1d524 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_2030.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_2030.c
@@ -22,6 +22,7 @@
#include "zbxdbhigh.h"
#include "log.h"
#include "zbxnum.h"
+#include "zbxexpr.h"
/*
* 2.4 development database patches
@@ -331,7 +332,7 @@ static int DBpatch_2030030(void)
static int DBpatch_2030031(void)
{
- /* 16 - CONDITION_TYPE_MAINTENANCE */
+ /* 16 - ZBX_CONDITION_TYPE_MAINTENANCE */
if (ZBX_DB_OK > DBexecute("update conditions set value='' where conditiontype=16"))
return FAIL;
@@ -478,7 +479,7 @@ static int DBpatch_2030044(void)
static int DBpatch_2030045(void)
{
- /* 17 - CONDITION_TYPE_NODE */
+ /* 17 - ZBX_CONDITION_TYPE_NODE */
const char *sql = "delete from conditions where conditiontype=17";
if (ZBX_DB_OK <= DBexecute("%s", sql))
@@ -1002,7 +1003,7 @@ static int parse_function(char **exp, char **func, char **params)
for (p = *exp, s = *exp, state_fn = 0; '\0' != *p; p++) /* check for function */
{
- if (SUCCEED == is_function_char(*p))
+ if (SUCCEED == zbx_is_function_char(*p))
{
state_fn = 1;
continue;
diff --git a/src/libs/zbxdbupgrade/dbupgrade_2050.c b/src/libs/zbxdbupgrade/dbupgrade_2050.c
index 6e0adf91e04..fcf473918a6 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_2050.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_2050.c
@@ -57,7 +57,7 @@ static int DBpatch_2050001(void)
param = zbx_strdup(NULL, row[1]);
zbx_snprintf_alloc(&oid, &oid_alloc, &oid_offset, "discovery[{#SNMPVALUE},%s]", param);
- if (FAIL == quote_key_param(&param, 0))
+ if (FAIL == zbx_quote_key_param(&param, 0))
{
zabbix_log(LOG_LEVEL_WARNING, "cannot convert SNMP discovery OID \"%s\":"
" OID contains invalid character(s)", row[1]);
@@ -178,9 +178,9 @@ static int DBpatch_2050012(void)
while (SUCCEED == ret && NULL != (row = DBfetch(result)))
{
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED != parse_item_key(row[2], &request))
+ if (SUCCEED != zbx_parse_item_key(row[2], &request))
{
zabbix_log(LOG_LEVEL_WARNING, "cannot parse item key \"%s\"", row[2]);
continue;
@@ -191,7 +191,7 @@ static int DBpatch_2050012(void)
/* NULL check to silence static analyzer warning */
if (NULL == param || (0 != strcmp("service.ntp", param) && 0 != strcmp("ntp", param)))
{
- free_request(&request);
+ zbx_free_agent_request(&request);
continue;
}
@@ -212,7 +212,7 @@ static int DBpatch_2050012(void)
while ('\0' != *(p++));
}
- free_request(&request);
+ zbx_free_agent_request(&request);
/* replace "net.tcp.service" with "net.udp.service" */
diff --git a/src/libs/zbxdbupgrade/dbupgrade_3010.c b/src/libs/zbxdbupgrade/dbupgrade_3010.c
index ad235022307..5b27f3904da 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_3010.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_3010.c
@@ -465,7 +465,7 @@ static int DBpatch_3010024_validate_action(zbx_uint64_t actionid, int eventsourc
DB_RESULT result;
int conditiontype, ret = ZBX_3010024_ACTION_DISABLE, value;
- /* evaltype: 0 - CONDITION_EVAL_TYPE_AND_OR, 1 - CONDITION_EVAL_TYPE_AND */
+ /* evaltype: 0 - ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR, 1 - ZBX_ACTION_CONDITION_EVAL_TYPE_AND */
if (evaltype != 0 && evaltype != 1)
return ret;
@@ -478,7 +478,7 @@ static int DBpatch_3010024_validate_action(zbx_uint64_t actionid, int eventsourc
/* eventsource: 0 - EVENT_SOURCE_TRIGGERS, 3 - EVENT_SOURCE_INTERNAL */
if (0 == eventsource)
{
- /* conditiontype: 5 - CONDITION_TYPE_TRIGGER_VALUE */
+ /* conditiontype: 5 - ZBX_CONDITION_TYPE_TRIGGER_VALUE */
if (5 != conditiontype)
continue;
@@ -510,7 +510,7 @@ static int DBpatch_3010024_validate_action(zbx_uint64_t actionid, int eventsourc
}
else if (3 == eventsource)
{
- /* conditiontype: 23 - CONDITION_TYPE_EVENT_TYPE */
+ /* conditiontype: 23 - ZBX_CONDITION_TYPE_EVENT_TYPE */
if (23 != conditiontype)
continue;
@@ -695,7 +695,7 @@ static void DBpatch_3010026_get_conditionids(zbx_uint64_t actionid, const char *
/* eventsource: 0 - EVENT_SOURCE_TRIGGERS, 3 - EVENT_SOURCE_INTERNAL */
if (0 == eventsource)
{
- /* conditiontype: 5 - CONDITION_TYPE_TRIGGER_VALUE */
+ /* conditiontype: 5 - ZBX_CONDITION_TYPE_TRIGGER_VALUE */
result = DBselect("select conditionid,value from conditions"
" where actionid=" ZBX_FS_UI64
" and conditiontype=5",
@@ -703,7 +703,7 @@ static void DBpatch_3010026_get_conditionids(zbx_uint64_t actionid, const char *
}
else if (3 == eventsource)
{
- /* conditiontype: 23 - CONDITION_TYPE_EVENT_TYPE */
+ /* conditiontype: 23 - ZBX_CONDITION_TYPE_EVENT_TYPE */
result = DBselect("select conditionid,value from conditions"
" where actionid=" ZBX_FS_UI64
" and conditiontype=23"
@@ -1045,7 +1045,7 @@ static int DBpatch_3010026(void)
index = conditionids.values_num;
DBpatch_3010026_get_conditionids(actionid, row[4], eventsource, &conditionids);
- /* evaltype: 3 - CONDITION_EVAL_TYPE_EXPRESSION */
+ /* evaltype: 3 - ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION */
if (3 != evaltype)
continue;
diff --git a/src/libs/zbxdbupgrade/dbupgrade_3030.c b/src/libs/zbxdbupgrade/dbupgrade_3030.c
index ee01303790c..1a549a26713 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_3030.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_3030.c
@@ -1749,7 +1749,7 @@ static int DBpatch_3030139(void)
static int DBpatch_3030140(void)
{
- /* CONDITION_TYPE_TIME_PERIOD */
+ /* ZBX_CONDITION_TYPE_TIME_PERIOD */
return DBpatch_trailing_semicolon_remove("conditions", "conditionid", "value", " where conditiontype=6");
}
diff --git a/src/libs/zbxdbupgrade/dbupgrade_3050.c b/src/libs/zbxdbupgrade/dbupgrade_3050.c
index 33a8eb25d7e..07253445bd6 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_3050.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_3050.c
@@ -1660,8 +1660,8 @@ static int DBpatch_3050145(void)
if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
return SUCCEED;
- /* CONDITION_OPERATOR_IN (4) -> CONDITION_OPERATOR_YES (10) */
- /* for conditiontype CONDITION_TYPE_SUPPRESSED (16) */
+ /* ZBX_CONDITION_OPERATOR_IN (4) -> ZBX_CONDITION_OPERATOR_YES (10) */
+ /* for conditiontype ZBX_CONDITION_TYPE_SUPPRESSED (16) */
ret = DBexecute("update conditions"
" set operator=10"
" where conditiontype=16"
@@ -1680,8 +1680,8 @@ static int DBpatch_3050146(void)
if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
return SUCCEED;
- /* CONDITION_OPERATOR_NOT_IN (7) -> CONDITION_OPERATOR_NO (11) */
- /* for conditiontype CONDITION_TYPE_SUPPRESSED (16) */
+ /* ZBX_CONDITION_OPERATOR_NOT_IN (7) -> ZBX_CONDITION_OPERATOR_NO (11) */
+ /* for conditiontype ZBX_CONDITION_TYPE_SUPPRESSED (16) */
ret = DBexecute("update conditions"
" set operator=11"
" where conditiontype=16"
diff --git a/src/libs/zbxdbupgrade/dbupgrade_4030.c b/src/libs/zbxdbupgrade/dbupgrade_4030.c
index 31cd0dc1598..6151c5f3c8d 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_4030.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_4030.c
@@ -19,9 +19,7 @@
#include "dbupgrade.h"
-#include "zbxexpr.h"
#include "zbxdbhigh.h"
-#include "zbxnum.h"
/*
* 4.4 development database patches
diff --git a/src/libs/zbxdbupgrade/dbupgrade_5010.c b/src/libs/zbxdbupgrade/dbupgrade_5010.c
index 04e38b7756c..7c982585efc 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_5010.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_5010.c
@@ -19,7 +19,6 @@
#include "dbupgrade.h"
-#include "zbxexpr.h"
#include "zbxdbhigh.h"
#include "log.h"
#include "zbxalgo.h"
diff --git a/src/libs/zbxdbupgrade/dbupgrade_5030.c b/src/libs/zbxdbupgrade/dbupgrade_5030.c
index 00797634b13..5c814e629c8 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_5030.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_5030.c
@@ -3858,18 +3858,18 @@ static int DBpatch_5030123(void)
static int DBpatch_5030127(void)
{
-#define CONDITION_TYPE_APPLICATION 15
+#define ZBX_CONDITION_TYPE_APPLICATION 15 /* deprecated */
if (0 == (program_type & ZBX_PROGRAM_TYPE_SERVER))
return SUCCEED;
if (ZBX_DB_OK > DBexecute("update conditions set conditiontype=%d,value2='Application' where conditiontype=%d",
- CONDITION_TYPE_EVENT_TAG_VALUE, CONDITION_TYPE_APPLICATION))
+ ZBX_CONDITION_TYPE_EVENT_TAG_VALUE, ZBX_CONDITION_TYPE_APPLICATION))
{
return FAIL;
}
return SUCCEED;
-#undef CONDITION_TYPE_APPLICATION
+#undef ZBX_CONDITION_TYPE_APPLICATION
}
static int DBpatch_5030128(void)
@@ -5168,7 +5168,7 @@ static char *dbpatch_formula_to_expression(zbx_uint64_t itemid, const char *form
ZBX_FS_UI64 "\" formula host:key parameter at %s", itemid, ptr);
}
- ret = parse_host_key(arg0, &host, &key);
+ ret = zbx_parse_host_key(arg0, &host, &key);
zbx_free(arg0);
if (FAIL == ret)
@@ -5469,9 +5469,9 @@ static int DBpatch_5030169(void)
params_offset = 0;
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED != parse_item_key(row[1], &request))
+ if (SUCCEED != zbx_parse_item_key(row[1], &request))
{
zabbix_log(LOG_LEVEL_WARNING, "Cannot parse aggregate checks item key \"%s\"", row[1]);
continue;
@@ -5479,7 +5479,7 @@ static int DBpatch_5030169(void)
ret_formula = dbpatch_aggregate2formula(row[0], &request, &params, &params_alloc, &params_offset,
&error);
- free_request(&request);
+ zbx_free_agent_request(&request);
if (FAIL == ret_formula)
{
diff --git a/src/libs/zbxdbupgrade/dbupgrade_5050.c b/src/libs/zbxdbupgrade/dbupgrade_5050.c
index 19019031141..3a0300d2a02 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_5050.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_5050.c
@@ -1590,6 +1590,7 @@ static void services_times_convert_downtime(zbx_vector_services_times_t *service
service_time_new.note = zbx_strdup(NULL, "");
zbx_vector_services_times_append(services_times, service_time_new);
+ service_time = &services_times->values[j];
}
service_time->to = service_downtime->from;
diff --git a/src/libs/zbxdbupgrade/dbupgrade_6010.c b/src/libs/zbxdbupgrade/dbupgrade_6010.c
index a25487ad766..eb9334c7033 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_6010.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_6010.c
@@ -759,7 +759,7 @@ static int DBpatch_6010033_split_groups(void)
ADD_GROUPIDS_FROM("opgroup");
ADD_GROUPIDS_FROM("scripts");
- /* 0 - CONDITION_TYPE_HOST_GROUP */
+ /* 0 - ZBX_CONDITION_TYPE_HOST_GROUP */
result = DBselect("select distinct value from conditions where conditiontype=0");
while (NULL != (row = DBfetch(result)))
diff --git a/src/libs/zbxdbupgrade/dbupgrade_6030.c b/src/libs/zbxdbupgrade/dbupgrade_6030.c
index f081969c31a..c9a97e161f2 100644
--- a/src/libs/zbxdbupgrade/dbupgrade_6030.c
+++ b/src/libs/zbxdbupgrade/dbupgrade_6030.c
@@ -20,6 +20,7 @@
#include "zbxcommon.h"
#include "zbxdbhigh.h"
#include "dbupgrade.h"
+#include "zbxdbschema.h"
extern unsigned char program_type;
@@ -162,6 +163,305 @@ static int DBpatch_6030006(void)
return DBmodify_field_type("proxy_autoreg_host", &field, &old_field);
}
+static int DBpatch_6030007(void)
+{
+ const ZBX_FIELD field = {"server_status", "", NULL, NULL, 0, ZBX_TYPE_SHORTTEXT, ZBX_NOTNULL, 0};
+
+ return DBadd_field("config", &field);
+}
+
+static int DBpatch_6030008(void)
+{
+ const ZBX_FIELD field = {"version", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0};
+
+ return DBadd_field("host_rtdata", &field);
+}
+
+static int DBpatch_6030009(void)
+{
+ const ZBX_FIELD field = {"compatibility", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0};
+
+ return DBadd_field("host_rtdata", &field);
+}
+
+static int DBpatch_6030010(void)
+{
+ const ZBX_FIELD field = {"url", "", NULL, NULL, 2048, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0};
+
+ return DBmodify_field_type("users", &field, NULL);
+}
+
+static int DBpatch_6030011(void)
+{
+ return DBcreate_changelog_insert_trigger("drules", "druleid");
+}
+
+static int DBpatch_6030012(void)
+{
+ return DBcreate_changelog_update_trigger("drules", "druleid");
+}
+
+static int DBpatch_6030013(void)
+{
+ return DBcreate_changelog_delete_trigger("drules", "druleid");
+}
+
+static int DBpatch_6030014(void)
+{
+ return DBcreate_changelog_insert_trigger("dchecks", "dcheckid");
+}
+
+static int DBpatch_6030015(void)
+{
+ return DBcreate_changelog_update_trigger("dchecks", "dcheckid");
+}
+
+static int DBpatch_6030016(void)
+{
+ return DBcreate_changelog_delete_trigger("dchecks", "dcheckid");
+}
+
+static int DBpatch_6030017(void)
+{
+ return DBcreate_changelog_insert_trigger("httptest", "httptestid");
+}
+
+static int DBpatch_6030018(void)
+{
+ return DBcreate_changelog_update_trigger("httptest", "httptestid");
+}
+
+static int DBpatch_6030019(void)
+{
+ return DBcreate_changelog_delete_trigger("httptest", "httptestid");
+}
+
+static int DBpatch_6030020(void)
+{
+ return DBcreate_changelog_insert_trigger("httptest_field", "httptest_fieldid");
+}
+
+static int DBpatch_6030021(void)
+{
+ return DBcreate_changelog_update_trigger("httptest_field", "httptest_fieldid");
+}
+
+static int DBpatch_6030022(void)
+{
+ return DBcreate_changelog_delete_trigger("httptest_field", "httptest_fieldid");
+}
+
+static int DBpatch_6030023(void)
+{
+ return DBcreate_changelog_insert_trigger("httptestitem", "httptestitemid");
+}
+
+static int DBpatch_6030024(void)
+{
+ return DBcreate_changelog_update_trigger("httptestitem", "httptestitemid");
+}
+
+static int DBpatch_6030025(void)
+{
+ return DBcreate_changelog_delete_trigger("httptestitem", "httptestitemid");
+}
+
+static int DBpatch_6030026(void)
+{
+ return DBcreate_changelog_insert_trigger("httpstep", "httpstepid");
+}
+
+static int DBpatch_6030027(void)
+{
+ return DBcreate_changelog_update_trigger("httpstep", "httpstepid");
+}
+
+static int DBpatch_6030028(void)
+{
+ return DBcreate_changelog_delete_trigger("httpstep", "httpstepid");
+}
+
+static int DBpatch_6030029(void)
+{
+ return DBcreate_changelog_insert_trigger("httpstep_field", "httpstep_fieldid");
+}
+
+static int DBpatch_6030030(void)
+{
+ return DBcreate_changelog_update_trigger("httpstep_field", "httpstep_fieldid");
+}
+
+static int DBpatch_6030031(void)
+{
+ return DBcreate_changelog_delete_trigger("httpstep_field", "httpstep_fieldid");
+}
+
+static int DBpatch_6030032(void)
+{
+ return DBcreate_changelog_insert_trigger("httpstepitem", "httpstepitemid");
+}
+
+static int DBpatch_6030033(void)
+{
+ return DBcreate_changelog_update_trigger("httpstepitem", "httpstepitemid");
+}
+
+static int DBpatch_6030034(void)
+{
+ return DBcreate_changelog_delete_trigger("httpstepitem", "httpstepitemid");
+}
+
+static int DBpatch_6030035(void)
+{
+ return DBdrop_field("drules", "nextcheck");
+}
+
+static int DBpatch_6030036(void)
+{
+ return DBdrop_field("httptest", "nextcheck");
+}
+
+static int DBpatch_6030037(void)
+{
+ const ZBX_FIELD field = {"discovery_groupid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, 0, 0};
+
+ return DBdrop_not_null("config", &field);
+}
+
+static int DBpatch_6030038(void)
+{
+ return DBdrop_foreign_key("dchecks", 1);
+}
+
+static int DBpatch_6030039(void)
+{
+ const ZBX_FIELD field = {"druleid", NULL, "drules", "druleid", 0, ZBX_TYPE_ID, 0, 0};
+
+ return DBadd_foreign_key("dchecks", 1, &field);
+}
+
+static int DBpatch_6030040(void)
+{
+ return DBdrop_foreign_key("httptest", 2);
+}
+
+static int DBpatch_6030041(void)
+{
+ const ZBX_FIELD field = {"hostid", NULL, "hosts", "hostid", 0, ZBX_TYPE_ID, 0, 0};
+
+ return DBadd_foreign_key("httptest", 2, &field);
+}
+
+static int DBpatch_6030042(void)
+{
+ return DBdrop_foreign_key("httptest", 3);
+}
+
+static int DBpatch_6030043(void)
+{
+ const ZBX_FIELD field = {"templateid", NULL, "httptest", "httptestid", 0, ZBX_TYPE_ID, 0, 0};
+
+ return DBadd_foreign_key("httptest", 3, &field);
+}
+
+static int DBpatch_6030044(void)
+{
+ return DBdrop_foreign_key("httpstep", 1);
+}
+
+static int DBpatch_6030045(void)
+{
+ const ZBX_FIELD field = {"httptestid", NULL, "httptest", "httptestid", 0, ZBX_TYPE_ID, 0, 0};
+
+ return DBadd_foreign_key("httpstep", 1, &field);
+}
+
+static int DBpatch_6030046(void)
+{
+ return DBdrop_foreign_key("httptestitem", 1);
+}
+
+static int DBpatch_6030047(void)
+{
+ const ZBX_FIELD field = {"httptestid", NULL, "httptest", "httptestid", 0, ZBX_TYPE_ID, 0, 0};
+
+ return DBadd_foreign_key("httptestitem", 1, &field);
+}
+
+static int DBpatch_6030048(void)
+{
+ return DBdrop_foreign_key("httptestitem", 2);
+}
+
+static int DBpatch_6030049(void)
+{
+ const ZBX_FIELD field = {"itemid", NULL, "items", "itemid", 0, ZBX_TYPE_ID, 0, 0};
+
+ return DBadd_foreign_key("httptestitem", 2, &field);
+}
+
+static int DBpatch_6030050(void)
+{
+ return DBdrop_foreign_key("httpstepitem", 1);
+}
+
+static int DBpatch_6030051(void)
+{
+ const ZBX_FIELD field = {"httpstepid", NULL, "httpstep", "httpstepid", 0, ZBX_TYPE_ID, 0, 0};
+
+ return DBadd_foreign_key("httpstepitem", 1, &field);
+}
+
+static int DBpatch_6030052(void)
+{
+ return DBdrop_foreign_key("httpstepitem", 2);
+}
+
+static int DBpatch_6030053(void)
+{
+ const ZBX_FIELD field = {"itemid", NULL, "items", "itemid", 0, ZBX_TYPE_ID, 0, 0};
+
+ return DBadd_foreign_key("httpstepitem", 2, &field);
+}
+
+static int DBpatch_6030054(void)
+{
+ return DBdrop_foreign_key("httptest_field", 1);
+}
+
+static int DBpatch_6030055(void)
+{
+ const ZBX_FIELD field = {"httptestid", NULL, "httptest", "httptestid", 0, ZBX_TYPE_ID, 0, 0};
+
+ return DBadd_foreign_key("httptest_field", 1, &field);
+}
+
+static int DBpatch_6030056(void)
+{
+ return DBdrop_foreign_key("httpstep_field", 1);
+}
+
+static int DBpatch_6030057(void)
+{
+ const ZBX_FIELD field = {"httpstepid", NULL, "httpstep", "httpstepid", 0, ZBX_TYPE_ID, 0, 0};
+
+ return DBadd_foreign_key("httpstep_field", 1, &field);
+}
+
+static int DBpatch_6030058(void)
+{
+ const ZBX_FIELD field = {"provider", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0};
+
+ return DBadd_field("media_type", &field);
+}
+
+static int DBpatch_6030059(void)
+{
+ const ZBX_FIELD field = {"status", "1", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0};
+
+ return DBset_default("media_type", &field);
+}
+
#endif
DBPATCH_START(6030)
@@ -175,5 +475,58 @@ DBPATCH_ADD(6030003, 0, 1)
DBPATCH_ADD(6030004, 0, 1)
DBPATCH_ADD(6030005, 0, 1)
DBPATCH_ADD(6030006, 0, 1)
+DBPATCH_ADD(6030007, 0, 1)
+DBPATCH_ADD(6030008, 0, 1)
+DBPATCH_ADD(6030009, 0, 1)
+DBPATCH_ADD(6030010, 0, 1)
+DBPATCH_ADD(6030011, 0, 1)
+DBPATCH_ADD(6030012, 0, 1)
+DBPATCH_ADD(6030013, 0, 1)
+DBPATCH_ADD(6030014, 0, 1)
+DBPATCH_ADD(6030015, 0, 1)
+DBPATCH_ADD(6030016, 0, 1)
+DBPATCH_ADD(6030017, 0, 1)
+DBPATCH_ADD(6030018, 0, 1)
+DBPATCH_ADD(6030019, 0, 1)
+DBPATCH_ADD(6030020, 0, 1)
+DBPATCH_ADD(6030021, 0, 1)
+DBPATCH_ADD(6030022, 0, 1)
+DBPATCH_ADD(6030023, 0, 1)
+DBPATCH_ADD(6030024, 0, 1)
+DBPATCH_ADD(6030025, 0, 1)
+DBPATCH_ADD(6030026, 0, 1)
+DBPATCH_ADD(6030027, 0, 1)
+DBPATCH_ADD(6030028, 0, 1)
+DBPATCH_ADD(6030029, 0, 1)
+DBPATCH_ADD(6030030, 0, 1)
+DBPATCH_ADD(6030031, 0, 1)
+DBPATCH_ADD(6030032, 0, 1)
+DBPATCH_ADD(6030033, 0, 1)
+DBPATCH_ADD(6030034, 0, 1)
+DBPATCH_ADD(6030035, 0, 1)
+DBPATCH_ADD(6030036, 0, 1)
+DBPATCH_ADD(6030037, 0, 1)
+DBPATCH_ADD(6030038, 0, 1)
+DBPATCH_ADD(6030039, 0, 1)
+DBPATCH_ADD(6030040, 0, 1)
+DBPATCH_ADD(6030041, 0, 1)
+DBPATCH_ADD(6030042, 0, 1)
+DBPATCH_ADD(6030043, 0, 1)
+DBPATCH_ADD(6030044, 0, 1)
+DBPATCH_ADD(6030045, 0, 1)
+DBPATCH_ADD(6030046, 0, 1)
+DBPATCH_ADD(6030047, 0, 1)
+DBPATCH_ADD(6030048, 0, 1)
+DBPATCH_ADD(6030049, 0, 1)
+DBPATCH_ADD(6030050, 0, 1)
+DBPATCH_ADD(6030051, 0, 1)
+DBPATCH_ADD(6030052, 0, 1)
+DBPATCH_ADD(6030053, 0, 1)
+DBPATCH_ADD(6030054, 0, 1)
+DBPATCH_ADD(6030055, 0, 1)
+DBPATCH_ADD(6030056, 0, 1)
+DBPATCH_ADD(6030057, 0, 1)
+DBPATCH_ADD(6030058, 0, 1)
+DBPATCH_ADD(6030059, 0, 1)
DBPATCH_END()
diff --git a/src/libs/zbxembed/global.c b/src/libs/zbxembed/global.c
index 914705dac28..cebb8553ec4 100644
--- a/src/libs/zbxembed/global.c
+++ b/src/libs/zbxembed/global.c
@@ -23,7 +23,6 @@
#include "embed.h"
#include "duktape.h"
#include "base64.h"
-#include "zbxhash.h"
#include "zbxcrypto.h"
/******************************************************************************
diff --git a/src/libs/zbxeval/execute.c b/src/libs/zbxeval/execute.c
index 3c4870341b8..8a669661a69 100644
--- a/src/libs/zbxeval/execute.c
+++ b/src/libs/zbxeval/execute.c
@@ -2031,7 +2031,7 @@ static int eval_execute_function_char(const zbx_eval_context_t *ctx, const zbx_e
if (SUCCEED != eval_convert_function_arg(ctx, token, ZBX_VARIANT_UI64, arg, error))
return FAIL;
- if (255 < arg->data.ui64)
+ if (127 < arg->data.ui64)
{
*error = zbx_dsprintf(*error, "function argument \"%s\" is out of allowed range at \"%s\"",
zbx_variant_value_desc(arg), ctx->expression + token->loc.l);
diff --git a/src/libs/zbxeval/parse.c b/src/libs/zbxeval/parse.c
index be33b950d38..e626eaa92f1 100644
--- a/src/libs/zbxeval/parse.c
+++ b/src/libs/zbxeval/parse.c
@@ -642,7 +642,7 @@ size_t eval_parse_query(const char *str, const char **phost, const char **pkey,
}
else if ('/' != *key)
{
- while (SUCCEED == is_hostname_char(*key))
+ while (SUCCEED == zbx_is_hostname_char(*key))
key++;
}
@@ -675,7 +675,7 @@ size_t eval_parse_query(const char *str, const char **phost, const char **pkey,
end += ZBX_CONST_STRLEN(MVAR_ITEM_KEY) + offset;
}
}
- else if (SUCCEED != parse_key(&end))
+ else if (SUCCEED != zbx_parse_key(&end))
return 0;
if (*end == '?')
diff --git a/src/libs/zbxexpr/Makefile.am b/src/libs/zbxexpr/Makefile.am
index 75027d380ce..72cbe843035 100644
--- a/src/libs/zbxexpr/Makefile.am
+++ b/src/libs/zbxexpr/Makefile.am
@@ -3,6 +3,9 @@
noinst_LIBRARIES = libzbxexpr.a
libzbxexpr_a_SOURCES = \
+ host.c \
+ macro.c \
+ function.c \
expr.c \
interval.c \
token.c
diff --git a/src/libs/zbxexpr/expr.c b/src/libs/zbxexpr/expr.c
index feb4b44cf0d..e9a20c3bb13 100644
--- a/src/libs/zbxexpr/expr.c
+++ b/src/libs/zbxexpr/expr.c
@@ -24,811 +24,144 @@
/******************************************************************************
* *
- * Purpose: validate parameters and give position of terminator if found and *
- * not quoted *
- * *
- * Parameters: expr - [IN] string to parse that contains parameters *
- * *
- * terminator - [IN] use ')' if parameters end with *
- * parenthesis or '\0' if ends with NULL *
- * terminator *
- * par_r - [OUT] position of the terminator if found *
- * lpp_offset - [OUT] offset of the last parsed parameter *
- * lpp_len - [OUT] length of the last parsed parameter *
+ * Return value: SUCCEED - the char is allowed in the item key *
+ * FAIL - otherwise *
* *
- * Return value: SUCCEED - closing parenthesis was found or other custom *
- * terminator and not quoted and return info about a *
- * last processed parameter. *
- * FAIL - does not look like a valid function parameter *
- * list and return info about a last processed *
- * parameter. *
+ * Comments: in key allowed characters: '0-9a-zA-Z._-' *
+ * !!! Don't forget to sync the code with PHP !!! *
* *
******************************************************************************/
-static int function_validate_parameters(const char *expr, char terminator, size_t *par_r, size_t *lpp_offset,
- size_t *lpp_len)
+int zbx_is_key_char(unsigned char c)
{
-#define ZBX_FUNC_PARAM_NEXT 0
-#define ZBX_FUNC_PARAM_QUOTED 1
-#define ZBX_FUNC_PARAM_UNQUOTED 2
-#define ZBX_FUNC_PARAM_POSTQUOTED 3
-
- const char *ptr;
- int state = ZBX_FUNC_PARAM_NEXT;
-
- *lpp_offset = 0;
-
- for (ptr = expr; '\0' != *ptr; ptr++)
- {
- if (terminator == *ptr && ZBX_FUNC_PARAM_QUOTED != state)
- {
- *par_r = ptr - expr;
- return SUCCEED;
- }
-
- switch (state)
- {
- case ZBX_FUNC_PARAM_NEXT:
- *lpp_offset = ptr - expr;
- if ('"' == *ptr)
- state = ZBX_FUNC_PARAM_QUOTED;
- else if (' ' != *ptr && ',' != *ptr)
- state = ZBX_FUNC_PARAM_UNQUOTED;
- break;
- case ZBX_FUNC_PARAM_QUOTED:
- if ('"' == *ptr && '\\' != *(ptr - 1))
- state = ZBX_FUNC_PARAM_POSTQUOTED;
- break;
- case ZBX_FUNC_PARAM_UNQUOTED:
- if (',' == *ptr)
- state = ZBX_FUNC_PARAM_NEXT;
- break;
- case ZBX_FUNC_PARAM_POSTQUOTED:
- if (',' == *ptr)
- {
- state = ZBX_FUNC_PARAM_NEXT;
- }
- else if (' ' != *ptr)
- {
- *lpp_len = ptr - (expr + *lpp_offset);
- return FAIL;
- }
- break;
- default:
- THIS_SHOULD_NEVER_HAPPEN;
- }
- }
-
- *lpp_len = ptr - (expr + *lpp_offset);
-
- if (terminator == *ptr && ZBX_FUNC_PARAM_QUOTED != state)
- {
- *par_r = ptr - expr;
+ if (0 != isalnum(c))
return SUCCEED;
- }
- return FAIL;
-
-#undef ZBX_FUNC_PARAM_NEXT
-#undef ZBX_FUNC_PARAM_QUOTED
-#undef ZBX_FUNC_PARAM_UNQUOTED
-#undef ZBX_FUNC_PARAM_POSTQUOTED
-}
-
-/******************************************************************************
- * *
- * Purpose: given the position of opening function parenthesis find the *
- * position of a closing one *
- * *
- * Parameters: expr - [IN] string to parse *
- * par_l - [IN] position of the opening parenthesis *
- * par_r - [OUT] position of the closing parenthesis *
- * lpp_offset - [OUT] offset of the last parsed parameter *
- * lpp_len - [OUT] length of the last parsed parameter *
- * *
- * Return value: SUCCEED - closing parenthesis was found *
- * FAIL - string after par_l does not look like a valid *
- * function parameter list *
- * *
- ******************************************************************************/
-static int function_match_parenthesis(const char *expr, size_t par_l, size_t *par_r, size_t *lpp_offset,
- size_t *lpp_len)
-{
- if (SUCCEED == function_validate_parameters(expr + par_l + 1, ')', par_r, lpp_offset, lpp_len))
- {
- *par_r += par_l + 1;
+ if (c == '.' || c == '_' || c == '-')
return SUCCEED;
- }
- *lpp_offset += par_l + 1;
return FAIL;
}
/******************************************************************************
* *
- * Purpose: parses function name *
+ * Purpose: advances pointer to first invalid character in string *
+ * ensuring that everything before it is a valid key *
* *
- * Parameters: expr - [IN] the function expression: func(p1, p2,...) *
- * length - [OUT] the function name length or the amount of *
- * characters that can be safely skipped *
+ * e.g., system.run[cat /etc/passwd | awk -F: '{ print $1 }'] *
* *
- * Return value: SUCCEED - the function name was successfully parsed *
- * FAIL - failed to parse function name *
+ * Parameters: exp - [IN/OUT] pointer to the first char of key *
* *
- ******************************************************************************/
-static int function_parse_name(const char *expr, size_t *length)
-{
- const char *ptr;
-
- for (ptr = expr; SUCCEED == is_function_char(*ptr); ptr++)
- ;
-
- *length = ptr - expr;
-
- return ptr != expr && '(' == *ptr ? SUCCEED : FAIL;
-}
-
-/******************************************************************************
+ * e.g., {host:system.run[cat /etc/passwd | awk -F: '{ print $1 }'].last(0)} *
+ * ^ *
+ * Return value: returns FAIL only if no key is present (length 0), *
+ * or the whole string is invalid. SUCCEED otherwise. *
* *
- * Purpose: check whether expression starts with a valid function *
- * *
- * Parameters: expr - [IN] string to parse *
- * par_l - [OUT] position of the opening parenthesis *
- * or the amount of characters to skip *
- * par_r - [OUT] position of the closing parenthesis *
- * error - [OUT] error message *
- * max_error_len - [IN] error size *
- * *
- * Return value: SUCCEED - string starts with a valid function *
- * FAIL - string does not start with a function and par_l *
- * characters can be safely skipped *
- * *
- ******************************************************************************/
-int zbx_function_validate(const char *expr, size_t *par_l, size_t *par_r, char *error, int max_error_len)
-{
- size_t lpp_offset, lpp_len;
-
- /* try to validate function name */
- if (SUCCEED == function_parse_name(expr, par_l))
- {
- /* now we know the position of '(', try to find ')' */
- if (SUCCEED == function_match_parenthesis(expr, *par_l, par_r, &lpp_offset, &lpp_len))
- return SUCCEED;
-
- if (NULL != error && *par_l > *par_r)
- {
- zbx_snprintf(error, max_error_len, "Incorrect function '%.*s' expression. "
- "Check expression part starting from: %.*s",
- (int)*par_l, expr, (int)lpp_len, expr + lpp_offset);
-
- return FAIL;
- }
- }
-
- if (NULL != error)
- zbx_snprintf(error, max_error_len, "Incorrect function expression: %s", expr);
-
- return FAIL;
-}
-
-/******************************************************************************
- * *
- * Purpose: validate parameters that end with '\0' *
- * *
- * Parameters: expr - [IN] string to parse that contains parameters *
- * length - [OUT] length of parameters *
- * *
- * Return value: SUCCEED - null termination encountered when quotes are *
- * closed and no other error *
- * FAIL - does not look like a valid *
- * function parameter list *
+ * Comments: the pointer is advanced to the first invalid character even if *
+ * FAIL is returned (meaning there is a syntax error in item key). *
+ * If necessary, the caller must keep a copy of pointer original *
+ * value. *
* *
******************************************************************************/
-int zbx_function_validate_parameters(const char *expr, size_t *length)
+int zbx_parse_key(const char **exp)
{
- size_t offset, len;
-
- return function_validate_parameters(expr, '\0', length, &offset, &len);
-}
-
-#define ZBX_MACRO_REGEX_PREFIX "regex:"
+ const char *s;
-/******************************************************************************
- * *
- * Purpose: *
- * parses user macro and finds its end position and context location *
- * *
- * Parameters: *
- * macro - [IN] the macro to parse *
- * macro_r - [OUT] the position of ending '}' character *
- * context_l - [OUT] the position of context start character (first non *
- * space character after context separator ':') *
- * 0 if macro does not have context specified. *
- * context_r - [OUT] the position of context end character (either the *
- * ending '"' for quoted context values or the last *
- * character before the ending '}' character) *
- * 0 if macro does not have context specified. *
- * context_op - [OUT] the context matching operator (optional): *
- * CONDITION_OPERATOR_EQUAL *
- * CONDITION_OPERATOR_REGEXP *
- * *
- * Return value: *
- * SUCCEED - the macro was parsed successfully. *
- * FAIL - the macro parsing failed, the content of output variables *
- * is not defined. *
- * *
- ******************************************************************************/
-int zbx_user_macro_parse(const char *macro, int *macro_r, int *context_l, int *context_r, unsigned char *context_op)
-{
- int i;
-
- /* find the end of macro name by skipping {$ characters and iterating through */
- /* valid macro name characters */
- for (i = 2; SUCCEED == is_macro_char(macro[i]); i++)
+ for (s = *exp; SUCCEED == zbx_is_key_char(*s); s++)
;
- /* check for empty macro name */
- if (2 == i)
- return FAIL;
-
- if ('}' == macro[i])
- {
- /* no macro context specified, parsing done */
- *macro_r = i;
- *context_l = 0;
- *context_r = 0;
-
- if (NULL != context_op)
- *context_op = CONDITION_OPERATOR_EQUAL;
-
- return SUCCEED;
- }
-
- /* fail if the next character is not a macro context separator */
- if (':' != macro[i])
- return FAIL;
-
- i++;
- if (NULL != context_op)
- {
- if (0 == strncmp(macro + i, ZBX_MACRO_REGEX_PREFIX, ZBX_CONST_STRLEN(ZBX_MACRO_REGEX_PREFIX)))
- {
- *context_op = CONDITION_OPERATOR_REGEXP;
- i += ZBX_CONST_STRLEN(ZBX_MACRO_REGEX_PREFIX);
- }
- else
- *context_op = CONDITION_OPERATOR_EQUAL;
- }
-
- /* skip the whitespace after macro context separator */
- while (' ' == macro[i])
- i++;
-
- *context_l = i;
-
- if ('"' == macro[i])
- {
- i++;
-
- /* process quoted context */
- for (; '"' != macro[i]; i++)
- {
- if ('\0' == macro[i])
- return FAIL;
-
- if ('\\' == macro[i] && '"' == macro[i + 1])
- i++;
- }
-
- *context_r = i;
-
- while (' ' == macro[++i])
- ;
- }
- else
- {
- /* process unquoted context */
- for (; '}' != macro[i]; i++)
- {
- if ('\0' == macro[i])
- return FAIL;
- }
-
- *context_r = i - 1;
- }
-
- if ('}' != macro[i])
- return FAIL;
-
- *macro_r = i;
-
- return SUCCEED;
-}
-
-/******************************************************************************
- * *
- * Purpose: *
- * parses user macro {$MACRO:<context>} into {$MACRO} and <context> *
- * strings *
- * *
- * Parameters: *
- * macro - [IN] the macro to parse *
- * name - [OUT] the macro name without context *
- * context - [OUT] the unquoted macro context, NULL for macros without *
- * context *
- * length - [OUT] the length of parsed macro (optional) *
- * context_op - [OUT] the context matching operator (optional): *
- * CONDITION_OPERATOR_EQUAL *
- * CONDITION_OPERATOR_REGEXP *
- * *
- * Return value: *
- * SUCCEED - the macro was parsed successfully *
- * FAIL - the macro parsing failed, invalid parameter syntax *
- * *
- ******************************************************************************/
-int zbx_user_macro_parse_dyn(const char *macro, char **name, char **context, int *length, unsigned char *context_op)
-{
- const char *ptr;
- int macro_r, context_l, context_r;
- size_t len;
-
- if (SUCCEED != zbx_user_macro_parse(macro, &macro_r, &context_l, &context_r, context_op))
+ if (*exp == s) /* the key is empty */
return FAIL;
- zbx_free(*context);
-
- if (0 != context_l)
- {
- ptr = macro + context_l;
-
- /* find the context separator ':' by stripping spaces before context */
- while (' ' == *(--ptr))
- ;
-
- /* remove regex: prefix from macro name for regex contexts */
- if (NULL != context_op && CONDITION_OPERATOR_REGEXP == *context_op)
- ptr -= ZBX_CONST_STRLEN(ZBX_MACRO_REGEX_PREFIX);
-
- /* extract the macro name and close with '}' character */
- len = ptr - macro + 1;
- *name = (char *)zbx_realloc(*name, len + 1);
- memcpy(*name, macro, len - 1);
- (*name)[len - 1] = '}';
- (*name)[len] = '\0';
-
- *context = zbx_user_macro_unquote_context_dyn(macro + context_l, context_r - context_l + 1);
- }
- else
- {
- *name = (char *)zbx_realloc(*name, macro_r + 2);
- zbx_strlcpy(*name, macro, macro_r + 2);
- }
-
- if (NULL != length)
- *length = macro_r + 1;
-
- return SUCCEED;
-}
-
-#undef ZBX_MACRO_REGEX_PREFIX
-
-/******************************************************************************
- * *
- * Purpose: *
- * extracts the macro context unquoting if necessary *
- * *
- * Parameters: *
- * context - [IN] the macro context inside a user macro *
- * len - [IN] the macro context length (including quotes for quoted *
- * contexts) *
- * *
- * Return value: *
- * A string containing extracted macro context. This string must be freed *
- * by the caller. *
- * *
- ******************************************************************************/
-char *zbx_user_macro_unquote_context_dyn(const char *context, int len)
-{
- int quoted = 0;
- char *buffer, *ptr;
-
- ptr = buffer = (char *)zbx_malloc(NULL, len + 1);
-
- if ('"' == *context)
- {
- quoted = 1;
- context++;
- len--;
- }
-
- while (0 < len)
- {
- if (1 == quoted && '\\' == *context && '"' == context[1])
- {
- context++;
- len--;
- }
-
- *ptr++ = *context++;
- len--;
- }
-
- if (1 == quoted)
- ptr--;
-
- *ptr = '\0';
-
- return buffer;
-}
-
-/******************************************************************************
- * *
- * Purpose: *
- * quotes user macro context if necessary *
- * *
- * Parameters: *
- * context - [IN] the macro context *
- * force_quote - [IN] if non zero then context quoting is enforced *
- * error - [OUT] the error message *
- * *
- * Return value: *
- * A string containing quoted macro context on success, NULL on error. *
- * *
- ******************************************************************************/
-char *zbx_user_macro_quote_context_dyn(const char *context, int force_quote, char **error)
-{
- int len, quotes = 0;
- char *buffer, *ptr_buffer;
- const char *ptr_context = context, *start = context;
-
- if ('"' == *ptr_context || ' ' == *ptr_context)
- force_quote = 1;
-
- for (; '\0' != *ptr_context; ptr_context++)
- {
- if ('}' == *ptr_context)
- force_quote = 1;
-
- if ('"' == *ptr_context)
- quotes++;
- }
-
- if (0 == force_quote)
- return zbx_strdup(NULL, context);
-
- len = (int)strlen(context) + 2 + quotes;
- ptr_buffer = buffer = (char *)zbx_malloc(NULL, len + 1);
-
- *ptr_buffer++ = '"';
-
- while ('\0' != *context)
- {
- if ('"' == *context)
- *ptr_buffer++ = '\\';
-
- *ptr_buffer++ = *context++;
- }
-
- if ('\\' == *(ptr_buffer - 1))
- {
- *error = zbx_dsprintf(*error, "quoted context \"%s\" cannot end with '\\' character", start);
- zbx_free(buffer);
- return NULL;
- }
-
- *ptr_buffer++ = '"';
- *ptr_buffer++ = '\0';
-
- return buffer;
-}
-
-/******************************************************************************
- * *
- * Purpose: count calculated item (prototype) formula characters that can be *
- * skipped without the risk of missing a function *
- * *
- ******************************************************************************/
-static size_t zbx_no_function(const char *expr)
-{
- const char *ptr = expr;
- int inside_quote = 0, len, c_l, c_r;
- zbx_token_t token;
-
- while ('\0' != *ptr)
- {
- switch (*ptr)
- {
- case '\\':
- if (0 != inside_quote)
- ptr++;
- break;
- case '"':
- inside_quote = !inside_quote;
- ptr++;
- continue;
- }
-
- if (inside_quote)
- {
- if ('\0' == *ptr)
- break;
- ptr++;
- continue;
- }
-
- if ('{' == *ptr && '$' == *(ptr + 1) && SUCCEED == zbx_user_macro_parse(ptr, &len, &c_l, &c_r, NULL))
- {
- ptr += len + 1; /* skip to the position after user macro */
- }
- else if ('{' == *ptr && '{' == *(ptr + 1) && '#' == *(ptr + 2) &&
- SUCCEED == zbx_token_parse_nested_macro(ptr, ptr, 0, &token))
- {
- ptr += token.loc.r - token.loc.l + 1;
- }
- else if (SUCCEED != is_function_char(*ptr))
- {
- ptr++; /* skip one character which cannot belong to function name */
- }
- else if ((0 == strncmp("and", ptr, len = ZBX_CONST_STRLEN("and")) ||
- 0 == strncmp("not", ptr, len = ZBX_CONST_STRLEN("not")) ||
- 0 == strncmp("or", ptr, len = ZBX_CONST_STRLEN("or"))) &&
- NULL != strchr("()" ZBX_WHITESPACE, ptr[len]))
- {
- ptr += len; /* skip to the position after and/or/not operator */
- }
- else if (ptr > expr && 0 != isdigit(*(ptr - 1)) && NULL != strchr(ZBX_UNIT_SYMBOLS, *ptr))
- {
- ptr++; /* skip unit suffix symbol if it's preceded by a digit */
- }
- else
- break;
- }
-
- return ptr - expr;
-}
-
-/******************************************************************************
- * *
- * Purpose: find the location of the next function and its parameters in *
- * calculated item (prototype) formula *
- * *
- * Parameters: expr - [IN] string to parse *
- * func_pos - [OUT] function position in the string *
- * par_l - [OUT] position of the opening parenthesis *
- * par_r - [OUT] position of the closing parenthesis *
- * error - [OUT] error message *
- * max_error_len - [IN] error size *
- * *
- * Return value: SUCCEED - function was found at func_pos *
- * FAIL - there are no functions in the expression *
- * *
- ******************************************************************************/
-int zbx_function_find(const char *expr, size_t *func_pos, size_t *par_l, size_t *par_r, char *error,
- int max_error_len)
-{
- const char *ptr;
-
- for (ptr = expr; '\0' != *ptr; ptr += *par_l)
- {
- /* skip the part of expression that is definitely not a function */
- ptr += zbx_no_function(ptr);
- *par_r = 0;
-
- /* try to validate function candidate */
- if (SUCCEED != zbx_function_validate(ptr, par_l, par_r, error, max_error_len))
- {
- if (*par_l > *par_r)
- return FAIL;
-
- continue;
- }
-
- *func_pos = ptr - expr;
- *par_l += *func_pos;
- *par_r += *func_pos;
- return SUCCEED;
- }
-
- zbx_snprintf(error, max_error_len, "Incorrect function expression: %s", expr);
-
- return FAIL;
-}
-
-/******************************************************************************
- * *
- * Purpose: parses function parameter *
- * *
- * Parameters: expr - [IN] pre-validated function parameter list *
- * param_pos - [OUT] the parameter position, excluding leading *
- * whitespace *
- * length - [OUT] the parameter length including trailing *
- * whitespace for unquoted parameter *
- * sep_pos - [OUT] the parameter separator character *
- * (',' or '\0' or ')') position *
- * *
- ******************************************************************************/
-void zbx_function_param_parse(const char *expr, size_t *param_pos, size_t *length, size_t *sep_pos)
-{
- const char *ptr = expr;
-
- /* skip the leading whitespace */
- while (' ' == *ptr)
- ptr++;
-
- *param_pos = ptr - expr;
-
- if ('"' == *ptr) /* quoted parameter */
- {
- for (ptr++; '"' != *ptr || '\\' == *(ptr - 1); ptr++)
- ;
-
- *length = ++ptr - expr - *param_pos;
-
- /* skip trailing whitespace to find the next parameter */
- while (' ' == *ptr)
- ptr++;
- }
- else /* unquoted parameter */
+ if ('[' == *s) /* for instance, net.tcp.port[,80] */
{
- for (ptr = expr; '\0' != *ptr && ')' != *ptr && ',' != *ptr; ptr++)
- ;
+ int state = 0; /* 0 - init, 1 - inside quoted param, 2 - inside unquoted param */
+ int array = 0; /* array nest level */
- *length = ptr - expr - *param_pos;
- }
-
- *sep_pos = ptr - expr;
-}
-
-/******************************************************************************
- * *
- * Purpose: unquotes function parameter *
- * *
- * Parameters: param - [IN] the parameter to unquote *
- * len - [IN] the parameter length *
- * quoted - [OUT] the flag that specifies whether parameter was *
- * quoted before extraction *
- * *
- * Return value: The unquoted parameter. This value must be freed by the *
- * caller. *
- * *
- ******************************************************************************/
-char *zbx_function_param_unquote_dyn(const char *param, size_t len, int *quoted)
-{
- char *out;
-
- out = (char *)zbx_malloc(NULL, len + 1);
-
- if (0 == (*quoted = (0 != len && '"' == *param)))
- {
- /* unquoted parameter - simply copy it */
- memcpy(out, param, len);
- out[len] = '\0';
- }
- else
- {
- /* quoted parameter - remove enclosing " and replace \" with " */
- const char *pin;
- char *pout = out;
-
- for (pin = param + 1; (size_t)(pin - param) < len - 1; pin++)
+ for (s++; '\0' != *s; s++)
{
- if ('\\' == pin[0] && '"' == pin[1])
- pin++;
-
- *pout++ = *pin;
+ switch (state)
+ {
+ /* init state */
+ case 0:
+ if (',' == *s)
+ ;
+ else if ('"' == *s)
+ state = 1;
+ else if ('[' == *s)
+ {
+ if (0 == array)
+ array = 1;
+ else
+ goto fail; /* incorrect syntax: multi-level array */
+ }
+ else if (']' == *s && 0 != array)
+ {
+ array = 0;
+ s++;
+
+ while (' ' == *s) /* skip trailing spaces after closing ']' */
+ s++;
+
+ if (']' == *s)
+ goto succeed;
+
+ if (',' != *s)
+ goto fail; /* incorrect syntax */
+ }
+ else if (']' == *s && 0 == array)
+ goto succeed;
+ else if (' ' != *s)
+ state = 2;
+ break;
+ /* quoted */
+ case 1:
+ if ('"' == *s)
+ {
+ while (' ' == s[1]) /* skip trailing spaces after closing quotes */
+ s++;
+
+ if (0 == array && ']' == s[1])
+ {
+ s++;
+ goto succeed;
+ }
+
+ if (',' != s[1] && !(0 != array && ']' == s[1]))
+ {
+ s++;
+ goto fail; /* incorrect syntax */
+ }
+
+ state = 0;
+ }
+ else if ('\\' == *s && '"' == s[1])
+ s++;
+ break;
+ /* unquoted */
+ case 2:
+ if (',' == *s || (']' == *s && 0 != array))
+ {
+ s--;
+ state = 0;
+ }
+ else if (']' == *s && 0 == array)
+ goto succeed;
+ break;
+ }
}
-
- *pout = '\0';
- }
-
- return out;
-}
-
-/******************************************************************************
- * *
- * Purpose: quotes function parameter *
- * *
- * Parameters: param - [IN/OUT] function parameter *
- * forced - [IN] 1 - enclose parameter in " even if it does not *
- * contain any special characters *
- * 0 - do nothing if the parameter does not *
- * contain any special characters *
- * *
- * Return value: SUCCEED - if parameter was successfully quoted or quoting *
- * was not necessary *
- * FAIL - if parameter needs to but cannot be quoted due to *
- * backslash in the end *
- * *
- ******************************************************************************/
-int zbx_function_param_quote(char **param, int forced)
-{
- size_t sz_src, sz_dst;
-
- if (0 == forced && '"' != **param && ' ' != **param && NULL == strchr(*param, ',') &&
- NULL == strchr(*param, ')'))
- {
- return SUCCEED;
- }
-
- if (0 != (sz_src = strlen(*param)) && '\\' == (*param)[sz_src - 1])
+fail:
+ *exp = s;
return FAIL;
-
- sz_dst = zbx_get_escape_string_len(*param, "\"") + 3;
-
- *param = (char *)zbx_realloc(*param, sz_dst);
-
- (*param)[--sz_dst] = '\0';
- (*param)[--sz_dst] = '"';
-
- while (0 < sz_src)
- {
- (*param)[--sz_dst] = (*param)[--sz_src];
- if ('"' == (*param)[sz_src])
- (*param)[--sz_dst] = '\\';
+succeed:
+ s++;
}
- (*param)[--sz_dst] = '"';
+ *exp = s;
return SUCCEED;
}
/******************************************************************************
* *
- * Purpose: return parameter by index (Nparam) from parameter list (params) *
- * *
- * Parameters: *
- * params - [IN] parameter list *
- * Nparam - [IN] requested parameter index (from 1) *
- * *
- * Return value: *
- * NULL - requested parameter missing *
- * otherwise - requested parameter *
- * *
- ******************************************************************************/
-char *zbx_function_get_param_dyn(const char *params, int Nparam)
-{
- const char *ptr;
- size_t sep_pos, params_len;
- char *out = NULL;
- int idx = 0;
-
- params_len = strlen(params) + 1;
-
- for (ptr = params; ++idx <= Nparam && ptr < params + params_len; ptr += sep_pos + 1)
- {
- size_t param_pos, param_len;
- int quoted;
-
- zbx_function_param_parse(ptr, &param_pos, &param_len, &sep_pos);
-
- if (idx == Nparam)
- out = zbx_function_param_unquote_dyn(ptr + param_pos, param_len, &quoted);
- }
-
- return out;
-}
-
-/******************************************************************************
- * *
- * Purpose: Returns function type based on its name *
- * *
- * Return value: Function type. *
- * *
- ******************************************************************************/
-zbx_function_type_t zbx_get_function_type(const char *func)
-{
- if (0 == strncmp(func, "trend", 5))
- return ZBX_FUNCTION_TYPE_TRENDS;
-
- if (0 == strncmp(func, "baseline", 8))
- return ZBX_FUNCTION_TYPE_TRENDS;
-
- if (0 == strcmp(func, "nodata"))
- return ZBX_FUNCTION_TYPE_TIMER;
-
- return ZBX_FUNCTION_TYPE_HISTORY;
-}
-
-/******************************************************************************
- * *
* Purpose: check if the string is double *
* *
* Parameters: str - string to check *
@@ -922,19 +255,19 @@ int zbx_strmatch_condition(const char *value, const char *pattern, unsigned char
switch (op)
{
- case CONDITION_OPERATOR_EQUAL:
+ case ZBX_CONDITION_OPERATOR_EQUAL:
if (0 == strcmp(value, pattern))
ret = SUCCEED;
break;
- case CONDITION_OPERATOR_NOT_EQUAL:
+ case ZBX_CONDITION_OPERATOR_NOT_EQUAL:
if (0 != strcmp(value, pattern))
ret = SUCCEED;
break;
- case CONDITION_OPERATOR_LIKE:
+ case ZBX_CONDITION_OPERATOR_LIKE:
if (NULL != strstr(value, pattern))
ret = SUCCEED;
break;
- case CONDITION_OPERATOR_NOT_LIKE:
+ case ZBX_CONDITION_OPERATOR_NOT_LIKE:
if (NULL == strstr(value, pattern))
ret = SUCCEED;
break;
diff --git a/src/libs/zbxexpr/function.c b/src/libs/zbxexpr/function.c
new file mode 100644
index 00000000000..3fb34d2907f
--- /dev/null
+++ b/src/libs/zbxexpr/function.c
@@ -0,0 +1,555 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2022 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 "zbxexpr.h"
+
+#include "zbxnum.h"
+#include "zbxstr.h"
+
+/******************************************************************************
+ * *
+ * Return value: SUCCEED - the char is allowed in the trigger function *
+ * FAIL - otherwise *
+ * *
+ * Comments: in trigger function allowed characters: 'a-z' *
+ * !!! Don't forget to sync the code with PHP !!! *
+ * *
+ ******************************************************************************/
+int zbx_is_function_char(unsigned char c)
+{
+ if (0 != islower(c))
+ return SUCCEED;
+
+ return FAIL;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: validate parameters and give position of terminator if found and *
+ * not quoted *
+ * *
+ * Parameters: expr - [IN] string to parse that contains parameters *
+ * *
+ * terminator - [IN] use ')' if parameters end with *
+ * parenthesis or '\0' if ends with NULL *
+ * terminator *
+ * par_r - [OUT] position of the terminator if found *
+ * lpp_offset - [OUT] offset of the last parsed parameter *
+ * lpp_len - [OUT] length of the last parsed parameter *
+ * *
+ * Return value: SUCCEED - closing parenthesis was found or other custom *
+ * terminator and not quoted and return info about a *
+ * last processed parameter. *
+ * FAIL - does not look like a valid function parameter *
+ * list and return info about a last processed *
+ * parameter. *
+ * *
+ ******************************************************************************/
+static int function_validate_parameters(const char *expr, char terminator, size_t *par_r, size_t *lpp_offset,
+ size_t *lpp_len)
+{
+#define ZBX_FUNC_PARAM_NEXT 0
+#define ZBX_FUNC_PARAM_QUOTED 1
+#define ZBX_FUNC_PARAM_UNQUOTED 2
+#define ZBX_FUNC_PARAM_POSTQUOTED 3
+
+ const char *ptr;
+ int state = ZBX_FUNC_PARAM_NEXT;
+
+ *lpp_offset = 0;
+
+ for (ptr = expr; '\0' != *ptr; ptr++)
+ {
+ if (terminator == *ptr && ZBX_FUNC_PARAM_QUOTED != state)
+ {
+ *par_r = ptr - expr;
+ return SUCCEED;
+ }
+
+ switch (state)
+ {
+ case ZBX_FUNC_PARAM_NEXT:
+ *lpp_offset = ptr - expr;
+ if ('"' == *ptr)
+ state = ZBX_FUNC_PARAM_QUOTED;
+ else if (' ' != *ptr && ',' != *ptr)
+ state = ZBX_FUNC_PARAM_UNQUOTED;
+ break;
+ case ZBX_FUNC_PARAM_QUOTED:
+ if ('"' == *ptr && '\\' != *(ptr - 1))
+ state = ZBX_FUNC_PARAM_POSTQUOTED;
+ break;
+ case ZBX_FUNC_PARAM_UNQUOTED:
+ if (',' == *ptr)
+ state = ZBX_FUNC_PARAM_NEXT;
+ break;
+ case ZBX_FUNC_PARAM_POSTQUOTED:
+ if (',' == *ptr)
+ {
+ state = ZBX_FUNC_PARAM_NEXT;
+ }
+ else if (' ' != *ptr)
+ {
+ *lpp_len = ptr - (expr + *lpp_offset);
+ return FAIL;
+ }
+ break;
+ default:
+ THIS_SHOULD_NEVER_HAPPEN;
+ }
+ }
+
+ *lpp_len = ptr - (expr + *lpp_offset);
+
+ if (terminator == *ptr && ZBX_FUNC_PARAM_QUOTED != state)
+ {
+ *par_r = ptr - expr;
+ return SUCCEED;
+ }
+
+ return FAIL;
+
+#undef ZBX_FUNC_PARAM_NEXT
+#undef ZBX_FUNC_PARAM_QUOTED
+#undef ZBX_FUNC_PARAM_UNQUOTED
+#undef ZBX_FUNC_PARAM_POSTQUOTED
+}
+
+/******************************************************************************
+ * *
+ * Purpose: given the position of opening function parenthesis find the *
+ * position of a closing one *
+ * *
+ * Parameters: expr - [IN] string to parse *
+ * par_l - [IN] position of the opening parenthesis *
+ * par_r - [OUT] position of the closing parenthesis *
+ * lpp_offset - [OUT] offset of the last parsed parameter *
+ * lpp_len - [OUT] length of the last parsed parameter *
+ * *
+ * Return value: SUCCEED - closing parenthesis was found *
+ * FAIL - string after par_l does not look like a valid *
+ * function parameter list *
+ * *
+ ******************************************************************************/
+static int function_match_parenthesis(const char *expr, size_t par_l, size_t *par_r, size_t *lpp_offset,
+ size_t *lpp_len)
+{
+ if (SUCCEED == function_validate_parameters(expr + par_l + 1, ')', par_r, lpp_offset, lpp_len))
+ {
+ *par_r += par_l + 1;
+ return SUCCEED;
+ }
+
+ *lpp_offset += par_l + 1;
+ return FAIL;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: parses function name *
+ * *
+ * Parameters: expr - [IN] the function expression: func(p1, p2,...) *
+ * length - [OUT] the function name length or the amount of *
+ * characters that can be safely skipped *
+ * *
+ * Return value: SUCCEED - the function name was successfully parsed *
+ * FAIL - failed to parse function name *
+ * *
+ ******************************************************************************/
+static int function_parse_name(const char *expr, size_t *length)
+{
+ const char *ptr;
+
+ for (ptr = expr; SUCCEED == zbx_is_function_char(*ptr); ptr++)
+ ;
+
+ *length = ptr - expr;
+
+ return ptr != expr && '(' == *ptr ? SUCCEED : FAIL;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: check whether expression starts with a valid function *
+ * *
+ * Parameters: expr - [IN] string to parse *
+ * par_l - [OUT] position of the opening parenthesis *
+ * or the amount of characters to skip *
+ * par_r - [OUT] position of the closing parenthesis *
+ * error - [OUT] error message *
+ * max_error_len - [IN] error size *
+ * *
+ * Return value: SUCCEED - string starts with a valid function *
+ * FAIL - string does not start with a function and par_l *
+ * characters can be safely skipped *
+ * *
+ ******************************************************************************/
+int zbx_function_validate(const char *expr, size_t *par_l, size_t *par_r, char *error, int max_error_len)
+{
+ size_t lpp_offset, lpp_len;
+
+ /* try to validate function name */
+ if (SUCCEED == function_parse_name(expr, par_l))
+ {
+ /* now we know the position of '(', try to find ')' */
+ if (SUCCEED == function_match_parenthesis(expr, *par_l, par_r, &lpp_offset, &lpp_len))
+ return SUCCEED;
+
+ if (NULL != error && *par_l > *par_r)
+ {
+ zbx_snprintf(error, max_error_len, "Incorrect function '%.*s' expression. "
+ "Check expression part starting from: %.*s",
+ (int)*par_l, expr, (int)lpp_len, expr + lpp_offset);
+
+ return FAIL;
+ }
+ }
+
+ if (NULL != error)
+ zbx_snprintf(error, max_error_len, "Incorrect function expression: %s", expr);
+
+ return FAIL;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: validate parameters that end with '\0' *
+ * *
+ * Parameters: expr - [IN] string to parse that contains parameters *
+ * length - [OUT] length of parameters *
+ * *
+ * Return value: SUCCEED - null termination encountered when quotes are *
+ * closed and no other error *
+ * FAIL - does not look like a valid *
+ * function parameter list *
+ * *
+ ******************************************************************************/
+int zbx_function_validate_parameters(const char *expr, size_t *length)
+{
+ size_t offset, len;
+
+ return function_validate_parameters(expr, '\0', length, &offset, &len);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: count calculated item (prototype) formula characters that can be *
+ * skipped without the risk of missing a function *
+ * *
+ ******************************************************************************/
+static size_t zbx_no_function(const char *expr)
+{
+ const char *ptr = expr;
+ int inside_quote = 0, len, c_l, c_r;
+ zbx_token_t token;
+
+ while ('\0' != *ptr)
+ {
+ switch (*ptr)
+ {
+ case '\\':
+ if (0 != inside_quote)
+ ptr++;
+ break;
+ case '"':
+ inside_quote = !inside_quote;
+ ptr++;
+ continue;
+ }
+
+ if (inside_quote)
+ {
+ if ('\0' == *ptr)
+ break;
+ ptr++;
+ continue;
+ }
+
+ if ('{' == *ptr && '$' == *(ptr + 1) && SUCCEED == zbx_user_macro_parse(ptr, &len, &c_l, &c_r, NULL))
+ {
+ ptr += len + 1; /* skip to the position after user macro */
+ }
+ else if ('{' == *ptr && '{' == *(ptr + 1) && '#' == *(ptr + 2) &&
+ SUCCEED == zbx_token_parse_nested_macro(ptr, ptr, 0, &token))
+ {
+ ptr += token.loc.r - token.loc.l + 1;
+ }
+ else if (SUCCEED != zbx_is_function_char(*ptr))
+ {
+ ptr++; /* skip one character which cannot belong to function name */
+ }
+ else if ((0 == strncmp("and", ptr, len = ZBX_CONST_STRLEN("and")) ||
+ 0 == strncmp("not", ptr, len = ZBX_CONST_STRLEN("not")) ||
+ 0 == strncmp("or", ptr, len = ZBX_CONST_STRLEN("or"))) &&
+ NULL != strchr("()" ZBX_WHITESPACE, ptr[len]))
+ {
+ ptr += len; /* skip to the position after and/or/not operator */
+ }
+ else if (ptr > expr && 0 != isdigit(*(ptr - 1)) && NULL != strchr(ZBX_UNIT_SYMBOLS, *ptr))
+ {
+ ptr++; /* skip unit suffix symbol if it's preceded by a digit */
+ }
+ else
+ break;
+ }
+
+ return ptr - expr;
+}
+
+
+/******************************************************************************
+ * *
+ * Purpose: find the location of the next function and its parameters in *
+ * calculated item (prototype) formula *
+ * *
+ * Parameters: expr - [IN] string to parse *
+ * func_pos - [OUT] function position in the string *
+ * par_l - [OUT] position of the opening parenthesis *
+ * par_r - [OUT] position of the closing parenthesis *
+ * error - [OUT] error message *
+ * max_error_len - [IN] error size *
+ * *
+ * Return value: SUCCEED - function was found at func_pos *
+ * FAIL - there are no functions in the expression *
+ * *
+ ******************************************************************************/
+int zbx_function_find(const char *expr, size_t *func_pos, size_t *par_l, size_t *par_r, char *error,
+ int max_error_len)
+{
+ const char *ptr;
+
+ for (ptr = expr; '\0' != *ptr; ptr += *par_l)
+ {
+ /* skip the part of expression that is definitely not a function */
+ ptr += zbx_no_function(ptr);
+ *par_r = 0;
+
+ /* try to validate function candidate */
+ if (SUCCEED != zbx_function_validate(ptr, par_l, par_r, error, max_error_len))
+ {
+ if (*par_l > *par_r)
+ return FAIL;
+
+ continue;
+ }
+
+ *func_pos = ptr - expr;
+ *par_l += *func_pos;
+ *par_r += *func_pos;
+ return SUCCEED;
+ }
+
+ zbx_snprintf(error, max_error_len, "Incorrect function expression: %s", expr);
+
+ return FAIL;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: parses function parameter *
+ * *
+ * Parameters: expr - [IN] pre-validated function parameter list *
+ * param_pos - [OUT] the parameter position, excluding leading *
+ * whitespace *
+ * length - [OUT] the parameter length including trailing *
+ * whitespace for unquoted parameter *
+ * sep_pos - [OUT] the parameter separator character *
+ * (',' or '\0' or ')') position *
+ * *
+ ******************************************************************************/
+void zbx_function_param_parse(const char *expr, size_t *param_pos, size_t *length, size_t *sep_pos)
+{
+ const char *ptr = expr;
+
+ /* skip the leading whitespace */
+ while (' ' == *ptr)
+ ptr++;
+
+ *param_pos = ptr - expr;
+
+ if ('"' == *ptr) /* quoted parameter */
+ {
+ for (ptr++; '"' != *ptr || '\\' == *(ptr - 1); ptr++)
+ ;
+
+ *length = ++ptr - expr - *param_pos;
+
+ /* skip trailing whitespace to find the next parameter */
+ while (' ' == *ptr)
+ ptr++;
+ }
+ else /* unquoted parameter */
+ {
+ for (ptr = expr; '\0' != *ptr && ')' != *ptr && ',' != *ptr; ptr++)
+ ;
+
+ *length = ptr - expr - *param_pos;
+ }
+
+ *sep_pos = ptr - expr;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: unquotes function parameter *
+ * *
+ * Parameters: param - [IN] the parameter to unquote *
+ * len - [IN] the parameter length *
+ * quoted - [OUT] the flag that specifies whether parameter was *
+ * quoted before extraction *
+ * *
+ * Return value: The unquoted parameter. This value must be freed by the *
+ * caller. *
+ * *
+ ******************************************************************************/
+char *zbx_function_param_unquote_dyn(const char *param, size_t len, int *quoted)
+{
+ char *out;
+
+ out = (char *)zbx_malloc(NULL, len + 1);
+
+ if (0 == (*quoted = (0 != len && '"' == *param)))
+ {
+ /* unquoted parameter - simply copy it */
+ memcpy(out, param, len);
+ out[len] = '\0';
+ }
+ else
+ {
+ /* quoted parameter - remove enclosing " and replace \" with " */
+ const char *pin;
+ char *pout = out;
+
+ for (pin = param + 1; (size_t)(pin - param) < len - 1; pin++)
+ {
+ if ('\\' == pin[0] && '"' == pin[1])
+ pin++;
+
+ *pout++ = *pin;
+ }
+
+ *pout = '\0';
+ }
+
+ return out;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: quotes function parameter *
+ * *
+ * Parameters: param - [IN/OUT] function parameter *
+ * forced - [IN] 1 - enclose parameter in " even if it does not *
+ * contain any special characters *
+ * 0 - do nothing if the parameter does not *
+ * contain any special characters *
+ * *
+ * Return value: SUCCEED - if parameter was successfully quoted or quoting *
+ * was not necessary *
+ * FAIL - if parameter needs to but cannot be quoted due to *
+ * backslash in the end *
+ * *
+ ******************************************************************************/
+int zbx_function_param_quote(char **param, int forced)
+{
+ size_t sz_src, sz_dst;
+
+ if (0 == forced && '"' != **param && ' ' != **param && NULL == strchr(*param, ',') &&
+ NULL == strchr(*param, ')'))
+ {
+ return SUCCEED;
+ }
+
+ if (0 != (sz_src = strlen(*param)) && '\\' == (*param)[sz_src - 1])
+ return FAIL;
+
+ sz_dst = zbx_get_escape_string_len(*param, "\"") + 3;
+
+ *param = (char *)zbx_realloc(*param, sz_dst);
+
+ (*param)[--sz_dst] = '\0';
+ (*param)[--sz_dst] = '"';
+
+ while (0 < sz_src)
+ {
+ (*param)[--sz_dst] = (*param)[--sz_src];
+ if ('"' == (*param)[sz_src])
+ (*param)[--sz_dst] = '\\';
+ }
+ (*param)[--sz_dst] = '"';
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: return parameter by index (Nparam) from parameter list (params) *
+ * *
+ * Parameters: *
+ * params - [IN] parameter list *
+ * Nparam - [IN] requested parameter index (from 1) *
+ * *
+ * Return value: *
+ * NULL - requested parameter missing *
+ * otherwise - requested parameter *
+ * *
+ ******************************************************************************/
+char *zbx_function_get_param_dyn(const char *params, int Nparam)
+{
+ const char *ptr;
+ size_t sep_pos, params_len;
+ char *out = NULL;
+ int idx = 0;
+
+ params_len = strlen(params) + 1;
+
+ for (ptr = params; ++idx <= Nparam && ptr < params + params_len; ptr += sep_pos + 1)
+ {
+ size_t param_pos, param_len;
+ int quoted;
+
+ zbx_function_param_parse(ptr, &param_pos, &param_len, &sep_pos);
+
+ if (idx == Nparam)
+ out = zbx_function_param_unquote_dyn(ptr + param_pos, param_len, &quoted);
+ }
+
+ return out;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: Returns function type based on its name *
+ * *
+ * Return value: Function type. *
+ * *
+ ******************************************************************************/
+zbx_function_type_t zbx_get_function_type(const char *func)
+{
+ if (0 == strncmp(func, "trend", 5))
+ return ZBX_FUNCTION_TYPE_TRENDS;
+
+ if (0 == strncmp(func, "baseline", 8))
+ return ZBX_FUNCTION_TYPE_TRENDS;
+
+ if (0 == strcmp(func, "nodata"))
+ return ZBX_FUNCTION_TYPE_TIMER;
+
+ return ZBX_FUNCTION_TYPE_HISTORY;
+}
diff --git a/src/libs/zbxexpr/host.c b/src/libs/zbxexpr/host.c
new file mode 100644
index 00000000000..1bd3ed993c3
--- /dev/null
+++ b/src/libs/zbxexpr/host.c
@@ -0,0 +1,150 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2022 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 "zbxexpr.h"
+
+/******************************************************************************
+ * *
+ * Return value: SUCCEED - the char is allowed in the host name *
+ * FAIL - otherwise *
+ * *
+ * Comments: in host name allowed characters: '0-9a-zA-Z. _-' *
+ * !!! Don't forget to sync the code with PHP !!! *
+ * *
+ ******************************************************************************/
+int zbx_is_hostname_char(unsigned char c)
+{
+ if (0 != isalnum(c))
+ return SUCCEED;
+
+ if (c == '.' || c == ' ' || c == '_' || c == '-')
+ return SUCCEED;
+
+ return FAIL;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: return hostname and key *
+ * <hostname:>key *
+ * *
+ * Parameters: *
+ * exp - pointer to the first char of hostname *
+ * host:key[key params] *
+ * ^ *
+ * *
+ * Return value: return SUCCEED or FAIL *
+ * *
+ ******************************************************************************/
+int zbx_parse_host_key(char *exp, char **host, char **key)
+{
+ char *p, *s;
+
+ if (NULL == exp || '\0' == *exp)
+ return FAIL;
+
+ for (p = exp, s = exp; '\0' != *p; p++) /* check for optional hostname */
+ {
+ if (':' == *p) /* hostname:vfs.fs.size[/,total]
+ * --------^
+ */
+ {
+ *p = '\0';
+ *host = zbx_strdup(NULL, s);
+ *p++ = ':';
+
+ s = p;
+ break;
+ }
+
+ if (SUCCEED != zbx_is_hostname_char(*p))
+ break;
+ }
+
+ *key = zbx_strdup(NULL, s);
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: replace all not-allowed hostname characters in the string *
+ * *
+ * Parameters: host - the target C-style string *
+ * *
+ * Comments: the string must be null-terminated, otherwise not secure! *
+ * *
+ ******************************************************************************/
+void zbx_make_hostname(char *host)
+{
+ char *c;
+
+ assert(host);
+
+ for (c = host; '\0' != *c; ++c)
+ {
+ if (FAIL == zbx_is_hostname_char(*c))
+ *c = '_';
+ }
+}
+
+/******************************************************************************
+ * *
+ * Purpose: check a byte stream for a valid hostname *
+ * *
+ * Parameters: hostname - pointer to the first char of hostname *
+ * error - pointer to the error message (can be NULL) *
+ * *
+ * Return value: return SUCCEED if hostname is valid *
+ * or FAIL if hostname contains invalid chars, is empty *
+ * or is longer than ZBX_MAX_HOSTNAME_LEN *
+ * *
+ ******************************************************************************/
+int zbx_check_hostname(const char *hostname, char **error)
+{
+ int len = 0;
+
+ while ('\0' != hostname[len])
+ {
+ if (FAIL == zbx_is_hostname_char(hostname[len]))
+ {
+ if (NULL != error)
+ *error = zbx_dsprintf(NULL, "name contains invalid character '%c'", hostname[len]);
+ return FAIL;
+ }
+
+ len++;
+ }
+
+ if (0 == len)
+ {
+ if (NULL != error)
+ *error = zbx_strdup(NULL, "name is empty");
+ return FAIL;
+ }
+
+ if (ZBX_MAX_HOSTNAME_LEN < len)
+ {
+ if (NULL != error)
+ *error = zbx_dsprintf(NULL, "name is too long (max %d characters)", ZBX_MAX_HOSTNAME_LEN);
+ return FAIL;
+ }
+
+ return SUCCEED;
+}
diff --git a/src/libs/zbxexpr/macro.c b/src/libs/zbxexpr/macro.c
new file mode 100644
index 00000000000..3440fbcbaa8
--- /dev/null
+++ b/src/libs/zbxexpr/macro.c
@@ -0,0 +1,360 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2022 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 "zbxexpr.h"
+
+/******************************************************************************
+ * *
+ * Return value: SUCCEED - the char is allowed in the macro name *
+ * FAIL - otherwise *
+ * *
+ * Comments: allowed characters in macro names: '0-9A-Z._' *
+ * !!! Don't forget to sync the code with PHP !!! *
+ * *
+ ******************************************************************************/
+int zbx_is_macro_char(unsigned char c)
+{
+ if (0 != isupper(c))
+ return SUCCEED;
+
+ if ('.' == c || '_' == c)
+ return SUCCEED;
+
+ if (0 != isdigit(c))
+ return SUCCEED;
+
+ return FAIL;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: checks if the name is a valid discovery macro *
+ * *
+ * Return value: SUCCEED - the name is a valid discovery macro *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+int zbx_is_discovery_macro(const char *name)
+{
+ if ('{' != *name++ || '#' != *name++)
+ return FAIL;
+
+ do
+ {
+ if (SUCCEED != zbx_is_macro_char(*name++))
+ return FAIL;
+
+ } while ('}' != *name);
+
+ if ('\0' != name[1])
+ return FAIL;
+
+ return SUCCEED;
+}
+
+#define ZBX_MACRO_REGEX_PREFIX "regex:"
+
+/******************************************************************************
+ * *
+ * Purpose: *
+ * parses user macro and finds its end position and context location *
+ * *
+ * Parameters: *
+ * macro - [IN] the macro to parse *
+ * macro_r - [OUT] the position of ending '}' character *
+ * context_l - [OUT] the position of context start character (first non *
+ * space character after context separator ':') *
+ * 0 if macro does not have context specified. *
+ * context_r - [OUT] the position of context end character (either the *
+ * ending '"' for quoted context values or the last *
+ * character before the ending '}' character) *
+ * 0 if macro does not have context specified. *
+ * context_op - [OUT] the context matching operator (optional): *
+ * ZBX_CONDITION_OPERATOR_EQUAL *
+ * ZBX_CONDITION_OPERATOR_REGEXP *
+ * *
+ * Return value: *
+ * SUCCEED - the macro was parsed successfully. *
+ * FAIL - the macro parsing failed, the content of output variables *
+ * is not defined. *
+ * *
+ ******************************************************************************/
+int zbx_user_macro_parse(const char *macro, int *macro_r, int *context_l, int *context_r, unsigned char *context_op)
+{
+ int i;
+
+ /* find the end of macro name by skipping {$ characters and iterating through */
+ /* valid macro name characters */
+ for (i = 2; SUCCEED == zbx_is_macro_char(macro[i]); i++)
+ ;
+
+ /* check for empty macro name */
+ if (2 == i)
+ return FAIL;
+
+ if ('}' == macro[i])
+ {
+ /* no macro context specified, parsing done */
+ *macro_r = i;
+ *context_l = 0;
+ *context_r = 0;
+
+ if (NULL != context_op)
+ *context_op = ZBX_CONDITION_OPERATOR_EQUAL;
+
+ return SUCCEED;
+ }
+
+ /* fail if the next character is not a macro context separator */
+ if (':' != macro[i])
+ return FAIL;
+
+ i++;
+ if (NULL != context_op)
+ {
+ if (0 == strncmp(macro + i, ZBX_MACRO_REGEX_PREFIX, ZBX_CONST_STRLEN(ZBX_MACRO_REGEX_PREFIX)))
+ {
+ *context_op = ZBX_CONDITION_OPERATOR_REGEXP;
+ i += ZBX_CONST_STRLEN(ZBX_MACRO_REGEX_PREFIX);
+ }
+ else
+ *context_op = ZBX_CONDITION_OPERATOR_EQUAL;
+ }
+
+ /* skip the whitespace after macro context separator */
+ while (' ' == macro[i])
+ i++;
+
+ *context_l = i;
+
+ if ('"' == macro[i])
+ {
+ i++;
+
+ /* process quoted context */
+ for (; '"' != macro[i]; i++)
+ {
+ if ('\0' == macro[i])
+ return FAIL;
+
+ if ('\\' == macro[i] && '"' == macro[i + 1])
+ i++;
+ }
+
+ *context_r = i;
+
+ while (' ' == macro[++i])
+ ;
+ }
+ else
+ {
+ /* process unquoted context */
+ for (; '}' != macro[i]; i++)
+ {
+ if ('\0' == macro[i])
+ return FAIL;
+ }
+
+ *context_r = i - 1;
+ }
+
+ if ('}' != macro[i])
+ return FAIL;
+
+ *macro_r = i;
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: *
+ * parses user macro {$MACRO:<context>} into {$MACRO} and <context> *
+ * strings *
+ * *
+ * Parameters: *
+ * macro - [IN] the macro to parse *
+ * name - [OUT] the macro name without context *
+ * context - [OUT] the unquoted macro context, NULL for macros without *
+ * context *
+ * length - [OUT] the length of parsed macro (optional) *
+ * context_op - [OUT] the context matching operator (optional): *
+ * ZBX_CONDITION_OPERATOR_EQUAL *
+ * ZBX_CONDITION_OPERATOR_REGEXP *
+ * *
+ * Return value: *
+ * SUCCEED - the macro was parsed successfully *
+ * FAIL - the macro parsing failed, invalid parameter syntax *
+ * *
+ ******************************************************************************/
+int zbx_user_macro_parse_dyn(const char *macro, char **name, char **context, int *length, unsigned char *context_op)
+{
+ const char *ptr;
+ int macro_r, context_l, context_r;
+ size_t len;
+
+ if (SUCCEED != zbx_user_macro_parse(macro, &macro_r, &context_l, &context_r, context_op))
+ return FAIL;
+
+ zbx_free(*context);
+
+ if (0 != context_l)
+ {
+ ptr = macro + context_l;
+
+ /* find the context separator ':' by stripping spaces before context */
+ while (' ' == *(--ptr))
+ ;
+
+ /* remove regex: prefix from macro name for regex contexts */
+ if (NULL != context_op && ZBX_CONDITION_OPERATOR_REGEXP == *context_op)
+ ptr -= ZBX_CONST_STRLEN(ZBX_MACRO_REGEX_PREFIX);
+
+ /* extract the macro name and close with '}' character */
+ len = ptr - macro + 1;
+ *name = (char *)zbx_realloc(*name, len + 1);
+ memcpy(*name, macro, len - 1);
+ (*name)[len - 1] = '}';
+ (*name)[len] = '\0';
+
+ *context = zbx_user_macro_unquote_context_dyn(macro + context_l, context_r - context_l + 1);
+ }
+ else
+ {
+ *name = (char *)zbx_realloc(*name, macro_r + 2);
+ zbx_strlcpy(*name, macro, macro_r + 2);
+ }
+
+ if (NULL != length)
+ *length = macro_r + 1;
+
+ return SUCCEED;
+}
+
+#undef ZBX_MACRO_REGEX_PREFIX
+
+/******************************************************************************
+ * *
+ * Purpose: *
+ * extracts the macro context unquoting if necessary *
+ * *
+ * Parameters: *
+ * context - [IN] the macro context inside a user macro *
+ * len - [IN] the macro context length (including quotes for quoted *
+ * contexts) *
+ * *
+ * Return value: *
+ * A string containing extracted macro context. This string must be freed *
+ * by the caller. *
+ * *
+ ******************************************************************************/
+char *zbx_user_macro_unquote_context_dyn(const char *context, int len)
+{
+ int quoted = 0;
+ char *buffer, *ptr;
+
+ ptr = buffer = (char *)zbx_malloc(NULL, len + 1);
+
+ if ('"' == *context)
+ {
+ quoted = 1;
+ context++;
+ len--;
+ }
+
+ while (0 < len)
+ {
+ if (1 == quoted && '\\' == *context && '"' == context[1])
+ {
+ context++;
+ len--;
+ }
+
+ *ptr++ = *context++;
+ len--;
+ }
+
+ if (1 == quoted)
+ ptr--;
+
+ *ptr = '\0';
+
+ return buffer;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: *
+ * quotes user macro context if necessary *
+ * *
+ * Parameters: *
+ * context - [IN] the macro context *
+ * force_quote - [IN] if non zero then context quoting is enforced *
+ * error - [OUT] the error message *
+ * *
+ * Return value: *
+ * A string containing quoted macro context on success, NULL on error. *
+ * *
+ ******************************************************************************/
+char *zbx_user_macro_quote_context_dyn(const char *context, int force_quote, char **error)
+{
+ int len, quotes = 0;
+ char *buffer, *ptr_buffer;
+ const char *ptr_context = context, *start = context;
+
+ if ('"' == *ptr_context || ' ' == *ptr_context)
+ force_quote = 1;
+
+ for (; '\0' != *ptr_context; ptr_context++)
+ {
+ if ('}' == *ptr_context)
+ force_quote = 1;
+
+ if ('"' == *ptr_context)
+ quotes++;
+ }
+
+ if (0 == force_quote)
+ return zbx_strdup(NULL, context);
+
+ len = (int)strlen(context) + 2 + quotes;
+ ptr_buffer = buffer = (char *)zbx_malloc(NULL, len + 1);
+
+ *ptr_buffer++ = '"';
+
+ while ('\0' != *context)
+ {
+ if ('"' == *context)
+ *ptr_buffer++ = '\\';
+
+ *ptr_buffer++ = *context++;
+ }
+
+ if ('\\' == *(ptr_buffer - 1))
+ {
+ *error = zbx_dsprintf(*error, "quoted context \"%s\" cannot end with '\\' character", start);
+ zbx_free(buffer);
+ return NULL;
+ }
+
+ *ptr_buffer++ = '"';
+ *ptr_buffer++ = '\0';
+
+ return buffer;
+}
diff --git a/src/libs/zbxexpr/token.c b/src/libs/zbxexpr/token.c
index 2480c22a766..9bf129d7376 100644
--- a/src/libs/zbxexpr/token.c
+++ b/src/libs/zbxexpr/token.c
@@ -106,7 +106,7 @@ static int token_parse_lld_macro(const char *expression, const char *macro, zbx_
if ('\0' == *ptr)
return FAIL;
- if (SUCCEED != is_macro_char(*ptr))
+ if (SUCCEED != zbx_is_macro_char(*ptr))
return FAIL;
}
@@ -554,7 +554,7 @@ static int token_parse_simple_macro_key(const char *expression, const char *macr
const char *ptr = key;
zbx_strloc_t key_loc, func_loc, func_param;
- if (SUCCEED != parse_key(&ptr))
+ if (SUCCEED != zbx_parse_key(&ptr))
{
zbx_token_t key_token;
@@ -564,7 +564,7 @@ static int token_parse_simple_macro_key(const char *expression, const char *macr
ptr = expression + key_token.loc.r + 1;
}
- /* If the key is without parameters, then parse_key() will move cursor past function name - */
+ /* If the key is without parameters, then zbx_parse_key() will move cursor past function name - */
/* at the start of its parameters. In this case move cursor back before function. */
if ('(' == *ptr)
{
@@ -643,7 +643,7 @@ static int token_parse_simple_macro(const char *expression, const char *macro, z
if ('\0' == *ptr)
return FAIL;
- if (SUCCEED != is_hostname_char(*ptr))
+ if (SUCCEED != zbx_is_hostname_char(*ptr))
return FAIL;
}
@@ -865,7 +865,7 @@ int zbx_token_parse_nested_macro(const char *expression, const char *macro, int
if ('\0' == *ptr)
return FAIL;
- if (SUCCEED != is_macro_char(*ptr))
+ if (SUCCEED != zbx_is_macro_char(*ptr))
return FAIL;
}
diff --git a/src/libs/zbxlog/log.c b/src/libs/zbxlog/log.c
index acb3357380c..41f166b0998 100644
--- a/src/libs/zbxlog/log.c
+++ b/src/libs/zbxlog/log.c
@@ -265,7 +265,7 @@ static void unlock_log(void)
static void lock_log(void)
{
#ifdef ZABBIX_AGENT
- if (0 == (ZBX_MUTEX_LOGGING_DENIED & get_thread_global_mutex_flag()))
+ if (0 == (ZBX_MUTEX_LOGGING_DENIED & zbx_get_thread_global_mutex_flag()))
#endif
LOCK_LOG;
}
@@ -273,7 +273,7 @@ static void lock_log(void)
static void unlock_log(void)
{
#ifdef ZABBIX_AGENT
- if (0 == (ZBX_MUTEX_LOGGING_DENIED & get_thread_global_mutex_flag()))
+ if (0 == (ZBX_MUTEX_LOGGING_DENIED & zbx_get_thread_global_mutex_flag()))
#endif
UNLOCK_LOG;
}
diff --git a/src/libs/zbxmedia/email.c b/src/libs/zbxmedia/email.c
index 7bcc3835ca3..9f7512f704b 100644
--- a/src/libs/zbxmedia/email.c
+++ b/src/libs/zbxmedia/email.c
@@ -37,6 +37,8 @@
/* separator for multipart mixed messages */
#define ZBX_MULTIPART_MIXED_BOUNDARY "MULTIPART-MIXED-BOUNDARY"
+#define OK_250 "250"
+
extern char *CONFIG_SSL_CA_LOCATION;
/******************************************************************************
@@ -433,19 +435,107 @@ out:
}
#endif
+static char *smtp_get_helo_from_system(void)
+{
+ struct utsname name;
+
+ if (-1 == uname(&name))
+ return NULL;
+
+ return zbx_strdup(NULL, name.nodename);
+}
+
+static char *smtp_get_helo_from_addr(const char *addr)
+{
+ const char *domain;
+ char *helo_addr;
+ size_t addr_len;
+
+ if (NULL == addr || '\0' == *addr || NULL == (domain = strrchr(addr, '@')))
+ return NULL;
+
+ addr_len = strlen(domain + 1);
+
+ if (1 == addr_len && '>' == *(domain + 1))
+ return NULL;
+
+ helo_addr = zbx_strdup(NULL, domain + 1);
+ helo_addr[addr_len - 1] = '\0';
+
+ return helo_addr;
+}
+
+static int send_smtp_helo_plain(const char *addr, const char *helo, zbx_socket_t *s, char **error,
+ size_t max_error_len)
+{
+ char cmd[MAX_STRING_LEN], *helo_parsed = NULL;
+ const char *response;
+ int ret = SUCCEED;
+
+ if ('\0' != *helo)
+ {
+ zbx_snprintf(cmd, sizeof(cmd), "HELO %s\r\n", helo);
+ }
+ else
+ {
+ if (NULL == (helo_parsed = smtp_get_helo_from_addr(addr)))
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() HELO is not specified and failed to parse HELO from email "
+ "address, trying to form HELO command using system's hostname", __func__);
+
+ if (NULL == (helo_parsed = smtp_get_helo_from_system()))
+ {
+ zbx_snprintf(*error, max_error_len, "failed to retrieve domain name for HELO command");
+ ret = FAIL;
+ goto out;
+ }
+ }
+
+ zbx_snprintf(cmd, sizeof(cmd), "HELO %s\r\n", helo_parsed);
+ }
+
+ if (-1 == write(s->socket, cmd, strlen(cmd)))
+ {
+ zbx_snprintf(*error, max_error_len, "error sending HELO to mailserver: %s",
+ zbx_strerror(errno));
+
+ ret = FAIL;
+ goto out;
+ }
+
+ if (FAIL == smtp_readln(s, &response))
+ {
+ zbx_snprintf(*error, max_error_len, "error receiving answer on HELO request: %s",
+ zbx_strerror(errno));
+
+ ret = FAIL;
+ goto out;
+ }
+
+ if (0 != strncmp(response, OK_250, ZBX_CONST_STRLEN(OK_250)))
+ {
+ zbx_snprintf(*error, max_error_len, "wrong answer on HELO \"%s\"", response);
+ ret = FAIL;
+ goto out;
+ }
+out:
+ zbx_free(helo_parsed);
+
+ return ret;
+}
+
static int send_email_plain(const char *smtp_server, unsigned short smtp_port, const char *smtp_helo,
zbx_vector_ptr_t *from_mails, zbx_vector_ptr_t *to_mails, const char *inreplyto,
const char *mailsubject, const char *mailbody, unsigned char content_type, int timeout, char *error,
size_t max_error_len)
{
+#define OK_220 "220"
+#define OK_251 "251"
+#define OK_354 "354"
zbx_socket_t s;
int err, ret = FAIL, i;
- char cmd[MAX_STRING_LEN], *cmdp = NULL;
+ char cmd[MAX_STRING_LEN], *cmdp = NULL, *helo_addr = NULL;
- const char *OK_220 = "220";
- const char *OK_250 = "250";
- const char *OK_251 = "251";
- const char *OK_354 = "354";
const char *response;
zbx_alarm_on(timeout);
@@ -467,38 +557,18 @@ static int send_email_plain(const char *smtp_server, unsigned short smtp_port, c
goto close;
}
- if (0 != strncmp(response, OK_220, strlen(OK_220)))
+ if (0 != strncmp(response, OK_220, ZBX_CONST_STRLEN(OK_220)))
{
zbx_snprintf(error, max_error_len, "no welcome message 220* from SMTP server \"%s\"", response);
goto close;
}
/* send HELO */
+ if (0 != from_mails->values_num)
+ helo_addr = ((zbx_mailaddr_t *)from_mails->values[0])->addr;
- if ('\0' != *smtp_helo)
- {
- zbx_snprintf(cmd, sizeof(cmd), "HELO %s\r\n", smtp_helo);
-
- if (-1 == write(s.socket, cmd, strlen(cmd)))
- {
- zbx_snprintf(error, max_error_len, "error sending HELO to mailserver: %s",
- zbx_strerror(errno));
- goto close;
- }
-
- if (FAIL == smtp_readln(&s, &response))
- {
- zbx_snprintf(error, max_error_len, "error receiving answer on HELO request: %s",
- zbx_strerror(errno));
- goto close;
- }
-
- if (0 != strncmp(response, OK_250, strlen(OK_250)))
- {
- zbx_snprintf(error, max_error_len, "wrong answer on HELO \"%s\"", response);
- goto close;
- }
- }
+ if (FAIL == send_smtp_helo_plain(helo_addr, smtp_helo, &s, &error, max_error_len))
+ goto close;
/* send MAIL FROM */
@@ -518,7 +588,7 @@ static int send_email_plain(const char *smtp_server, unsigned short smtp_port, c
goto close;
}
- if (0 != strncmp(response, OK_250, strlen(OK_250)))
+ if (0 != strncmp(response, OK_250, ZBX_CONST_STRLEN(OK_250)))
{
zbx_snprintf(error, max_error_len, "wrong answer on MAIL FROM \"%s\"", response);
goto close;
@@ -544,7 +614,8 @@ static int send_email_plain(const char *smtp_server, unsigned short smtp_port, c
}
/* May return 251 as well: User not local; will forward to <forward-path>. See RFC825. */
- if (0 != strncmp(response, OK_250, strlen(OK_250)) && 0 != strncmp(response, OK_251, strlen(OK_251)))
+ if (0 != strncmp(response, OK_250, ZBX_CONST_STRLEN(OK_250)) &&
+ 0 != strncmp(response, OK_251, ZBX_CONST_STRLEN(OK_251)))
{
zbx_snprintf(error, max_error_len, "wrong answer on RCPT TO \"%s\"", response);
goto close;
@@ -567,7 +638,7 @@ static int send_email_plain(const char *smtp_server, unsigned short smtp_port, c
goto close;
}
- if (0 != strncmp(response, OK_354, strlen(OK_354)))
+ if (0 != strncmp(response, OK_354, ZBX_CONST_STRLEN(OK_354)))
{
zbx_snprintf(error, max_error_len, "wrong answer on DATA \"%s\"", response);
goto close;
@@ -600,7 +671,7 @@ static int send_email_plain(const char *smtp_server, unsigned short smtp_port, c
goto close;
}
- if (0 != strncmp(response, OK_250, strlen(OK_250)))
+ if (0 != strncmp(response, OK_250, ZBX_CONST_STRLEN(OK_250)))
{
zbx_snprintf(error, max_error_len, "wrong answer on end of data \"%s\"", response);
goto close;
@@ -623,6 +694,9 @@ out:
zbx_alarm_off();
return ret;
+#undef OK_220
+#undef OK_251
+#undef OK_354
}
static int send_email_curl(const char *smtp_server, unsigned short smtp_port, const char *smtp_helo,
@@ -657,7 +731,36 @@ static int send_email_curl(const char *smtp_server, unsigned short smtp_port, co
url_offset += zbx_snprintf(url + url_offset, sizeof(url) - url_offset, "%s:%hu", smtp_server, smtp_port);
if ('\0' != *smtp_helo)
+ {
zbx_snprintf(url + url_offset, sizeof(url) - url_offset, "/%s", smtp_helo);
+ }
+ else
+ {
+ char *helo_domain = NULL;
+
+ if (0 != from_mails->values_num)
+ {
+ if (NULL == (helo_domain =
+ smtp_get_helo_from_addr(((zbx_mailaddr_t *)from_mails->values[0])->addr)))
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() HELO is not specified and failed to parse HELO "
+ "from email address, trying to form HELO command using system's "
+ "hostname", __func__);
+ }
+ }
+
+ if (NULL == helo_domain)
+ {
+ if (NULL == (helo_domain = smtp_get_helo_from_system()))
+ {
+ zbx_strlcpy(error, "failed to retrieve domain name for HELO command", max_error_len);
+ goto clean;
+ }
+ }
+
+ zbx_snprintf(url + url_offset, sizeof(url) - url_offset, "/%s", helo_domain);
+ zbx_free(helo_domain);
+ }
if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_URL, url)))
goto error;
diff --git a/src/libs/zbxmodules/modules.c b/src/libs/zbxmodules/modules.c
index 34c7f26d2ba..237ec00a98c 100644
--- a/src/libs/zbxmodules/modules.c
+++ b/src/libs/zbxmodules/modules.c
@@ -64,7 +64,7 @@ static int zbx_register_module_items(ZBX_METRIC *metrics, char *error, size_t ma
/* the flag means that the items comes from a loadable module */
metrics[i].flags |= CF_MODULE;
- if (SUCCEED != add_metric(&metrics[i], error, max_error_len))
+ if (SUCCEED != zbx_add_metric(&metrics[i], error, max_error_len))
return FAIL;
}
diff --git a/src/libs/zbxmutexs/mutexs.c b/src/libs/zbxmutexs/mutexs.c
index c050ed56fe3..30048fa0914 100644
--- a/src/libs/zbxmutexs/mutexs.c
+++ b/src/libs/zbxmutexs/mutexs.c
@@ -412,7 +412,7 @@ void __zbx_mutex_lock(const char *filename, int line, zbx_mutex_t mutex)
#ifdef _WINDOWS
#ifdef ZABBIX_AGENT
- if (0 != (ZBX_MUTEX_THREAD_DENIED & get_thread_global_mutex_flag()))
+ if (0 != (ZBX_MUTEX_THREAD_DENIED & zbx_get_thread_global_mutex_flag()))
{
zbx_error("[file:'%s',line:%d] lock failed: ZBX_MUTEX_THREAD_DENIED is set for thread with id = %d",
filename, line, zbx_get_thread_id());
diff --git a/src/libs/zbxnum/num.c b/src/libs/zbxnum/num.c
index 4dc2036bec6..9c06ffa138f 100644
--- a/src/libs/zbxnum/num.c
+++ b/src/libs/zbxnum/num.c
@@ -42,7 +42,7 @@
int zbx_is_uint_n_range(const char *str, size_t n, void *value, size_t size, zbx_uint64_t min, zbx_uint64_t max)
{
zbx_uint64_t value_uint64 = 0, c;
- const zbx_uint64_t max_uint64 = ~(zbx_uint64_t)__UINT64_C(0);
+ const zbx_uint64_t max_uint64 = ~__UINT64_C(0);
if ('\0' == *str || 0 == n || sizeof(zbx_uint64_t) < size || (0 == size && NULL != value))
return FAIL;
@@ -100,7 +100,7 @@ int zbx_is_uint_n_range(const char *str, size_t n, void *value, size_t size, zbx
int zbx_is_hex_n_range(const char *str, size_t n, void *value, size_t size, zbx_uint64_t min, zbx_uint64_t max)
{
zbx_uint64_t value_uint64 = 0, c;
- const zbx_uint64_t max_uint64 = ~(zbx_uint64_t)__UINT64_C(0);
+ const zbx_uint64_t max_uint64 = ~__UINT64_C(0);
int len = 0;
if ('\0' == *str || 0 == n || sizeof(zbx_uint64_t) < size || (0 == size && NULL != value))
@@ -575,3 +575,41 @@ int zbx_is_hex_string(const char *str)
return SUCCEED;
}
+
+/******************************************************************************
+ * *
+ * Purpose: validate and optionally convert a string to a number of type *
+ * 'int' *
+ * *
+ * Parameters: str - [IN] string to check *
+ * value - [OUT] output buffer where to write the converted value *
+ * (optional, can be NULL) *
+ * *
+ * Return value: SUCCEED - the string can be converted to 'int' and *
+ * was converted if 'value' is not NULL *
+ * FAIL - the string does not represent a valid 'int' or *
+ * its value is outside of valid range *
+ * *
+ ******************************************************************************/
+int zbx_is_int(const char *str, int *value)
+{
+ const char *ptr;
+ zbx_uint32_t value_ui32;
+ int sign;
+
+ if ('-' == *(ptr = str))
+ {
+ ptr++;
+ sign = -1;
+ }
+ else
+ sign = 1;
+
+ if (SUCCEED != zbx_is_uint31(ptr, &value_ui32))
+ return FAIL;
+
+ if (NULL != value)
+ *value = ((int)value_ui32 * sign);
+
+ return SUCCEED;
+}
diff --git a/src/libs/zbxparam/param.c b/src/libs/zbxparam/param.c
index 3750713010e..662006cc873 100644
--- a/src/libs/zbxparam/param.c
+++ b/src/libs/zbxparam/param.c
@@ -512,7 +512,7 @@ int zbx_replace_key_params_dyn(char **data, int key_type, zbx_replace_key_param_
if (ZBX_KEY_TYPE_ITEM == key_type)
{
- for (; SUCCEED == is_key_char((*data)[i]) && '\0' != (*data)[i]; i++)
+ for (; SUCCEED == zbx_is_key_char((*data)[i]) && '\0' != (*data)[i]; i++)
;
if (0 == i)
diff --git a/src/libs/zbxrtc/rtc_client.c b/src/libs/zbxrtc/rtc_client.c
index a43872563c9..3233d3b175e 100644
--- a/src/libs/zbxrtc/rtc_client.c
+++ b/src/libs/zbxrtc/rtc_client.c
@@ -303,12 +303,12 @@ int zbx_rtc_wait(zbx_ipc_async_socket_t *rtc, zbx_uint32_t *cmd, unsigned char *
int ret;
if (0 != timeout)
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
ret = zbx_ipc_async_socket_recv(rtc, timeout, &message);
if (0 != timeout)
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
if (FAIL == ret)
return FAIL;
diff --git a/src/libs/zbxself/selfmon.c b/src/libs/zbxself/selfmon.c
index 06482bd3e1a..e3790981982 100644
--- a/src/libs/zbxself/selfmon.c
+++ b/src/libs/zbxself/selfmon.c
@@ -105,7 +105,6 @@ extern int CONFIG_TIMER_FORKS;
extern int CONFIG_HOUSEKEEPER_FORKS;
extern int CONFIG_DATASENDER_FORKS;
extern int CONFIG_CONFSYNCER_FORKS;
-extern int CONFIG_HEARTBEAT_FORKS;
extern int CONFIG_SELFMON_FORKS;
extern int CONFIG_VMWARE_FORKS;
extern int CONFIG_COLLECTOR_FORKS;
@@ -175,8 +174,6 @@ int get_process_type_forks(unsigned char proc_type)
return CONFIG_DATASENDER_FORKS;
case ZBX_PROCESS_TYPE_CONFSYNCER:
return CONFIG_CONFSYNCER_FORKS;
- case ZBX_PROCESS_TYPE_HEARTBEAT:
- return CONFIG_HEARTBEAT_FORKS;
case ZBX_PROCESS_TYPE_SELFMON:
return CONFIG_SELFMON_FORKS;
case ZBX_PROCESS_TYPE_VMWARE:
@@ -225,7 +222,7 @@ int get_process_type_forks(unsigned char proc_type)
* for self-monitoring collector *
* *
******************************************************************************/
-int init_selfmon_collector(char **error)
+int zbx_init_selfmon_collector(char **error)
{
size_t sz, sz_array, sz_process[ZBX_PROCESS_TYPE_COUNT], sz_total;
char *p;
@@ -293,7 +290,7 @@ out:
* Purpose: Free memory allocated for self-monitoring collector *
* *
******************************************************************************/
-void free_selfmon_collector(void)
+void zbx_free_selfmon_collector(void)
{
zabbix_log(LOG_LEVEL_DEBUG, "In %s() collector:%p", __func__, (void *)collector);
@@ -317,7 +314,7 @@ void free_selfmon_collector(void)
* Parameters: state - [IN] new process state; ZBX_PROCESS_STATE_* *
* *
******************************************************************************/
-void update_selfmon_counter(unsigned char state)
+void zbx_update_selfmon_counter(unsigned char state)
{
zbx_stat_process_t *process;
clock_t ticks;
@@ -379,7 +376,7 @@ void update_selfmon_counter(unsigned char state)
process->cache.ticks = ticks;
}
-void collect_selfmon_stats(void)
+void zbx_collect_selfmon_stats(void)
{
zbx_stat_process_t *process;
clock_t ticks, ticks_done;
@@ -466,7 +463,7 @@ out:
* requested statistics *
* *
******************************************************************************/
-void get_selfmon_stats(unsigned char proc_type, unsigned char aggr_func, int proc_num, unsigned char state,
+void zbx_get_selfmon_stats(unsigned char proc_type, unsigned char aggr_func, int proc_num, unsigned char state,
double *value)
{
unsigned int total = 0, counter = 0;
@@ -663,7 +660,7 @@ void zbx_sleep_loop(int sleeptime)
sleep_remains = sleeptime;
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
do
{
@@ -671,16 +668,6 @@ void zbx_sleep_loop(int sleeptime)
}
while (0 < --sleep_remains);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
-}
-
-void zbx_wakeup(void)
-{
- sleep_remains = 0;
-}
-
-int zbx_sleep_get_remainder(void)
-{
- return sleep_remains;
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
}
#endif
diff --git a/src/libs/zbxserver/anomalystl.c b/src/libs/zbxserver/anomalystl.c
index 48e5098773b..effaaa0f98a 100644
--- a/src/libs/zbxserver/anomalystl.c
+++ b/src/libs/zbxserver/anomalystl.c
@@ -316,7 +316,7 @@ static void apply_loess_smoothing(const zbx_vector_history_record_t *y, int n, i
{
int nsh;
- nsh = (int)((length + 1) / 2);
+ nsh = (length + 1) / 2;
nleft = 1;
nright = length;
@@ -345,7 +345,7 @@ static void apply_loess_smoothing(const zbx_vector_history_record_t *y, int n, i
{
int nsh;
- nsh = (int)((length + 1) / 2);
+ nsh = (length + 1) / 2;
for (i = 1; i < n + 1; i = i + newnj)
{
@@ -395,7 +395,7 @@ static void apply_loess_smoothing(const zbx_vector_history_record_t *y, int n, i
ys->values[j].value.dbl = ys->values[i].value.dbl + (delta * (j - i));
}
- k = (int)(((n - 1)/newnj) * newnj + 1);
+ k = ((n - 1)/newnj) * newnj + 1;
if (k != n)
{
diff --git a/src/libs/zbxserver/calc_checks_eval.c b/src/libs/zbxserver/calc_checks_eval.c
index ac2a824d4b4..d7c06b854a2 100644
--- a/src/libs/zbxserver/calc_checks_eval.c
+++ b/src/libs/zbxserver/calc_checks_eval.c
@@ -324,12 +324,12 @@ static int replace_key_param_wildcard_cb(const char *data, int key_type, int lev
return SUCCEED;
tmp = zbx_strdup(NULL, data);
- unquote_key_param(tmp);
+ zbx_unquote_key_param(tmp);
*param = zbx_dyn_escape_string(tmp, "\\%%");
zbx_free(tmp);
/* escaping cannot result in unquotable parameter */
- if (FAIL == quote_key_param(param, quoted))
+ if (FAIL == zbx_quote_key_param(param, quoted))
{
THIS_SHOULD_NEVER_HAPPEN;
zbx_free(*param);
@@ -351,9 +351,9 @@ static int expression_match_item_key(const char *item_key, const AGENT_REQUEST *
AGENT_REQUEST key;
int i, ret = FAIL;
- init_request(&key);
+ zbx_init_agent_request(&key);
- if (SUCCEED != parse_item_key(item_key, &key))
+ if (SUCCEED != zbx_parse_item_key(item_key, &key))
goto out;
if (pattern->nparam != key.nparam)
@@ -373,7 +373,7 @@ static int expression_match_item_key(const char *item_key, const AGENT_REQUEST *
ret = SUCCEED;
out:
- free_request(&key);
+ zbx_free_agent_request(&key);
return ret;
}
@@ -413,8 +413,8 @@ static void expression_get_item_candidates(zbx_expression_eval_t *eval, const zb
if (0 != (query->flags & ZBX_ITEM_QUERY_KEY_SOME))
{
- init_request(&pattern);
- if (SUCCEED != parse_item_key(query->ref.key, &pattern))
+ zbx_init_agent_request(&pattern);
+ if (SUCCEED != zbx_parse_item_key(query->ref.key, &pattern))
{
THIS_SHOULD_NEVER_HAPPEN;
zbx_free(sql);
@@ -524,7 +524,7 @@ static void expression_get_item_candidates(zbx_expression_eval_t *eval, const zb
DBfree_result(result);
if (0 != (query->flags & ZBX_ITEM_QUERY_KEY_SOME))
- free_request(&pattern);
+ zbx_free_agent_request(&pattern);
zbx_free(sql);
}
diff --git a/src/libs/zbxserver/evalfunc.c b/src/libs/zbxserver/evalfunc.c
index e5a9177392d..cc2bf8048c7 100644
--- a/src/libs/zbxserver/evalfunc.c
+++ b/src/libs/zbxserver/evalfunc.c
@@ -2827,7 +2827,7 @@ static int evaluate_TREND(zbx_variant_t *value, const DC_ITEM *item, const char
season_processed = (int)((double)season / 3600);
ret = trends_eval_stl(table, item->itemid, start, end, start_detect_period, end_detect_period,
- (int)season_processed, deviations, dev_alg, (int)s_window, &value_dbl, error);
+ season_processed, deviations, dev_alg, (int)s_window, &value_dbl, error);
zbx_free(dev_alg);
}
diff --git a/src/libs/zbxserver/expression.c b/src/libs/zbxserver/expression.c
index e3bbe0c79c9..9891873f2e6 100644
--- a/src/libs/zbxserver/expression.c
+++ b/src/libs/zbxserver/expression.c
@@ -6388,7 +6388,7 @@ static int replace_key_param_cb(const char *data, int key_type, int level, int n
*param = zbx_strdup(NULL, data);
if (0 != level)
- unquote_key_param(*param);
+ zbx_unquote_key_param(*param);
if (NULL == jp_row)
substitute_simple_macros_impl(NULL, NULL, NULL, NULL, hostid, NULL, dc_item, NULL, NULL, NULL, NULL,
@@ -6398,7 +6398,7 @@ static int replace_key_param_cb(const char *data, int key_type, int level, int n
if (0 != level)
{
- if (FAIL == (ret = quote_key_param(param, quoted)))
+ if (FAIL == (ret = zbx_quote_key_param(param, quoted)))
zbx_free(*param);
}
@@ -6530,7 +6530,7 @@ int zbx_substitute_function_lld_param(const char *e, size_t len, unsigned char k
{
char *key = NULL, *host = NULL;
- if (SUCCEED != parse_host_key(param, &host, &key) ||
+ if (SUCCEED != zbx_parse_host_key(param, &host, &key) ||
SUCCEED != substitute_key_macros_impl(&key, NULL, NULL, jp_row, lld_macro_paths,
MACRO_TYPE_ITEM_KEY, NULL, 0))
{
diff --git a/src/libs/zbxserver/zabbix_stats.c b/src/libs/zbxserver/zabbix_stats.c
index 9411a8023dc..387366cded8 100644
--- a/src/libs/zbxserver/zabbix_stats.c
+++ b/src/libs/zbxserver/zabbix_stats.c
@@ -17,27 +17,28 @@
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-#include "zbxserver.h"
+#include "zbxstats.h"
#include "zbxcommon.h"
#include "dbcache.h"
#include "zbxself.h"
#include "../../zabbix_server/vmware/vmware.h"
#include "preproc.h"
+#include "zbxcomms.h"
extern unsigned char program_type;
extern int CONFIG_SERVER_STARTUP_TIME;
-static zbx_get_zabbix_stats_ext_func_t stats_ex_cb;
+static zbx_zabbix_stats_ext_get_func_t stats_ex_cb;
/******************************************************************************
* *
* Purpose: sets stats callback function *
* *
- * Parameters: cb - [IN] callback function *
+ * Parameters: cb - [IN] callback function *
* *
******************************************************************************/
-void zbx_zabbix_stats_init(zbx_get_zabbix_stats_ext_func_t cb)
+void zbx_zabbix_stats_init(zbx_zabbix_stats_ext_get_func_t cb)
{
stats_ex_cb = cb;
}
@@ -46,10 +47,11 @@ void zbx_zabbix_stats_init(zbx_get_zabbix_stats_ext_func_t cb)
* *
* Purpose: collects all metrics required for Zabbix stats request *
* *
- * Parameters: json - [OUT] the json data *
+ * Parameters: json - [OUT] the json data *
+ * zbx_config - [IN] Zabbix server/proxy config *
* *
******************************************************************************/
-void zbx_get_zabbix_stats(struct zbx_json *json)
+void zbx_zabbix_stats_get(struct zbx_json *json, const zbx_config_comms_args_t *zbx_config)
{
zbx_config_cache_info_t count_stats;
zbx_vmware_stats_t vmware_stats;
@@ -71,8 +73,8 @@ void zbx_get_zabbix_stats(struct zbx_json *json)
/* zabbix[items] */
zbx_json_adduint64(json, "items", count_stats.items);
- /* zabbix[item_unsupported] */
- zbx_json_adduint64(json, "item_unsupported", count_stats.items_unsupported);
+ /* zabbix[items_unsupported] */
+ zbx_json_adduint64(json, "items_unsupported", count_stats.items_unsupported);
/* zabbix[requiredperformance] */
zbx_json_addfloat(json, "requiredperformance", count_stats.requiredperformance);
@@ -80,7 +82,7 @@ void zbx_get_zabbix_stats(struct zbx_json *json)
/* zabbix[preprocessing_queue] */
zbx_json_adduint64(json, "preprocessing_queue", zbx_preprocessor_get_queue_size());
- stats_ex_cb(json);
+ stats_ex_cb(json, zbx_config);
/* zabbix[rcache,<cache>,<mode>] */
zbx_json_addobject(json, "rcache");
diff --git a/src/libs/zbxshmem/memalloc.c b/src/libs/zbxshmem/memalloc.c
index 67453bc1f07..89f5355eb79 100644
--- a/src/libs/zbxshmem/memalloc.c
+++ b/src/libs/zbxshmem/memalloc.c
@@ -548,8 +548,8 @@ int zbx_shmem_create(zbx_shmem_info_t **info, zbx_uint64_t size, const char *des
if (!(SHMEM_MIN_SIZE <= size && size <= SHMEM_MAX_SIZE))
{
- *error = zbx_dsprintf(*error, "requested size " ZBX_FS_SIZE_T " not within bounds [" ZBX_FS_UI64
- " <= size <= " ZBX_FS_UI64 "]", (zbx_fs_size_t)size, SHMEM_MIN_SIZE, SHMEM_MAX_SIZE);
+ *error = zbx_dsprintf(*error, "requested size " ZBX_FS_UI64 " not within bounds [" ZBX_FS_UI64
+ " <= size <= " ZBX_FS_UI64 "]", size, SHMEM_MIN_SIZE, SHMEM_MAX_SIZE);
goto out;
}
diff --git a/src/libs/zbxsysinfo/agent/agent.c b/src/libs/zbxsysinfo/agent/agent.c
index 754da15cb3d..cc04634700a 100644
--- a/src/libs/zbxsysinfo/agent/agent.c
+++ b/src/libs/zbxsysinfo/agent/agent.c
@@ -74,8 +74,8 @@ static int AGENT_HOSTMETADATA(AGENT_REQUEST *request, AGENT_RESULT *result)
}
else if (NULL != CONFIG_HOST_METADATA_ITEM)
{
- if (SUCCEED != process(CONFIG_HOST_METADATA_ITEM, ZBX_PROCESS_LOCAL_COMMAND | ZBX_PROCESS_WITH_ALIAS,
- result) || NULL == ZBX_GET_STR_RESULT(result))
+ if (SUCCEED != zbx_execute_agent_check(CONFIG_HOST_METADATA_ITEM, ZBX_PROCESS_LOCAL_COMMAND |
+ ZBX_PROCESS_WITH_ALIAS, result) || NULL == ZBX_GET_STR_RESULT(result))
{
SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot get host metadata using item \"%s\"",
CONFIG_HOST_METADATA_ITEM));
diff --git a/src/libs/zbxsysinfo/aix/cpu.c b/src/libs/zbxsysinfo/aix/cpu.c
index e438a92e260..940313474de 100644
--- a/src/libs/zbxsysinfo/aix/cpu.c
+++ b/src/libs/zbxsysinfo/aix/cpu.c
@@ -214,6 +214,8 @@ int SYSTEM_CPU_SWITCHES(AGENT_REQUEST *request, AGENT_RESULT *result)
#ifdef HAVE_LIBPERFSTAT
perfstat_cpu_total_t ps_cpu_total;
+ ZBX_UNUSED(request);
+
if (-1 == perfstat_cpu_total(NULL, &ps_cpu_total, sizeof(ps_cpu_total), 1))
{
SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno)));
@@ -224,6 +226,8 @@ int SYSTEM_CPU_SWITCHES(AGENT_REQUEST *request, AGENT_RESULT *result)
return SYSINFO_RET_OK;
#else
+ ZBX_UNUSED(request);
+
SET_MSG_RESULT(result, zbx_strdup(NULL, "Agent was compiled without support for Perfstat API."));
return SYSINFO_RET_FAIL;
@@ -232,6 +236,7 @@ int SYSTEM_CPU_SWITCHES(AGENT_REQUEST *request, AGENT_RESULT *result)
int SYSTEM_CPU_INTR(AGENT_REQUEST *request, AGENT_RESULT *result)
{
+ ZBX_UNUSED(request);
#ifdef HAVE_LIBPERFSTAT
perfstat_cpu_total_t ps_cpu_total;
diff --git a/src/libs/zbxsysinfo/aix/diskio.c b/src/libs/zbxsysinfo/aix/diskio.c
index be41b53160d..387e1ecce51 100644
--- a/src/libs/zbxsysinfo/aix/diskio.c
+++ b/src/libs/zbxsysinfo/aix/diskio.c
@@ -31,8 +31,11 @@ typedef struct
}
zbx_perfstat_t;
-int get_diskstat(const char *devname, zbx_uint64_t *dstat)
+int zbx_get_diskstat(const char *devname, zbx_uint64_t *dstat)
{
+ ZBX_UNUSED(devname);
+ ZBX_UNUSED(dstat);
+
return FAIL;
}
diff --git a/src/libs/zbxsysinfo/aix/diskspace.c b/src/libs/zbxsysinfo/aix/diskspace.c
index 1dc8b98531a..64517ca45a1 100644
--- a/src/libs/zbxsysinfo/aix/diskspace.c
+++ b/src/libs/zbxsysinfo/aix/diskspace.c
@@ -240,6 +240,8 @@ int VFS_FS_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result)
struct vmount *vms = NULL, *vm;
struct zbx_json j;
+ ZBX_UNUSED(request);
+
/* check how many bytes to allocate for the mounted filesystems */
if (-1 == (rc = mntctl(MCTL_QUERY, sizeof(sz), (char *)&sz)))
{
@@ -302,6 +304,8 @@ static int vfs_fs_get(AGENT_REQUEST *request, AGENT_RESULT *result)
zbx_mpoint_t *mntpoint;
char *mpoint;
+ ZBX_UNUSED(request);
+
/* check how many bytes to allocate for the mounted filesystems */
if (-1 == (rc = mntctl(MCTL_QUERY, sizeof(sz), (char *)&sz)))
{
diff --git a/src/libs/zbxsysinfo/aix/hostname.c b/src/libs/zbxsysinfo/aix/hostname.c
index 5913dd7b4a0..f17648f076e 100644
--- a/src/libs/zbxsysinfo/aix/hostname.c
+++ b/src/libs/zbxsysinfo/aix/hostname.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/aix/inodes.c b/src/libs/zbxsysinfo/aix/inodes.c
index c0de3f2e700..0b9ae8f4d73 100644
--- a/src/libs/zbxsysinfo/aix/inodes.c
+++ b/src/libs/zbxsysinfo/aix/inodes.c
@@ -18,7 +18,7 @@
**/
#include "zbxsysinfo.h"
-
+#include "../sysinfo.h"
#include "inodes.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/aix/net.c b/src/libs/zbxsysinfo/aix/net.c
index 75d7a0f9041..e09a0c7ef24 100644
--- a/src/libs/zbxsysinfo/aix/net.c
+++ b/src/libs/zbxsysinfo/aix/net.c
@@ -210,6 +210,8 @@ int NET_IF_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result)
perfstat_netinterface_t *ps_netif = NULL;
struct zbx_json j;
+ ZBX_UNUSED(request);
+
/* check how many perfstat_netinterface_t structures are available */
if (-1 == (rc = perfstat_netinterface(NULL, NULL, sizeof(perfstat_netinterface_t), 0)))
{
@@ -253,6 +255,8 @@ end:
return ret;
#else
+ ZBX_UNUSED(request);
+
SET_MSG_RESULT(result, zbx_strdup(NULL, "Agent was compiled without support for Perfstat API."));
return SYSINFO_RET_FAIL;
diff --git a/src/libs/zbxsysinfo/aix/proc.c b/src/libs/zbxsysinfo/aix/proc.c
index 4ded8679021..fa8d43a96e8 100644
--- a/src/libs/zbxsysinfo/aix/proc.c
+++ b/src/libs/zbxsysinfo/aix/proc.c
@@ -43,8 +43,8 @@ static int check_procstate(struct procentry64 *procentry, int zbx_proc_stat)
static int check_procargs(struct procentry64 *procentry, const char *proccomm)
{
- int i;
- char procargs[MAX_BUFFER_LEN];
+ unsigned int i;
+ char procargs[MAX_BUFFER_LEN];
if (0 != getargs(procentry, (int)sizeof(*procentry), procargs, (int)sizeof(procargs)))
return FAIL;
diff --git a/src/libs/zbxsysinfo/aix/software.c b/src/libs/zbxsysinfo/aix/software.c
index 43cffe3022f..f1c84189cf3 100644
--- a/src/libs/zbxsysinfo/aix/software.c
+++ b/src/libs/zbxsysinfo/aix/software.c
@@ -29,6 +29,8 @@ int SYSTEM_SW_ARCH(AGENT_REQUEST *request, AGENT_RESULT *result)
{
struct utsname name;
+ ZBX_UNUSED(request);
+
if (-1 == uname(&name))
{
SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno)));
diff --git a/src/libs/zbxsysinfo/aix/system.c b/src/libs/zbxsysinfo/aix/system.c
index ec3f8896f84..21ee95f65a8 100644
--- a/src/libs/zbxsysinfo/aix/system.c
+++ b/src/libs/zbxsysinfo/aix/system.c
@@ -29,6 +29,8 @@ int SYSTEM_UNAME(AGENT_REQUEST *request, AGENT_RESULT *result)
{
struct utsname name;
+ ZBX_UNUSED(request);
+
if (-1 == uname(&name))
{
SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno)));
diff --git a/src/libs/zbxsysinfo/aix/uptime.c b/src/libs/zbxsysinfo/aix/uptime.c
index eedf3574e4d..2133ed86df5 100644
--- a/src/libs/zbxsysinfo/aix/uptime.c
+++ b/src/libs/zbxsysinfo/aix/uptime.c
@@ -28,6 +28,8 @@ int SYSTEM_UPTIME(AGENT_REQUEST *request, AGENT_RESULT *result)
#if defined(HAVE_LIBPERFSTAT)
perfstat_cpu_total_t ps_cpu_total;
+ ZBX_UNUSED(request);
+
if (0 >= hertz)
{
hertz = sysconf(_SC_CLK_TCK);
@@ -58,6 +60,8 @@ int SYSTEM_UPTIME(AGENT_REQUEST *request, AGENT_RESULT *result)
return SYSINFO_RET_OK;
#else
+ ZBX_UNUSED(request);
+
SET_MSG_RESULT(result, zbx_strdup(NULL, "Agent was compiled without support for Perfstat API."));
return SYSINFO_RET_FAIL;
diff --git a/src/libs/zbxsysinfo/alias/alias.c b/src/libs/zbxsysinfo/alias/alias.c
index 8b05876fb1f..d400a246fc9 100644
--- a/src/libs/zbxsysinfo/alias/alias.c
+++ b/src/libs/zbxsysinfo/alias/alias.c
@@ -22,6 +22,7 @@
#include "zbxstr.h"
#include "log.h"
+#include "zbxexpr.h"
static ALIAS *aliasList = NULL;
@@ -30,7 +31,7 @@ void test_aliases(void)
ALIAS *alias;
for (alias = aliasList; NULL != alias; alias = alias->next)
- test_parameter(alias->name);
+ zbx_test_parameter(alias->name);
}
void zbx_add_alias(const char *name, const char *value)
@@ -89,7 +90,7 @@ const char *zbx_alias_get(const char *orig)
size_t buffer_offset = 0;
const char *p = orig;
- if (SUCCEED != parse_key(&p) || '\0' != *p)
+ if (SUCCEED != zbx_parse_key(&p) || '\0' != *p)
return orig;
for (alias = aliasList; NULL != alias; alias = alias->next)
diff --git a/src/libs/zbxsysinfo/common/dir.c b/src/libs/zbxsysinfo/common/dir.c
index f427e1559f4..1aa33e2ed03 100644
--- a/src/libs/zbxsysinfo/common/dir.c
+++ b/src/libs/zbxsysinfo/common/dir.c
@@ -19,6 +19,7 @@
#include "dir.h"
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "zbxstr.h"
#include "zbxnum.h"
diff --git a/src/libs/zbxsysinfo/common/dns.c b/src/libs/zbxsysinfo/common/dns.c
index 37df7ec7029..5877c074e0b 100644
--- a/src/libs/zbxsysinfo/common/dns.c
+++ b/src/libs/zbxsysinfo/common/dns.c
@@ -19,6 +19,7 @@
#include "dns.h"
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "zbxstr.h"
#include "zbxnum.h"
diff --git a/src/libs/zbxsysinfo/common/zabbix_stats.c b/src/libs/zbxsysinfo/common/zabbix_stats.c
index 8f703911efe..ff579f729b7 100644
--- a/src/libs/zbxsysinfo/common/zabbix_stats.c
+++ b/src/libs/zbxsysinfo/common/zabbix_stats.c
@@ -94,7 +94,7 @@ static void get_remote_zabbix_stats(const struct zbx_json *json, const char *ip,
"Cannot obtain internal statistics: received empty response."));
}
else if (SUCCEED == check_response(s.buffer, result))
- set_result_type(result, ITEM_VALUE_TYPE_TEXT, s.buffer);
+ zbx_set_agent_result_type(result, ITEM_VALUE_TYPE_TEXT, s.buffer);
}
else
{
diff --git a/src/libs/zbxsysinfo/common/zbxsysinfo_common.c b/src/libs/zbxsysinfo/common/zbxsysinfo_common.c
index 22e6e5a00e7..f772ecdbb23 100644
--- a/src/libs/zbxsysinfo/common/zbxsysinfo_common.c
+++ b/src/libs/zbxsysinfo/common/zbxsysinfo_common.c
@@ -96,7 +96,7 @@ ZBX_METRIC parameters_common[] =
static const char *user_parameter_dir = NULL;
-void set_user_parameter_dir(const char *path)
+void zbx_set_user_parameter_dir(const char *path)
{
user_parameter_dir = path;
}
diff --git a/src/libs/zbxsysinfo/freebsd/diskio.c b/src/libs/zbxsysinfo/freebsd/diskio.c
index fdf03ddfc69..2a73712bff7 100644
--- a/src/libs/zbxsysinfo/freebsd/diskio.c
+++ b/src/libs/zbxsysinfo/freebsd/diskio.c
@@ -29,7 +29,7 @@
static struct statinfo *si = NULL;
-int get_diskstat(const char *devname, zbx_uint64_t *dstat)
+int zbx_get_diskstat(const char *devname, zbx_uint64_t *dstat)
{
int i;
struct devstat *ds = NULL;
@@ -148,7 +148,7 @@ static int vfs_dev_rw(AGENT_REQUEST *request, AGENT_RESULT *result, int rw)
return SYSINFO_RET_FAIL;
}
- if (FAIL == get_diskstat(pd, dstats))
+ if (FAIL == zbx_get_diskstat(pd, dstats))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain disk information."));
return SYSINFO_RET_FAIL;
@@ -190,7 +190,7 @@ static int vfs_dev_rw(AGENT_REQUEST *request, AGENT_RESULT *result, int rw)
if (NULL == (device = collector_diskdevice_get(pd)))
{
- if (FAIL == get_diskstat(pd, dstats)) /* validate device name */
+ if (FAIL == zbx_get_diskstat(pd, dstats)) /* validate device name */
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain disk information."));
return SYSINFO_RET_FAIL;
diff --git a/src/libs/zbxsysinfo/freebsd/hostname.c b/src/libs/zbxsysinfo/freebsd/hostname.c
index 5913dd7b4a0..f17648f076e 100644
--- a/src/libs/zbxsysinfo/freebsd/hostname.c
+++ b/src/libs/zbxsysinfo/freebsd/hostname.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/freebsd/inodes.c b/src/libs/zbxsysinfo/freebsd/inodes.c
index 4a3e67267f5..d3e27b90bac 100644
--- a/src/libs/zbxsysinfo/freebsd/inodes.c
+++ b/src/libs/zbxsysinfo/freebsd/inodes.c
@@ -17,8 +17,9 @@
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-#include "inodes.h"
#include "zbxsysinfo.h"
+#include "inodes.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/freebsd/proc.c b/src/libs/zbxsysinfo/freebsd/proc.c
index 44db5c149b6..f313c4b90f3 100644
--- a/src/libs/zbxsysinfo/freebsd/proc.c
+++ b/src/libs/zbxsysinfo/freebsd/proc.c
@@ -147,18 +147,25 @@ static void proc_data_free(proc_data_t *proc_data)
zbx_free(proc_data);
}
+#define ARGV_START_SIZE 64
static char *get_commandline(struct kinfo_proc *proc)
{
int mib[4], i;
size_t sz;
static char *args = NULL;
+#if (__FreeBSD_version >= 802510)
static int args_alloc = 0;
+#else
+ int argv_max, err = -1;
+ static int args_alloc = ARGV_START_SIZE;
+#endif
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_ARGS;
mib[3] = proc->ZBX_PROC_PID;
+#if (__FreeBSD_version >= 802510)
if (-1 == sysctl(mib, 4, NULL, &sz, NULL, 0))
return NULL;
@@ -175,16 +182,50 @@ static char *get_commandline(struct kinfo_proc *proc)
if (-1 == sysctl(mib, 4, args, &sz, NULL, 0))
return NULL;
+#else
+ /*
+ * Before FreeBSD 8.3 sysctl() API for kern.proc.args didn't follow the regular convention
+ * that a user can query the needed size for results by passing in a NULL old pointer
+ * and a valid oldsize, given that we have to estimate the required output buffer size manually:
+ *
+ * https://github.com/freebsd/freebsd-src/commit/9f688f2ce3c01f30b0c98d17c6ce057660819c8c
+ */
+
+ if (NULL == args)
+ args = zbx_malloc(args, args_alloc);
+
+ if (-1 == (argv_max = sysconf(_SC_ARG_MAX)))
+ return NULL;
+
+ while (0 != err && args_alloc < argv_max)
+ {
+ sz = (size_t)args_alloc;
+ if (-1 == (err = sysctl(mib, 4, args, &sz, NULL, 0)))
+ {
+ if (ENOMEM == errno)
+ {
+ args_alloc *= 2;
+ args = zbx_realloc(args, args_alloc);
+ }
+ else
+ return NULL;
+ }
+ }
+
+ if (-1 == err)
+ return NULL;
+#endif
for (i = 0; i < (int)(sz - 1); i++)
if (args[i] == '\0')
args[i] = ' ';
- if (sz == 0)
+ if (0 == sz)
zbx_strlcpy(args, proc->ZBX_PROC_COMM, args_alloc);
return args;
}
+#undef ARGV_START_SIZE
int PROC_MEM(AGENT_REQUEST *request, AGENT_RESULT *result)
{
diff --git a/src/libs/zbxsysinfo/hpux/diskio.c b/src/libs/zbxsysinfo/hpux/diskio.c
index f2dd74e02a2..606ca389bc3 100644
--- a/src/libs/zbxsysinfo/hpux/diskio.c
+++ b/src/libs/zbxsysinfo/hpux/diskio.c
@@ -19,7 +19,7 @@
#include "zbxsysinfo.h"
-int get_diskstat(const char *devname, zbx_uint64_t *dstat)
+int zbx_get_diskstat(const char *devname, zbx_uint64_t *dstat)
{
return FAIL;
}
diff --git a/src/libs/zbxsysinfo/hpux/hostname.c b/src/libs/zbxsysinfo/hpux/hostname.c
index 0fff7cca94f..1b20aadc1e7 100644
--- a/src/libs/zbxsysinfo/hpux/hostname.c
+++ b/src/libs/zbxsysinfo/hpux/hostname.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/linux/diskio.c b/src/libs/zbxsysinfo/linux/diskio.c
index 81eee4e571f..873f66c6608 100644
--- a/src/libs/zbxsysinfo/linux/diskio.c
+++ b/src/libs/zbxsysinfo/linux/diskio.c
@@ -72,7 +72,7 @@
) continue
#endif
-int get_diskstat(const char *devname, zbx_uint64_t *dstat)
+int zbx_get_diskstat(const char *devname, zbx_uint64_t *dstat)
{
FILE *f;
char tmp[MAX_STRING_LEN], name[MAX_STRING_LEN], dev_path[MAX_STRING_LEN];
@@ -211,7 +211,7 @@ static int vfs_dev_rw(AGENT_REQUEST *request, AGENT_RESULT *result, int rw)
return SYSINFO_RET_FAIL;
}
- if (SUCCEED != get_diskstat(devname, dstats))
+ if (SUCCEED != zbx_get_diskstat(devname, dstats))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain disk information."));
return SYSINFO_RET_FAIL;
@@ -263,7 +263,7 @@ static int vfs_dev_rw(AGENT_REQUEST *request, AGENT_RESULT *result, int rw)
if (NULL == (device = collector_diskdevice_get(kernel_devname)))
{
- if (SUCCEED != get_diskstat(kernel_devname, dstats))
+ if (SUCCEED != zbx_get_diskstat(kernel_devname, dstats))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain disk information."));
diff --git a/src/libs/zbxsysinfo/linux/hostname.c b/src/libs/zbxsysinfo/linux/hostname.c
index 5913dd7b4a0..f17648f076e 100644
--- a/src/libs/zbxsysinfo/linux/hostname.c
+++ b/src/libs/zbxsysinfo/linux/hostname.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/linux/inodes.c b/src/libs/zbxsysinfo/linux/inodes.c
index 4dea50b9de5..791bbdb7322 100644
--- a/src/libs/zbxsysinfo/linux/inodes.c
+++ b/src/libs/zbxsysinfo/linux/inodes.c
@@ -19,6 +19,7 @@
#include "inodes.h"
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/linux/memory.c b/src/libs/zbxsysinfo/linux/memory.c
index 9a84e307778..02907b9a72d 100644
--- a/src/libs/zbxsysinfo/linux/memory.c
+++ b/src/libs/zbxsysinfo/linux/memory.c
@@ -168,7 +168,7 @@ static int VM_MEMORY_PAVAILABLE(AGENT_RESULT *result)
return SYSINFO_RET_FAIL;
}
- init_result(&result_tmp);
+ zbx_init_agent_result(&result_tmp);
ret = VM_MEMORY_AVAILABLE(&result_tmp);
@@ -190,7 +190,7 @@ static int VM_MEMORY_PAVAILABLE(AGENT_RESULT *result)
SET_DBL_RESULT(result, available / (double)total * 100);
clean:
- free_result(&result_tmp);
+ zbx_free_agent_result(&result_tmp);
return ret;
}
diff --git a/src/libs/zbxsysinfo/netbsd/diskio.c b/src/libs/zbxsysinfo/netbsd/diskio.c
index f2dd74e02a2..606ca389bc3 100644
--- a/src/libs/zbxsysinfo/netbsd/diskio.c
+++ b/src/libs/zbxsysinfo/netbsd/diskio.c
@@ -19,7 +19,7 @@
#include "zbxsysinfo.h"
-int get_diskstat(const char *devname, zbx_uint64_t *dstat)
+int zbx_get_diskstat(const char *devname, zbx_uint64_t *dstat)
{
return FAIL;
}
diff --git a/src/libs/zbxsysinfo/netbsd/hostname.c b/src/libs/zbxsysinfo/netbsd/hostname.c
index 5913dd7b4a0..f17648f076e 100644
--- a/src/libs/zbxsysinfo/netbsd/hostname.c
+++ b/src/libs/zbxsysinfo/netbsd/hostname.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/netbsd/inodes.c b/src/libs/zbxsysinfo/netbsd/inodes.c
index 85060eace97..072bcd18836 100644
--- a/src/libs/zbxsysinfo/netbsd/inodes.c
+++ b/src/libs/zbxsysinfo/netbsd/inodes.c
@@ -19,6 +19,7 @@
#include "inodes.h"
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/openbsd/diskio.c b/src/libs/zbxsysinfo/openbsd/diskio.c
index 85a09df212b..5cea1603a41 100644
--- a/src/libs/zbxsysinfo/openbsd/diskio.c
+++ b/src/libs/zbxsysinfo/openbsd/diskio.c
@@ -22,7 +22,7 @@
#include "log.h"
#include "zbxstr.h"
-int get_diskstat(const char *devname, zbx_uint64_t *dstat)
+int zbx_get_diskstat(const char *devname, zbx_uint64_t *dstat)
{
return FAIL;
}
diff --git a/src/libs/zbxsysinfo/openbsd/hostname.c b/src/libs/zbxsysinfo/openbsd/hostname.c
index 5913dd7b4a0..f17648f076e 100644
--- a/src/libs/zbxsysinfo/openbsd/hostname.c
+++ b/src/libs/zbxsysinfo/openbsd/hostname.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/osf/diskio.c b/src/libs/zbxsysinfo/osf/diskio.c
index f2dd74e02a2..606ca389bc3 100644
--- a/src/libs/zbxsysinfo/osf/diskio.c
+++ b/src/libs/zbxsysinfo/osf/diskio.c
@@ -19,7 +19,7 @@
#include "zbxsysinfo.h"
-int get_diskstat(const char *devname, zbx_uint64_t *dstat)
+int zbx_get_diskstat(const char *devname, zbx_uint64_t *dstat)
{
return FAIL;
}
diff --git a/src/libs/zbxsysinfo/osf/diskspace.c b/src/libs/zbxsysinfo/osf/diskspace.c
index 2bcd38bbfad..76df1a5b190 100644
--- a/src/libs/zbxsysinfo/osf/diskspace.c
+++ b/src/libs/zbxsysinfo/osf/diskspace.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/osf/hostname.c b/src/libs/zbxsysinfo/osf/hostname.c
index 5913dd7b4a0..f17648f076e 100644
--- a/src/libs/zbxsysinfo/osf/hostname.c
+++ b/src/libs/zbxsysinfo/osf/hostname.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/osf/inodes.c b/src/libs/zbxsysinfo/osf/inodes.c
index 4c983a03b43..cc9d1cc3658 100644
--- a/src/libs/zbxsysinfo/osf/inodes.c
+++ b/src/libs/zbxsysinfo/osf/inodes.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/osf/memory.c b/src/libs/zbxsysinfo/osf/memory.c
index c4af371dae3..de910b18479 100644
--- a/src/libs/zbxsysinfo/osf/memory.c
+++ b/src/libs/zbxsysinfo/osf/memory.c
@@ -36,7 +36,7 @@ static int VM_MEMORY_USED(AGENT_RESULT *result)
AGENT_RESULT result_tmp;
zbx_uint64_t free, total;
- init_result(&result_tmp);
+ zbx_init_agent_result(&result_tmp);
if (SYSINFO_RET_OK != VM_MEMORY_FREE(&result_tmp))
{
@@ -58,7 +58,7 @@ static int VM_MEMORY_USED(AGENT_RESULT *result)
ret = SYSINFO_RET_OK;
clean:
- free_result(&result_tmp);
+ zbx_free_agent_result(&result_tmp);
return ret;
}
@@ -69,7 +69,7 @@ static int VM_MEMORY_PUSED(AGENT_RESULT *result)
AGENT_RESULT result_tmp;
zbx_uint64_t free, total;
- init_result(&result_tmp);
+ zbx_init_agent_result(&result_tmp);
if (SYSINFO_RET_OK != VM_MEMORY_FREE(&result_tmp))
{
@@ -97,7 +97,7 @@ static int VM_MEMORY_PUSED(AGENT_RESULT *result)
ret = SYSINFO_RET_OK;
clean:
- free_result(&result_tmp);
+ zbx_free_agent_result(&result_tmp);
return ret;
}
@@ -113,7 +113,7 @@ static int VM_MEMORY_PAVAILABLE(AGENT_RESULT *result)
AGENT_RESULT result_tmp;
zbx_uint64_t free, total;
- init_result(&result_tmp);
+ zbx_init_agent_result(&result_tmp);
if (SYSINFO_RET_OK != VM_MEMORY_FREE(&result_tmp))
{
@@ -141,7 +141,7 @@ static int VM_MEMORY_PAVAILABLE(AGENT_RESULT *result)
ret = SYSINFO_RET_OK;
clean:
- free_result(&result_tmp);
+ zbx_free_agent_result(&result_tmp);
return ret;
}
diff --git a/src/libs/zbxsysinfo/osf/swap.c b/src/libs/zbxsysinfo/osf/swap.c
index 74da58c6c2a..11c08179bec 100644
--- a/src/libs/zbxsysinfo/osf/swap.c
+++ b/src/libs/zbxsysinfo/osf/swap.c
@@ -202,7 +202,7 @@ static int SYSTEM_SWAP_PFREE(AGENT_RESULT *result)
zbx_uint64_t tot_val = 0;
zbx_uint64_t free_val = 0;
- init_result(&result_tmp);
+ zbx_init_agent_result(&result_tmp);
if (SYSINFO_RET_OK != SYSTEM_SWAP_TOTAL(&result_tmp) || !(result_tmp.type & AR_UINT64))
return SYSINFO_RET_FAIL;
@@ -211,7 +211,7 @@ static int SYSTEM_SWAP_PFREE(AGENT_RESULT *result)
/* Check for division by zero */
if (0 == tot_val)
{
- free_result(&result_tmp);
+ zbx_free_agent_result(&result_tmp);
return SYSINFO_RET_FAIL;
}
@@ -219,7 +219,7 @@ static int SYSTEM_SWAP_PFREE(AGENT_RESULT *result)
return SYSINFO_RET_FAIL;
free_val = result_tmp.ui64;
- free_result(&result_tmp);
+ zbx_free_agent_result(&result_tmp);
SET_DBL_RESULT(result, (100.0 * (double)free_val) / (double)tot_val);
@@ -232,7 +232,7 @@ static int SYSTEM_SWAP_PUSED(AGENT_RESULT *result)
zbx_uint64_t tot_val = 0;
zbx_uint64_t free_val = 0;
- init_result(&result_tmp);
+ zbx_init_agent_result(&result_tmp);
if (SYSINFO_RET_OK != SYSTEM_SWAP_TOTAL(&result_tmp) || !(result_tmp.type & AR_UINT64))
return SYSINFO_RET_FAIL;
@@ -241,7 +241,7 @@ static int SYSTEM_SWAP_PUSED(AGENT_RESULT *result)
/* Check for division by zero */
if (0 == tot_val)
{
- free_result(&result_tmp);
+ zbx_free_agent_result(&result_tmp);
return SYSINFO_RET_FAIL;
}
@@ -249,7 +249,7 @@ static int SYSTEM_SWAP_PUSED(AGENT_RESULT *result)
return SYSINFO_RET_FAIL;
free_val = result_tmp.ui64;
- free_result(&result_tmp);
+ zbx_free_agent_result(&result_tmp);
SET_DBL_RESULT(result, 100.0 - (100.0 * (double)free_val) / (double)tot_val);
diff --git a/src/libs/zbxsysinfo/osx/diskio.c b/src/libs/zbxsysinfo/osx/diskio.c
index f2dd74e02a2..606ca389bc3 100644
--- a/src/libs/zbxsysinfo/osx/diskio.c
+++ b/src/libs/zbxsysinfo/osx/diskio.c
@@ -19,7 +19,7 @@
#include "zbxsysinfo.h"
-int get_diskstat(const char *devname, zbx_uint64_t *dstat)
+int zbx_get_diskstat(const char *devname, zbx_uint64_t *dstat)
{
return FAIL;
}
diff --git a/src/libs/zbxsysinfo/osx/hostname.c b/src/libs/zbxsysinfo/osx/hostname.c
index 5913dd7b4a0..f17648f076e 100644
--- a/src/libs/zbxsysinfo/osx/hostname.c
+++ b/src/libs/zbxsysinfo/osx/hostname.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/solaris/Makefile.am b/src/libs/zbxsysinfo/solaris/Makefile.am
index a2f8e6fe46b..662bf67e13c 100644
--- a/src/libs/zbxsysinfo/solaris/Makefile.am
+++ b/src/libs/zbxsysinfo/solaris/Makefile.am
@@ -5,6 +5,8 @@ noinst_LIBRARIES = libspecsysinfo.a libspechostnamesysinfo.a
libspecsysinfo_a_CFLAGS = -I$(top_srcdir)/src/zabbix_agent
libspecsysinfo_a_SOURCES = \
+ zbx_sysinfo_kstat.c \
+ zbx_sysinfo_kstat.h \
boottime.c \
cpu.c \
diskio.c \
diff --git a/src/libs/zbxsysinfo/solaris/boottime.c b/src/libs/zbxsysinfo/solaris/boottime.c
index c463cbc2a69..20786fd3fbd 100644
--- a/src/libs/zbxsysinfo/solaris/boottime.c
+++ b/src/libs/zbxsysinfo/solaris/boottime.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "zbx_sysinfo_kstat.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/solaris/cpu.c b/src/libs/zbxsysinfo/solaris/cpu.c
index 623f9e51c36..c18da58e2cc 100644
--- a/src/libs/zbxsysinfo/solaris/cpu.c
+++ b/src/libs/zbxsysinfo/solaris/cpu.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "zbx_sysinfo_kstat.h"
#include "stats.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/solaris/diskio.c b/src/libs/zbxsysinfo/solaris/diskio.c
index 3ecc1df13ba..544b40360a3 100644
--- a/src/libs/zbxsysinfo/solaris/diskio.c
+++ b/src/libs/zbxsysinfo/solaris/diskio.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
@@ -30,7 +31,7 @@ typedef struct
}
zbx_kstat_t;
-int get_diskstat(const char *devname, zbx_uint64_t *dstat)
+int zbx_get_diskstat(const char *devname, zbx_uint64_t *dstat)
{
return FAIL;
}
@@ -170,6 +171,13 @@ static int VFS_DEV_WRITE_OPERATIONS(const char *devname, AGENT_RESULT *result)
return SYSINFO_RET_OK;
}
+typedef struct
+{
+ const char *mode;
+ int (*function)(const char *devname, AGENT_RESULT *result);
+}
+MODE_FUNCTION;
+
static int process_mode_function(AGENT_REQUEST *request, AGENT_RESULT *result, const MODE_FUNCTION *fl)
{
const char *devname, *mode;
diff --git a/src/libs/zbxsysinfo/solaris/hostname.c b/src/libs/zbxsysinfo/solaris/hostname.c
index 5913dd7b4a0..f17648f076e 100644
--- a/src/libs/zbxsysinfo/solaris/hostname.c
+++ b/src/libs/zbxsysinfo/solaris/hostname.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/solaris/inodes.c b/src/libs/zbxsysinfo/solaris/inodes.c
index 85060eace97..072bcd18836 100644
--- a/src/libs/zbxsysinfo/solaris/inodes.c
+++ b/src/libs/zbxsysinfo/solaris/inodes.c
@@ -19,6 +19,7 @@
#include "inodes.h"
#include "zbxsysinfo.h"
+#include "../sysinfo.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/solaris/net.c b/src/libs/zbxsysinfo/solaris/net.c
index efa76407d7e..aed08bdbfa4 100644
--- a/src/libs/zbxsysinfo/solaris/net.c
+++ b/src/libs/zbxsysinfo/solaris/net.c
@@ -19,6 +19,7 @@
#include "zbxsysinfo.h"
#include "../common/zbxsysinfo_common.h"
+#include "zbx_sysinfo_kstat.h"
#include "zbxjson.h"
#include "log.h"
diff --git a/src/libs/zbxsysinfo/solaris/zbx_sysinfo_kstat.c b/src/libs/zbxsysinfo/solaris/zbx_sysinfo_kstat.c
new file mode 100644
index 00000000000..7ecb54bca98
--- /dev/null
+++ b/src/libs/zbxsysinfo/solaris/zbx_sysinfo_kstat.c
@@ -0,0 +1,41 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2022 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 "zbx_sysinfo_kstat.h"
+#include "zbxcommon.h"
+
+#ifdef HAVE_KSTAT_H
+zbx_uint64_t get_kstat_numeric_value(const kstat_named_t *kn)
+{
+ switch (kn->data_type)
+ {
+ case KSTAT_DATA_INT32:
+ return kn->value.i32;
+ case KSTAT_DATA_UINT32:
+ return kn->value.ui32;
+ case KSTAT_DATA_INT64:
+ return kn->value.i64;
+ case KSTAT_DATA_UINT64:
+ return kn->value.ui64;
+ default:
+ THIS_SHOULD_NEVER_HAPPEN;
+ return 0;
+ }
+}
+#endif /* HAVE_KSTAT_H */
diff --git a/src/zabbix_server/trapper/proxyconfig.h b/src/libs/zbxsysinfo/solaris/zbx_sysinfo_kstat.h
index 579ebe33b61..6b42dc1a06b 100644
--- a/src/zabbix_server/trapper/proxyconfig.h
+++ b/src/libs/zbxsysinfo/solaris/zbx_sysinfo_kstat.h
@@ -17,16 +17,8 @@
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-#ifndef ZABBIX_PROXYCFG_H
-#define ZABBIX_PROXYCFG_H
+#include "zbxtypes.h"
-#include "zbxcomms.h"
-#include "zbxjson.h"
-
-extern int CONFIG_TIMEOUT;
-extern int CONFIG_TRAPPER_TIMEOUT;
-
-void send_proxyconfig(zbx_socket_t *sock, struct zbx_json_parse *jp);
-void recv_proxyconfig(zbx_socket_t *sock, struct zbx_json_parse *jp, const zbx_config_tls_t *zbx_config_tls);
-
-#endif
+#ifdef HAVE_KSTAT_H
+zbx_uint64_t get_kstat_numeric_value(const kstat_named_t *kn);
+#endif /* HAVE_KSTAT_H */
diff --git a/src/libs/zbxsysinfo/sysinfo.c b/src/libs/zbxsysinfo/sysinfo.c
index b626bf9e718..167c135e0a6 100644
--- a/src/libs/zbxsysinfo/sysinfo.c
+++ b/src/libs/zbxsysinfo/sysinfo.c
@@ -18,6 +18,7 @@
**/
#include "zbxsysinfo.h"
+#include "sysinfo.h"
#include "alias/alias.h"
#include "log.h"
@@ -30,6 +31,7 @@
#include "zbxstr.h"
#include "zbxnum.h"
#include "zbxparam.h"
+#include "zbxexpr.h"
extern int CONFIG_TIMEOUT;
@@ -75,7 +77,7 @@ zbx_vector_ptr_t key_access_rules;
#define ZBX_COMMAND_WITH_PARAMS 2
static int compare_key_access_rules(const void *rule_a, const void *rule_b);
-static int parse_key_access_rule(char *pattern, zbx_key_access_rule_t *rule);
+static int zbx_parse_key_access_rule(char *pattern, zbx_key_access_rule_t *rule);
/******************************************************************************
* *
@@ -92,7 +94,7 @@ static int parse_command_dyn(const char *command, char **cmd, char **param)
size_t cmd_alloc = 0, param_alloc = 0,
cmd_offset = 0, param_offset = 0;
- for (pl = command; SUCCEED == is_key_char(*pl); pl++)
+ for (pl = command; SUCCEED == zbx_is_key_char(*pl); pl++)
;
if (pl == command)
@@ -147,7 +149,7 @@ static int add_to_metrics(ZBX_METRIC **metrics, ZBX_METRIC *metric, char *error,
* Purpose: registers a new item key into the system *
* *
******************************************************************************/
-int add_metric(ZBX_METRIC *metric, char *error, size_t max_error_len)
+int zbx_add_metric(ZBX_METRIC *metric, char *error, size_t max_error_len)
{
return add_to_metrics(&commands, metric, error, max_error_len);
}
@@ -157,22 +159,22 @@ int add_metric(ZBX_METRIC *metric, char *error, size_t max_error_len)
* Purpose: registers a new item key as local into the system *
* *
******************************************************************************/
-int add_metric_local(ZBX_METRIC *metric, char *error, size_t max_error_len)
+static int add_metric_local(ZBX_METRIC *metric, char *error, size_t max_error_len)
{
return add_to_metrics(&commands_local, metric, error, max_error_len);
}
#if !defined(__MINGW32__)
-int add_user_parameter(const char *itemkey, char *command, char *error, size_t max_error_len)
+int zbx_add_user_parameter(const char *itemkey, char *command, char *error, size_t max_error_len)
{
int ret;
unsigned flags = CF_USERPARAMETER;
ZBX_METRIC metric;
AGENT_REQUEST request;
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED == (ret = parse_item_key(itemkey, &request)))
+ if (SUCCEED == (ret = zbx_parse_item_key(itemkey, &request)))
{
if (1 == get_rparams_num(&request) && 0 == strcmp("[*]", itemkey + strlen(get_rkey(&request))))
flags |= CF_HAVEPARAMS;
@@ -187,17 +189,17 @@ int add_user_parameter(const char *itemkey, char *command, char *error, size_t m
metric.function = &EXECUTE_USER_PARAMETER;
metric.test_param = command;
- ret = add_metric(&metric, error, max_error_len);
+ ret = zbx_add_metric(&metric, error, max_error_len);
}
else
zbx_strlcpy(error, "syntax error", max_error_len);
- free_request(&request);
+ zbx_free_agent_request(&request);
return ret;
}
-void remove_user_parameters(void)
+void zbx_remove_user_parameters(void)
{
int i, usr = -1;
@@ -227,7 +229,7 @@ void remove_user_parameters(void)
}
}
-void get_metrics_copy(ZBX_METRIC **metrics)
+void zbx_get_metrics_copy(ZBX_METRIC **metrics)
{
unsigned int i;
@@ -254,19 +256,19 @@ void get_metrics_copy(ZBX_METRIC **metrics)
memset(&(*metrics)[i], 0, sizeof(ZBX_METRIC));
}
-void set_metrics(ZBX_METRIC *metrics)
+void zbx_set_metrics(ZBX_METRIC *metrics)
{
- free_metrics_ext(&commands);
+ zbx_free_metrics_ext(&commands);
commands = metrics;
}
#endif
-void init_metrics(void)
+void zbx_init_metrics(void)
{
int i;
char error[MAX_STRING_LEN];
- init_key_access_rules();
+ zbx_init_key_access_rules();
commands = (ZBX_METRIC *)zbx_malloc(commands, sizeof(ZBX_METRIC));
commands[0].key = NULL;
@@ -276,7 +278,7 @@ void init_metrics(void)
#ifdef WITH_AGENT_METRICS
for (i = 0; NULL != parameters_agent[i].key; i++)
{
- if (SUCCEED != add_metric(&parameters_agent[i], error, sizeof(error)))
+ if (SUCCEED != zbx_add_metric(&parameters_agent[i], error, sizeof(error)))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot add item key: %s", error);
exit(EXIT_FAILURE);
@@ -287,7 +289,7 @@ void init_metrics(void)
#ifdef WITH_COMMON_METRICS
for (i = 0; NULL != parameters_common[i].key; i++)
{
- if (SUCCEED != add_metric(&parameters_common[i], error, sizeof(error)))
+ if (SUCCEED != zbx_add_metric(&parameters_common[i], error, sizeof(error)))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot add item key: %s", error);
exit(EXIT_FAILURE);
@@ -307,7 +309,7 @@ void init_metrics(void)
#ifdef WITH_HTTP_METRICS
for (i = 0; NULL != parameters_common_http[i].key; i++)
{
- if (SUCCEED != add_metric(&parameters_common_http[i], error, sizeof(error)))
+ if (SUCCEED != zbx_add_metric(&parameters_common_http[i], error, sizeof(error)))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot add item key: %s", error);
exit(EXIT_FAILURE);
@@ -318,7 +320,7 @@ void init_metrics(void)
#ifdef WITH_SPECIFIC_METRICS
for (i = 0; NULL != parameters_specific[i].key; i++)
{
- if (SUCCEED != add_metric(&parameters_specific[i], error, sizeof(error)))
+ if (SUCCEED != zbx_add_metric(&parameters_specific[i], error, sizeof(error)))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot add item key: %s", error);
exit(EXIT_FAILURE);
@@ -329,7 +331,7 @@ void init_metrics(void)
#ifdef WITH_SIMPLE_METRICS
for (i = 0; NULL != parameters_simple[i].key; i++)
{
- if (SUCCEED != add_metric(&parameters_simple[i], error, sizeof(error)))
+ if (SUCCEED != zbx_add_metric(&parameters_simple[i], error, sizeof(error)))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot add item key: %s", error);
exit(EXIT_FAILURE);
@@ -338,7 +340,7 @@ void init_metrics(void)
#endif
#ifdef WITH_HOSTNAME_METRIC
- if (SUCCEED != add_metric(&parameter_hostname, error, sizeof(error)))
+ if (SUCCEED != zbx_add_metric(&parameter_hostname, error, sizeof(error)))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot add item key: %s", error);
exit(EXIT_FAILURE);
@@ -346,7 +348,7 @@ void init_metrics(void)
#endif
}
-void free_metrics_ext(ZBX_METRIC **metrics)
+void zbx_free_metrics_ext(ZBX_METRIC **metrics)
{
if (NULL != *metrics)
{
@@ -362,11 +364,11 @@ void free_metrics_ext(ZBX_METRIC **metrics)
}
}
-void free_metrics(void)
+void zbx_free_metrics(void)
{
- free_metrics_ext(&commands);
- free_metrics_ext(&commands_local);
- free_key_access_rules();
+ zbx_free_metrics_ext(&commands);
+ zbx_free_metrics_ext(&commands_local);
+ zbx_free_key_access_rules();
}
/******************************************************************************
@@ -374,7 +376,7 @@ void free_metrics(void)
* Purpose: initializes key access rule list *
* *
******************************************************************************/
-void init_key_access_rules(void)
+void zbx_init_key_access_rules(void)
{
zbx_vector_ptr_create(&key_access_rules);
}
@@ -411,7 +413,7 @@ static zbx_key_access_rule_t *zbx_key_access_rule_create(char *pattern, zbx_key_
rule->pattern = zbx_strdup(NULL, pattern);
zbx_vector_str_create(&rule->elements);
- if (SUCCEED != parse_key_access_rule(pattern, rule))
+ if (SUCCEED != zbx_parse_key_access_rule(pattern, rule))
{
zbx_key_access_rule_free(rule);
rule = NULL;
@@ -424,7 +426,7 @@ static zbx_key_access_rule_t *zbx_key_access_rule_create(char *pattern, zbx_key_
* Purpose: validates key access rules configuration *
* *
******************************************************************************/
-void finalize_key_access_rules_configuration(void)
+void zbx_finalize_key_access_rules_configuration(void)
{
int i, j, rules_num, sysrun_index = ZBX_MAX_UINT31_1;
zbx_key_access_rule_t *rule, *sysrun_deny;
@@ -525,13 +527,13 @@ void finalize_key_access_rules_configuration(void)
* FAIL - pattern parsing failed *
* *
******************************************************************************/
-static int parse_key_access_rule(char *pattern, zbx_key_access_rule_t *rule)
+static int zbx_parse_key_access_rule(char *pattern, zbx_key_access_rule_t *rule)
{
char *pl, *pr = NULL, *param;
size_t alloc = 0, offset = 0;
int i, size;
- for (pl = pattern; SUCCEED == is_key_char(*pl) || '*' == *pl; pl++);
+ for (pl = pattern; SUCCEED == zbx_is_key_char(*pl) || '*' == *pl; pl++);
if (pl == pattern)
return FAIL; /* empty key */
@@ -634,7 +636,7 @@ static int compare_key_access_rules(const void *rule_a, const void *rule_b)
* FAIL - pattern parsing failed *
* *
******************************************************************************/
-int add_key_access_rule(const char *parameter, char *pattern, zbx_key_access_rule_type_t type)
+int zbx_add_key_access_rule(const char *parameter, char *pattern, zbx_key_access_rule_type_t type)
{
zbx_key_access_rule_t *rule, *r;
int i;
@@ -673,7 +675,7 @@ int add_key_access_rule(const char *parameter, char *pattern, zbx_key_access_rul
* ZBX_KEY_ACCESS_DENY - metric access denied *
* *
******************************************************************************/
-int check_request_access_rules(AGENT_REQUEST *request)
+int zbx_check_request_access_rules(AGENT_REQUEST *request)
{
int i, j, empty_arguments;
zbx_key_access_rule_t *rule;
@@ -757,19 +759,19 @@ int check_request_access_rules(AGENT_REQUEST *request)
* ZBX_KEY_ACCESS_DENY - metric access denied *
* *
******************************************************************************/
-int check_key_access_rules(const char *metric)
+int zbx_check_key_access_rules(const char *metric)
{
int ret;
AGENT_REQUEST request;
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED == parse_item_key(metric, &request))
- ret = check_request_access_rules(&request);
+ if (SUCCEED == zbx_parse_item_key(metric, &request))
+ ret = zbx_check_request_access_rules(&request);
else
ret = ZBX_KEY_ACCESS_DENY;
- free_request(&request);
+ zbx_free_agent_request(&request);
return ret;
}
@@ -779,7 +781,7 @@ int check_key_access_rules(const char *metric)
* Purpose: cleanup key access rule list *
* *
******************************************************************************/
-void free_key_access_rules(void)
+void zbx_free_key_access_rules(void)
{
int i;
@@ -798,7 +800,7 @@ static void zbx_log_init(zbx_log_t *log)
log->logeventid = 0;
}
-void init_result(AGENT_RESULT *result)
+void zbx_init_agent_result(AGENT_RESULT *result)
{
memset(result, 0, sizeof(AGENT_RESULT));
}
@@ -815,7 +817,7 @@ void zbx_log_free(zbx_log_t *log)
zbx_free(log);
}
-void free_result(AGENT_RESULT *result)
+void zbx_free_agent_result(AGENT_RESULT *result)
{
ZBX_UNSET_UI64_RESULT(result);
ZBX_UNSET_DBL_RESULT(result);
@@ -832,7 +834,7 @@ void free_result(AGENT_RESULT *result)
* Parameters: request - pointer to the structure *
* *
******************************************************************************/
-void init_request(AGENT_REQUEST *request)
+void zbx_init_agent_request(AGENT_REQUEST *request)
{
request->key = NULL;
request->nparam = 0;
@@ -868,7 +870,7 @@ static void free_request_params(AGENT_REQUEST *request)
* Parameters: request - pointer to the request structure *
* *
******************************************************************************/
-void free_request(AGENT_REQUEST *request)
+void zbx_free_agent_request(AGENT_REQUEST *request)
{
zbx_free(request->key);
free_request_params(request);
@@ -904,7 +906,7 @@ static void add_request_param(AGENT_REQUEST *request, char *pvalue, zbx_request_
* Comments: thread-safe *
* *
******************************************************************************/
-int parse_item_key(const char *itemkey, AGENT_REQUEST *request)
+int zbx_parse_item_key(const char *itemkey, AGENT_REQUEST *request)
{
int i, ret = FAIL;
char *key = NULL, *params = NULL;
@@ -940,16 +942,16 @@ out:
#undef ZBX_COMMAND_WITHOUT_PARAMS
#undef ZBX_COMMAND_WITH_PARAMS
-void test_parameter(const char *key)
+void zbx_test_parameter(const char *key)
{
#define ZBX_KEY_COLUMN_WIDTH 45
AGENT_RESULT result;
printf("%-*s", ZBX_KEY_COLUMN_WIDTH, key);
- init_result(&result);
+ zbx_init_agent_result(&result);
- if (SUCCEED == process(key, ZBX_PROCESS_WITH_ALIAS, &result))
+ if (SUCCEED == zbx_execute_agent_check(key, ZBX_PROCESS_WITH_ALIAS, &result))
{
char buffer[ZBX_MAX_DOUBLE_LEN + 1];
@@ -976,7 +978,7 @@ void test_parameter(const char *key)
printf(" [m|" ZBX_NOTSUPPORTED "]");
}
- free_result(&result);
+ zbx_free_agent_result(&result);
printf("\n");
@@ -984,7 +986,7 @@ void test_parameter(const char *key)
#undef ZBX_KEY_COLUMN_WIDTH
}
-void test_parameters(void)
+void zbx_test_parameters(void)
{
int i;
char *key = NULL;
@@ -1005,8 +1007,8 @@ void test_parameters(void)
zbx_chrcpy_alloc(&key, &key_alloc, &key_offset, ']');
}
- if (ZBX_KEY_ACCESS_ALLOW == check_key_access_rules(key))
- test_parameter(key);
+ if (ZBX_KEY_ACCESS_ALLOW == zbx_check_key_access_rules(key))
+ zbx_test_parameter(key);
}
}
@@ -1104,8 +1106,6 @@ static int replace_param(const char *cmd, const AGENT_REQUEST *request, char **o
/**********************************************************************************
* *
- * Purpose: execute agent check *
- * *
* Parameters: in_command - item key *
* flags - ZBX_PROCESS_LOCAL_COMMAND, allow execution of system.run *
* ZBX_PROCESS_MODULE_COMMAND, execute item from a module *
@@ -1116,22 +1116,23 @@ static int replace_param(const char *cmd, const AGENT_REQUEST *request, char **o
* result - contains item value or error message *
* *
**********************************************************************************/
-int process(const char *in_command, unsigned flags, AGENT_RESULT *result)
+int zbx_execute_agent_check(const char *in_command, unsigned flags, AGENT_RESULT *result)
{
int ret = NOTSUPPORTED;
ZBX_METRIC *command = NULL;
AGENT_REQUEST request;
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED != parse_item_key((0 == (flags & ZBX_PROCESS_WITH_ALIAS) ? in_command : zbx_alias_get(in_command)),
- &request))
+ if (SUCCEED != zbx_parse_item_key((0 == (flags & ZBX_PROCESS_WITH_ALIAS) ? in_command :
+ zbx_alias_get(in_command)), &request))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid item key format."));
goto notsupported;
}
- if (0 == (flags & ZBX_PROCESS_LOCAL_COMMAND) && ZBX_KEY_ACCESS_ALLOW != check_request_access_rules(&request))
+ if (0 == (flags & ZBX_PROCESS_LOCAL_COMMAND) && ZBX_KEY_ACCESS_ALLOW !=
+ zbx_check_request_access_rules(&request))
{
zabbix_log(LOG_LEVEL_DEBUG, "Key access denied: \"%s\"", in_command);
SET_MSG_RESULT(result, zbx_strdup(NULL, "Unsupported item key."));
@@ -1220,7 +1221,7 @@ int process(const char *in_command, unsigned flags, AGENT_RESULT *result)
ret = SUCCEED;
notsupported:
- free_request(&request);
+ zbx_free_agent_request(&request);
return ret;
}
@@ -1235,7 +1236,7 @@ static void add_log_result(AGENT_RESULT *result, const char *value)
result->type |= AR_LOG;
}
-int set_result_type(AGENT_RESULT *result, int value_type, char *c)
+int zbx_set_agent_result_type(AGENT_RESULT *result, int value_type, char *c)
{
zbx_uint64_t value_uint64;
int ret = FAIL;
@@ -1285,7 +1286,7 @@ int set_result_type(AGENT_RESULT *result, int value_type, char *c)
return ret;
}
-void set_result_meta(AGENT_RESULT *result, zbx_uint64_t lastlogsize, int mtime)
+void zbx_set_agent_result_meta(AGENT_RESULT *result, zbx_uint64_t lastlogsize, int mtime)
{
result->lastlogsize = lastlogsize;
result->mtime = mtime;
@@ -1522,7 +1523,7 @@ void *get_result_value_by_type(AGENT_RESULT *result, int require_type)
* "\"param\"" => "param" *
* *
******************************************************************************/
-void unquote_key_param(char *param)
+void zbx_unquote_key_param(char *param)
{
char *dst;
@@ -1555,7 +1556,7 @@ void unquote_key_param(char *param)
* backslash in the end *
* *
******************************************************************************/
-int quote_key_param(char **param, int forced)
+int zbx_quote_key_param(char **param, int forced)
{
size_t sz_src, sz_dst;
@@ -1589,26 +1590,6 @@ int quote_key_param(char **param, int forced)
return SUCCEED;
}
-#ifdef HAVE_KSTAT_H
-zbx_uint64_t get_kstat_numeric_value(const kstat_named_t *kn)
-{
- switch (kn->data_type)
- {
- case KSTAT_DATA_INT32:
- return kn->value.i32;
- case KSTAT_DATA_UINT32:
- return kn->value.ui32;
- case KSTAT_DATA_INT64:
- return kn->value.i64;
- case KSTAT_DATA_UINT64:
- return kn->value.ui64;
- default:
- THIS_SHOULD_NEVER_HAPPEN;
- return 0;
- }
-}
-#endif
-
#if !defined(_WINDOWS) && !defined(__MINGW32__)
#if defined(WITH_AGENT2_METRICS)
int zbx_execute_threaded_metric(zbx_metric_func_t metric_func, AGENT_REQUEST *request, AGENT_RESULT *result)
@@ -1731,16 +1712,16 @@ static int deserialize_agent_result(char *data, AGENT_RESULT *result)
switch (type)
{
case 't':
- ret = set_result_type(result, ITEM_VALUE_TYPE_TEXT, data);
+ ret = zbx_set_agent_result_type(result, ITEM_VALUE_TYPE_TEXT, data);
break;
case 's':
- ret = set_result_type(result, ITEM_VALUE_TYPE_STR, data);
+ ret = zbx_set_agent_result_type(result, ITEM_VALUE_TYPE_STR, data);
break;
case 'u':
- ret = set_result_type(result, ITEM_VALUE_TYPE_UINT64, data);
+ ret = zbx_set_agent_result_type(result, ITEM_VALUE_TYPE_UINT64, data);
break;
case 'd':
- ret = set_result_type(result, ITEM_VALUE_TYPE_FLOAT, data);
+ ret = zbx_set_agent_result_type(result, ITEM_VALUE_TYPE_FLOAT, data);
break;
default:
ret = SUCCEED;
@@ -1805,7 +1786,7 @@ int zbx_execute_threaded_metric(zbx_metric_func_t metric_func, AGENT_REQUEST *re
ret = zbx_write_all(fds[1], data, data_offset);
zbx_free(data);
- free_result(result);
+ zbx_free_agent_result(result);
close(fds[1]);
@@ -1891,7 +1872,7 @@ out:
static ZBX_THREAD_LOCAL zbx_uint32_t mutex_flag = ZBX_MUTEX_ALL_ALLOW;
-zbx_uint32_t get_thread_global_mutex_flag()
+zbx_uint32_t zbx_get_thread_global_mutex_flag()
{
return mutex_flag;
}
diff --git a/src/libs/zbxsysinfo/sysinfo.h b/src/libs/zbxsysinfo/sysinfo.h
index 3ac199797bf..7c2a2a59a82 100644
--- a/src/libs/zbxsysinfo/sysinfo.h
+++ b/src/libs/zbxsysinfo/sysinfo.h
@@ -20,6 +20,9 @@
#ifndef ZABBIX_SYSINFO_H
#define ZABBIX_SYSINFO_H
+#include "zbxsysinfo.h"
+#include "module.h"
+
#define ZBX_PROC_STAT_ALL 0
#define ZBX_PROC_STAT_RUN 1
#define ZBX_PROC_STAT_SLEEP 2
@@ -74,4 +77,46 @@
#define ZBX_SYSINFO_FILE_TAG_TIME_MODIFY "modify"
#define ZBX_SYSINFO_FILE_TAG_TIME_CHANGE "change"
+#if defined(_WINDOWS) || defined(__MINGW32__)
+typedef int (*zbx_metric_func_t)(AGENT_REQUEST *request, AGENT_RESULT *result, HANDLE timeout_event);
+#else
+typedef int (*zbx_metric_func_t)(AGENT_REQUEST *request, AGENT_RESULT *result);
+#endif
+
+typedef struct
+{
+ zbx_uint64_t total;
+ zbx_uint64_t not_used;
+ zbx_uint64_t used;
+ double pfree;
+ double pused;
+}
+zbx_fs_metrics_t;
+
+typedef struct
+{
+ char fsname[MAX_STRING_LEN];
+ char fstype[MAX_STRING_LEN];
+ zbx_fs_metrics_t bytes;
+ zbx_fs_metrics_t inodes;
+ char *options;
+}
+zbx_mpoint_t;
+
+int zbx_execute_threaded_metric(zbx_metric_func_t metric_func, AGENT_REQUEST *request, AGENT_RESULT *result);
+void zbx_mpoints_free(zbx_mpoint_t *mpoint);
+
+#ifndef _WINDOWS
+int hostname_handle_params(AGENT_REQUEST *request, AGENT_RESULT *result, char *hostname);
+
+typedef struct
+{
+ zbx_uint64_t flag;
+ const char *name;
+}
+zbx_mntopt_t;
+
+char *zbx_format_mntopt_string(zbx_mntopt_t mntopts[], int flags);
+#endif
+
#endif /* ZABBIX_SYSINFO_H */
diff --git a/src/libs/zbxsysinfo/unknown/diskio.c b/src/libs/zbxsysinfo/unknown/diskio.c
index f2dd74e02a2..606ca389bc3 100644
--- a/src/libs/zbxsysinfo/unknown/diskio.c
+++ b/src/libs/zbxsysinfo/unknown/diskio.c
@@ -19,7 +19,7 @@
#include "zbxsysinfo.h"
-int get_diskstat(const char *devname, zbx_uint64_t *dstat)
+int zbx_get_diskstat(const char *devname, zbx_uint64_t *dstat)
{
return FAIL;
}
diff --git a/src/libs/zbxsysinfo/win32/diskio.c b/src/libs/zbxsysinfo/win32/diskio.c
index f2dd74e02a2..606ca389bc3 100644
--- a/src/libs/zbxsysinfo/win32/diskio.c
+++ b/src/libs/zbxsysinfo/win32/diskio.c
@@ -19,7 +19,7 @@
#include "zbxsysinfo.h"
-int get_diskstat(const char *devname, zbx_uint64_t *dstat)
+int zbx_get_diskstat(const char *devname, zbx_uint64_t *dstat)
{
return FAIL;
}
diff --git a/src/libs/zbxthreads/threads.c b/src/libs/zbxthreads/threads.c
index f53f74f26ea..debb07e06c0 100644
--- a/src/libs/zbxthreads/threads.c
+++ b/src/libs/zbxthreads/threads.c
@@ -22,20 +22,11 @@
#include "log.h"
#if defined(_WINDOWS) || defined(__MINGW32__)
-int zbx_win_exception_filter(unsigned int code, struct _EXCEPTION_POINTERS *ep);
-
static ZBX_THREAD_ENTRY(zbx_win_thread_entry, args)
{
- __try
- {
- zbx_thread_args_t *thread_args = (zbx_thread_args_t *)args;
+ zbx_thread_args_t *thread_args = (zbx_thread_args_t *)args;
- return thread_args->entry(thread_args);
- }
- __except(zbx_win_exception_filter(GetExceptionCode(), GetExceptionInformation()))
- {
- zbx_thread_exit(EXIT_SUCCESS);
- }
+ return thread_args->entry(thread_args);
}
void CALLBACK ZBXEndThread(ULONG_PTR dwParam)
diff --git a/src/libs/zbxversion/version.c b/src/libs/zbxversion/version.c
index 91c984d4228..4ccdd2f4406 100644
--- a/src/libs/zbxversion/version.c
+++ b/src/libs/zbxversion/version.c
@@ -17,33 +17,62 @@
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-#include "version.h"
+#include "zbxversion.h"
#include "zbxtypes.h"
+#include "zbxcommon.h"
/******************************************************************************
* *
- * Purpose: extracts protocol version from value *
- * *
- * Note: Function modifies argument 'value'! *
+ * Purpose: Extracts protocol version from string cont. Alphanumeric release *
+ * candidate version part is ignored. *
* *
* Parameters: *
- * value - [IN] textual representation of version *
+ * version_str - [IN] textual representation of version *
+ * Example: "6.4.0alpha1", "6.4.0" or "6.4" *
* *
* Return value: The protocol version if it was successfully extracted, *
* otherwise FAIL *
* *
******************************************************************************/
-int zbx_get_component_version(char *value)
+int zbx_get_component_version(const char *version_str)
{
- char *pminor, *ptr;
+ char *pmid, *plow;
+ char version_buf[ZBX_VERSION_BUF_LEN];
+
+ zbx_strlcpy(version_buf, version_str, sizeof(version_buf));
- if (NULL == (pminor = strchr(value, '.')))
+ if (NULL == (pmid = strchr(version_buf, '.')))
return FAIL;
- *pminor++ = '\0';
+ *pmid++ = '\0';
+
+ if (NULL == (plow = strchr(pmid, '.')))
+ return ZBX_COMPONENT_VERSION(atoi(version_buf), atoi(pmid), 0);
+
+ *plow++ = '\0';
+
+ return ZBX_COMPONENT_VERSION(atoi(version_buf), atoi(pmid), atoi(plow));
+}
+
+/******************************************************************************
+ * *
+ * Purpose: Extracts protocol version from string. Only the two most *
+ * significant groups of digits are extracted. *
+ * *
+ * Parameters: *
+ * value - [IN] textual representation of version *
+ * Example: "6.4.0alpha1" *
+ * *
+ * Return value: The protocol version if it was successfully extracted, *
+ * otherwise FAIL *
+ * *
+ ******************************************************************************/
+int zbx_get_component_version_without_patch(const char *value)
+{
+ int ver;
- if (NULL != (ptr = strchr(pminor, '.')))
- *ptr = '\0';
+ if (FAIL == (ver = zbx_get_component_version(value)))
+ return FAIL;
- return ZBX_COMPONENT_VERSION(atoi(value), atoi(pminor));
+ return ZBX_COMPONENT_VERSION_WITHOUT_PATCH(ver);
}
diff --git a/src/libs/zbxwin32/fatal.c b/src/libs/zbxwin32/fatal.c
index e4923f5f2ec..9e040c6dca5 100644
--- a/src/libs/zbxwin32/fatal.c
+++ b/src/libs/zbxwin32/fatal.c
@@ -231,10 +231,10 @@ static void print_backtrace(CONTEXT *pctx)
zbx_free(pSym);
}
-int zbx_win_exception_filter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
+int zbx_win_exception_filter(struct _EXCEPTION_POINTERS *ep)
{
- zabbix_log(LOG_LEVEL_CRIT, "Unhandled exception %x detected at 0x%p. Crashing ...", code,
- ep->ExceptionRecord->ExceptionAddress);
+ zabbix_log(LOG_LEVEL_CRIT, "Unhandled exception %x detected at 0x%p. Crashing ...",
+ ep->ExceptionRecord->ExceptionCode, ep->ExceptionRecord->ExceptionAddress);
print_fatal_info(ep->ContextRecord);
print_backtrace(ep->ContextRecord);
diff --git a/src/libs/zbxwin32/service.c b/src/libs/zbxwin32/service.c
index 503ab50d729..af9ce932f73 100644
--- a/src/libs/zbxwin32/service.c
+++ b/src/libs/zbxwin32/service.c
@@ -78,6 +78,19 @@ static VOID WINAPI ServiceCtrlHandler(DWORD ctrlCode)
switch (ctrlCode)
{
case SERVICE_CONTROL_STOP:
+ zabbix_log(LOG_LEVEL_INFORMATION, "Zabbix Agent received stop request.");
+ break;
+ case SERVICE_CONTROL_SHUTDOWN:
+ zabbix_log(LOG_LEVEL_INFORMATION, "Zabbix Agent received shutdown request.");
+ break;
+ default:
+ zabbix_log(LOG_LEVEL_DEBUG, "Zabbix Agent received request:%u.", ctrlCode);
+ break;
+ }
+
+ switch (ctrlCode)
+ {
+ case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
serviceStatus.dwWaitHint = 4000;
diff --git a/src/zabbix_agent/active.c b/src/zabbix_agent/active.c
index 979e3e1f85f..2be2e632cfb 100644
--- a/src/zabbix_agent/active.c
+++ b/src/zabbix_agent/active.c
@@ -272,16 +272,16 @@ static int mode_parameter_is_skip(unsigned char flags, const char *itemkey)
else /* log.count[] */
max_num_parameters = 6;
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED == parse_item_key(itemkey, &request) && 0 < get_rparams_num(&request) &&
+ if (SUCCEED == zbx_parse_item_key(itemkey, &request) && 0 < get_rparams_num(&request) &&
max_num_parameters >= get_rparams_num(&request) && NULL != (skip = get_rparam(&request, 4)) &&
0 == strcmp(skip, "skip"))
{
ret = SUCCEED;
}
- free_request(&request);
+ zbx_free_agent_request(&request);
return ret;
}
@@ -559,9 +559,9 @@ static void process_config_item(struct zbx_json *json, char *config, size_t leng
config_type = "interface";
}
- init_result(&result);
+ zbx_init_agent_result(&result);
- if (SUCCEED == process(config, ZBX_PROCESS_LOCAL_COMMAND | ZBX_PROCESS_WITH_ALIAS, &result) &&
+ if (SUCCEED == zbx_execute_agent_check(config, ZBX_PROCESS_LOCAL_COMMAND | ZBX_PROCESS_WITH_ALIAS, &result) &&
NULL != (value = ZBX_GET_STR_RESULT(&result)) && NULL != *value)
{
if (SUCCEED != zbx_is_utf8(*value))
@@ -590,7 +590,7 @@ static void process_config_item(struct zbx_json *json, char *config, size_t leng
zabbix_log(LOG_LEVEL_WARNING, "cannot get host %s using \"%s\" item specified by"
" \"%s\" configuration parameter",config_type, config,config_name);
- free_result(&result);
+ zbx_free_agent_result(&result);
}
/******************************************************************************
@@ -1159,9 +1159,9 @@ static int process_common_check(zbx_vector_ptr_t *addrs, ZBX_ACTIVE_METRIC *metr
AGENT_RESULT result;
char **pvalue;
- init_result(&result);
+ zbx_init_agent_result(&result);
- if (SUCCEED != (ret = process(metric->key, 0, &result)))
+ if (SUCCEED != (ret = zbx_execute_agent_check(metric->key, 0, &result)))
{
if (NULL != (pvalue = ZBX_GET_MSG_RESULT(&result)))
*error = zbx_strdup(*error, *pvalue);
@@ -1176,7 +1176,7 @@ static int process_common_check(zbx_vector_ptr_t *addrs, ZBX_ACTIVE_METRIC *metr
NULL, NULL, NULL, NULL, metric->flags, zbx_config_tls);
}
out:
- free_result(&result);
+ zbx_free_agent_result(&result);
return ret;
}
diff --git a/src/zabbix_agent/diskdevices.c b/src/zabbix_agent/diskdevices.c
index 32efdb0c9df..1dc9aa7c324 100644
--- a/src/zabbix_agent/diskdevices.c
+++ b/src/zabbix_agent/diskdevices.c
@@ -102,7 +102,7 @@ static void process_diskstat(ZBX_SINGLE_DISKDEVICE_DATA *device)
zbx_uint64_t dstat[ZBX_DSTAT_MAX];
now = time(NULL);
- if (FAIL == get_diskstat(device->name, dstat))
+ if (FAIL == zbx_get_diskstat(device->name, dstat))
return;
apply_diskstat(device, now, dstat);
diff --git a/src/zabbix_agent/eventlog.c b/src/zabbix_agent/eventlog.c
index d9adfae948f..9797537654b 100644
--- a/src/zabbix_agent/eventlog.c
+++ b/src/zabbix_agent/eventlog.c
@@ -1701,9 +1701,9 @@ int process_eventlog_check(zbx_vector_ptr_t *addrs, zbx_vector_ptr_t *agent2_res
int rate;
OSVERSIONINFO versionInfo;
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED != parse_item_key(metric->key, &request))
+ if (SUCCEED != zbx_parse_item_key(metric->key, &request))
{
*error = zbx_strdup(*error, "Invalid item key format.");
goto out;
@@ -1827,7 +1827,7 @@ int process_eventlog_check(zbx_vector_ptr_t *addrs, zbx_vector_ptr_t *agent2_res
error);
}
out:
- free_request(&request);
+ zbx_free_agent_request(&request);
return ret;
}
diff --git a/src/zabbix_agent/listener.c b/src/zabbix_agent/listener.c
index d75a3b5d0a7..230d46f980a 100644
--- a/src/zabbix_agent/listener.c
+++ b/src/zabbix_agent/listener.c
@@ -50,9 +50,9 @@ static void process_listener(zbx_socket_t *s)
zabbix_log(LOG_LEVEL_DEBUG, "Requested [%s]", s->buffer);
- init_result(&result);
+ zbx_init_agent_result(&result);
- if (SUCCEED == process(s->buffer, ZBX_PROCESS_WITH_ALIAS, &result))
+ if (SUCCEED == zbx_execute_agent_check(s->buffer, ZBX_PROCESS_WITH_ALIAS, &result))
{
if (NULL != (value = ZBX_GET_TEXT_RESULT(&result)))
{
@@ -90,7 +90,7 @@ static void process_listener(zbx_socket_t *s)
}
}
- free_result(&result);
+ zbx_free_agent_result(&result);
}
if (FAIL == ret)
@@ -126,7 +126,7 @@ ZBX_THREAD_ENTRY(listener_thread, args)
get_program_type_string(init_child_args_in->zbx_get_program_type_cb_arg()),
server_num, get_process_type_string(process_type), process_num);
- memcpy(&s, (zbx_socket_t *)(init_child_args_in->listen_sock), sizeof(zbx_socket_t));
+ memcpy(&s, init_child_args_in->listen_sock, sizeof(zbx_socket_t));
zbx_free(args);
diff --git a/src/zabbix_agent/logfiles/logfiles.c b/src/zabbix_agent/logfiles/logfiles.c
index 0f632cd7d19..475855af795 100644
--- a/src/zabbix_agent/logfiles/logfiles.c
+++ b/src/zabbix_agent/logfiles/logfiles.c
@@ -3850,7 +3850,7 @@ int process_log_check(zbx_vector_ptr_t *addrs, zbx_vector_ptr_t *agent2_result,
else
is_count_item = 0;
- init_request(&request);
+ zbx_init_agent_request(&request);
/* Expected parameters by item: */
/* log [file, <regexp>,<encoding>,<maxlines>, <mode>,<output>,<maxdelay>, <options>,<persistent_dir>] 9 params */
@@ -3858,7 +3858,7 @@ int process_log_check(zbx_vector_ptr_t *addrs, zbx_vector_ptr_t *agent2_result,
/* logrt [file_regexp,<regexp>,<encoding>,<maxlines>, <mode>,<output>,<maxdelay>, <options>,<persistent_dir>] 9 params */
/* logrt.count[file_regexp,<regexp>,<encoding>,<maxproclines>,<mode>, <maxdelay>, <options>,<persistent_dir>] 8 params */
- if (SUCCEED != parse_item_key(metric->key, &request))
+ if (SUCCEED != zbx_parse_item_key(metric->key, &request))
{
*error = zbx_strdup(*error, "Invalid item key format.");
goto out;
@@ -4146,7 +4146,7 @@ int process_log_check(zbx_vector_ptr_t *addrs, zbx_vector_ptr_t *agent2_result,
}
out:
zbx_free(encoding_uc);
- free_request(&request);
+ zbx_free_agent_request(&request);
return ret;
}
diff --git a/src/zabbix_agent/zabbix_agentd.c b/src/zabbix_agent/zabbix_agentd.c
index 30094fe19c1..ff4d1877c13 100644
--- a/src/zabbix_agent/zabbix_agentd.c
+++ b/src/zabbix_agent/zabbix_agentd.c
@@ -24,6 +24,7 @@
#include "modbtype.h"
#include "zbxstr.h"
#include "zbxip.h"
+#include "zbxexpr.h"
static char *CONFIG_PID_FILE = NULL;
@@ -261,7 +262,6 @@ int CONFIG_JAVAPOLLER_FORKS = 0;
int CONFIG_ESCALATOR_FORKS = 0;
int CONFIG_SELFMON_FORKS = 0;
int CONFIG_DATASENDER_FORKS = 0;
-int CONFIG_HEARTBEAT_FORKS = 0;
int CONFIG_PROXYPOLLER_FORKS = 0;
int CONFIG_HISTSYNCER_FORKS = 0;
int CONFIG_CONFSYNCER_FORKS = 0;
@@ -286,6 +286,7 @@ char *opt = NULL;
#ifdef _WINDOWS
void zbx_co_uninitialize();
+int zbx_win_exception_filter(struct _EXCEPTION_POINTERS *ep);
#endif
int get_process_info_by_thread(int local_server_num, unsigned char *local_process_type, int *local_process_num);
@@ -554,10 +555,10 @@ static void set_defaults(void)
if (NULL == CONFIG_HOSTNAME_ITEM)
CONFIG_HOSTNAME_ITEM = zbx_strdup(CONFIG_HOSTNAME_ITEM, "system.hostname");
- init_result(&result);
+ zbx_init_agent_result(&result);
- if (SUCCEED == process(CONFIG_HOSTNAME_ITEM, ZBX_PROCESS_LOCAL_COMMAND | ZBX_PROCESS_WITH_ALIAS,
- &result) && NULL != (value = ZBX_GET_STR_RESULT(&result)))
+ if (SUCCEED == zbx_execute_agent_check(CONFIG_HOSTNAME_ITEM, ZBX_PROCESS_LOCAL_COMMAND |
+ ZBX_PROCESS_WITH_ALIAS, &result) && NULL != (value = ZBX_GET_STR_RESULT(&result)))
{
assert(*value);
zbx_trim_str_list(*value, ',');
@@ -573,7 +574,7 @@ static void set_defaults(void)
else
zabbix_log(LOG_LEVEL_WARNING, "failed to get system hostname from [%s])", CONFIG_HOSTNAME_ITEM);
- free_result(&result);
+ zbx_free_agent_result(&result);
}
else if (NULL != CONFIG_HOSTNAME_ITEM)
zabbix_log(LOG_LEVEL_WARNING, "both Hostname and HostnameItem defined, using [%s]", CONFIG_HOSTNAMES);
@@ -800,7 +801,7 @@ static int load_enable_remote_commands(const char *value, const struct cfg_line
zabbix_log(LOG_LEVEL_WARNING, "EnableRemoteCommands parameter is deprecated,"
" use AllowKey=system.run[*] or DenyKey=system.run[*] instead");
- return add_key_access_rule(cfg->parameter, sysrun, rule_type);
+ return zbx_add_key_access_rule(cfg->parameter, sysrun, rule_type);
}
/******************************************************************************
@@ -955,7 +956,7 @@ static void zbx_load_config(int requirement, ZBX_TASK_EX *task)
#endif
parse_cfg_file(CONFIG_FILE, cfg, requirement, ZBX_CFG_STRICT, ZBX_CFG_EXIT_FAILURE);
- finalize_key_access_rules_configuration();
+ zbx_finalize_key_access_rules_configuration();
set_defaults();
@@ -1079,6 +1080,8 @@ int MAIN_ZABBIX_ENTRY(int flags)
int i, j = 0, ret = SUCCEED;
#ifdef _WINDOWS
DWORD res;
+
+ AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)&zbx_win_exception_filter);
#endif
if (0 != (flags & ZBX_TASK_FLAG_FOREGROUND))
{
@@ -1305,7 +1308,7 @@ void zbx_free_service_resources(int ret)
#ifdef HAVE_PTHREAD_PROCESS_SHARED
zbx_locks_disable();
#endif
- free_metrics();
+ zbx_free_metrics();
zbx_alias_list_free();
free_collector_data();
zbx_deinit_modbus();
@@ -1361,7 +1364,7 @@ int main(int argc, char **argv)
#endif
/* this is needed to set default hostname in zbx_load_config() */
- init_metrics();
+ zbx_init_metrics();
switch (t.task)
{
@@ -1404,7 +1407,7 @@ int main(int argc, char **argv)
while (0 == WSACleanup())
;
- free_metrics();
+ zbx_free_metrics();
exit(SUCCEED == ret ? EXIT_SUCCESS : EXIT_FAILURE);
break;
#endif
@@ -1430,7 +1433,7 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
#endif
- set_user_parameter_dir(CONFIG_USER_PARAMETER_DIR);
+ zbx_set_user_parameter_dir(CONFIG_USER_PARAMETER_DIR);
if (FAIL == load_user_parameters(CONFIG_USER_PARAMETERS, &error))
{
@@ -1442,9 +1445,9 @@ int main(int argc, char **argv)
load_aliases(CONFIG_ALIASES);
zbx_free_config();
if (ZBX_TASK_TEST_METRIC == t.task)
- test_parameter(TEST_METRIC);
+ zbx_test_parameter(TEST_METRIC);
else
- test_parameters();
+ zbx_test_parameters();
#ifdef _WINDOWS
free_perf_collector(); /* cpu_collector must be freed before perf_collector is freed */
@@ -1456,7 +1459,7 @@ int main(int argc, char **argv)
#ifndef _WINDOWS
zbx_unload_modules();
#endif
- free_metrics();
+ zbx_free_metrics();
zbx_alias_list_free();
exit(EXIT_SUCCESS);
break;
@@ -1478,7 +1481,7 @@ int main(int argc, char **argv)
break;
default:
zbx_load_config(ZBX_CFG_FILE_REQUIRED, &t);
- set_user_parameter_dir(CONFIG_USER_PARAMETER_DIR);
+ zbx_set_user_parameter_dir(CONFIG_USER_PARAMETER_DIR);
load_aliases(CONFIG_ALIASES);
break;
}
diff --git a/src/zabbix_agent/zbxconf.c b/src/zabbix_agent/zbxconf.c
index 9dbe6a18c7c..1b406cb8ad7 100644
--- a/src/zabbix_agent/zbxconf.c
+++ b/src/zabbix_agent/zbxconf.c
@@ -23,6 +23,7 @@
#include "zbxsysinfo.h"
#include "zbxstr.h"
#include "zbxparam.h"
+#include "zbxexpr.h"
#ifdef _WINDOWS
# include "perfstat.h"
@@ -46,7 +47,7 @@ void load_aliases(char **lines)
char *c;
const char *r = *pline;
- if (SUCCEED != parse_key(&r) || ':' != *r)
+ if (SUCCEED != zbx_parse_key(&r) || ':' != *r)
{
zabbix_log(LOG_LEVEL_CRIT, "cannot add alias \"%s\": invalid character at position %d",
*pline, (int)((r - *pline) + 1));
@@ -55,7 +56,7 @@ void load_aliases(char **lines)
c = (char *)r++;
- if (SUCCEED != parse_key(&r) || '\0' != *r)
+ if (SUCCEED != zbx_parse_key(&r) || '\0' != *r)
{
zabbix_log(LOG_LEVEL_CRIT, "cannot add alias \"%s\": invalid character at position %d",
*pline, (int)((r - *pline) + 1));
@@ -80,7 +81,7 @@ void load_aliases(char **lines)
* Return value: SUCCEED - successfully loaded user parameters *
* FAIL - failed to load user parameters *
* *
- * Comments: calls add_user_parameter() for each entry *
+ * Comments: calls zbx_add_user_parameter() for each entry *
* *
******************************************************************************/
int load_user_parameters(char **lines, char **err)
@@ -96,7 +97,7 @@ int load_user_parameters(char **lines, char **err)
}
*p = '\0';
- if (FAIL == add_user_parameter(*pline, p + 1, error, sizeof(error)))
+ if (FAIL == zbx_add_user_parameter(*pline, p + 1, error, sizeof(error)))
{
*p = ',';
*err = zbx_dsprintf(*err, "user parameter \"%s\": %s", *pline, error);
@@ -130,7 +131,7 @@ int load_key_access_rule(const char *value, const struct cfg_line *cfg)
else
return FAIL;
- return add_key_access_rule(cfg->parameter, (char *)value, rule_type);
+ return zbx_add_key_access_rule(cfg->parameter, (char *)value, rule_type);
}
#ifdef _WINDOWS
@@ -259,19 +260,19 @@ void reload_user_parameters(unsigned char process_type, int process_num)
goto out;
}
- get_metrics_copy(&metrics_fallback);
- remove_user_parameters();
+ zbx_get_metrics_copy(&metrics_fallback);
+ zbx_remove_user_parameters();
if (FAIL == load_user_parameters(CONFIG_USER_PARAMETERS, &error))
{
- set_metrics(metrics_fallback);
+ zbx_set_metrics(metrics_fallback);
zabbix_log(LOG_LEVEL_ERR, "cannot reload user parameters [%s #%d], %s",
get_process_type_string(process_type), process_num, error);
zbx_free(error);
goto out;
}
- free_metrics_ext(&metrics_fallback);
+ zbx_free_metrics_ext(&metrics_fallback);
zabbix_log(LOG_LEVEL_INFORMATION, "user parameters reloaded [%s #%d]", get_process_type_string(process_type),
process_num);
out:
diff --git a/src/zabbix_java/src/com/zabbix/gateway/GeneralInformation.java b/src/zabbix_java/src/com/zabbix/gateway/GeneralInformation.java
index 80855ec682e..89f4a89ea14 100644
--- a/src/zabbix_java/src/com/zabbix/gateway/GeneralInformation.java
+++ b/src/zabbix_java/src/com/zabbix/gateway/GeneralInformation.java
@@ -22,9 +22,9 @@ package com.zabbix.gateway;
class GeneralInformation
{
static final String APPLICATION_NAME = "Zabbix Java Gateway";
- static final String REVISION_DATE = "14 September 2022";
+ static final String REVISION_DATE = "29 September 2022";
static final String REVISION = "{ZABBIX_REVISION}";
- static final String VERSION = "6.4.0alpha2";
+ static final String VERSION = "6.4.0beta2";
static void printVersion()
{
diff --git a/src/zabbix_proxy/Makefile.am b/src/zabbix_proxy/Makefile.am
index c905ae3dc3a..fbe48e46723 100644
--- a/src/zabbix_proxy/Makefile.am
+++ b/src/zabbix_proxy/Makefile.am
@@ -2,12 +2,12 @@
SUBDIRS = \
diag \
- heart \
housekeeper \
proxyconfig \
datasender \
stats \
- taskmanager
+ taskmanager \
+ proxyconfigwrite
sbin_PROGRAMS = zabbix_proxy
@@ -25,7 +25,6 @@ zabbix_proxy_SOURCES = proxy.c
zabbix_proxy_LDADD = \
diag/libzbxdiag_proxy.a \
- heart/libzbxheart.a \
$(top_builddir)/src/zabbix_server/dbsyncer/libzbxdbsyncer.a \
$(top_builddir)/src/zabbix_server/discoverer/libzbxdiscoverer.a \
housekeeper/libzbxhousekeeper.a \
@@ -39,6 +38,7 @@ zabbix_proxy_LDADD = \
$(top_builddir)/src/zabbix_server/snmptrapper/libzbxsnmptrapper.a \
$(top_builddir)/src/zabbix_server/odbc/libzbxodbc.a \
datasender/libzbxdatasender.a \
+ proxyconfigwrite/libzbxproxyconfigwrite.a \
$(top_builddir)/src/zabbix_server/preprocessor/libpreprocessor.a \
$(top_builddir)/src/libs/zbxvariant/libzbxvariant.a \
$(top_builddir)/src/libs/zbxxml/libzbxxml.a \
diff --git a/src/zabbix_proxy/datasender/datasender.c b/src/zabbix_proxy/datasender/datasender.c
index f17ba9982b9..cf47e50b201 100644
--- a/src/zabbix_proxy/datasender/datasender.c
+++ b/src/zabbix_proxy/datasender/datasender.c
@@ -141,7 +141,7 @@ static int proxy_data_sender(int *more, int now, int *hist_upload_state, time_t
{
task_timestamp = now;
- zbx_tm_get_remote_tasks(&tasks, 0);
+ zbx_tm_get_remote_tasks(&tasks, 0, 0);
if (0 != tasks.values_num)
{
@@ -184,20 +184,20 @@ static int proxy_data_sender(int *more, int now, int *hist_upload_state, time_t
reserved = j.buffer_size;
zbx_json_free(&j); /* json buffer can be large, free as fast as possible */
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
/* retry till have a connection */
if (FAIL == zbx_connect_to_server(&sock, CONFIG_SOURCE_IP, &zbx_addrs, 600, CONFIG_TIMEOUT,
CONFIG_PROXYDATA_FREQUENCY, LOG_LEVEL_WARNING, zbx_config_tls))
{
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
if (*last_conn_time + ZBX_PROXY_ACTIVE_CHECK_AVAIL_TIMEOUT >= time(NULL))
zbx_availability_send(ZBX_IPC_AVAILMAN_PROXY_FLUSH_ALL_HOSTS, NULL, 0, NULL);
goto clean;
}
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
upload_state = zbx_put_data_to_server(&sock, &buffer, buffer_size, reserved, &error);
get_hist_upload_state(sock.buffer, hist_upload_state);
@@ -306,7 +306,7 @@ ZBX_THREAD_ENTRY(datasender_thread, args)
get_program_type_string(datasender_args_in->zbx_get_program_type_cb_arg()),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
zbx_tls_init_child(datasender_args_in->zbx_config_tls, datasender_args_in->zbx_get_program_type_cb_arg);
diff --git a/src/zabbix_proxy/heart/Makefile.am b/src/zabbix_proxy/heart/Makefile.am
deleted file mode 100644
index a96da81e936..00000000000
--- a/src/zabbix_proxy/heart/Makefile.am
+++ /dev/null
@@ -1,7 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-noinst_LIBRARIES = libzbxheart.a
-
-libzbxheart_a_SOURCES = \
- heart.c \
- heart.h
diff --git a/src/zabbix_proxy/heart/heart.c b/src/zabbix_proxy/heart/heart.c
deleted file mode 100644
index 81c18200274..00000000000
--- a/src/zabbix_proxy/heart/heart.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
-** Zabbix
-** Copyright (C) 2001-2022 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 "heart.h"
-
-#include "zbxnix.h"
-#include "log.h"
-#include "zbxjson.h"
-#include "zbxself.h"
-#include "zbxtime.h"
-
-#include "zbxcompress.h"
-#include "zbxcommshigh.h"
-
-extern ZBX_THREAD_LOCAL unsigned char process_type;
-extern ZBX_THREAD_LOCAL int server_num, process_num;
-
-extern zbx_vector_ptr_t zbx_addrs;
-extern char *CONFIG_HOSTNAME;
-extern char *CONFIG_SOURCE_IP;
-extern int CONFIG_TIMEOUT;
-
-static int send_heartbeat(const zbx_config_tls_t *zbx_config_tls)
-{
- zbx_socket_t sock;
- struct zbx_json j;
- int ret = SUCCEED;
- char *error = NULL, *buffer = NULL;
- size_t buffer_size, reserved;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In send_heartbeat()");
-
- zbx_json_init(&j, 128);
- zbx_json_addstring(&j, "request", ZBX_PROTO_VALUE_PROXY_HEARTBEAT, ZBX_JSON_TYPE_STRING);
- zbx_json_addstring(&j, "host", CONFIG_HOSTNAME, ZBX_JSON_TYPE_STRING);
- zbx_json_addstring(&j, ZBX_PROTO_TAG_VERSION, ZABBIX_VERSION, ZBX_JSON_TYPE_STRING);
-
- if (SUCCEED != zbx_compress(j.buffer, j.buffer_size, &buffer, &buffer_size))
- {
- zabbix_log(LOG_LEVEL_ERR,"cannot compress data: %s", zbx_compress_strerror());
- goto clean;
- }
-
- reserved = j.buffer_size;
-
- if (FAIL == (ret = zbx_connect_to_server(&sock, CONFIG_SOURCE_IP, &zbx_addrs, CONFIG_HEARTBEAT_FREQUENCY,
- CONFIG_TIMEOUT, 0, LOG_LEVEL_DEBUG, zbx_config_tls))) /* do not retry */
- {
- goto clean;
- }
-
- if (SUCCEED != (ret = zbx_put_data_to_server(&sock, &buffer, buffer_size, reserved, &error)))
- {
- zabbix_log(LOG_LEVEL_WARNING, "cannot send heartbeat message to server at \"%s\": %s", sock.peer,
- error);
- }
-
- zbx_disconnect_from_server(&sock);
- zbx_free(error);
-clean:
- zbx_free(buffer);
- zbx_json_free(&j);
-
- return ret;
-}
-
-/******************************************************************************
- * *
- * Purpose: periodically send heartbeat message to the server *
- * *
- ******************************************************************************/
-ZBX_THREAD_ENTRY(heart_thread, args)
-{
- zbx_thread_heart_args *heart_args_in = (zbx_thread_heart_args *) (((zbx_thread_args_t *)args)->args);
- int start, sleeptime = 0, res;
- double sec, total_sec = 0.0, old_total_sec = 0.0;
- time_t last_stat_time;
-
-#define STAT_INTERVAL 5 /* if a process is busy and does not sleep then update status not faster than */
- /* once in STAT_INTERVAL seconds */
-
- process_type = ((zbx_thread_args_t *)args)->process_type;
- server_num = ((zbx_thread_args_t *)args)->server_num;
- process_num = ((zbx_thread_args_t *)args)->process_num;
-
- zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]",
- get_program_type_string(heart_args_in->zbx_get_program_type_cb_arg()),
- server_num, get_process_type_string(process_type), process_num);
-
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
-
-#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
- zbx_tls_init_child(heart_args_in->zbx_config_tls, heart_args_in->zbx_get_program_type_cb_arg);
-#endif
- last_stat_time = time(NULL);
-
- zbx_setproctitle("%s [sending heartbeat message]", get_process_type_string(process_type));
-
- while (ZBX_IS_RUNNING())
- {
- sec = zbx_time();
- zbx_update_env(sec);
-
- if (0 != sleeptime)
- {
- zbx_setproctitle("%s [sending heartbeat message %s in " ZBX_FS_DBL " sec, "
- "sending heartbeat message]",
- get_process_type_string(process_type),
- SUCCEED == res ? "success" : "failed", old_total_sec);
- }
-
- start = time(NULL);
- res = send_heartbeat(heart_args_in->zbx_config_tls);
- total_sec += zbx_time() - sec;
-
- sleeptime = CONFIG_HEARTBEAT_FREQUENCY - (time(NULL) - start);
-
- if (0 != sleeptime || STAT_INTERVAL <= time(NULL) - last_stat_time)
- {
- if (0 == sleeptime)
- {
- zbx_setproctitle("%s [sending heartbeat message %s in " ZBX_FS_DBL " sec, "
- "sending heartbeat message]",
- get_process_type_string(process_type),
- SUCCEED == res ? "success" : "failed", total_sec);
-
- }
- else
- {
- zbx_setproctitle("%s [sending heartbeat message %s in " ZBX_FS_DBL " sec, "
- "idle %d sec]",
- get_process_type_string(process_type),
- SUCCEED == res ? "success" : "failed", total_sec, sleeptime);
-
- old_total_sec = total_sec;
- }
- total_sec = 0.0;
- last_stat_time = time(NULL);
- }
-
- zbx_sleep_loop(sleeptime);
- }
-
- zbx_setproctitle("%s #%d [terminated]", get_process_type_string(process_type), process_num);
-
- while (1)
- zbx_sleep(SEC_PER_MIN);
-#undef STAT_INTERVAL
-}
diff --git a/src/zabbix_proxy/housekeeper/housekeeper.c b/src/zabbix_proxy/housekeeper/housekeeper.c
index e58fbd65d79..263d0eb1011 100644
--- a/src/zabbix_proxy/housekeeper/housekeeper.c
+++ b/src/zabbix_proxy/housekeeper/housekeeper.c
@@ -156,7 +156,7 @@ ZBX_THREAD_ENTRY(housekeeper_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
if (0 == CONFIG_HOUSEKEEPING_FREQUENCY)
{
diff --git a/src/zabbix_proxy/proxy.c b/src/zabbix_proxy/proxy.c
index 93a983a4ec4..2c7e09d6fd0 100644
--- a/src/zabbix_proxy/proxy.c
+++ b/src/zabbix_proxy/proxy.c
@@ -43,7 +43,6 @@
#include "../zabbix_server/snmptrapper/snmptrapper.h"
#include "proxyconfig/proxyconfig.h"
#include "datasender/datasender.h"
-#include "heart/heart.h"
#include "taskmanager/taskmanager.h"
#include "../zabbix_server/selfmon/selfmon.h"
#include "../zabbix_server/vmware/vmware.h"
@@ -58,7 +57,7 @@
#include "diag/diag_proxy.h"
#include "zbxrtc.h"
#include "../zabbix_server/availability/avail_manager.h"
-#include "zbxserver.h"
+#include "zbxstats.h"
#include "stats/zabbix_stats.h"
#include "zbxip.h"
@@ -103,9 +102,9 @@ const char *help_message[] = {
" Log level control targets:",
" process-type All processes of specified type",
" (configuration syncer, data sender, discoverer,",
- " heartbeat sender, history syncer, housekeeper,",
- " http poller, icmp pinger, ipmi manager,",
- " ipmi poller, java poller, poller,",
+ " history syncer, housekeeper, http poller,",
+ " icmp pinger, ipmi manager, ipmi poller,",
+ " java poller, poller,",
" self-monitoring, snmp trapper, task manager,",
" trapper, unreachable poller, vmware collector,"
" availability manager, odbc poller)",
@@ -175,7 +174,6 @@ int CONFIG_PROXYPOLLER_FORKS = 0;
int CONFIG_ESCALATOR_FORKS = 0;
int CONFIG_ALERTER_FORKS = 0;
int CONFIG_TIMER_FORKS = 0;
-int CONFIG_HEARTBEAT_FORKS = 1;
int CONFIG_COLLECTOR_FORKS = 0;
int CONFIG_PASSIVE_FORKS = 0;
int CONFIG_ACTIVE_FORKS = 0;
@@ -202,15 +200,16 @@ int CONFIG_HOUSEKEEPING_FREQUENCY = 1;
int CONFIG_PROXY_LOCAL_BUFFER = 0;
int CONFIG_PROXY_OFFLINE_BUFFER = 1;
-int CONFIG_HEARTBEAT_FREQUENCY = 60;
+int CONFIG_HEARTBEAT_FREQUENCY = -1;
/* how often active Zabbix proxy requests configuration data from server, in seconds */
-int CONFIG_PROXYCONFIG_FREQUENCY = SEC_PER_MIN * 5;
+int CONFIG_PROXYCONFIG_FREQUENCY = 0; /* will be set to default 5 seconds if not configured */
int CONFIG_PROXYDATA_FREQUENCY = 1;
int CONFIG_HISTSYNCER_FORKS = 4;
int CONFIG_HISTSYNCER_FREQUENCY = 1;
int CONFIG_CONFSYNCER_FORKS = 1;
+int CONFIG_CONFSYNCER_FREQUENCY = 0;
int CONFIG_VMWARE_FORKS = 0;
int CONFIG_VMWARE_FREQUENCY = 60;
@@ -336,11 +335,6 @@ int get_process_info_by_thread(int local_server_num, unsigned char *local_proces
*local_process_type = ZBX_PROCESS_TYPE_PREPROCESSOR;
*local_process_num = local_server_num - server_count + CONFIG_PREPROCESSOR_FORKS;
}
- else if (local_server_num <= (server_count += CONFIG_HEARTBEAT_FORKS))
- {
- *local_process_type = ZBX_PROCESS_TYPE_HEARTBEAT;
- *local_process_num = local_server_num - server_count + CONFIG_HEARTBEAT_FORKS;
- }
else if (local_server_num <= (server_count += CONFIG_DATASENDER_FORKS))
{
*local_process_type = ZBX_PROCESS_TYPE_DATASENDER;
@@ -449,9 +443,9 @@ static void zbx_set_defaults(void)
if (NULL == CONFIG_HOSTNAME_ITEM)
CONFIG_HOSTNAME_ITEM = zbx_strdup(CONFIG_HOSTNAME_ITEM, "system.hostname");
- init_result(&result);
+ zbx_init_agent_result(&result);
- if (SUCCEED == process(CONFIG_HOSTNAME_ITEM, ZBX_PROCESS_LOCAL_COMMAND, &result) &&
+ if (SUCCEED == zbx_execute_agent_check(CONFIG_HOSTNAME_ITEM, ZBX_PROCESS_LOCAL_COMMAND, &result) &&
NULL != (value = ZBX_GET_STR_RESULT(&result)))
{
assert(*value);
@@ -467,7 +461,7 @@ static void zbx_set_defaults(void)
else
zabbix_log(LOG_LEVEL_WARNING, "failed to get proxy name from [%s])", CONFIG_HOSTNAME_ITEM);
- free_result(&result);
+ zbx_free_agent_result(&result);
}
else if (NULL != CONFIG_HOSTNAME_ITEM)
{
@@ -504,9 +498,6 @@ static void zbx_set_defaults(void)
if (NULL == CONFIG_SSL_KEY_LOCATION)
CONFIG_SSL_KEY_LOCATION = zbx_strdup(CONFIG_SSL_KEY_LOCATION, DEFAULT_SSL_KEY_LOCATION);
#endif
- if (ZBX_PROXYMODE_ACTIVE != CONFIG_PROXYMODE || 0 == CONFIG_HEARTBEAT_FREQUENCY)
- CONFIG_HEARTBEAT_FORKS = 0;
-
if (ZBX_PROXYMODE_PASSIVE == CONFIG_PROXYMODE)
{
CONFIG_DATASENDER_FORKS = 0;
@@ -525,6 +516,9 @@ static void zbx_set_defaults(void)
if (NULL == CONFIG_VAULTURL)
CONFIG_VAULTURL = zbx_strdup(CONFIG_VAULTURL, "https://127.0.0.1:8200");
+ if (-1 != CONFIG_HEARTBEAT_FREQUENCY)
+ zabbix_log(LOG_LEVEL_WARNING, "HeartbeatFrequency parameter is deprecated, and has no effect");
+
if (0 == CONFIG_SERVER_PORT)
{
CONFIG_SERVER_PORT = ZBX_DEFAULT_SERVER_PORT;
@@ -655,6 +649,25 @@ static void zbx_validate_config(ZBX_TASK_EX *task)
#if !defined(HAVE_OPENIPMI)
err |= (FAIL == check_cfg_feature_int("StartIPMIPollers", CONFIG_IPMIPOLLER_FORKS, "IPMI support"));
#endif
+ if (0 != CONFIG_CONFSYNCER_FREQUENCY)
+ {
+ if (0 != CONFIG_PROXYCONFIG_FREQUENCY)
+ {
+ zabbix_log(LOG_LEVEL_CRIT, "Deprecated \"ConfigFrequency\" configuration parameter cannot"
+ " be used together with \"ProxyConfigFrequency\" parameter");
+ err = 1;
+ }
+ else
+ {
+ CONFIG_PROXYCONFIG_FREQUENCY = CONFIG_CONFSYNCER_FREQUENCY;
+ zabbix_log(LOG_LEVEL_WARNING, "\"ConfigFrequency\" configuration parameter is deprecated, "
+ "use \"ProxyConfigFrequency\" instead");
+ }
+ }
+
+ /* assign default ProxyConfigFrequency value if not configured */
+ if (0 == CONFIG_PROXYCONFIG_FREQUENCY)
+ CONFIG_PROXYCONFIG_FREQUENCY = 10;
err |= (FAIL == zbx_db_validate_config_features());
@@ -735,7 +748,9 @@ static void zbx_load_config(ZBX_TASK_EX *task)
PARM_OPT, 1, 720},
{"HeartbeatFrequency", &CONFIG_HEARTBEAT_FREQUENCY, TYPE_INT,
PARM_OPT, 0, ZBX_PROXY_HEARTBEAT_FREQUENCY_MAX},
- {"ConfigFrequency", &CONFIG_PROXYCONFIG_FREQUENCY, TYPE_INT,
+ {"ConfigFrequency", &CONFIG_CONFSYNCER_FREQUENCY, TYPE_INT,
+ PARM_OPT, 1, SEC_PER_WEEK},
+ {"ProxyConfigFrequency", &CONFIG_PROXYCONFIG_FREQUENCY, TYPE_INT,
PARM_OPT, 1, SEC_PER_WEEK},
{"DataSenderFrequency", &CONFIG_PROXYDATA_FREQUENCY, TYPE_INT,
PARM_OPT, 1, SEC_PER_HOUR},
@@ -956,7 +971,7 @@ static void zbx_on_exit(int ret)
#ifdef HAVE_PTHREAD_PROCESS_SHARED
zbx_locks_disable();
#endif
- free_metrics();
+ zbx_free_metrics();
zbx_ipc_service_free_env();
DBconnect(ZBX_DB_CONNECT_EXIT);
@@ -969,7 +984,7 @@ static void zbx_on_exit(int ret)
/* free vmware support */
zbx_vmware_destroy();
- free_selfmon_collector();
+ zbx_free_selfmon_collector();
free_proxy_history_lock();
zbx_unload_modules();
@@ -1079,7 +1094,7 @@ int main(int argc, char **argv)
CONFIG_FILE = zbx_strdup(NULL, DEFAULT_CONFIG_FILE);
/* required for simple checks */
- init_metrics();
+ zbx_init_metrics();
zbx_load_config(&t);
@@ -1185,14 +1200,16 @@ int MAIN_ZABBIX_ENTRY(int flags)
zbx_rtc_t rtc;
zbx_timespec_t rtc_timeout = {1, 0};
+ zbx_config_comms_args_t zbx_config = {zbx_config_tls, CONFIG_HOSTNAME, CONFIG_PROXYMODE};
+
zbx_thread_args_t thread_args;
- zbx_thread_poller_args poller_args = {zbx_config_tls, get_program_type, ZBX_NO_POLLER};
- zbx_thread_heart_args heart_args = {zbx_config_tls, get_program_type};
+ zbx_thread_poller_args poller_args = {&zbx_config, get_program_type, ZBX_NO_POLLER};
zbx_thread_proxyconfig_args proxyconfig_args = {zbx_config_tls, get_program_type};
zbx_thread_datasender_args datasender_args = {zbx_config_tls, get_program_type};
- zbx_thread_taskmanager_args taskmanager_args = {zbx_config_tls, get_program_type};
+ zbx_thread_taskmanager_args taskmanager_args = {&zbx_config, get_program_type};
zbx_thread_discoverer_args discoverer_args = {zbx_config_tls, get_program_type};
- zbx_thread_trapper_args trapper_args = {zbx_config_tls, get_program_type, &listen_sock};
+ zbx_thread_trapper_args trapper_args = {&zbx_config, get_program_type, &listen_sock};
+
if (0 != (flags & ZBX_TASK_FLAG_FOREGROUND))
{
@@ -1323,7 +1340,7 @@ int MAIN_ZABBIX_ENTRY(int flags)
exit(EXIT_FAILURE);
}
- if (SUCCEED != init_selfmon_collector(&error))
+ if (SUCCEED != zbx_init_selfmon_collector(&error))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot initialize self-monitoring: %s", error);
zbx_free(error);
@@ -1362,7 +1379,7 @@ int MAIN_ZABBIX_ENTRY(int flags)
change_proxy_history_count(proxy_get_history_count());
- threads_num = CONFIG_CONFSYNCER_FORKS + CONFIG_HEARTBEAT_FORKS + CONFIG_DATASENDER_FORKS
+ threads_num = CONFIG_CONFSYNCER_FORKS + CONFIG_DATASENDER_FORKS
+ CONFIG_POLLER_FORKS + CONFIG_UNREACHABLE_POLLER_FORKS + CONFIG_TRAPPER_FORKS
+ CONFIG_PINGER_FORKS + CONFIG_HOUSEKEEPER_FORKS + CONFIG_HTTPPOLLER_FORKS
+ CONFIG_DISCOVERER_FORKS + CONFIG_HISTSYNCER_FORKS + CONFIG_IPMIPOLLER_FORKS
@@ -1387,7 +1404,7 @@ int MAIN_ZABBIX_ENTRY(int flags)
zabbix_log(LOG_LEVEL_INFORMATION, "proxy #0 started [main process]");
- zbx_zabbix_stats_init(zbx_get_zabbix_stats_ext);
+ zbx_zabbix_stats_init(zbx_zabbix_stats_ext_get);
zbx_diag_init(diag_add_section_info);
for (i = 0; i < threads_num; i++)
@@ -1413,10 +1430,6 @@ int MAIN_ZABBIX_ENTRY(int flags)
thread_args.args = &trapper_args;
zbx_thread_start(trapper_thread, &thread_args, &threads[i]);
break;
- case ZBX_PROCESS_TYPE_HEARTBEAT:
- thread_args.args = &heart_args;
- zbx_thread_start(heart_thread, &thread_args, &threads[i]);
- break;
case ZBX_PROCESS_TYPE_DATASENDER:
thread_args.args = &datasender_args;
zbx_thread_start(datasender_thread, &thread_args, &threads[i]);
diff --git a/src/zabbix_proxy/proxyconfig/Makefile.am b/src/zabbix_proxy/proxyconfig/Makefile.am
index a6497c5b978..0d5d718c86d 100644
--- a/src/zabbix_proxy/proxyconfig/Makefile.am
+++ b/src/zabbix_proxy/proxyconfig/Makefile.am
@@ -5,3 +5,5 @@ noinst_LIBRARIES = libzbxproxyconfig.a
libzbxproxyconfig_a_SOURCES = \
proxyconfig.c \
proxyconfig.h
+
+libzbxproxyconfig_a_CFLAGS = -I$(top_srcdir)/src/zabbix_proxy
diff --git a/src/zabbix_proxy/proxyconfig/proxyconfig.c b/src/zabbix_proxy/proxyconfig/proxyconfig.c
index 0013622be08..8513189e87c 100644
--- a/src/zabbix_proxy/proxyconfig/proxyconfig.c
+++ b/src/zabbix_proxy/proxyconfig/proxyconfig.c
@@ -28,6 +28,7 @@
#include "zbxcompress.h"
#include "zbxrtc.h"
#include "zbxcommshigh.h"
+#include "proxyconfigwrite/proxyconfig_write.h"
#define CONFIG_PROXYCONFIG_RETRY 120 /* seconds */
@@ -47,6 +48,7 @@ static void process_configuration_sync(size_t *data_size, zbx_synced_new_config_
char value[16], *error = NULL, *buffer = NULL;
size_t buffer_size, reserved;
struct zbx_json j;
+ int ret = FAIL;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
@@ -57,6 +59,8 @@ static void process_configuration_sync(size_t *data_size, zbx_synced_new_config_
zbx_json_addstring(&j, "request", ZBX_PROTO_VALUE_PROXY_CONFIG, ZBX_JSON_TYPE_STRING);
zbx_json_addstring(&j, "host", CONFIG_HOSTNAME, ZBX_JSON_TYPE_STRING);
zbx_json_addstring(&j, ZBX_PROTO_TAG_VERSION, ZABBIX_VERSION, ZBX_JSON_TYPE_STRING);
+ zbx_json_addstring(&j, ZBX_PROTO_TAG_SESSION, zbx_dc_get_session_token(), ZBX_JSON_TYPE_STRING);
+ zbx_json_adduint64(&j, ZBX_PROTO_TAG_CONFIG_REVISION, zbx_dc_get_received_revision());
if (SUCCEED != zbx_compress(j.buffer, j.buffer_size, &buffer, &buffer_size))
{
@@ -67,16 +71,16 @@ static void process_configuration_sync(size_t *data_size, zbx_synced_new_config_
reserved = j.buffer_size;
zbx_json_free(&j);
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
if (FAIL == zbx_connect_to_server(&sock,CONFIG_SOURCE_IP, &zbx_addrs, 600, CONFIG_TIMEOUT,
CONFIG_PROXYCONFIG_RETRY, LOG_LEVEL_WARNING, zbx_config_tls)) /* retry till have a connection */
{
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
goto out;
}
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
if (SUCCEED != zbx_get_data_from_server(&sock, &buffer, buffer_size, reserved, &error))
{
@@ -118,21 +122,30 @@ static void process_configuration_sync(size_t *data_size, zbx_synced_new_config_
goto error;
}
- zabbix_log(LOG_LEVEL_WARNING, "received configuration data from server at \"%s\", datalen " ZBX_FS_SIZE_T,
- sock.peer, (zbx_fs_size_t)*data_size);
-
- if (SUCCEED == process_proxyconfig(&jp, &jp_kvs_paths))
+ if (SUCCEED == (ret = zbx_proxyconfig_process(sock.peer, &jp, &error)))
{
- DCsync_configuration(ZBX_DBSYNC_UPDATE, *synced);
+ DCsync_configuration(ZBX_DBSYNC_UPDATE, *synced, NULL);
*synced = ZBX_SYNCED_NEW_CONFIG_YES;
- if (NULL != jp_kvs_paths.start)
+ if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_MACRO_SECRETS, &jp_kvs_paths))
DCsync_kvs_paths(&jp_kvs_paths);
DCupdate_interfaces_availability();
}
+ else
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot process received configuration data from server at \"%s\": %s",
+ sock.peer, error);
+ zbx_free(error);
+ }
error:
zbx_disconnect_from_server(&sock);
+ if (SUCCEED != ret)
+ {
+ /* reset received config_revision to force full resync after data transfer failure */
+ zbx_dc_update_received_revision(0);
+ }
+
out:
zbx_free(error);
zbx_free(buffer);
@@ -141,6 +154,80 @@ out:
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
}
+static void proxyconfig_remove_unused_templates(void)
+{
+ zbx_vector_uint64_t hostids, templateids;
+ zbx_hashset_t templates;
+ int removed_num;
+ DB_ROW row;
+ DB_RESULT result;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ zbx_vector_uint64_create(&hostids);
+ zbx_vector_uint64_create(&templateids);
+ zbx_hashset_create(&templates, 100, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
+ result = DBselect("select hostid,status from hosts");
+
+ while (NULL != (row = DBfetch(result)))
+ {
+ zbx_uint64_t hostid;
+ unsigned char status;
+
+ ZBX_STR2UINT64(hostid, row[0]);
+ ZBX_STR2UCHAR(status, row[1]);
+
+ if (HOST_STATUS_TEMPLATE == status)
+ zbx_hashset_insert(&templates, &hostid, sizeof(hostid));
+ else
+ zbx_vector_uint64_append(&hostids, hostid);
+ }
+ DBfree_result(result);
+
+ zbx_dc_get_unused_macro_templates(&templates, &hostids, &templateids);
+
+ if (0 != templateids.values_num)
+ {
+ char *sql = NULL;
+ size_t sql_alloc = 0, sql_offset = 0;
+
+ DBbegin();
+
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from hosts_templates where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", templateids.values,
+ templateids.values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto fail;
+
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from hostmacro where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", templateids.values,
+ templateids.values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto fail;
+
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from hosts where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", templateids.values,
+ templateids.values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto fail;
+fail:
+ DBcommit();
+
+ zbx_free(sql);
+ }
+
+ removed_num = templateids.values_num;
+
+ zbx_hashset_destroy(&templates);
+ zbx_vector_uint64_destroy(&templateids);
+ zbx_vector_uint64_destroy(&hostids);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s() removed:%d", __func__, removed_num);
+}
+
/******************************************************************************
* *
* Purpose: periodically request config data *
@@ -153,7 +240,7 @@ ZBX_THREAD_ENTRY(proxyconfig_thread, args)
zbx_thread_proxyconfig_args *proxyconfig_args_in = (zbx_thread_proxyconfig_args *)
(((zbx_thread_args_t *)args)->args);
size_t data_size;
- double sec;
+ double sec, last_template_cleanup_sec = 0, interval;
zbx_ipc_async_socket_t rtc;
int sleeptime;
zbx_synced_new_config_t synced = ZBX_SYNCED_NEW_CONFIG_NO;
@@ -165,7 +252,7 @@ ZBX_THREAD_ENTRY(proxyconfig_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]",
get_program_type_string(proxyconfig_args_in->zbx_get_program_type_cb_arg()),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
zbx_tls_init_child(proxyconfig_args_in->zbx_config_tls, proxyconfig_args_in->zbx_get_program_type_cb_arg);
#endif
@@ -177,7 +264,7 @@ ZBX_THREAD_ENTRY(proxyconfig_thread, args)
DBconnect(ZBX_DB_CONNECT_NORMAL);
zbx_setproctitle("%s [syncing configuration]", get_process_type_string(process_type));
- DCsync_configuration(ZBX_DBSYNC_INIT, ZBX_SYNCED_NEW_CONFIG_NO);
+ DCsync_configuration(ZBX_DBSYNC_INIT, ZBX_SYNCED_NEW_CONFIG_NO, NULL);
zbx_rtc_notify_config_sync(&rtc);
@@ -208,11 +295,17 @@ ZBX_THREAD_ENTRY(proxyconfig_thread, args)
{
zbx_setproctitle("%s [loading configuration]", get_process_type_string(process_type));
- DCsync_configuration(ZBX_DBSYNC_UPDATE, synced);
+ DCsync_configuration(ZBX_DBSYNC_UPDATE, synced, NULL);
synced = ZBX_SYNCED_NEW_CONFIG_YES;
DCupdate_interfaces_availability();
zbx_rtc_notify_config_sync(&rtc);
+ if (SEC_PER_HOUR < sec - last_template_cleanup_sec)
+ {
+ proxyconfig_remove_unused_templates();
+ last_template_cleanup_sec = sec;
+ }
+
zbx_setproctitle("%s [synced config in " ZBX_FS_DBL " sec]",
get_process_type_string(process_type), zbx_time() - sec);
}
@@ -227,12 +320,18 @@ ZBX_THREAD_ENTRY(proxyconfig_thread, args)
zbx_setproctitle("%s [loading configuration]", get_process_type_string(process_type));
process_configuration_sync(&data_size, &synced, proxyconfig_args_in->zbx_config_tls);
- sec = zbx_time() - sec;
+ interval = zbx_time() - sec;
zbx_setproctitle("%s [synced config " ZBX_FS_SIZE_T " bytes in " ZBX_FS_DBL " sec, idle %d sec]",
- get_process_type_string(process_type), (zbx_fs_size_t)data_size, sec,
+ get_process_type_string(process_type), (zbx_fs_size_t)data_size, interval,
CONFIG_PROXYCONFIG_FREQUENCY);
+ if (SEC_PER_HOUR < sec - last_template_cleanup_sec)
+ {
+ proxyconfig_remove_unused_templates();
+ last_template_cleanup_sec = sec;
+ }
+
sleeptime = CONFIG_PROXYCONFIG_FREQUENCY;
}
stop:
diff --git a/src/zabbix_proxy/proxyconfigwrite/Makefile.am b/src/zabbix_proxy/proxyconfigwrite/Makefile.am
new file mode 100644
index 00000000000..175513c0de6
--- /dev/null
+++ b/src/zabbix_proxy/proxyconfigwrite/Makefile.am
@@ -0,0 +1,9 @@
+## Process this file with automake to produce Makefile.in
+
+noinst_LIBRARIES = libzbxproxyconfigwrite.a
+
+libzbxproxyconfigwrite_a_SOURCES = \
+ proxyconfig_write.c \
+ proxyconfig_write.h
+
+libzbxproxyconfigwrite_a_CFLAGS = -I$(top_srcdir)/src
diff --git a/src/zabbix_proxy/proxyconfigwrite/proxyconfig_write.c b/src/zabbix_proxy/proxyconfigwrite/proxyconfig_write.c
new file mode 100644
index 00000000000..e364e87d80d
--- /dev/null
+++ b/src/zabbix_proxy/proxyconfigwrite/proxyconfig_write.c
@@ -0,0 +1,2133 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2022 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 "proxyconfig_write.h"
+
+#include "proxy.h"
+#include "zbxdbhigh.h"
+#include "zbxcommshigh.h"
+#include "zbxrtc.h"
+
+/*
+ * The configuration sync is split into 4 parts for each table:
+ * 1) proxyconfig_prepare_rows()
+ * Renames rename_field to '#'||rename_field for all rows to be updated. It's done to avoid
+ * possible conflicts when two field values used in unique index are swapped.
+ * Resets reset_field to null for all rows to be deleted or updated. It's done to avoid
+ * possible foreign key violation when rows in self referencing table are updated or deleted.
+ * The changed fields are marked as updated, so during update processing the correct values
+ * will be assigned to them.
+ *
+ * 2) proxyconfig_delete_rows()
+ * Deletes all existing rows within scope that are not present in received table data. The scope
+ * is limited to received hosts when partial updates are done.
+ *
+ * 3) proxyconfig_insert_rows()
+ * Inserts new rows that were not present in database.
+ *
+ * 4) proxyconfig_update_rows()
+ * Update changed fields.
+ *
+ * When processing related tables (for example drules, dchecks) the prepare and delete operations are
+ * done from child tables to master tables. The insert and update operations are done from master
+ * tables to child tables. This is done to avoid child rows being removed with cascaded deletes and
+ * have parent rows updated/inserted when updating/inserting child rows.
+ *
+ */
+
+extern int CONFIG_TRAPPER_TIMEOUT;
+
+typedef struct
+{
+ const ZBX_FIELD *field;
+}
+zbx_const_field_ptr_t;
+
+ZBX_VECTOR_DECL(const_field, zbx_const_field_ptr_t)
+ZBX_VECTOR_IMPL(const_field, zbx_const_field_ptr_t)
+
+/*
+ * 128 bit flags to support update flags for host_invetory table which has more that 64 columns
+ */
+typedef struct
+{
+ zbx_uint64_t blocks[128 / 64];
+}
+zbx_flags128_t;
+
+static void zbx_flags128_set(zbx_flags128_t *flags, int bit)
+{
+ flags->blocks[bit >> 6] |= (__UINT64_C(1) << (bit & 0x3f));
+}
+
+static void zbx_flags128_clear(zbx_flags128_t *flags, int bit)
+{
+ flags->blocks[bit >> 6] &= ~(__UINT64_C(1) << (bit & 0x3f));
+}
+
+static void zbx_flags128_init(zbx_flags128_t *flags)
+{
+ memset(flags->blocks, 0, sizeof(zbx_uint64_t) * (128 / 64));
+}
+
+static int zbx_flags128_isset(zbx_flags128_t *flags, int bit)
+{
+ return (0 != (flags->blocks[bit >> 6] & (__UINT64_C(1) << (bit & 0x3f)))) ? SUCCEED : FAIL;
+}
+
+static int zbx_flags128_isclear(zbx_flags128_t *flags)
+{
+ if (0 != flags->blocks[0])
+ return FAIL;
+
+ if (0 != flags->blocks[1])
+ return FAIL;
+
+ return SUCCEED;
+}
+
+ZBX_PTR_VECTOR_DECL(table_row_ptr, struct zbx_table_row *)
+
+/* bit defines for proxyconfig row flags, lower bits are reserved for field update flags */
+#define PROXYCONFIG_ROW_EXISTS 127
+
+typedef struct zbx_table_row
+{
+ zbx_uint64_t recid;
+ struct zbx_json_parse columns;
+ zbx_flags128_t flags;
+}
+zbx_table_row_t;
+
+ZBX_PTR_VECTOR_IMPL(table_row_ptr, zbx_table_row_t *)
+
+typedef struct
+{
+ const ZBX_TABLE *table;
+ zbx_vector_const_field_t fields;
+ zbx_hashset_t rows;
+
+ /* identifiers of the rows that must be deleted */
+ zbx_vector_uint64_t del_ids;
+
+ /* row that must be updated */
+ zbx_vector_table_row_ptr_t updates;
+
+ /* to avoid unique key conflicts when syncing rows the key */
+ /* field will be renamed for all update rows and marked */
+ /* for update */
+ const char *rename_field;
+
+ /* To avoid self referencing foreign key conflicts when */
+ /* syncing rows the reset field will be set to NULL for */
+ /* all update and delete rows and marked for update. */
+ /* As such only ID fields can be set as reset_field. */
+ const char *reset_field;
+
+ /* optional sql filter to limit managed object scope (exclude templates from hosts) */
+ char *sql_filter;
+}
+zbx_table_data_t;
+
+ZBX_PTR_VECTOR_DECL(table_data_ptr, zbx_table_data_t *)
+ZBX_PTR_VECTOR_IMPL(table_data_ptr, zbx_table_data_t *)
+
+static void table_data_free(zbx_table_data_t *td)
+{
+ zbx_vector_const_field_destroy(&td->fields);
+ zbx_vector_uint64_destroy(&td->del_ids);
+ zbx_vector_table_row_ptr_destroy(&td->updates);
+ zbx_hashset_destroy(&td->rows);
+ zbx_free(td->sql_filter);
+ zbx_free(td);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: get table data by name from configuration updates *
+ * *
+ * Return: The parsed table data or NULL if table data was not found *
+ * *
+ ******************************************************************************/
+static zbx_table_data_t *proxyconfig_get_table(zbx_vector_table_data_ptr_t *config_tables, const char *name)
+{
+ int i;
+
+ for (i = 0; i < config_tables->values_num; i++)
+ {
+ if (0 == strcmp(config_tables->values[i]->table->table, name))
+ return config_tables->values[i];
+ }
+
+ return NULL;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: validate parsed table fields against fields retrieved from *
+ * database schema *
+ * *
+ * Parameters: td - [IN] the table *
+ * jp_table - [IN] the received table data in json format *
+ * error - [OUT] the error message *
+ * *
+ * Return: SUCCEED - the parsed fields match schema fields *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_validate_table_fields(const zbx_table_data_t *td, struct zbx_json_parse *jp_table,
+ char **error)
+{
+ const char *p;
+ int ret = FAIL, i;
+ struct zbx_json_parse jp;
+ char buf[ZBX_FIELDNAME_LEN_MAX];
+
+ /* get table columns (line 3 in T1) */
+ if (FAIL == zbx_json_brackets_by_name(jp_table, "fields", &jp))
+ {
+ *error = zbx_strdup(*error, zbx_json_strerror());
+ goto out;
+ }
+
+ /* validate received fields */
+
+ p = NULL;
+ /* iterate column names (lines 4-6 in T1) */
+ for (i = 0; NULL != (p = zbx_json_next_value(&jp, p, buf, sizeof(buf), NULL)); i++)
+ {
+ if (i >= td->fields.values_num || 0 != strcmp(buf, td->fields.values[i].field->name))
+ {
+ *error = zbx_dsprintf(*error, "unexpected field \"%s.%s\"", td->table->table, buf);
+ goto out;
+ }
+ }
+
+ if (i != td->fields.values_num)
+ {
+ *error = zbx_dsprintf(*error, "missing field \"%s.%s\"", td->table->table,
+ td->fields.values[i].field->name);
+ goto out;
+ }
+
+ ret = SUCCEED;
+out:
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: parse table rows in received configuration data *
+ * *
+ * Parameters: td - [IN] the table *
+ * jp_table - [IN] the received table data in json format *
+ * error - [OUT] the error message *
+ * *
+ * Return: SUCCEED - the rows were parsed successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_parse_table_rows(zbx_table_data_t *td, struct zbx_json_parse *jp_table, char **error)
+{
+ const char *p;
+ int ret = FAIL;
+ struct zbx_json_parse jp, jp_row;
+ char *buf;
+ size_t buf_alloc = ZBX_KIBIBYTE;
+
+ buf = (char *)zbx_malloc(NULL, buf_alloc);
+
+ /* get the entries (line 8 in T1) */
+ if (FAIL == zbx_json_brackets_by_name(jp_table, ZBX_PROTO_TAG_DATA, &jp))
+ {
+ *error = zbx_strdup(*error, zbx_json_strerror());
+ goto out;
+ }
+
+ for (p = NULL; NULL != (p = zbx_json_next(&jp, p)); )
+ {
+ zbx_table_row_t *row, row_local;
+
+ if (FAIL == zbx_json_brackets_open(p, &jp_row) ||
+ NULL == zbx_json_next_value_dyn(&jp_row, NULL, &buf, &buf_alloc, NULL))
+ {
+ *error = zbx_strdup(*error, zbx_json_strerror());
+ goto out;
+ }
+
+ if (SUCCEED != zbx_is_uint64(buf, &row_local.recid))
+ {
+ *error = zbx_dsprintf(*error, "invalid record identifier: \"%s\"", buf);
+ goto out;
+ }
+ row = (zbx_table_row_t *)zbx_hashset_insert(&td->rows, &row_local, sizeof(row_local));
+ row->columns = jp_row;
+ zbx_flags128_init(&row->flags);
+ }
+
+ ret = SUCCEED;
+out:
+ zbx_free(buf);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: create and initialize table data object *
+ * *
+ * Parameters: name - [IN] the table name *
+ * *
+ * Return: The table data object or null, if invalid table name was given. *
+ * *
+ ******************************************************************************/
+static zbx_table_data_t *proxyconfig_create_table(const char *name)
+{
+ const ZBX_TABLE *table;
+ const ZBX_FIELD *field;
+ zbx_table_data_t *td;
+ zbx_const_field_ptr_t ptr;
+
+ if (NULL == (table = DBget_table(name)))
+ return NULL;
+
+ td = (zbx_table_data_t *)zbx_malloc(NULL, sizeof(zbx_table_data_t));
+
+ td->table = table;
+ td->rename_field = NULL;
+ td->reset_field = NULL;
+ td->sql_filter = NULL;
+
+ zbx_vector_const_field_create(&td->fields);
+ zbx_hashset_create(&td->rows, 100, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+ zbx_vector_uint64_create(&td->del_ids);
+ zbx_vector_table_row_ptr_create(&td->updates);
+
+ /* apply table specific configuration settings */
+
+ if (0 == strcmp(table->table, "globalmacro"))
+ {
+ td->rename_field = "macro";
+ }
+ if (0 == strcmp(table->table, "hostmacro"))
+ {
+ td->rename_field = "macro";
+ }
+ else if (0 == strcmp(table->table, "drules"))
+ {
+ td->rename_field = "name";
+ }
+ else if (0 == strcmp(table->table, "regexps"))
+ {
+ td->rename_field = "name";
+ }
+ else if (0 == strcmp(table->table, "httptest"))
+ {
+ td->rename_field = "name";
+ }
+ else if (0 == strcmp(table->table, "hosts"))
+ {
+ td->sql_filter = zbx_dsprintf(NULL, "status<>%d", HOST_STATUS_TEMPLATE);
+ }
+ else if (0 == strcmp(table->table, "items"))
+ td->reset_field = "master_itemid";
+
+ /* get table fields from database schema */
+
+ field = table->fields;
+ ptr.field = field++;
+ zbx_vector_const_field_append(&td->fields, ptr);
+
+ for (; NULL != field->name; field++)
+ {
+ if (0 != (field->flags & ZBX_PROXY))
+ {
+ ptr.field = field;
+ zbx_vector_const_field_append(&td->fields, ptr);
+ }
+ }
+
+ return td;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: parse received configuration data *
+ * *
+ * Parameters: jp_data - [IN] the configuration data in json format *
+ * config_tables - [OUT] the parsed table data *
+ * error - [IN] the error message *
+ * *
+ * Return: SUCCEED - the rows were parsed successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_parse_data(struct zbx_json_parse *jp_data, zbx_vector_table_data_ptr_t *config_tables,
+ char **error)
+{
+ const char *p;
+ char buf[ZBX_TABLENAME_LEN_MAX];
+ struct zbx_json_parse jp_table;
+ int ret = FAIL;
+
+ /************************************************************************************/
+ /* T1. RECEIVED JSON (jp_obj) DATA FORMAT */
+ /************************************************************************************/
+ /* Line | Data | Corresponding structure in DB */
+ /* -----+-------------------------------------------+------------------------------ */
+ /* 1 | { | */
+ /* 2 | "hosts": { | first table */
+ /* 3 | "fields": [ | list of table's columns */
+ /* 4 | "hostid", | first column */
+ /* 5 | "host", | second column */
+ /* 6 | ... | ...columns */
+ /* 7 | ], | */
+ /* 8 | "data": [ | the table data */
+ /* 9 | [ | first entry */
+ /* 10 | 1, | value for first column */
+ /* 11 | "zbx01", | value for second column */
+ /* 12 | ... | ...values */
+ /* 13 | ], | */
+ /* 14 | [ | second entry */
+ /* 15 | 2, | value for first column */
+ /* 16 | "zbx02", | value for second column */
+ /* 17 | ... | ...values */
+ /* 18 | ], | */
+ /* 19 | ... | ...entries */
+ /* 20 | ] | */
+ /* 21 | }, | */
+ /* 22 | "items": { | second table */
+ /* 23 | ... | ... */
+ /* 24 | }, | */
+ /* 25 | ... | ...tables */
+ /* 26 | } | */
+ /************************************************************************************/
+
+ /* iterate the tables (lines 2, 22 and 25 in T1) */
+ for (p = NULL; NULL != (p = zbx_json_pair_next(jp_data, p, buf, sizeof(buf))); )
+ {
+ zbx_table_data_t *td;
+
+ if (FAIL == zbx_json_brackets_open(p, &jp_table))
+ {
+ *error = zbx_strdup(NULL, zbx_json_strerror());
+ goto out;
+ }
+
+ if (NULL == (td = proxyconfig_create_table(buf)))
+ {
+ *error = zbx_dsprintf(NULL, "invalid table name \"%s\"", buf);
+ goto out;
+ }
+
+ if (SUCCEED != proxyconfig_validate_table_fields(td, &jp_table, error) ||
+ SUCCEED != proxyconfig_parse_table_rows(td, &jp_table, error))
+ {
+ table_data_free(td);
+ goto out;
+ }
+
+ zbx_vector_table_data_ptr_append(config_tables, td);
+ }
+
+ ret = SUCCEED;
+out:
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: add default tables to configuration data *
+ * *
+ * Parameters: config_tables - [IN] the parsed table data *
+ * *
+ * Comments: In some cases empty tables might not be sent, but still need to *
+ * be processed to support old data removal. This function adds *
+ * empty tables that will be used to check and remove old records. *
+ * *
+ ******************************************************************************/
+static void proxyconfig_add_default_tables(zbx_vector_table_data_ptr_t *config_tables)
+{
+ if (NULL != proxyconfig_get_table(config_tables, "hosts") &&
+ NULL == proxyconfig_get_table(config_tables, "httptest"))
+ {
+ char *httptest_tables[] = {"httptest", "httptestitem", "httptest_field",
+ "httpstep", "httpstepitem", "httpstep_field"};
+ size_t i;
+
+ for (i = 0; i < ARRSIZE(httptest_tables); i++)
+ zbx_vector_table_data_ptr_append(config_tables, proxyconfig_create_table(httptest_tables[i]));
+ }
+}
+
+/******************************************************************************
+ * *
+ * Purpose: dump table data object contents *
+ * *
+ * Parameters: td - [IN] the table data object *
+ * *
+ ******************************************************************************/
+static void proxyconfig_dump_table(zbx_table_data_t *td)
+{
+ char *str = NULL;
+ size_t str_alloc = 0, str_offset = 0, buf_alloc = ZBX_KIBIBYTE;
+ int i;
+ zbx_hashset_iter_t iter;
+ zbx_table_row_t *row;
+ char *buf;
+
+ buf = (char *)zbx_malloc(NULL, buf_alloc);
+
+ zabbix_log(LOG_LEVEL_TRACE, "table:%s", td->table->table);
+
+ zbx_strcpy_alloc(&str, &str_alloc, &str_offset, "||");
+
+ for (i = 0; i < td->fields.values_num; i++)
+ zbx_snprintf_alloc(&str, &str_alloc, &str_offset, "%s||", td->fields.values[i].field->name);
+
+ zabbix_log(LOG_LEVEL_TRACE, " %s", str);
+
+ zbx_hashset_iter_reset(&td->rows, &iter);
+ while (NULL != (row = (zbx_table_row_t *)zbx_hashset_iter_next(&iter)))
+ {
+ const char *pf = NULL;
+
+ str_offset = 0;
+ zbx_chrcpy_alloc(&str, &str_alloc, &str_offset, '|');
+
+ while (NULL != (pf = zbx_json_next_value_dyn(&row->columns, pf, &buf, &buf_alloc, NULL)))
+ zbx_snprintf_alloc(&str, &str_alloc, &str_offset, "%s|", buf);
+
+ zabbix_log(LOG_LEVEL_TRACE, " %s", str);
+ }
+
+ zbx_free(str);
+ zbx_free(buf);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: dump parsed configuration contents *
+ * *
+ * Parameters: config_tables - [IN] the parsed table data *
+ * *
+ ******************************************************************************/
+static void proxyconfig_dump_data(const zbx_vector_table_data_ptr_t *config_tables)
+{
+ int i;
+
+ zabbix_log(LOG_LEVEL_TRACE, "=== Received configuration ===");
+
+ for (i = 0; i < config_tables->values_num; i++)
+ proxyconfig_dump_table(config_tables->values[i]);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: compare database row with received data *
+ * *
+ * Parameters: row - [IN] the received row *
+ * dbrow - [IN] the database row *
+ * buf - [IN/OUT] the buffer for value parsing *
+ * buf_alloc - [IN/OUT] the buffer size *
+ * *
+ * Return value: SUCCEED - the rows match *
+ * FAIl - the rows doesn't match *
+ * *
+ * Comments: The checked rows will be flagged as 'exists'. Also update flag *
+ * will be set for each not matching column. Finally global row *
+ * update flag will be set if at last one match failed. *
+ * *
+ ******************************************************************************/
+static int proxyconfig_compare_row(zbx_table_row_t *row, DB_ROW dbrow, char **buf, size_t *buf_alloc)
+{
+ int i, ret = SUCCEED;
+ const char *pf;
+ zbx_json_type_t type;
+
+ /* skip first row containing record id */
+ pf = zbx_json_next(&row->columns, NULL);
+
+ for (i = 1; NULL != (pf = zbx_json_next_value_dyn(&row->columns, pf, buf, buf_alloc, &type)); i++)
+ {
+ if (ZBX_JSON_TYPE_NULL == type)
+ {
+ if (SUCCEED != DBis_null(dbrow[i]))
+ zbx_flags128_set(&row->flags, i);
+ continue;
+ }
+
+ if (SUCCEED == DBis_null(dbrow[i]) || 0 != strcmp(*buf, dbrow[i]))
+ zbx_flags128_set(&row->flags, i);
+ }
+
+ if (SUCCEED != zbx_flags128_isclear(&row->flags))
+ ret = FAIL;
+
+ zbx_flags128_set(&row->flags, PROXYCONFIG_ROW_EXISTS);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: get field index in table fields list by name *
+ * *
+ * Parameters: td - [IN] the table data object *
+ * field_name - [OUT] the field name *
+ * *
+ * Return value: The field index or -1 if field was not found. *
+ * *
+ ******************************************************************************/
+static int table_data_get_field_index(const zbx_table_data_t *td, const char *field_name)
+{
+ int i;
+
+ /* skip first field - recid */
+ for (i = 1; i < td->fields.values_num; i++)
+ {
+ if (0 == strcmp(td->fields.values[i].field->name, field_name))
+ return i;
+ }
+
+ return -1;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: delete rows that are not present in new configuration data *
+ * *
+ * Parameters: td - [IN] the table data object *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the rows were deleted successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_delete_rows(const zbx_table_data_t *td, char **error)
+{
+ char *sql = NULL;
+ size_t sql_alloc = 0, sql_offset = 0;
+ int ret;
+
+ if (0 == td->del_ids.values_num)
+ return SUCCEED;
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "delete from %s where", td->table->table);
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, td->table->recid, td->del_ids.values,
+ td->del_ids.values_num);
+
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ {
+ *error = zbx_dsprintf(NULL, "cannot remove old objects from table \"%s\"", td->table->table);
+ ret = FAIL;
+ }
+ else
+ ret = SUCCEED;
+
+ zbx_free(sql);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: prepare existing rows for udpate/delete *
+ * *
+ * Parameters: td - [IN] the table data object *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the rows were prepared successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_prepare_rows(zbx_table_data_t *td, char **error)
+{
+ char *sql = NULL, delim = ' ';
+ size_t sql_alloc = 0, sql_offset = 0;
+ int i, ret, rename_index = -1, reset_index = -1;
+ zbx_vector_uint64_t updateids;
+
+ if (NULL == td->rename_field && NULL == td->reset_field)
+ return SUCCEED;
+
+ if (NULL != td->rename_field && -1 == (rename_index = table_data_get_field_index(td, td->rename_field)))
+ {
+ *error = zbx_dsprintf(NULL, "unknown rename field \"%s\" for table \"%s\"", td->rename_field,
+ td->table->table);
+ return FAIL;
+ }
+
+ if (NULL != td->reset_field)
+ {
+ if (-1 == (reset_index = table_data_get_field_index(td, td->reset_field)))
+ {
+ *error = zbx_dsprintf(NULL, "unknown rename field \"%s\" for table \"%s\"", td->reset_field,
+ td->table->table);
+ return FAIL;
+ }
+
+ if (ZBX_TYPE_ID != td->fields.values[reset_index].field->type)
+ {
+ *error = zbx_dsprintf(NULL, "only ID fields can be reset");
+ return FAIL;
+ }
+ }
+
+ zbx_vector_uint64_create(&updateids);
+ zbx_vector_uint64_reserve(&updateids, (size_t)td->updates.values_num);
+
+ for (i = 0; i < td->updates.values_num; i++)
+ {
+ zbx_vector_uint64_append(&updateids, td->updates.values[i]->recid);
+
+ /* force renamed/reset fields to be updated */
+
+ if (-1 != rename_index)
+ zbx_flags128_set(&td->updates.values[i]->flags, rename_index);
+
+ if (-1 != reset_index)
+ zbx_flags128_set(&td->updates.values[i]->flags, reset_index);
+ }
+
+ if (-1 != reset_index)
+ zbx_vector_uint64_append_array(&updateids, td->del_ids.values, td->del_ids.values_num);
+
+ if (0 == updateids.values_num)
+ {
+ ret = SUCCEED;
+ goto out;
+ }
+
+ zbx_vector_uint64_sort(&updateids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update %s set", td->table->table);
+
+ if (-1 != rename_index)
+ {
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%c%s=" ZBX_SQL_CONCAT(),
+ delim, td->rename_field, "'#'", td->rename_field);
+ delim = ',';
+ }
+
+ if (-1 != reset_index)
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%c%s=null", delim, td->reset_field);
+
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, td->table->recid, updateids.values, updateids.values_num);
+
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ {
+ *error = zbx_dsprintf(NULL, "cannot prepare rows for update in table \"%s\"", td->table->table);
+ ret = FAIL;
+ }
+ else
+ ret = SUCCEED;
+
+ zbx_free(sql);
+out:
+ zbx_vector_uint64_destroy(&updateids);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: convert text value to the database value according to its field *
+ * type *
+ * *
+ * Parameters: table - [IN] *
+ * field - [IN] *
+ * buf - [IN] the value to convert *
+ * type - [IN] the json value type *
+ * value - [OUT] the converted value (optional) *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the operation was successful *
+ * FAIL - otherwise *
+ * *
+ * Comments: This function can be used to validate buffer by using NULL *
+ * output value. *
+ * *
+ ******************************************************************************/
+static int proxyconfig_convert_value(const ZBX_TABLE *table, const ZBX_FIELD *field, const char *buf,
+ zbx_json_type_t type, zbx_db_value_t **value, char **error)
+{
+ zbx_db_value_t value_local;
+ int ret;
+
+ switch (field->type)
+ {
+ case ZBX_TYPE_INT:
+ ret = zbx_is_int(buf, &value_local.i32);
+ break;
+ case ZBX_TYPE_UINT:
+ ret = zbx_is_uint64(buf, &value_local.ui64);
+ break;
+ case ZBX_TYPE_ID:
+ if (ZBX_JSON_TYPE_NULL == type)
+ {
+ value_local.ui64 = 0;
+ ret = SUCCEED;
+ }
+ else
+ ret = zbx_is_uint64(buf, &value_local.ui64);
+ break;
+ case ZBX_TYPE_FLOAT:
+ ret = zbx_is_double(buf, &value_local.dbl);
+ break;
+ case ZBX_TYPE_CHAR:
+ case ZBX_TYPE_TEXT:
+ case ZBX_TYPE_SHORTTEXT:
+ case ZBX_TYPE_LONGTEXT:
+ if (NULL != value)
+ value_local.str = zbx_strdup(NULL, ZBX_NULL2EMPTY_STR(buf));
+ ret = SUCCEED;
+ break;
+ default:
+ *error = zbx_dsprintf(*error, "unsupported field type %d in \"%s.%s\"",
+ field->type, table->table, field->name);
+ return FAIL;
+ }
+
+ if (SUCCEED != ret)
+ {
+ *error = zbx_dsprintf(*error, "invalid field \"%s.%s\" value \"%s\"",
+ table->table, field->name, buf);
+ return FAIL;
+ }
+
+ if (NULL != value)
+ {
+ *value = (zbx_db_value_t *)zbx_malloc(NULL, sizeof(zbx_db_value_t));
+ **value = value_local;
+ }
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: update existing rows with new field values *
+ * *
+ * Parameters: td - [IN] the table data object *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the rows were updated successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_update_rows(zbx_table_data_t *td, char **error)
+{
+ char *sql = NULL, *buf;
+ size_t sql_alloc = 0, sql_offset = 0, buf_alloc = ZBX_KIBIBYTE;
+ int i, j, ret = FAIL;
+
+ if (0 == td->updates.values_num)
+ return SUCCEED;
+
+ buf = (char *)zbx_malloc(NULL, buf_alloc);
+
+ zbx_DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
+
+ for (i = 0; i < td->updates.values_num; i++)
+ {
+ char delim = ' ';
+ const char *pf;
+ zbx_table_row_t *row = td->updates.values[i];
+ zbx_json_type_t type;
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update %s set", td->table->table);
+
+ pf = zbx_json_next(&row->columns, NULL);
+
+ for (j = 1; NULL != (pf = zbx_json_next_value_dyn(&row->columns, pf, &buf, &buf_alloc, &type)); j++)
+ {
+ const ZBX_FIELD *field = td->fields.values[j].field;
+ char *value_esc;
+
+ if (SUCCEED != zbx_flags128_isset(&row->flags, j))
+ continue;
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%c%s=", delim, field->name);
+ delim = ',';
+
+ if (ZBX_JSON_TYPE_NULL == type)
+ {
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "null");
+ continue;
+ }
+
+ if (SUCCEED != proxyconfig_convert_value(td->table, field, buf, type, NULL, error))
+ goto out;
+
+ switch (field->type)
+ {
+ case ZBX_TYPE_ID:
+ case ZBX_TYPE_UINT:
+ case ZBX_TYPE_FLOAT:
+ case ZBX_TYPE_INT:
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, buf);
+ break;
+ case ZBX_TYPE_CHAR:
+ case ZBX_TYPE_TEXT:
+ case ZBX_TYPE_SHORTTEXT:
+ case ZBX_TYPE_LONGTEXT:
+ value_esc = DBdyn_escape_string_len(buf, field->length);
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "'%s'", value_esc);
+ zbx_free(value_esc);
+ break;
+ default:
+ *error = zbx_dsprintf(*error, "unsupported field type %d in \"%s.%s\"",
+ (int)field->type, td->table->table, field->name);
+ goto out;
+ }
+ }
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where %s=" ZBX_FS_UI64 ";\n",
+ td->table->recid, row->recid);
+
+ if (SUCCEED != DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset))
+ goto out;
+ }
+
+ zbx_DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
+
+ if (16 < sql_offset && ZBX_DB_OK > DBexecute("%s", sql))
+ goto out;
+
+ ret = SUCCEED;
+out:
+ zbx_free(sql);
+ zbx_free(buf);
+
+ if (SUCCEED != ret && NULL == *error)
+ *error = zbx_dsprintf(NULL, "cannot update rows in table \"%s\"", td->table->table);
+
+ return ret;
+}
+
+ZBX_PTR_VECTOR_DECL(db_value_ptr, zbx_db_value_t *)
+ZBX_PTR_VECTOR_IMPL(db_value_ptr, zbx_db_value_t *)
+
+/******************************************************************************
+ * *
+ * Purpose: insert new rows *
+ * *
+ * Parameters: td - [IN] the table data object *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the rows were inserted successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_insert_rows(zbx_table_data_t *td, char **error)
+{
+ int ret = SUCCEED, reset_index = -1;
+ zbx_hashset_iter_t iter;
+ zbx_vector_table_row_ptr_t rows;
+ zbx_table_row_t *row;
+
+ /* invalid reset_index would have generated error during row preparation */
+ if (NULL != td->reset_field)
+ reset_index = table_data_get_field_index(td, td->reset_field);
+
+ zbx_vector_table_row_ptr_create(&rows);
+
+ zbx_hashset_iter_reset(&td->rows, &iter);
+ while (NULL != (row = (zbx_table_row_t *)zbx_hashset_iter_next(&iter)))
+ {
+ if (SUCCEED != zbx_flags128_isset(&row->flags, PROXYCONFIG_ROW_EXISTS))
+ zbx_vector_table_row_ptr_append(&rows, row);
+ }
+
+ if (0 != rows.values_num)
+ {
+ zbx_vector_db_value_ptr_t values;
+ zbx_db_insert_t db_insert;
+ const ZBX_FIELD *fields[ZBX_MAX_FIELDS];
+ int i, j;
+ char *buf;
+ size_t buf_alloc = ZBX_KIBIBYTE;
+
+ buf = (char *)zbx_malloc(NULL, buf_alloc);
+
+ zbx_vector_db_value_ptr_create(&values);
+
+ for (i = 0; i < td->fields.values_num; i++)
+ fields[i] = td->fields.values[i].field;
+
+ zbx_db_insert_prepare_dyn(&db_insert, td->table, fields, td->fields.values_num);
+
+ for (i = 0; i < rows.values_num && SUCCEED == ret; i++)
+ {
+ const char *pf = NULL;
+ zbx_json_type_t type;
+
+ row = rows.values[i];
+
+ for (j = 0; NULL != (pf = zbx_json_next_value_dyn(&row->columns, pf, &buf, &buf_alloc, &type));
+ j++)
+ {
+ zbx_db_value_t *value;
+
+ if (j == reset_index)
+ {
+ if (ZBX_TYPE_ID != fields[j]->type)
+ {
+ /* Field resetting is used to avoid foreign key conflicts in self */
+ /* referenced tables during inserts. Such fields are inserted as */
+ /* nulls and then updated to correct values. */
+ /* For now only ID fields can be used in foreign keys. */
+ THIS_SHOULD_NEVER_HAPPEN;
+
+ *error = zbx_dsprintf(NULL, "cannot reset field \"%s.%s\" of type %d "
+ "to NULL value",
+ td->table->table, fields[j]->name, fields[j]->type);
+ ret = FAIL;
+ goto clean;
+ }
+
+ /* insert null ID and add this row to updates, */
+ /* so the correct ID will be updated later */
+ zbx_flags128_set(&row->flags, PROXYCONFIG_ROW_EXISTS);
+ zbx_flags128_set(&row->flags, j);
+ zbx_vector_table_row_ptr_append(&td->updates, row);
+
+ value = (zbx_db_value_t *)zbx_malloc(NULL, sizeof(zbx_db_value_t));
+ value->ui64 = 0;
+ }
+ else
+ {
+ if (SUCCEED != (ret = proxyconfig_convert_value(td->table, fields[j], buf, type,
+ &value, error)))
+ {
+ goto clean;
+ }
+ }
+
+ zbx_vector_db_value_ptr_append(&values, value);
+ }
+
+ zbx_db_insert_add_values_dyn(&db_insert, (const zbx_db_value_t **)values.values,
+ values.values_num);
+clean:
+ for (j = 0; j < values.values_num; j++)
+ {
+ switch (fields[j]->type)
+ {
+ case ZBX_TYPE_CHAR:
+ case ZBX_TYPE_TEXT:
+ case ZBX_TYPE_SHORTTEXT:
+ case ZBX_TYPE_LONGTEXT:
+ zbx_free(values.values[j]->str);
+ }
+ zbx_free(values.values[j]);
+ }
+ zbx_vector_db_value_ptr_clear(&values);
+ }
+
+ if (SUCCEED == ret)
+ ret = zbx_db_insert_execute(&db_insert);
+
+ zbx_db_insert_clean(&db_insert);
+ zbx_vector_db_value_ptr_destroy(&values);
+ zbx_free(buf);
+
+ }
+
+ zbx_vector_table_row_ptr_destroy(&rows);
+
+ if (SUCCEED != ret && NULL == *error)
+ *error = zbx_dsprintf(NULL, "cannot insert rows in table \"%s\"", td->table->table);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: prepare table for configuration sync by checking existing data *
+ * against received data and mark row updates/deletes accordingly *
+ * *
+ * Parameters: td - [IN] the table data object *
+ * key_field - [IN] the key field (optional) *
+ * key_ids - [IN] the key identifiers (optional) *
+ * recids - [OUT] the selected row record identifiers *
+ * (optional) *
+ * *
+ * Comments: The key_field and key_ids allow to specify scope within which the*
+ * table sync will be made. *
+ * *
+ ******************************************************************************/
+static void proxyconfig_prepare_table(zbx_table_data_t *td, const char *key_field, zbx_vector_uint64_t *key_ids,
+ zbx_vector_uint64_t *recids)
+{
+ DB_RESULT result;
+ DB_ROW dbrow;
+ char *sql = NULL, *buf, *delim = " where";
+ size_t sql_alloc = 0, sql_offset = 0, buf_alloc = ZBX_KIBIBYTE;
+ zbx_uint64_t recid;
+ zbx_table_row_t *row;
+ int i;
+
+ if (NULL != key_ids && 0 == key_ids->values_num)
+ return;
+
+ buf = (char *)zbx_malloc(NULL, buf_alloc);
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select %s", td->table->recid);
+
+ for (i = 1; i < td->fields.values_num; i++)
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, ",%s", td->fields.values[i].field->name);
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " from %s", td->table->table);
+ if (NULL != key_ids)
+ {
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, delim);
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, key_field, key_ids->values, key_ids->values_num);
+ delim = " and";
+ }
+
+ if (NULL != td->sql_filter)
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%s %s", delim, td->sql_filter);
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " order by %s", td->table->recid);
+
+ result = DBselect("%s", sql);
+
+ while (NULL != (dbrow = DBfetch(result)))
+ {
+ ZBX_STR2UINT64(recid, dbrow[0]);
+
+ if (NULL != recids)
+ zbx_vector_uint64_append(recids, recid);
+
+ if (NULL == (row = (zbx_table_row_t *)zbx_hashset_search(&td->rows, &recid)))
+ {
+ zbx_vector_uint64_append(&td->del_ids, recid);
+ continue;
+ }
+
+ if (SUCCEED != proxyconfig_compare_row(row, dbrow, &buf, &buf_alloc))
+ zbx_vector_table_row_ptr_append(&td->updates, row);
+ }
+ DBfree_result(result);
+
+ zbx_free(sql);
+ zbx_free(buf);
+
+ if (0 != td->del_ids.values_num)
+ zbx_vector_uint64_sort(&td->del_ids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
+ if (0 != td->updates.values_num)
+ zbx_vector_table_row_ptr_sort(&td->updates, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
+
+ if (NULL != recids)
+ zbx_vector_uint64_sort(recids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: sync table rows *
+ * *
+ * Parameters: config_tables - [IN] the received table data *
+ * table - [IN] the name of table to sync *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the table was synced successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_sync_table(zbx_vector_table_data_ptr_t *config_tables, const char *table, char **error)
+{
+ zbx_table_data_t *td;
+
+ if (NULL == (td = proxyconfig_get_table(config_tables, table)))
+ return SUCCEED;
+
+ proxyconfig_prepare_table(td, NULL, NULL, NULL);
+
+ if (SUCCEED != proxyconfig_prepare_rows(td, error))
+ return FAIL;
+
+ if (SUCCEED != proxyconfig_delete_rows(td, error))
+ return FAIL;
+
+ if (SUCCEED != proxyconfig_insert_rows(td, error))
+ return FAIL;
+
+ return proxyconfig_update_rows(td, error);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: sync network discovery tables *
+ * *
+ * Parameters: config_tables - [IN] the received table data *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the tables were synced successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_sync_network_discovery(zbx_vector_table_data_ptr_t *config_tables, char **error)
+{
+ zbx_table_data_t *dchecks;
+
+ dchecks = proxyconfig_get_table(config_tables, "dchecks");
+
+ if (NULL != dchecks)
+ {
+ proxyconfig_prepare_table(dchecks, NULL, NULL, NULL);
+
+ if (SUCCEED != proxyconfig_prepare_rows(dchecks, error))
+ return FAIL;
+
+ if (SUCCEED != proxyconfig_delete_rows(dchecks, error))
+ return FAIL;
+ }
+
+ if (SUCCEED != proxyconfig_sync_table(config_tables, "drules", error))
+ return FAIL;
+
+ if (NULL == dchecks)
+ return SUCCEED;
+
+ if (SUCCEED != proxyconfig_insert_rows(dchecks, error))
+ return FAIL;
+
+ return proxyconfig_update_rows(dchecks, error);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: sync global regular expression tables *
+ * *
+ * Parameters: config_tables - [IN] the received table data *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the tables were synced successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_sync_regexps(zbx_vector_table_data_ptr_t *config_tables, char **error)
+{
+ zbx_table_data_t *expressions;
+
+ expressions = proxyconfig_get_table(config_tables, "expressions");
+
+ if (NULL != expressions)
+ {
+ proxyconfig_prepare_table(expressions, NULL, NULL, NULL);
+
+ if (SUCCEED != proxyconfig_prepare_rows(expressions, error))
+ return FAIL;
+
+ if (SUCCEED != proxyconfig_delete_rows(expressions, error))
+ return FAIL;
+ }
+
+ if (SUCCEED != proxyconfig_sync_table(config_tables, "regexps", error))
+ return FAIL;
+
+ if (NULL == expressions)
+ return SUCCEED;
+
+ if (SUCCEED != proxyconfig_insert_rows(expressions, error))
+ return FAIL;
+
+ return proxyconfig_update_rows(expressions, error);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: force proxy to re-send host availability data if server and proxy *
+ * interface availability value is different and block proxy from *
+ * updating interface availability in database *
+ * *
+ * Parameters: td - [IN] the interface table data *
+ * *
+ ******************************************************************************/
+static void proxyconfig_check_interface_availability(zbx_table_data_t *td)
+{
+ zbx_vector_uint64_t interfaceids;
+ int i, index;
+
+ if (-1 == (index = table_data_get_field_index(td, "available")))
+ return;
+
+ zbx_vector_uint64_create(&interfaceids);
+
+ for (i = 0; i < td->updates.values_num;)
+ {
+ if (SUCCEED == zbx_flags128_isset(&td->updates.values[i]->flags, index))
+ {
+ zbx_flags128_t flags;
+
+ zbx_vector_uint64_append(&interfaceids, td->updates.values[i]->recid);
+ zbx_flags128_clear(&td->updates.values[i]->flags, index);
+
+ flags = td->updates.values[i]->flags;
+ zbx_flags128_clear(&flags, PROXYCONFIG_ROW_EXISTS);
+ if (SUCCEED == zbx_flags128_isclear(&flags))
+ {
+ zbx_vector_table_row_ptr_remove(&td->updates, i);
+ continue;
+ }
+ }
+
+ i++;
+ }
+
+ if (0 != interfaceids.values_num)
+ DCtouch_interfaces_availability(&interfaceids);
+
+ zbx_vector_uint64_destroy(&interfaceids);
+}
+
+#define ZBX_PROXYCONFIG_GET_TABLE(table) \
+ if (NULL == (table = proxyconfig_get_table(config_tables, #table))) \
+ { \
+ *error = zbx_strdup(NULL, "cannot find " #table " data"); \
+ goto out; \
+ } \
+ zbx_vector_table_data_ptr_append(&host_tables, table)
+
+/******************************************************************************
+ * *
+ * Purpose: sync host and related tables *
+ * *
+ * Parameters: config_tables - [IN] the received table data *
+ * full_sync - [IN] 1 if full sync must be done, 0 otherwise *
+ * table - [IN] the name of table to sync *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the tables were synced successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_sync_hosts(zbx_vector_table_data_ptr_t *config_tables, int full_sync, char **error)
+{
+ zbx_table_data_t *hosts, *host_inventory, *interface, *interface_snmp, *items, *item_rtdata,
+ *item_preproc, *item_parameter, *httptest, *httptestitem, *httptest_field,
+ *httpstep, *httpstepitem, *httpstep_field;
+ int i, ret = FAIL;
+ zbx_vector_table_data_ptr_t host_tables;
+
+ if (NULL == (hosts = proxyconfig_get_table(config_tables, "hosts")))
+ return SUCCEED;
+
+ zbx_vector_table_data_ptr_create(&host_tables);
+ zbx_vector_table_data_ptr_append(&host_tables, hosts);
+
+ /* host related tables must always be present (even empty) if at least one host is synced */
+ ZBX_PROXYCONFIG_GET_TABLE(host_inventory);
+ ZBX_PROXYCONFIG_GET_TABLE(interface);
+ ZBX_PROXYCONFIG_GET_TABLE(interface_snmp);
+ ZBX_PROXYCONFIG_GET_TABLE(items);
+ ZBX_PROXYCONFIG_GET_TABLE(item_rtdata);
+ ZBX_PROXYCONFIG_GET_TABLE(item_preproc);
+ ZBX_PROXYCONFIG_GET_TABLE(item_parameter);
+ ZBX_PROXYCONFIG_GET_TABLE(httptest);
+ ZBX_PROXYCONFIG_GET_TABLE(httptestitem);
+ ZBX_PROXYCONFIG_GET_TABLE(httptest_field);
+ ZBX_PROXYCONFIG_GET_TABLE(httpstep);
+ ZBX_PROXYCONFIG_GET_TABLE(httpstepitem);
+ ZBX_PROXYCONFIG_GET_TABLE(httpstep_field);
+
+ if (0 == full_sync)
+ {
+ zbx_vector_uint64_t recids, hostids, interfaceids, itemids, httptestids, httpstepids;
+ zbx_hashset_iter_t iter;
+ zbx_table_row_t *row;
+
+ zbx_vector_uint64_create(&recids);
+ zbx_vector_uint64_create(&hostids);
+ zbx_vector_uint64_create(&interfaceids);
+ zbx_vector_uint64_create(&itemids);
+ zbx_vector_uint64_create(&httptestids);
+ zbx_vector_uint64_create(&httpstepids);
+
+ zbx_hashset_iter_reset(&hosts->rows, &iter);
+ while (NULL != (row = (zbx_table_row_t *)zbx_hashset_iter_next(&iter)))
+ zbx_vector_uint64_append(&recids, row->recid);
+
+ proxyconfig_prepare_table(hosts, "hostid", &recids, &hostids);
+ proxyconfig_prepare_table(host_inventory, "hostid", &hostids, NULL);
+ proxyconfig_prepare_table(interface, "hostid", &hostids, &interfaceids);
+ proxyconfig_prepare_table(interface_snmp, "interfaceid", &interfaceids, NULL);
+
+ proxyconfig_prepare_table(items, "hostid", &hostids, &itemids);
+ proxyconfig_prepare_table(item_rtdata, "itemid", &itemids, NULL);
+ proxyconfig_prepare_table(item_preproc, "itemid", &itemids, NULL);
+ proxyconfig_prepare_table(item_parameter, "itemid", &itemids, NULL);
+
+ proxyconfig_prepare_table(httptest, "hostid", &hostids, &httptestids);
+ proxyconfig_prepare_table(httptestitem, "httptestid", &httptestids, NULL);
+ proxyconfig_prepare_table(httptest_field, "httptestid", &httptestids, NULL);
+ proxyconfig_prepare_table(httpstep, "httptestid", &httptestids, &httpstepids);
+ proxyconfig_prepare_table(httpstepitem, "httpstepid", &httpstepids, NULL);
+ proxyconfig_prepare_table(httpstep_field, "httpstepid", &httpstepids, NULL);
+
+ zbx_vector_uint64_destroy(&httpstepids);
+ zbx_vector_uint64_destroy(&httptestids);
+ zbx_vector_uint64_destroy(&itemids);
+ zbx_vector_uint64_destroy(&interfaceids);
+ zbx_vector_uint64_destroy(&hostids);
+ zbx_vector_uint64_destroy(&recids);
+ }
+ else
+ {
+ proxyconfig_prepare_table(hosts, NULL, NULL, NULL);
+ proxyconfig_prepare_table(host_inventory, NULL, NULL, NULL);
+ proxyconfig_prepare_table(interface, NULL, NULL, NULL);
+ proxyconfig_prepare_table(interface_snmp, NULL, NULL, NULL);
+
+ proxyconfig_prepare_table(items, NULL, NULL, NULL);
+ proxyconfig_prepare_table(item_rtdata, NULL, NULL, NULL);
+ proxyconfig_prepare_table(item_preproc, NULL, NULL, NULL);
+ proxyconfig_prepare_table(item_parameter, NULL, NULL, NULL);
+
+ proxyconfig_prepare_table(httptest, NULL, NULL, NULL);
+ proxyconfig_prepare_table(httptestitem, NULL, NULL, NULL);
+ proxyconfig_prepare_table(httptest_field, NULL, NULL, NULL);
+ proxyconfig_prepare_table(httpstep, NULL, NULL, NULL);
+ proxyconfig_prepare_table(httpstepitem, NULL, NULL, NULL);
+ proxyconfig_prepare_table(httpstep_field, NULL, NULL, NULL);
+ }
+
+ /* item_rtdata must be only inserted/removed and never updated */
+ zbx_vector_table_row_ptr_clear(&item_rtdata->updates);
+
+ /* interface availability changes are never updated in database, but must be marked in cache */
+ proxyconfig_check_interface_availability(interface);
+
+ /* remove rows in reverse order to avoid depending on cascaded deletes */
+ for (i = host_tables.values_num - 1; 0 <= i; i--)
+ {
+ if (SUCCEED != proxyconfig_prepare_rows(host_tables.values[i], error))
+ goto out;
+
+ if (SUCCEED != proxyconfig_delete_rows(host_tables.values[i], error))
+ goto out;
+ }
+
+ for (i = 0; i < host_tables.values_num; i++)
+ {
+ if (SUCCEED != proxyconfig_insert_rows(host_tables.values[i], error))
+ goto out;
+
+ if (SUCCEED != proxyconfig_update_rows(host_tables.values[i], error))
+ goto out;
+ }
+
+ ret = SUCCEED;
+out:
+ zbx_vector_table_data_ptr_destroy(&host_tables);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: prepare hostmacro and hosts_templates tables *
+ * *
+ * Parameters: hostmacro - [IN] the hostmacro table *
+ * hosts_templates - [IN] the hosts templates table *
+ * full_sync - [IN] 1 if full sync must be done, 0 otherwise*
+ * *
+ ******************************************************************************/
+static void proxyconfig_prepare_hostmacros(zbx_table_data_t *hostmacro, zbx_table_data_t *hosts_templates,
+ int full_sync)
+{
+ zbx_vector_uint64_t hostids, *key_ids = NULL;
+ zbx_hashset_iter_t iter;
+ zbx_table_row_t *row;
+ char *key_field = NULL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ zbx_vector_uint64_create(&hostids);
+
+ if (0 == full_sync)
+ {
+ /* limit the scope to the hosts sent with hostmacros or hosts_templates */
+ zbx_hashset_iter_reset(&hostmacro->rows, &iter);
+ while (NULL != (row = (zbx_table_row_t *)zbx_hashset_iter_next(&iter)))
+ {
+ const char *pf;
+ char buf[ZBX_MAX_UINT64_LEN + 1];
+ zbx_uint64_t hostid;
+
+ pf = zbx_json_next(&row->columns, NULL);
+
+ if (NULL != zbx_json_next_value(&row->columns, pf, buf, sizeof(buf), NULL) &&
+ SUCCEED == zbx_is_uint64(buf, &hostid))
+ {
+ zbx_vector_uint64_append(&hostids, hostid);
+ }
+ }
+
+ zbx_hashset_iter_reset(&hosts_templates->rows, &iter);
+ while (NULL != (row = (zbx_table_row_t *)zbx_hashset_iter_next(&iter)))
+ {
+ const char *pf;
+ char buf[ZBX_MAX_UINT64_LEN + 1];
+ zbx_uint64_t hostid;
+
+ pf = zbx_json_next(&row->columns, NULL);
+
+ if (NULL != zbx_json_next_value(&row->columns, pf, buf, sizeof(buf), NULL) &&
+ SUCCEED == zbx_is_uint64(buf, &hostid))
+ {
+ zbx_vector_uint64_append(&hostids, hostid);
+ }
+ }
+
+ zbx_vector_uint64_sort(&hostids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+ zbx_vector_uint64_uniq(&hostids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
+ key_ids = &hostids;
+ key_field = "hostid";
+ }
+
+ proxyconfig_prepare_table(hostmacro, key_field, key_ids, NULL);
+ proxyconfig_prepare_table(hosts_templates, key_field, key_ids, NULL);
+
+ zbx_vector_uint64_destroy(&hostids);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: sync templates by creating empty templates when necessary to link *
+ * to other templates *
+ * *
+ * Parameters: hosts_templates - [IN] the hosts_temlates data *
+ * hostmacro - [IN] the hostmacro data *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the templates were synced successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_sync_templates(zbx_table_data_t *hosts_templates, zbx_table_data_t *hostmacro, char **error)
+{
+ zbx_hashset_iter_t iter;
+ zbx_table_row_t *row;
+ zbx_vector_uint64_t templateids;
+ int ret;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ zbx_vector_uint64_create(&templateids);
+
+ zbx_hashset_iter_reset(&hosts_templates->rows, &iter);
+ while (NULL != (row = (zbx_table_row_t *)zbx_hashset_iter_next(&iter)))
+ {
+ const char *pf;
+ char buf[ZBX_MAX_UINT64_LEN + 1];
+ zbx_uint64_t templateid;
+
+ pf = zbx_json_next(&row->columns, NULL);
+
+ if (NULL != (pf = zbx_json_next_value(&row->columns, pf, buf, sizeof(buf), NULL)) &&
+ SUCCEED == zbx_is_uint64(buf, &templateid))
+ {
+ zbx_vector_uint64_append(&templateids, templateid);
+ }
+
+ if (NULL != zbx_json_next_value(&row->columns, pf, buf, sizeof(buf), NULL) &&
+ SUCCEED == zbx_is_uint64(buf, &templateid))
+ {
+ zbx_vector_uint64_append(&templateids, templateid);
+ }
+ }
+
+ zbx_hashset_iter_reset(&hostmacro->rows, &iter);
+ while (NULL != (row = (zbx_table_row_t *)zbx_hashset_iter_next(&iter)))
+ {
+ const char *pf;
+ char buf[ZBX_MAX_UINT64_LEN + 1];
+ zbx_uint64_t templateid;
+
+ pf = zbx_json_next(&row->columns, NULL);
+
+ if (NULL != zbx_json_next_value(&row->columns, pf, buf, sizeof(buf), NULL) &&
+ SUCCEED == zbx_is_uint64(buf, &templateid))
+ {
+ zbx_vector_uint64_append(&templateids, templateid);
+ }
+ }
+
+ /* check for existing templates and create empty templates if necessary */
+ if (0 != templateids.values_num)
+ {
+ DB_ROW dbrow;
+ DB_RESULT result;
+ char *sql = NULL;
+ size_t sql_alloc = 0, sql_offset = 0;
+ zbx_hashset_t templates;
+ zbx_db_insert_t db_insert;
+ int i;
+
+ zbx_hashset_create(&templates, 100, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
+ zbx_vector_uint64_sort(&templateids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+ zbx_vector_uint64_uniq(&templateids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select hostid from hosts where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", templateids.values,
+ templateids.values_num);
+
+ result = DBselect("%s", sql);
+ zbx_free(sql);
+
+ while (NULL != (dbrow = DBfetch(result)))
+ {
+ zbx_uint64_t templateid;
+
+ ZBX_STR2UINT64(templateid, dbrow[0]);
+ zbx_hashset_insert(&templates, &templateid, sizeof(templateid));
+ }
+ DBfree_result(result);
+
+ zbx_db_insert_prepare(&db_insert, "hosts", "hostid", "status", NULL);
+
+ for (i = 0; i < templateids.values_num; i++)
+ {
+ if (NULL != zbx_hashset_search(&templates, &templateids.values[i]))
+ continue;
+
+ zbx_db_insert_add_values(&db_insert, templateids.values[i], (int)HOST_STATUS_TEMPLATE);
+ }
+
+ ret = zbx_db_insert_execute(&db_insert);
+ zbx_db_insert_clean(&db_insert);
+
+ zbx_hashset_destroy(&templates);
+
+ if (SUCCEED != ret)
+ goto out;
+ }
+
+ if (SUCCEED != proxyconfig_insert_rows(hosts_templates, error))
+ goto out;
+
+ ret = proxyconfig_update_rows(hosts_templates, error);
+out:
+ zbx_vector_uint64_destroy(&templateids);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: sync received configuration data *
+ * *
+ * Parameters: config_tables - [IN] the received table data *
+ * full_sync - [IN] 1 if full sync must be done, 0 otherwise *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the tables were synced successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_sync_data(zbx_vector_table_data_ptr_t *config_tables, int full_sync, char **error)
+{
+ zbx_table_data_t *hostmacro, *hosts_templates;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ /* first sync isolated tables without relations to other tables */
+
+ if (SUCCEED != proxyconfig_sync_table(config_tables, "globalmacro", error))
+ return FAIL;
+
+ if (SUCCEED != proxyconfig_sync_table(config_tables, "config_autoreg_tls", error))
+ return FAIL;
+
+ if (SUCCEED != proxyconfig_sync_table(config_tables, "config", error))
+ return FAIL;
+
+ /* process related tables by scope */
+
+ if (SUCCEED != proxyconfig_sync_network_discovery(config_tables, error))
+ return FAIL;
+
+ if (SUCCEED != proxyconfig_sync_regexps(config_tables, error))
+ return FAIL;
+
+ if (NULL != (hostmacro = proxyconfig_get_table(config_tables, "hostmacro")))
+ {
+ if (NULL == (hosts_templates = proxyconfig_get_table(config_tables, "hosts_templates")))
+ {
+ *error = zbx_strdup(NULL, "cannot find host template data");
+ return FAIL;
+ }
+
+ proxyconfig_prepare_hostmacros(hostmacro, hosts_templates, full_sync);
+
+ if (SUCCEED != proxyconfig_prepare_rows(hostmacro, error))
+ return FAIL;
+
+ if (SUCCEED != proxyconfig_delete_rows(hostmacro, error))
+ return FAIL;
+
+ if (SUCCEED != proxyconfig_prepare_rows(hosts_templates, error))
+ return FAIL;
+
+ if (SUCCEED != proxyconfig_delete_rows(hosts_templates, error))
+ return FAIL;
+ }
+
+ if (SUCCEED != proxyconfig_sync_hosts(config_tables, full_sync, error))
+ return FAIL;
+
+ if (NULL != hostmacro)
+ {
+ if (SUCCEED != proxyconfig_sync_templates(hosts_templates, hostmacro, error))
+ return FAIL;
+
+ if (SUCCEED != proxyconfig_insert_rows(hostmacro, error))
+ return FAIL;
+
+ if (SUCCEED != proxyconfig_update_rows(hostmacro, error))
+ return FAIL;
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: delete unmonitored hosts and their contents *
+ * *
+ * Parameters: hostids - [IN] identifiers of the hosts to delete *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the hosts were deleted successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_delete_hosts(const zbx_vector_uint64_t *hostids, char **error)
+{
+ char *sql = NULL;
+ size_t sql_alloc = 0, sql_offset = 0;
+ int ret = FAIL;
+ zbx_vector_uint64_t itemids, httptestids, httpstepids;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ zbx_vector_uint64_create(&itemids);
+ zbx_vector_uint64_create(&httptestids);
+ zbx_vector_uint64_create(&httpstepids);
+
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select itemid from items where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", hostids->values, hostids->values_num);
+ DBselect_uint64(sql, &itemids);
+
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select httptestid from httptest where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", hostids->values, hostids->values_num);
+ DBselect_uint64(sql, &httptestids);
+
+ if (0 != httptestids.values_num)
+ {
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select httpstepid from httpstep where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "httptestid", httptestids.values,
+ httptestids.values_num);
+ DBselect_uint64(sql, &httpstepids);
+
+ if (0 != httpstepids.values_num)
+ {
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from httpstep_field where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "httpstepid", httpstepids.values,
+ httpstepids.values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto out;
+
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from httpstepitem where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "httpstepid", httpstepids.values,
+ httpstepids.values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto out;
+
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from httpstep where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "httpstepid", httpstepids.values,
+ httpstepids.values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto out;
+
+ }
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from httptest_field where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "httptestid", httptestids.values,
+ httptestids.values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto out;
+
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from httptestitem where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "httptestid", httptestids.values,
+ httptestids.values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto out;
+
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from httptest where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "httptestid", httptestids.values,
+ httptestids.values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto out;
+ }
+
+ if (0 != itemids.values_num)
+ {
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from item_preproc where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto out;
+
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update items set master_itemid=null where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto out;
+
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from items where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto out;
+ }
+
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from hosts where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", hostids->values, hostids->values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto out;
+
+ ret = SUCCEED;
+out:
+ zbx_free(sql);
+
+ zbx_vector_uint64_destroy(&httpstepids);
+ zbx_vector_uint64_destroy(&httptestids);
+ zbx_vector_uint64_destroy(&itemids);
+
+ if (SUCCEED != ret)
+ *error = zbx_strdup(NULL, "cannot delete hosts");
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: delete corresponding records when all macros are removed/templates*
+ * unlinked from a host *
+ * *
+ * Parameters: hostids - [IN] identifiers of the cleared hosts *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the hosts were cleared successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_delete_hostmacros(const zbx_vector_uint64_t *hostids, char **error)
+{
+ char *sql = NULL;
+ size_t sql_alloc = 0, sql_offset = 0;
+ int ret = FAIL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from hostmacro where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", hostids->values, hostids->values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto out;
+
+ sql_offset = 0;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from hosts_templates where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", hostids->values, hostids->values_num);
+ if (ZBX_DB_OK > DBexecute("%s", sql))
+ goto out;
+
+ ret = SUCCEED;
+
+out:
+ zbx_free(sql);
+
+ if (FAIL == ret)
+ *error = zbx_strdup(NULL, "cannot delete host macros");
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: delete all global macros *
+ * *
+ * Return value: SUCCEED - the global macros were deleted successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_delete_globalmacros(char **error)
+{
+ int ret;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ if (ZBX_DB_OK > DBexecute("delete from globalmacro"))
+ {
+ *error = zbx_strdup(NULL, "cannot delete global macros");
+ ret = FAIL;
+ }
+ else
+ ret = SUCCEED;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+
+ return ret;
+}
+
+#define proxyconfig_ZBX_TABLE_NUM 24
+
+/******************************************************************************
+ * *
+ * Purpose: update configuration *
+ * *
+ ******************************************************************************/
+int zbx_proxyconfig_process(const char *addr, struct zbx_json_parse *jp, char **error)
+{
+ zbx_vector_table_data_ptr_t config_tables;
+ int ret = SUCCEED, full_sync = 0, delete_globalmacros = 0, loglevel;
+ char tmp[ZBX_MAX_UINT64_LEN + 1];
+ struct zbx_json_parse jp_data = {NULL, NULL}, jp_del_hostids = {NULL, NULL},
+ jp_del_macro_hostids = {NULL, NULL};
+ zbx_uint64_t config_revision;
+ zbx_vector_uint64_t del_hostids, del_macro_hostids;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ (void)zbx_json_brackets_by_name(jp, ZBX_PROTO_TAG_DATA, &jp_data);
+ (void)zbx_json_brackets_by_name(jp, ZBX_PROTO_TAG_REMOVED_HOSTIDS, &jp_del_hostids);
+ (void)zbx_json_brackets_by_name(jp, ZBX_PROTO_TAG_REMOVED_MACRO_HOSTIDS, &jp_del_macro_hostids);
+
+ if ((NULL == jp_data.start || 1 == jp_data.end - jp_data.start) && NULL == jp_del_hostids.start &&
+ NULL == jp_del_macro_hostids.start)
+ {
+ loglevel = LOG_LEVEL_DEBUG;
+ }
+ else
+ loglevel = LOG_LEVEL_WARNING;
+
+ zabbix_log(loglevel, "received configuration data from server at \"%s\", datalen " ZBX_FS_SSIZE_T,
+ addr, jp->end - jp->start + 1);
+
+ if (1 == jp->end - jp->start)
+ {
+ /* no configuration updates */
+ goto out;
+ }
+
+ if (SUCCEED != (ret = zbx_json_value_by_name(jp, ZBX_PROTO_TAG_CONFIG_REVISION, tmp, sizeof(tmp), NULL)))
+ {
+ *error = zbx_strdup(NULL, "no config_revision tag in proxy configuration response");
+ goto out;
+ }
+
+ if (SUCCEED != (ret = zbx_is_uint64(tmp, &config_revision)))
+ {
+ *error = zbx_strdup(NULL, "invalid config_revision value in proxy configuration response");
+ goto out;
+ }
+
+ if (SUCCEED == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_FULL_SYNC, tmp, sizeof(tmp), NULL))
+ full_sync = atoi(tmp);
+
+ zbx_vector_table_data_ptr_create(&config_tables);
+ zbx_vector_table_data_ptr_reserve(&config_tables, proxyconfig_ZBX_TABLE_NUM);
+ zbx_vector_uint64_create(&del_hostids);
+ zbx_vector_uint64_create(&del_macro_hostids);
+
+ if (NULL != jp_data.start)
+ {
+ if (SUCCEED != (ret = proxyconfig_parse_data(&jp_data, &config_tables, error)))
+ goto clean;
+
+ if (SUCCEED == ZBX_CHECK_LOG_LEVEL(LOG_LEVEL_TRACE))
+ proxyconfig_dump_data(&config_tables);
+
+ proxyconfig_add_default_tables(&config_tables);
+ }
+
+ if (NULL != jp_del_hostids.start)
+ {
+ const char *p;
+ zbx_uint64_t hostid;
+
+ for (p = 0; NULL != (p = zbx_json_next_value(&jp_del_hostids, p, tmp, sizeof(tmp), NULL));)
+ {
+ if (SUCCEED == zbx_is_uint64(tmp, &hostid))
+ zbx_vector_uint64_append(&del_hostids, hostid);
+ }
+ }
+
+ if (NULL != jp_del_macro_hostids.start)
+ {
+ const char *p;
+ zbx_uint64_t hostid;
+
+ for (p = 0; NULL != (p = zbx_json_next_value(&jp_del_macro_hostids, p, tmp, sizeof(tmp), NULL));)
+ {
+ if (SUCCEED == zbx_is_uint64(tmp, &hostid))
+ {
+ if (0 != hostid)
+ zbx_vector_uint64_append(&del_macro_hostids, hostid);
+ else
+ delete_globalmacros = 1;
+ }
+ }
+ }
+
+ DBbegin();
+
+ if (0 != config_tables.values_num)
+ ret = proxyconfig_sync_data(&config_tables, full_sync, error);
+
+ if (SUCCEED == ret && 0 != del_hostids.values_num)
+ ret = proxyconfig_delete_hosts(&del_hostids, error);
+
+ if (SUCCEED == ret && 0 != del_macro_hostids.values_num)
+ ret = proxyconfig_delete_hostmacros(&del_macro_hostids, error);
+
+ if (SUCCEED == ret && 0 != delete_globalmacros)
+ ret = proxyconfig_delete_globalmacros(error);
+
+ if (SUCCEED == ret)
+ {
+ if (ZBX_DB_OK == DBcommit())
+ zbx_dc_update_received_revision(config_revision);
+ }
+ else
+ DBrollback();
+clean:
+ zbx_vector_uint64_destroy(&del_macro_hostids);
+ zbx_vector_uint64_destroy(&del_hostids);
+ zbx_vector_table_data_ptr_clear_ext(&config_tables, table_data_free);
+ zbx_vector_table_data_ptr_destroy(&config_tables);
+
+out:
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: receive configuration tables from server (passive proxies) *
+ * *
+ ******************************************************************************/
+void zbx_recv_proxyconfig(zbx_socket_t *sock, const zbx_config_tls_t *zbx_config_tls)
+{
+ struct zbx_json_parse jp_config, jp_kvs_paths = {0};
+ int ret;
+ struct zbx_json j;
+ char *error = NULL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ if (SUCCEED != check_access_passive_proxy(sock, ZBX_SEND_RESPONSE, "configuration update", zbx_config_tls))
+ goto out;
+
+ zbx_json_init(&j, 1024);
+ zbx_json_addstring(&j, ZBX_PROTO_TAG_VERSION, ZABBIX_VERSION, ZBX_JSON_TYPE_STRING);
+ zbx_json_addstring(&j, ZBX_PROTO_TAG_SESSION, zbx_dc_get_session_token(), ZBX_JSON_TYPE_STRING);
+ zbx_json_adduint64(&j, ZBX_PROTO_TAG_CONFIG_REVISION, (zbx_uint64_t)zbx_dc_get_received_revision());
+
+ if (SUCCEED != zbx_tcp_send_ext(sock, j.buffer, j.buffer_size, 0, (unsigned char)sock->protocol,
+ CONFIG_TIMEOUT))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot send proxy configuration information to sever at \"%s\": %s",
+ sock->peer, zbx_json_strerror());
+ goto out;
+ }
+
+ if (FAIL == zbx_tcp_recv_ext(sock, CONFIG_TRAPPER_TIMEOUT, ZBX_TCP_LARGE))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot receive proxy configuration data from server at \"%s\": %s",
+ sock->peer, zbx_json_strerror());
+ goto out;
+ }
+
+ if (NULL == sock->buffer)
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot parse empty proxy configuration data received from server at"
+ " \"%s\"", sock->peer);
+ zbx_send_proxy_response(sock, FAIL, "cannot parse empty data", CONFIG_TIMEOUT);
+ goto out;
+ }
+
+ if (SUCCEED != (ret = zbx_json_open(sock->buffer, &jp_config)))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot parse proxy configuration data received from server at"
+ " \"%s\": %s", sock->peer, zbx_json_strerror());
+ zbx_send_proxy_response(sock, ret, zbx_json_strerror(), CONFIG_TIMEOUT);
+ goto out;
+ }
+
+ if (SUCCEED == (ret = zbx_proxyconfig_process(sock->peer, &jp_config, &error)))
+ {
+ if (SUCCEED == zbx_rtc_reload_config_cache(&error))
+ {
+ if (SUCCEED == zbx_json_brackets_by_name(&jp_config, ZBX_PROTO_TAG_MACRO_SECRETS, &jp_kvs_paths))
+ DCsync_kvs_paths(&jp_kvs_paths);
+ }
+ else
+ {
+ THIS_SHOULD_NEVER_HAPPEN;
+ zabbix_log(LOG_LEVEL_WARNING, "cannot send message to configuration syncer: %s", error);
+ zbx_free(error);
+ }
+ }
+ else
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot process proxy onfiguration data received from server at"
+ " \"%s\": %s", sock->peer, error);
+ }
+ zbx_send_proxy_response(sock, ret, error, CONFIG_TIMEOUT);
+ zbx_free(error);
+out:
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+}
diff --git a/src/zabbix_proxy/heart/heart.h b/src/zabbix_proxy/proxyconfigwrite/proxyconfig_write.h
index 41d951cc819..c88200a340d 100644
--- a/src/zabbix_proxy/heart/heart.h
+++ b/src/zabbix_proxy/proxyconfigwrite/proxyconfig_write.h
@@ -17,22 +17,14 @@
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
-#ifndef ZABBIX_HEART_H
-#define ZABBIX_HEART_H
-
-#include "zbxthreads.h"
+#ifndef ZABBIX_PROXYCONFIG_READ_H
+#define ZABBIX_PROXYCONFIG_READ_H
#include "zbxcomms.h"
+#include "zbxjson.h"
-extern int CONFIG_HEARTBEAT_FREQUENCY;
-
-typedef struct
-{
- zbx_config_tls_t *zbx_config_tls;
- zbx_get_program_type_f zbx_get_program_type_cb_arg;
-}
-zbx_thread_heart_args;
+int zbx_proxyconfig_process(const char *addr, struct zbx_json_parse *jp, char **error);
-ZBX_THREAD_ENTRY(heart_thread, args);
+void zbx_recv_proxyconfig(zbx_socket_t *sock, const zbx_config_tls_t *zbx_config_tls);
#endif
diff --git a/src/zabbix_proxy/stats/zabbix_stats.h b/src/zabbix_proxy/stats/zabbix_stats.h
index 10b610ef9f0..608d63ad1f5 100644
--- a/src/zabbix_proxy/stats/zabbix_stats.h
+++ b/src/zabbix_proxy/stats/zabbix_stats.h
@@ -21,7 +21,8 @@
#define ZABBIX_ZABBIX_STATS_H_
#include "zbxjson.h"
+#include "zbxstats.h"
-void zbx_get_zabbix_stats_ext(struct zbx_json *json);
+void zbx_zabbix_stats_ext_get(struct zbx_json *json, const zbx_config_comms_args_t *zbx_config);
#endif /* ZABBIX_ZABBIX_STATS_H_ */
diff --git a/src/zabbix_proxy/stats/zabbix_stats_proxy.c b/src/zabbix_proxy/stats/zabbix_stats_proxy.c
index 1c230ee3162..2ab441acc48 100644
--- a/src/zabbix_proxy/stats/zabbix_stats_proxy.c
+++ b/src/zabbix_proxy/stats/zabbix_stats_proxy.c
@@ -18,22 +18,47 @@
**/
#include "zabbix_stats.h"
-
-#include "zbxcommon.h"
+#include "proxy.h"
+#include "zbxcomms.h"
+#include "zbxjson.h"
+#include "zbxstr.h"
/******************************************************************************
* *
* Purpose: get program type (proxy) specific internal statistics *
* *
- * Parameters: json - [IN/OUT] the json data *
+ * Parameters: json - [OUT] the json data *
+ * zbx_config - [IN] proxy config *
* *
* Comments: This function is used to gather proxy specific internal *
* statistics. *
* *
******************************************************************************/
-void zbx_get_zabbix_stats_ext(struct zbx_json *json)
+void zbx_zabbix_stats_ext_get(struct zbx_json *json, const zbx_config_comms_args_t *zbx_config)
{
- ZBX_UNUSED(json);
+ unsigned int encryption;
+
+ zbx_json_addstring(json, "name", ZBX_NULL2EMPTY_STR(zbx_config->hostname), ZBX_JSON_TYPE_STRING);
+
+ if (ZBX_PROXYMODE_PASSIVE == zbx_config->proxymode)
+ {
+ zbx_json_addstring(json, "passive", "true", ZBX_JSON_TYPE_INT);
+ encryption = zbx_config->zbx_config_tls->accept_modes;
+ }
+ else
+ {
+ zbx_json_addstring(json, "passive", "false", ZBX_JSON_TYPE_INT);
+ encryption = zbx_config->zbx_config_tls->connect_mode;
+ }
+
+ zbx_json_addstring(json, ZBX_TCP_SEC_UNENCRYPTED_TXT,
+ 0 < (encryption & ZBX_TCP_SEC_UNENCRYPTED) ? "true" : "false", ZBX_JSON_TYPE_INT);
+
+ zbx_json_addstring(json, ZBX_TCP_SEC_TLS_PSK_TXT,
+ 0 < (encryption & ZBX_TCP_SEC_TLS_PSK) ? "true" : "false", ZBX_JSON_TYPE_INT);
+
+ zbx_json_addstring(json, ZBX_TCP_SEC_TLS_CERT_TXT,
+ 0 < (encryption & ZBX_TCP_SEC_TLS_CERT) ? "true" : "false", ZBX_JSON_TYPE_INT);
return;
}
diff --git a/src/zabbix_proxy/taskmanager/server_tasks.c b/src/zabbix_proxy/taskmanager/server_tasks.c
index 6c4c7e2908d..d68a980fb20 100644
--- a/src/zabbix_proxy/taskmanager/server_tasks.c
+++ b/src/zabbix_proxy/taskmanager/server_tasks.c
@@ -20,24 +20,28 @@
#include "zbxtasks.h"
#include "zbxnum.h"
#include "zbxdbhigh.h"
+#include "zbxversion.h"
/******************************************************************************
* *
* Purpose: get tasks scheduled to be executed on the server *
* *
- * Parameters: tasks - [OUT] the tasks to execute *
- * proxy_hostid - [IN] (ignored) *
+ * Parameters: tasks - [OUT] the tasks to execute *
+ * proxy_hostid - [IN] (ignored) *
+ * compatibility - [IN] (ignored) *
* *
* Comments: This function is used by proxy to get tasks to be sent to the *
* server. *
* *
******************************************************************************/
-void zbx_tm_get_remote_tasks(zbx_vector_ptr_t *tasks, zbx_uint64_t proxy_hostid)
+void zbx_tm_get_remote_tasks(zbx_vector_ptr_t *tasks, zbx_uint64_t proxy_hostid,
+ zbx_proxy_compatibility_t compatibility)
{
DB_RESULT result;
DB_ROW row;
ZBX_UNUSED(proxy_hostid);
+ ZBX_UNUSED(compatibility);
result = DBselect(
"select t.taskid,t.type,t.clock,t.ttl,"
diff --git a/src/zabbix_proxy/taskmanager/taskmanager.c b/src/zabbix_proxy/taskmanager/taskmanager.c
index 09b39a005c3..ec67459511f 100644
--- a/src/zabbix_proxy/taskmanager/taskmanager.c
+++ b/src/zabbix_proxy/taskmanager/taskmanager.c
@@ -78,7 +78,7 @@ static int tm_execute_remote_command(zbx_uint64_t taskid, int clock, int ttl, in
if (NULL == (row = DBfetch(result)))
goto finish;
- task = zbx_tm_task_create(0, ZBX_TM_TASK_REMOTE_COMMAND_RESULT, ZBX_TM_STATUS_NEW, time(NULL), 0, 0);
+ task = zbx_tm_task_create(0, ZBX_TM_TASK_REMOTE_COMMAND_RESULT, ZBX_TM_STATUS_NEW, zbx_time(), 0, 0);
ZBX_STR2UINT64(parent_taskid, row[9]);
@@ -195,7 +195,7 @@ static int tm_process_check_now(zbx_vector_uint64_t *taskids)
DBfree_result(result);
if (0 != (processed_num = itemids.values_num))
- zbx_dc_reschedule_items(&itemids, time(NULL), NULL);
+ zbx_dc_reschedule_items(&itemids, zbx_time(), NULL);
if (0 != taskids->values_num)
{
@@ -223,7 +223,7 @@ static int tm_process_check_now(zbx_vector_uint64_t *taskids)
* FAIL - otherwise *
* *
******************************************************************************/
-static int tm_execute_data_json(int type, const char *data, char **info)
+static int tm_execute_data_json(int type, const char *data, char **info, const zbx_config_comms_args_t *zbx_config)
{
struct zbx_json_parse jp_data;
@@ -236,7 +236,7 @@ static int tm_execute_data_json(int type, const char *data, char **info)
switch (type)
{
case ZBX_TM_DATA_TYPE_TEST_ITEM:
- return zbx_trapper_item_test_run(&jp_data, 0, info);
+ return zbx_trapper_item_test_run(&jp_data, 0, info, zbx_config);
case ZBX_TM_DATA_TYPE_DIAGINFO:
return zbx_diag_get_info(&jp_data, info);
}
@@ -255,7 +255,8 @@ static int tm_execute_data_json(int type, const char *data, char **info)
* FAIL - otherwise *
* *
******************************************************************************/
-static int tm_execute_data(zbx_ipc_async_socket_t *rtc, zbx_uint64_t taskid, int clock, int ttl, int now)
+static int tm_execute_data(zbx_ipc_async_socket_t *rtc, zbx_uint64_t taskid, int clock, int ttl, int now,
+ const zbx_config_comms_args_t *zbx_config)
{
DB_ROW row;
DB_RESULT result;
@@ -272,7 +273,7 @@ static int tm_execute_data(zbx_ipc_async_socket_t *rtc, zbx_uint64_t taskid, int
if (NULL == (row = DBfetch(result)))
goto finish;
- task = zbx_tm_task_create(0, ZBX_TM_TASK_DATA_RESULT, ZBX_TM_STATUS_NEW, time(NULL), 0, 0);
+ task = zbx_tm_task_create(0, ZBX_TM_TASK_DATA_RESULT, ZBX_TM_STATUS_NEW, zbx_time(), 0, 0);
ZBX_STR2UINT64(parent_taskid, row[0]);
if (0 != ttl && clock + ttl < now)
@@ -285,7 +286,7 @@ static int tm_execute_data(zbx_ipc_async_socket_t *rtc, zbx_uint64_t taskid, int
{
case ZBX_TM_DATA_TYPE_TEST_ITEM:
case ZBX_TM_DATA_TYPE_DIAGINFO:
- ret = tm_execute_data_json(data_type, row[1], &info);
+ ret = tm_execute_data_json(data_type, row[1], &info, zbx_config);
break;
case ZBX_TM_DATA_TYPE_ACTIVE_PROXY_CONFIG_RELOAD:
if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_ACTIVE))
@@ -324,7 +325,7 @@ finish:
* Return value: The number of successfully processed tasks *
* *
******************************************************************************/
-static int tm_process_tasks(zbx_ipc_async_socket_t *rtc, int now)
+static int tm_process_tasks(zbx_ipc_async_socket_t *rtc, int now, const zbx_config_comms_args_t *zbx_config)
{
DB_ROW row;
DB_RESULT result;
@@ -359,7 +360,7 @@ static int tm_process_tasks(zbx_ipc_async_socket_t *rtc, int now)
zbx_vector_uint64_append(&check_now_taskids, taskid);
break;
case ZBX_TM_TASK_DATA:
- if (SUCCEED == tm_execute_data(rtc, taskid, clock, ttl, now))
+ if (SUCCEED == tm_execute_data(rtc, taskid, clock, ttl, now, zbx_config))
processed_num++;
break;
default:
@@ -440,10 +441,11 @@ ZBX_THREAD_ENTRY(taskmanager_thread, args)
get_program_type_string(taskmanager_args_in->zbx_get_program_type_cb_arg()),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
- zbx_tls_init_child(taskmanager_args_in->zbx_config_tls, taskmanager_args_in->zbx_get_program_type_cb_arg);
+ zbx_tls_init_child(taskmanager_args_in->zbx_config->zbx_config_tls,
+ taskmanager_args_in->zbx_get_program_type_cb_arg);
#endif
zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type));
DBconnect(ZBX_DB_CONNECT_NORMAL);
@@ -481,7 +483,7 @@ ZBX_THREAD_ENTRY(taskmanager_thread, args)
zbx_setproctitle("%s [processing tasks]", get_process_type_string(process_type));
- tasks_num = tm_process_tasks(&rtc, (int)sec1);
+ tasks_num = tm_process_tasks(&rtc, (int)sec1, taskmanager_args_in->zbx_config);
if (ZBX_TM_CLEANUP_PERIOD <= sec1 - cleanup_time)
{
tm_remove_old_tasks((int)sec1);
diff --git a/src/zabbix_proxy/taskmanager/taskmanager.h b/src/zabbix_proxy/taskmanager/taskmanager.h
index c4125bd1456..c8d15e359a9 100644
--- a/src/zabbix_proxy/taskmanager/taskmanager.h
+++ b/src/zabbix_proxy/taskmanager/taskmanager.h
@@ -26,7 +26,7 @@
typedef struct
{
- zbx_config_tls_t *zbx_config_tls;
+ const zbx_config_comms_args_t *zbx_config;
zbx_get_program_type_f zbx_get_program_type_cb_arg;
}
zbx_thread_taskmanager_args;
diff --git a/src/zabbix_server/Makefile.am b/src/zabbix_server/Makefile.am
index 4dbb8b72fdf..12295cfac89 100644
--- a/src/zabbix_server/Makefile.am
+++ b/src/zabbix_server/Makefile.am
@@ -27,7 +27,8 @@ SUBDIRS = \
lld \
reporter \
service \
- ha
+ ha \
+ proxyconfigread
sbin_PROGRAMS = zabbix_server
@@ -69,6 +70,7 @@ zabbix_server_LDADD = \
httppoller/libzbxhttppoller.a \
escalator/libzbxescalator.a \
proxypoller/libzbxproxypoller.a \
+ proxyconfigread/libzbxproxyconfigread.a \
selfmon/libzbxselfmon.a \
vmware/libzbxvmware.a \
taskmanager/libzbxtaskmanager.a \
diff --git a/src/zabbix_server/actions.c b/src/zabbix_server/actions.c
index 6d91f311b72..02880e50e0d 100644
--- a/src/zabbix_server/actions.c
+++ b/src/zabbix_server/actions.c
@@ -140,7 +140,7 @@ static int check_host_group_condition(const zbx_vector_ptr_t *esc_events, zbx_co
zbx_vector_uint64_t objectids, groupids;
zbx_uint64_t condition_value;
- if (CONDITION_OPERATOR_EQUAL != condition->op && CONDITION_OPERATOR_NOT_EQUAL != condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL != condition->op && ZBX_CONDITION_OPERATOR_NOT_EQUAL != condition->op)
return NOTSUPPORTED;
ZBX_STR2UINT64(condition_value, condition->value);
@@ -172,7 +172,7 @@ static int check_host_group_condition(const zbx_vector_ptr_t *esc_events, zbx_co
zbx_uint64_t objectid;
ZBX_STR2UINT64(objectid, row[0]);
- if (CONDITION_OPERATOR_NOT_EQUAL == condition->op)
+ if (ZBX_CONDITION_OPERATOR_NOT_EQUAL == condition->op)
{
int index;
@@ -188,7 +188,7 @@ static int check_host_group_condition(const zbx_vector_ptr_t *esc_events, zbx_co
}
DBfree_result(result);
- if (CONDITION_OPERATOR_NOT_EQUAL == condition->op)
+ if (ZBX_CONDITION_OPERATOR_NOT_EQUAL == condition->op)
{
int i;
@@ -330,7 +330,7 @@ static void check_object_hierarchy(int object, const zbx_vector_ptr_t *esc_event
if (value == condition_value)
{
- if (CONDITION_OPERATOR_EQUAL != condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL != condition->op)
{
int j;
@@ -375,7 +375,7 @@ static void check_object_hierarchy(int object, const zbx_vector_ptr_t *esc_event
}
/* equals are deleted so copy to result those that are left (not equals) */
- if (CONDITION_OPERATOR_NOT_EQUAL == condition->op)
+ if (ZBX_CONDITION_OPERATOR_NOT_EQUAL == condition->op)
{
for (i = 0; i < objectids->values_num; i++)
add_condition_match(esc_events, condition, objectids->values[i], object);
@@ -407,7 +407,7 @@ static int check_host_template_condition(const zbx_vector_ptr_t *esc_events, zbx
zbx_vector_uint64_t objectids;
zbx_vector_uint64_pair_t objectids_pair;
- if (CONDITION_OPERATOR_EQUAL != condition->op && CONDITION_OPERATOR_NOT_EQUAL != condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL != condition->op && ZBX_CONDITION_OPERATOR_NOT_EQUAL != condition->op)
return NOTSUPPORTED;
zbx_vector_uint64_create(&objectids);
@@ -470,9 +470,9 @@ static int check_host_condition(const zbx_vector_ptr_t *esc_events, zbx_conditio
zbx_vector_uint64_t objectids;
zbx_uint64_t condition_value;
- if (CONDITION_OPERATOR_EQUAL == condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL == condition->op)
operation = " and";
- else if (CONDITION_OPERATOR_NOT_EQUAL == condition->op)
+ else if (ZBX_CONDITION_OPERATOR_NOT_EQUAL == condition->op)
operation = " and not";
else
return NOTSUPPORTED;
@@ -530,7 +530,7 @@ static int check_trigger_id_condition(const zbx_vector_ptr_t *esc_events, zbx_co
zbx_vector_uint64_pair_t objectids_pair;
int i;
- if (CONDITION_OPERATOR_EQUAL != condition->op && CONDITION_OPERATOR_NOT_EQUAL != condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL != condition->op && ZBX_CONDITION_OPERATOR_NOT_EQUAL != condition->op)
return NOTSUPPORTED;
ZBX_STR2UINT64(condition_value, condition->value);
@@ -544,7 +544,7 @@ static int check_trigger_id_condition(const zbx_vector_ptr_t *esc_events, zbx_co
if (event->objectid == condition_value)
{
- if (CONDITION_OPERATOR_EQUAL == condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL == condition->op)
zbx_vector_uint64_append(&condition->eventids, event->eventid);
}
else
@@ -585,7 +585,7 @@ static int check_trigger_name_condition(const zbx_vector_ptr_t *esc_events, zbx_
{
int i;
- if (CONDITION_OPERATOR_LIKE != condition->op && CONDITION_OPERATOR_NOT_LIKE != condition->op)
+ if (ZBX_CONDITION_OPERATOR_LIKE != condition->op && ZBX_CONDITION_OPERATOR_NOT_LIKE != condition->op)
return NOTSUPPORTED;
for (i = 0; i < esc_events->values_num; i++)
@@ -594,11 +594,11 @@ static int check_trigger_name_condition(const zbx_vector_ptr_t *esc_events, zbx_
switch (condition->op)
{
- case CONDITION_OPERATOR_LIKE:
+ case ZBX_CONDITION_OPERATOR_LIKE:
if (NULL != strstr(event->name, condition->value))
zbx_vector_uint64_append(&condition->eventids, event->eventid);
break;
- case CONDITION_OPERATOR_NOT_LIKE:
+ case ZBX_CONDITION_OPERATOR_NOT_LIKE:
if (NULL == strstr(event->name, condition->value))
zbx_vector_uint64_append(&condition->eventids, event->eventid);
break;
@@ -633,19 +633,19 @@ static int check_trigger_severity_condition(const zbx_vector_ptr_t *esc_events,
switch (condition->op)
{
- case CONDITION_OPERATOR_EQUAL:
+ case ZBX_CONDITION_OPERATOR_EQUAL:
if (event->trigger.priority == condition_value)
zbx_vector_uint64_append(&condition->eventids, event->eventid);
break;
- case CONDITION_OPERATOR_NOT_EQUAL:
+ case ZBX_CONDITION_OPERATOR_NOT_EQUAL:
if (event->trigger.priority != condition_value)
zbx_vector_uint64_append(&condition->eventids, event->eventid);
break;
- case CONDITION_OPERATOR_MORE_EQUAL:
+ case ZBX_CONDITION_OPERATOR_MORE_EQUAL:
if (event->trigger.priority >= condition_value)
zbx_vector_uint64_append(&condition->eventids, event->eventid);
break;
- case CONDITION_OPERATOR_LESS_EQUAL:
+ case ZBX_CONDITION_OPERATOR_LESS_EQUAL:
if (event->trigger.priority <= condition_value)
zbx_vector_uint64_append(&condition->eventids, event->eventid);
break;
@@ -674,7 +674,7 @@ static int check_time_period_condition(const zbx_vector_ptr_t *esc_events, zbx_c
char *period;
int i;
- if (CONDITION_OPERATOR_IN != condition->op && CONDITION_OPERATOR_NOT_IN != condition->op)
+ if (ZBX_CONDITION_OPERATOR_IN != condition->op && ZBX_CONDITION_OPERATOR_NOT_IN != condition->op)
return NOTSUPPORTED;
period = zbx_strdup(NULL, condition->value);
@@ -690,11 +690,11 @@ static int check_time_period_condition(const zbx_vector_ptr_t *esc_events, zbx_c
{
switch (condition->op)
{
- case CONDITION_OPERATOR_IN:
+ case ZBX_CONDITION_OPERATOR_IN:
if (SUCCEED == res)
zbx_vector_uint64_append(&condition->eventids, event->eventid);
break;
- case CONDITION_OPERATOR_NOT_IN:
+ case ZBX_CONDITION_OPERATOR_NOT_IN:
if (FAIL == res)
zbx_vector_uint64_append(&condition->eventids, event->eventid);
break;
@@ -722,11 +722,11 @@ static int check_suppressed_condition(const zbx_vector_ptr_t *esc_events, zbx_co
switch (condition->op)
{
- case CONDITION_OPERATOR_YES:
+ case ZBX_CONDITION_OPERATOR_YES:
if (ZBX_PROBLEM_SUPPRESSED_TRUE == event->suppressed)
zbx_vector_uint64_append(&condition->eventids, event->eventid);
break;
- case CONDITION_OPERATOR_NO:
+ case ZBX_CONDITION_OPERATOR_NO:
if (ZBX_PROBLEM_SUPPRESSED_FALSE == event->suppressed)
zbx_vector_uint64_append(&condition->eventids, event->eventid);
break;
@@ -777,7 +777,7 @@ static int check_acknowledged_condition(const zbx_vector_ptr_t *esc_events, zbx_
ZBX_STR2UINT64(eventid, row[0]);
switch (condition->op)
{
- case CONDITION_OPERATOR_EQUAL:
+ case ZBX_CONDITION_OPERATOR_EQUAL:
zbx_vector_uint64_append(&condition->eventids, eventid);
break;
default:
@@ -806,7 +806,7 @@ static void check_condition_event_tag(const zbx_vector_ptr_t *esc_events, zbx_co
{
int i, ret, ret_continue;
- if (CONDITION_OPERATOR_NOT_EQUAL == condition->op || CONDITION_OPERATOR_NOT_LIKE == condition->op)
+ if (ZBX_CONDITION_OPERATOR_NOT_EQUAL == condition->op || ZBX_CONDITION_OPERATOR_NOT_LIKE == condition->op)
ret_continue = SUCCEED;
else
ret_continue = FAIL;
@@ -843,7 +843,7 @@ static void check_condition_event_tag_value(const zbx_vector_ptr_t *esc_events,
{
int i, ret, ret_continue;
- if (CONDITION_OPERATOR_NOT_EQUAL == condition->op || CONDITION_OPERATOR_NOT_LIKE == condition->op)
+ if (ZBX_CONDITION_OPERATOR_NOT_EQUAL == condition->op || ZBX_CONDITION_OPERATOR_NOT_LIKE == condition->op)
ret_continue = SUCCEED;
else
ret_continue = FAIL;
@@ -887,38 +887,38 @@ static void check_trigger_condition(const zbx_vector_ptr_t *esc_events, zbx_cond
switch (condition->conditiontype)
{
- case CONDITION_TYPE_HOST_GROUP:
+ case ZBX_CONDITION_TYPE_HOST_GROUP:
ret = check_host_group_condition(esc_events, condition);
break;
- case CONDITION_TYPE_HOST_TEMPLATE:
+ case ZBX_CONDITION_TYPE_HOST_TEMPLATE:
ret = check_host_template_condition(esc_events, condition);
break;
- case CONDITION_TYPE_HOST:
+ case ZBX_CONDITION_TYPE_HOST:
ret = check_host_condition(esc_events, condition);
break;
- case CONDITION_TYPE_TRIGGER:
+ case ZBX_CONDITION_TYPE_TRIGGER:
ret = check_trigger_id_condition(esc_events, condition);
break;
- case CONDITION_TYPE_TRIGGER_NAME:
+ case ZBX_CONDITION_TYPE_TRIGGER_NAME:
ret = check_trigger_name_condition(esc_events, condition);
break;
- case CONDITION_TYPE_TRIGGER_SEVERITY:
+ case ZBX_CONDITION_TYPE_TRIGGER_SEVERITY:
ret = check_trigger_severity_condition(esc_events, condition);
break;
- case CONDITION_TYPE_TIME_PERIOD:
+ case ZBX_CONDITION_TYPE_TIME_PERIOD:
ret = check_time_period_condition(esc_events, condition);
break;
- case CONDITION_TYPE_SUPPRESSED:
+ case ZBX_CONDITION_TYPE_SUPPRESSED:
ret = check_suppressed_condition(esc_events, condition);
break;
- case CONDITION_TYPE_EVENT_ACKNOWLEDGED:
+ case ZBX_CONDITION_TYPE_EVENT_ACKNOWLEDGED:
ret = check_acknowledged_condition(esc_events, condition);
break;
- case CONDITION_TYPE_EVENT_TAG:
+ case ZBX_CONDITION_TYPE_EVENT_TAG:
check_condition_event_tag(esc_events, condition);
ret = SUCCEED;
break;
- case CONDITION_TYPE_EVENT_TAG_VALUE:
+ case ZBX_CONDITION_TYPE_EVENT_TAG_VALUE:
check_condition_event_tag_value(esc_events,condition);
ret = SUCCEED;
break;
@@ -986,12 +986,12 @@ static int check_drule_condition(const zbx_vector_ptr_t *esc_events, zbx_conditi
zbx_vector_uint64_t objectids[2];
zbx_uint64_t condition_value;
- if (CONDITION_OPERATOR_EQUAL == condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL == condition->op)
{
operation_and = " and";
operation_where = " where";
}
- else if (CONDITION_OPERATOR_NOT_EQUAL == condition->op)
+ else if (ZBX_CONDITION_OPERATOR_NOT_EQUAL == condition->op)
{
operation_and = " and not";
operation_where = " where not";
@@ -1082,9 +1082,9 @@ static int check_dcheck_condition(const zbx_vector_ptr_t *esc_events, zbx_condit
zbx_vector_uint64_t objectids;
zbx_uint64_t condition_value;
- if (CONDITION_OPERATOR_EQUAL == condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL == condition->op)
operation_where = " where";
- else if (CONDITION_OPERATOR_NOT_EQUAL == condition->op)
+ else if (ZBX_CONDITION_OPERATOR_NOT_EQUAL == condition->op)
operation_where = " where not";
else
return NOTSUPPORTED;
@@ -1149,7 +1149,7 @@ static int check_dobject_condition(const zbx_vector_ptr_t *esc_events, zbx_condi
{
int i, condition_value_i = atoi(condition->value);
- if (CONDITION_OPERATOR_EQUAL != condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL != condition->op)
return NOTSUPPORTED;
for (i = 0; i < esc_events->values_num; i++)
@@ -1185,9 +1185,9 @@ static int check_proxy_condition(const zbx_vector_ptr_t *esc_events, zbx_conditi
zbx_vector_uint64_t objectids[2];
zbx_uint64_t condition_value;
- if (CONDITION_OPERATOR_EQUAL == condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL == condition->op)
operation_and = " and";
- else if (CONDITION_OPERATOR_NOT_EQUAL == condition->op)
+ else if (ZBX_CONDITION_OPERATOR_NOT_EQUAL == condition->op)
operation_and = " and not";
else
return NOTSUPPORTED;
@@ -1279,12 +1279,12 @@ static int check_dvalue_condition(const zbx_vector_ptr_t *esc_events, zbx_condit
switch (condition->op)
{
- case CONDITION_OPERATOR_EQUAL:
- case CONDITION_OPERATOR_NOT_EQUAL:
- case CONDITION_OPERATOR_MORE_EQUAL:
- case CONDITION_OPERATOR_LESS_EQUAL:
- case CONDITION_OPERATOR_LIKE:
- case CONDITION_OPERATOR_NOT_LIKE:
+ case ZBX_CONDITION_OPERATOR_EQUAL:
+ case ZBX_CONDITION_OPERATOR_NOT_EQUAL:
+ case ZBX_CONDITION_OPERATOR_MORE_EQUAL:
+ case ZBX_CONDITION_OPERATOR_LESS_EQUAL:
+ case ZBX_CONDITION_OPERATOR_LIKE:
+ case ZBX_CONDITION_OPERATOR_NOT_LIKE:
break;
default:
return NOTSUPPORTED;
@@ -1321,27 +1321,27 @@ static int check_dvalue_condition(const zbx_vector_ptr_t *esc_events, zbx_condit
switch (condition->op)
{
- case CONDITION_OPERATOR_EQUAL:
+ case ZBX_CONDITION_OPERATOR_EQUAL:
if (0 == strcmp(condition->value, row[1]))
add_condition_match(esc_events, condition, objectid, object);
break;
- case CONDITION_OPERATOR_NOT_EQUAL:
+ case ZBX_CONDITION_OPERATOR_NOT_EQUAL:
if (0 != strcmp(condition->value, row[1]))
add_condition_match(esc_events, condition, objectid, object);
break;
- case CONDITION_OPERATOR_MORE_EQUAL:
+ case ZBX_CONDITION_OPERATOR_MORE_EQUAL:
if (0 <= strcmp(row[1], condition->value))
add_condition_match(esc_events, condition, objectid, object);
break;
- case CONDITION_OPERATOR_LESS_EQUAL:
+ case ZBX_CONDITION_OPERATOR_LESS_EQUAL:
if (0 >= strcmp(row[1], condition->value))
add_condition_match(esc_events, condition, objectid, object);
break;
- case CONDITION_OPERATOR_LIKE:
+ case ZBX_CONDITION_OPERATOR_LIKE:
if (NULL != strstr(row[1], condition->value))
add_condition_match(esc_events, condition, objectid, object);
break;
- case CONDITION_OPERATOR_NOT_LIKE:
+ case ZBX_CONDITION_OPERATOR_NOT_LIKE:
if (NULL == strstr(row[1], condition->value))
add_condition_match(esc_events, condition, objectid, object);
break;
@@ -1378,7 +1378,7 @@ static int check_dhost_ip_condition(const zbx_vector_ptr_t *esc_events, zbx_cond
zbx_vector_uint64_t objectids[2];
zbx_uint64_t condition_value;
- if (CONDITION_OPERATOR_EQUAL != condition->op && CONDITION_OPERATOR_NOT_EQUAL != condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL != condition->op && ZBX_CONDITION_OPERATOR_NOT_EQUAL != condition->op)
return NOTSUPPORTED;
ZBX_STR2UINT64(condition_value, condition->value);
@@ -1425,11 +1425,11 @@ static int check_dhost_ip_condition(const zbx_vector_ptr_t *esc_events, zbx_cond
ZBX_STR2UINT64(objectid, row[0]);
switch (condition->op)
{
- case CONDITION_OPERATOR_EQUAL:
+ case ZBX_CONDITION_OPERATOR_EQUAL:
if (SUCCEED == zbx_ip_in_list(condition->value, row[1]))
add_condition_match(esc_events, condition, objectid, objects[i]);
break;
- case CONDITION_OPERATOR_NOT_EQUAL:
+ case ZBX_CONDITION_OPERATOR_NOT_EQUAL:
if (SUCCEED != zbx_ip_in_list(condition->value, row[1]))
add_condition_match(esc_events, condition, objectid, objects[i]);
break;
@@ -1467,7 +1467,7 @@ static int check_dservice_type_condition(const zbx_vector_ptr_t *esc_events, zbx
zbx_vector_uint64_t objectids;
int i, condition_value_i;
- if (CONDITION_OPERATOR_EQUAL != condition->op && CONDITION_OPERATOR_NOT_EQUAL != condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL != condition->op && ZBX_CONDITION_OPERATOR_NOT_EQUAL != condition->op)
return NOTSUPPORTED;
condition_value_i = atoi(condition->value);
@@ -1506,11 +1506,11 @@ static int check_dservice_type_condition(const zbx_vector_ptr_t *esc_events, zbx
switch (condition->op)
{
- case CONDITION_OPERATOR_EQUAL:
+ case ZBX_CONDITION_OPERATOR_EQUAL:
if (condition_value_i == tmp_int)
add_condition_match(esc_events, condition, objectid, object);
break;
- case CONDITION_OPERATOR_NOT_EQUAL:
+ case ZBX_CONDITION_OPERATOR_NOT_EQUAL:
if (condition_value_i != tmp_int)
add_condition_match(esc_events, condition, objectid, object);
break;
@@ -1547,11 +1547,11 @@ static int check_dstatus_condition(const zbx_vector_ptr_t *esc_events, zbx_condi
switch (condition->op)
{
- case CONDITION_OPERATOR_EQUAL:
+ case ZBX_CONDITION_OPERATOR_EQUAL:
if (condition_value_i == event->value)
zbx_vector_uint64_append(&condition->eventids, event->eventid);
break;
- case CONDITION_OPERATOR_NOT_EQUAL:
+ case ZBX_CONDITION_OPERATOR_NOT_EQUAL:
if (condition_value_i != event->value)
zbx_vector_uint64_append(&condition->eventids, event->eventid);
break;
@@ -1585,7 +1585,7 @@ static int check_duptime_condition(const zbx_vector_ptr_t *esc_events, zbx_condi
zbx_vector_uint64_t objectids[2];
int condition_value_i;
- if (CONDITION_OPERATOR_LESS_EQUAL != condition->op && CONDITION_OPERATOR_MORE_EQUAL != condition->op)
+ if (ZBX_CONDITION_OPERATOR_LESS_EQUAL != condition->op && ZBX_CONDITION_OPERATOR_MORE_EQUAL != condition->op)
return NOTSUPPORTED;
condition_value_i = atoi(condition->value);
@@ -1637,11 +1637,11 @@ static int check_duptime_condition(const zbx_vector_ptr_t *esc_events, zbx_condi
switch (condition->op)
{
- case CONDITION_OPERATOR_LESS_EQUAL:
+ case ZBX_CONDITION_OPERATOR_LESS_EQUAL:
if (0 != tmp_int && (now - tmp_int) <= condition_value_i)
add_condition_match(esc_events, condition, objectid, objects[i]);
break;
- case CONDITION_OPERATOR_MORE_EQUAL:
+ case ZBX_CONDITION_OPERATOR_MORE_EQUAL:
if (0 != tmp_int && (now - tmp_int) >= condition_value_i)
add_condition_match(esc_events, condition, objectid, objects[i]);
break;
@@ -1679,7 +1679,7 @@ static int check_dservice_port_condition(const zbx_vector_ptr_t *esc_events, zbx
zbx_vector_uint64_t objectids;
int i;
- if (CONDITION_OPERATOR_EQUAL != condition->op && CONDITION_OPERATOR_NOT_EQUAL != condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL != condition->op && ZBX_CONDITION_OPERATOR_NOT_EQUAL != condition->op)
return NOTSUPPORTED;
zbx_vector_uint64_create(&objectids);
@@ -1712,11 +1712,11 @@ static int check_dservice_port_condition(const zbx_vector_ptr_t *esc_events, zbx
ZBX_STR2UINT64(objectid, row[0]);
switch (condition->op)
{
- case CONDITION_OPERATOR_EQUAL:
+ case ZBX_CONDITION_OPERATOR_EQUAL:
if (SUCCEED == zbx_int_in_list(condition->value, atoi(row[1])))
add_condition_match(esc_events, condition, objectid, object);
break;
- case CONDITION_OPERATOR_NOT_EQUAL:
+ case ZBX_CONDITION_OPERATOR_NOT_EQUAL:
if (SUCCEED != zbx_int_in_list(condition->value, atoi(row[1])))
add_condition_match(esc_events, condition, objectid, object);
break;
@@ -1750,34 +1750,34 @@ static void check_discovery_condition(const zbx_vector_ptr_t *esc_events, zbx_co
switch (condition->conditiontype)
{
- case CONDITION_TYPE_DRULE:
+ case ZBX_CONDITION_TYPE_DRULE:
ret = check_drule_condition(esc_events, condition);
break;
- case CONDITION_TYPE_DCHECK:
+ case ZBX_CONDITION_TYPE_DCHECK:
ret = check_dcheck_condition(esc_events, condition);
break;
- case CONDITION_TYPE_DOBJECT:
+ case ZBX_CONDITION_TYPE_DOBJECT:
ret = check_dobject_condition(esc_events, condition);
break;
- case CONDITION_TYPE_PROXY:
+ case ZBX_CONDITION_TYPE_PROXY:
ret = check_proxy_condition(esc_events, condition);
break;
- case CONDITION_TYPE_DVALUE:
+ case ZBX_CONDITION_TYPE_DVALUE:
ret = check_dvalue_condition(esc_events, condition);
break;
- case CONDITION_TYPE_DHOST_IP:
+ case ZBX_CONDITION_TYPE_DHOST_IP:
ret = check_dhost_ip_condition(esc_events, condition);
break;
- case CONDITION_TYPE_DSERVICE_TYPE:
+ case ZBX_CONDITION_TYPE_DSERVICE_TYPE:
ret = check_dservice_type_condition(esc_events, condition);
break;
- case CONDITION_TYPE_DSTATUS:
+ case ZBX_CONDITION_TYPE_DSTATUS:
ret = check_dstatus_condition(esc_events, condition);
break;
- case CONDITION_TYPE_DUPTIME:
+ case ZBX_CONDITION_TYPE_DUPTIME:
ret = check_duptime_condition(esc_events, condition);
break;
- case CONDITION_TYPE_DSERVICE_PORT:
+ case ZBX_CONDITION_TYPE_DSERVICE_PORT:
ret = check_dservice_port_condition(esc_events, condition);
break;
default:
@@ -1819,16 +1819,16 @@ static int check_hostname_metadata_condition(const zbx_vector_ptr_t *esc_events,
switch(condition->op)
{
- case CONDITION_OPERATOR_LIKE:
- case CONDITION_OPERATOR_NOT_LIKE:
- case CONDITION_OPERATOR_REGEXP:
- case CONDITION_OPERATOR_NOT_REGEXP:
+ case ZBX_CONDITION_OPERATOR_LIKE:
+ case ZBX_CONDITION_OPERATOR_NOT_LIKE:
+ case ZBX_CONDITION_OPERATOR_REGEXP:
+ case ZBX_CONDITION_OPERATOR_NOT_REGEXP:
break;
default:
return NOTSUPPORTED;
}
- if (CONDITION_TYPE_HOST_NAME == condition->conditiontype)
+ if (ZBX_CONDITION_TYPE_HOST_NAME == condition->conditiontype)
condition_field = "host";
else
condition_field = "host_metadata";
@@ -1854,19 +1854,19 @@ static int check_hostname_metadata_condition(const zbx_vector_ptr_t *esc_events,
switch (condition->op)
{
- case CONDITION_OPERATOR_LIKE:
+ case ZBX_CONDITION_OPERATOR_LIKE:
if (NULL != strstr(row[1], condition->value))
add_condition_match(esc_events, condition, objectid, object);
break;
- case CONDITION_OPERATOR_NOT_LIKE:
+ case ZBX_CONDITION_OPERATOR_NOT_LIKE:
if (NULL == strstr(row[1], condition->value))
add_condition_match(esc_events, condition, objectid, object);
break;
- case CONDITION_OPERATOR_REGEXP:
+ case ZBX_CONDITION_OPERATOR_REGEXP:
if (NULL != zbx_regexp_match(row[1], condition->value, NULL))
add_condition_match(esc_events, condition, objectid, object);
break;
- case CONDITION_OPERATOR_NOT_REGEXP:
+ case ZBX_CONDITION_OPERATOR_NOT_REGEXP:
if (NULL == zbx_regexp_match(row[1], condition->value, NULL))
add_condition_match(esc_events, condition, objectid, object);
break;
@@ -1904,7 +1904,7 @@ static int check_areg_proxy_condition(const zbx_vector_ptr_t *esc_events, zbx_co
ZBX_STR2UINT64(condition_value, condition->value);
- if (CONDITION_OPERATOR_EQUAL != condition->op && CONDITION_OPERATOR_NOT_EQUAL != condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL != condition->op && ZBX_CONDITION_OPERATOR_NOT_EQUAL != condition->op)
return NOTSUPPORTED;
zbx_vector_uint64_create(&objectids);
@@ -1930,11 +1930,11 @@ static int check_areg_proxy_condition(const zbx_vector_ptr_t *esc_events, zbx_co
switch (condition->op)
{
- case CONDITION_OPERATOR_EQUAL:
+ case ZBX_CONDITION_OPERATOR_EQUAL:
if (id == condition_value)
add_condition_match(esc_events, condition, objectid, object);
break;
- case CONDITION_OPERATOR_NOT_EQUAL:
+ case ZBX_CONDITION_OPERATOR_NOT_EQUAL:
if (id != condition_value)
add_condition_match(esc_events, condition, objectid, object);
break;
@@ -1968,11 +1968,11 @@ static void check_autoregistration_condition(const zbx_vector_ptr_t *esc_events,
switch (condition->conditiontype)
{
- case CONDITION_TYPE_HOST_NAME:
- case CONDITION_TYPE_HOST_METADATA:
+ case ZBX_CONDITION_TYPE_HOST_NAME:
+ case ZBX_CONDITION_TYPE_HOST_METADATA:
ret = check_hostname_metadata_condition(esc_events, condition);
break;
- case CONDITION_TYPE_PROXY:
+ case ZBX_CONDITION_TYPE_PROXY:
ret = check_areg_proxy_condition(esc_events, condition);
break;
default:
@@ -2020,6 +2020,14 @@ static int is_supported_event_object(const ZBX_DB_EVENT *event)
******************************************************************************/
static int check_intern_event_type_condition(const zbx_vector_ptr_t *esc_events, zbx_condition_t *condition)
{
+/* event type action condition values */
+/* SYNC WITH PHP! */
+#define EVENT_TYPE_ITEM_NOTSUPPORTED 0
+/* #define EVENT_TYPE_ITEM_NORMAL 1 deprecated */
+#define EVENT_TYPE_LLDRULE_NOTSUPPORTED 2
+/* #define EVENT_TYPE_LLDRULE_NORMAL 3 deprecated */
+#define EVENT_TYPE_TRIGGER_UNKNOWN 4
+/* #define EVENT_TYPE_TRIGGER_NORMAL 5 deprecated */
int i;
zbx_uint64_t condition_value;
@@ -2056,6 +2064,9 @@ static int check_intern_event_type_condition(const zbx_vector_ptr_t *esc_events,
}
return SUCCEED;
+#undef EVENT_TYPE_ITEM_NOTSUPPORTED
+#undef EVENT_TYPE_LLDRULE_NOTSUPPORTED
+#undef EVENT_TYPE_TRIGGER_UNKNOWN
}
/******************************************************************************
@@ -2118,7 +2129,7 @@ static int check_intern_host_group_condition(const zbx_vector_ptr_t *esc_events,
zbx_vector_uint64_t objectids[3], groupids;
zbx_uint64_t condition_value;
- if (CONDITION_OPERATOR_EQUAL != condition->op && CONDITION_OPERATOR_NOT_EQUAL != condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL != condition->op && ZBX_CONDITION_OPERATOR_NOT_EQUAL != condition->op)
return NOTSUPPORTED;
ZBX_STR2UINT64(condition_value, condition->value);
@@ -2176,7 +2187,7 @@ static int check_intern_host_group_condition(const zbx_vector_ptr_t *esc_events,
zbx_uint64_t objectid;
ZBX_STR2UINT64(objectid, row[0]);
- if (CONDITION_OPERATOR_NOT_EQUAL == condition->op)
+ if (ZBX_CONDITION_OPERATOR_NOT_EQUAL == condition->op)
{
int index;
@@ -2194,7 +2205,7 @@ static int check_intern_host_group_condition(const zbx_vector_ptr_t *esc_events,
for (i = 0; i < (int)ARRSIZE(objects); i++)
{
- if (CONDITION_OPERATOR_NOT_EQUAL == condition->op)
+ if (ZBX_CONDITION_OPERATOR_NOT_EQUAL == condition->op)
{
int j;
@@ -2261,7 +2272,7 @@ static int check_intern_host_template_condition(const zbx_vector_ptr_t *esc_even
zbx_vector_uint64_t objectids[3];
zbx_vector_uint64_pair_t objectids_pair[3];
- if (CONDITION_OPERATOR_EQUAL != condition->op && CONDITION_OPERATOR_NOT_EQUAL != condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL != condition->op && ZBX_CONDITION_OPERATOR_NOT_EQUAL != condition->op)
return NOTSUPPORTED;
for (i = 0; i < (int)ARRSIZE(objects); i++)
@@ -2352,12 +2363,12 @@ static int check_intern_host_condition(const zbx_vector_ptr_t *esc_events, zbx_c
zbx_vector_uint64_t objectids[3];
zbx_uint64_t condition_value;
- if (CONDITION_OPERATOR_EQUAL == condition->op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL == condition->op)
{
operation = " and";
operation_item = " where";
}
- else if (CONDITION_OPERATOR_NOT_EQUAL == condition->op)
+ else if (ZBX_CONDITION_OPERATOR_NOT_EQUAL == condition->op)
{
operation = " and not";
operation_item = " where not";
@@ -2445,23 +2456,23 @@ static void check_internal_condition(const zbx_vector_ptr_t *esc_events, zbx_con
switch (condition->conditiontype)
{
- case CONDITION_TYPE_EVENT_TYPE:
+ case ZBX_CONDITION_TYPE_EVENT_TYPE:
ret = check_intern_event_type_condition(esc_events, condition);
break;
- case CONDITION_TYPE_HOST_GROUP:
+ case ZBX_CONDITION_TYPE_HOST_GROUP:
ret = check_intern_host_group_condition(esc_events, condition);
break;
- case CONDITION_TYPE_HOST_TEMPLATE:
+ case ZBX_CONDITION_TYPE_HOST_TEMPLATE:
ret = check_intern_host_template_condition(esc_events, condition);
break;
- case CONDITION_TYPE_HOST:
+ case ZBX_CONDITION_TYPE_HOST:
ret = check_intern_host_condition(esc_events, condition);
break;
- case CONDITION_TYPE_EVENT_TAG:
+ case ZBX_CONDITION_TYPE_EVENT_TAG:
check_condition_event_tag(esc_events, condition);
ret = SUCCEED;
break;
- case CONDITION_TYPE_EVENT_TAG_VALUE:
+ case ZBX_CONDITION_TYPE_EVENT_TAG_VALUE:
check_condition_event_tag_value(esc_events,condition);
ret = SUCCEED;
break;
@@ -2575,15 +2586,15 @@ static int check_action_conditions(zbx_uint64_t eventid, const zbx_action_eval_t
zabbix_log(LOG_LEVEL_DEBUG, "In %s() actionid:" ZBX_FS_UI64 " eventsource:%d", __func__,
action->actionid, (int)action->eventsource);
- if (CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
expression = zbx_strdup(expression, action->formula);
for (i = 0; i < action->conditions.values_num; i++)
{
condition = (zbx_condition_t *)action->conditions.values[i];
- if (CONDITION_EVAL_TYPE_AND_OR == action->evaltype && old_type == condition->conditiontype &&
- SUCCEED == ret)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == action->evaltype &&
+ old_type == condition->conditiontype && SUCCEED == ret)
{
continue; /* short-circuit true OR condition block to the next AND condition */
}
@@ -2597,8 +2608,8 @@ static int check_action_conditions(zbx_uint64_t eventid, const zbx_action_eval_t
switch (action->evaltype)
{
- case CONDITION_EVAL_TYPE_AND_OR:
- if (old_type == condition->conditiontype) /* assume conditions are sorted by type */
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR:
+ if (old_type == condition->conditiontype) /* assume conditions are sorted by type */
{
if (SUCCEED == condition_result)
ret = SUCCEED;
@@ -2613,7 +2624,7 @@ static int check_action_conditions(zbx_uint64_t eventid, const zbx_action_eval_t
}
break;
- case CONDITION_EVAL_TYPE_AND:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_AND:
if (FAIL == condition_result) /* break if any AND condition is FALSE */
{
ret = FAIL;
@@ -2621,7 +2632,7 @@ static int check_action_conditions(zbx_uint64_t eventid, const zbx_action_eval_t
}
break;
- case CONDITION_EVAL_TYPE_OR:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_OR:
if (SUCCEED == condition_result) /* break if any OR condition is TRUE */
{
ret = SUCCEED;
@@ -2630,7 +2641,7 @@ static int check_action_conditions(zbx_uint64_t eventid, const zbx_action_eval_t
ret = FAIL;
break;
- case CONDITION_EVAL_TYPE_EXPRESSION:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION:
zbx_snprintf(tmp, sizeof(tmp), "{" ZBX_FS_UI64 "}", condition->conditionid);
id_len = strlen(tmp);
@@ -2647,7 +2658,7 @@ static int check_action_conditions(zbx_uint64_t eventid, const zbx_action_eval_t
}
}
- if (CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
{
if (SUCCEED == zbx_evaluate(&eval_result, expression, error, sizeof(error), NULL))
ret = (SUCCEED != zbx_double_compare(eval_result, 0) ? SUCCEED : FAIL);
@@ -3041,7 +3052,7 @@ static void prepare_actions_conditions_eval(zbx_vector_ptr_t *actions, zbx_hashs
}
else
{
- if (CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
{
char search[ZBX_MAX_UINT64_LEN + 2];
char replace[ZBX_MAX_UINT64_LEN + 2];
diff --git a/src/zabbix_server/alerter/alert_manager.c b/src/zabbix_server/alerter/alert_manager.c
index c0799de6302..9a40b39246b 100644
--- a/src/zabbix_server/alerter/alert_manager.c
+++ b/src/zabbix_server/alerter/alert_manager.c
@@ -2251,7 +2251,7 @@ ZBX_THREAD_ENTRY(alert_manager_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
if (FAIL == am_init(&manager, &error))
{
@@ -2324,9 +2324,9 @@ ZBX_THREAD_ENTRY(alert_manager_thread, args)
time_mediatype = now;
}
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
ret = zbx_ipc_service_recv(&manager.ipc, &timeout, &client, &message);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
sec = zbx_time();
zbx_update_env(sec);
diff --git a/src/zabbix_server/alerter/alert_syncer.c b/src/zabbix_server/alerter/alert_syncer.c
index 684ac2bac0f..df66a409690 100644
--- a/src/zabbix_server/alerter/alert_syncer.c
+++ b/src/zabbix_server/alerter/alert_syncer.c
@@ -627,7 +627,7 @@ static void am_db_validate_tags_for_update(zbx_vector_events_tags_t *update_even
for (j = 0; j < local_event_tags->tags.values_num; j++)
{
- tag = (zbx_tag_t *)(local_event_tags->tags).values[j];
+ tag = local_event_tags->tags.values[j];
zbx_db_insert_add_values(db_event, __UINT64_C(0), local_event_tags->eventid, tag->tag,
tag->value);
diff --git a/src/zabbix_server/alerter/alerter.c b/src/zabbix_server/alerter/alerter.c
index 157b516871d..01880350760 100644
--- a/src/zabbix_server/alerter/alerter.c
+++ b/src/zabbix_server/alerter/alerter.c
@@ -299,7 +299,7 @@ ZBX_THREAD_ENTRY(alerter_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type));
@@ -320,7 +320,7 @@ ZBX_THREAD_ENTRY(alerter_thread, args)
zbx_setproctitle("%s #%d started", get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
while (ZBX_IS_RUNNING())
{
@@ -338,7 +338,7 @@ ZBX_THREAD_ENTRY(alerter_thread, args)
fail_num = 0;
}
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
if (SUCCEED != zbx_ipc_socket_read(&alerter_socket, &message))
{
@@ -346,7 +346,7 @@ ZBX_THREAD_ENTRY(alerter_thread, args)
exit(EXIT_FAILURE);
}
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
time_read = zbx_time();
time_idle += time_read - time_now;
diff --git a/src/zabbix_server/availability/avail_manager.c b/src/zabbix_server/availability/avail_manager.c
index 88726502a4b..8f2526fd8fa 100644
--- a/src/zabbix_server/availability/avail_manager.c
+++ b/src/zabbix_server/availability/avail_manager.c
@@ -418,7 +418,7 @@ ZBX_THREAD_ENTRY(availability_manager_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num);
@@ -461,9 +461,9 @@ ZBX_THREAD_ENTRY(availability_manager_thread, args)
processed_num = 0;
}
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
ret = zbx_ipc_service_recv(&service, &timeout, &client, &message);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
sec = zbx_time();
zbx_update_env(sec);
diff --git a/src/zabbix_server/dbconfig/Makefile.am b/src/zabbix_server/dbconfig/Makefile.am
index e7cf0ff9301..279f9f08e16 100644
--- a/src/zabbix_server/dbconfig/Makefile.am
+++ b/src/zabbix_server/dbconfig/Makefile.am
@@ -5,3 +5,5 @@ noinst_LIBRARIES = libzbxdbconfig.a
libzbxdbconfig_a_SOURCES = \
dbconfig.c \
dbconfig.h
+
+libzbxdbconfig_a_CFLAGS = -I$(top_srcdir)/src/libs/zbxdbcache
diff --git a/src/zabbix_server/dbconfig/dbconfig.c b/src/zabbix_server/dbconfig/dbconfig.c
index 885a4f4dd00..adeb3b2fe9f 100644
--- a/src/zabbix_server/dbconfig/dbconfig.c
+++ b/src/zabbix_server/dbconfig/dbconfig.c
@@ -25,6 +25,7 @@
#include "dbcache.h"
#include "zbxrtc.h"
#include "zbxtime.h"
+#include "valuecache.h"
extern int CONFIG_CONFSYNCER_FREQUENCY;
extern ZBX_THREAD_LOCAL unsigned char process_type;
@@ -41,7 +42,7 @@ extern ZBX_THREAD_LOCAL int server_num, process_num;
ZBX_THREAD_ENTRY(dbconfig_thread, args)
{
double sec = 0.0;
- int nextcheck = 0, sleeptime, secrets_reload = 0;
+ int nextcheck = 0, sleeptime, secrets_reload = 0, cache_reload = 0;
zbx_ipc_async_socket_t rtc;
process_type = ((zbx_thread_args_t *)args)->process_type;
@@ -51,7 +52,7 @@ ZBX_THREAD_ENTRY(dbconfig_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
zbx_rtc_subscribe(&rtc, process_type, process_num);
@@ -61,7 +62,7 @@ ZBX_THREAD_ENTRY(dbconfig_thread, args)
sec = zbx_time();
zbx_setproctitle("%s [syncing configuration]", get_process_type_string(process_type));
- DCsync_configuration(ZBX_DBSYNC_INIT, ZBX_SYNCED_NEW_CONFIG_NO);
+ DCsync_configuration(ZBX_DBSYNC_INIT, ZBX_SYNCED_NEW_CONFIG_NO, NULL);
DCsync_kvs_paths(NULL);
zbx_setproctitle("%s [synced configuration in " ZBX_FS_DBL " sec, idle %d sec]",
get_process_type_string(process_type), (sec = zbx_time() - sec), CONFIG_CONFSYNCER_FREQUENCY);
@@ -81,10 +82,10 @@ ZBX_THREAD_ENTRY(dbconfig_thread, args)
{
if (ZBX_RTC_CONFIG_CACHE_RELOAD == rtc_cmd)
{
- if (0 != nextcheck)
+ if (0 == cache_reload)
{
zabbix_log(LOG_LEVEL_WARNING, "forced reloading of the configuration cache");
- nextcheck = 0;
+ cache_reload = 1;
}
else
zabbix_log(LOG_LEVEL_WARNING, "configuration cache reloading is already in progress");
@@ -113,15 +114,29 @@ ZBX_THREAD_ENTRY(dbconfig_thread, args)
if (0 == secrets_reload)
{
- DCsync_configuration(ZBX_DBSYNC_UPDATE, ZBX_SYNCED_NEW_CONFIG_YES);
+ zbx_vector_uint64_t deleted_itemids;
+
+ zbx_vector_uint64_create(&deleted_itemids);
+
+ DCsync_configuration(ZBX_DBSYNC_UPDATE, ZBX_SYNCED_NEW_CONFIG_YES, &deleted_itemids);
DCsync_kvs_paths(NULL);
DCupdate_interfaces_availability();
nextcheck = (int)time(NULL) + CONFIG_CONFSYNCER_FREQUENCY;
+
+ zbx_vc_remove_items_by_ids(&deleted_itemids);
+ zbx_vector_uint64_destroy(&deleted_itemids);
+
+ if (0 != cache_reload)
+ {
+ cache_reload = 0;
+ zabbix_log(LOG_LEVEL_WARNING, "finished forced reloading of the configuration cache");
+ }
}
else
{
DCsync_kvs_paths(NULL);
secrets_reload = 0;
+ zabbix_log(LOG_LEVEL_WARNING, "finished forced reloading of the secrets");
}
sec = zbx_time() - sec;
diff --git a/src/zabbix_server/dbsyncer/dbsyncer.c b/src/zabbix_server/dbsyncer/dbsyncer.c
index fa951cb7142..6edf51720c6 100644
--- a/src/zabbix_server/dbsyncer/dbsyncer.c
+++ b/src/zabbix_server/dbsyncer/dbsyncer.c
@@ -97,7 +97,7 @@ ZBX_THREAD_ENTRY(dbsyncer_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type), server_num,
(process_name = get_process_type_string(process_type)), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
#define STAT_INTERVAL 5 /* if a process is busy and does not sleep then update status not faster than */
/* once in STAT_INTERVAL seconds */
diff --git a/src/zabbix_server/discoverer/discoverer.c b/src/zabbix_server/discoverer/discoverer.c
index f48603e9609..fc94395d889 100644
--- a/src/zabbix_server/discoverer/discoverer.c
+++ b/src/zabbix_server/discoverer/discoverer.c
@@ -34,7 +34,6 @@
#include "zbxip.h"
#include "zbxsysinfo.h"
-extern int CONFIG_DISCOVERER_FORKS;
extern ZBX_THREAD_LOCAL unsigned char process_type;
extern unsigned char program_type;
extern ZBX_THREAD_LOCAL int server_num, process_num;
@@ -122,7 +121,7 @@ static int discover_service(const DB_DCHECK *dcheck, char *ip, int port, char **
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
- init_result(&result);
+ zbx_init_agent_result(&result);
**value = '\0';
@@ -198,8 +197,8 @@ static int discover_service(const DB_DCHECK *dcheck, char *ip, int port, char **
case SVC_TELNET:
zbx_snprintf(key, sizeof(key), "net.tcp.service[%s,%s,%d]", service, ip, port);
- if (SUCCEED != process(key, 0, &result) || NULL == ZBX_GET_UI64_RESULT(&result) ||
- 0 == result.ui64)
+ if (SUCCEED != zbx_execute_agent_check(key, 0, &result) || NULL ==
+ ZBX_GET_UI64_RESULT(&result) || 0 == result.ui64)
{
ret = FAIL;
}
@@ -335,7 +334,7 @@ static int discover_service(const DB_DCHECK *dcheck, char *ip, int port, char **
zbx_alarm_off();
}
- free_result(&result);
+ zbx_free_agent_result(&result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
@@ -749,117 +748,80 @@ out:
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
}
-static int process_discovery(void)
+static int process_discovery(time_t *nextcheck)
{
DB_RESULT result;
DB_ROW row;
- int rule_count = 0;
+ int rule_count = 0, delay;
char *delay_str = NULL;
zbx_dc_um_handle_t *um_handle;
+ zbx_uint64_t druleid;
+ time_t now;
- result = DBselect(
- "select distinct r.druleid,r.iprange,r.name,c.dcheckid,r.proxy_hostid,r.delay"
- " from drules r"
- " left join dchecks c"
- " on c.druleid=r.druleid"
- " and c.uniq=1"
- " where r.status=%d"
- " and r.nextcheck<=%d"
- " and " ZBX_SQL_MOD(r.druleid,%d) "=%d",
- DRULE_STATUS_MONITORED,
- (int)time(NULL),
- CONFIG_DISCOVERER_FORKS,
- process_num - 1);
+ now = time(NULL);
+
+ if (SUCCEED != zbx_dc_drule_next(now, &druleid, nextcheck))
+ return 0;
um_handle = zbx_dc_open_user_macros();
- while (ZBX_IS_RUNNING() && NULL != (row = DBfetch(result)))
+ do
{
- int now, delay;
- zbx_uint64_t druleid;
-
- rule_count++;
-
- ZBX_STR2UINT64(druleid, row[0]);
-
- delay_str = zbx_strdup(delay_str, row[5]);
- zbx_substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- &delay_str, MACRO_TYPE_COMMON, NULL, 0);
-
- if (SUCCEED != zbx_is_time_suffix(delay_str, &delay, ZBX_LENGTH_UNLIMITED))
+ result = DBselect(
+ "select distinct r.iprange,r.name,c.dcheckid,r.delay"
+ " from drules r"
+ " left join dchecks c"
+ " on c.druleid=r.druleid"
+ " and c.uniq=1"
+ " where r.druleid=" ZBX_FS_UI64, druleid);
+
+ if (NULL != (row = DBfetch(result)))
{
- zabbix_log(LOG_LEVEL_WARNING, "discovery rule \"%s\": invalid update interval \"%s\"",
- row[2], delay_str);
+ ZBX_DB_DRULE drule;
- now = (int)time(NULL);
+ rule_count++;
- DBexecute("update drules set nextcheck=%d where druleid=" ZBX_FS_UI64,
- 0 > now ? ZBX_JAN_2038 : now + SEC_PER_MIN, druleid);
+ delay_str = zbx_strdup(delay_str, row[3]);
+ zbx_substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ &delay_str, MACRO_TYPE_COMMON, NULL, 0);
- continue;
- }
+ if (SUCCEED != zbx_is_time_suffix(delay_str, &delay, ZBX_LENGTH_UNLIMITED))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "discovery rule \"%s\": invalid update interval \"%s\"",
+ row[1], delay_str);
- if (SUCCEED == DBis_null(row[4]))
- {
- ZBX_DB_DRULE drule;
+ delay = ZBX_DEFAULT_INTERVAL;
+ }
+ else
+ {
+ memset(&drule, 0, sizeof(drule));
- memset(&drule, 0, sizeof(drule));
+ drule.druleid = druleid;
+ drule.iprange = row[0];
+ drule.name = row[1];
+ ZBX_DBROW2UINT64(drule.unique_dcheckid, row[2]);
- drule.druleid = druleid;
- drule.iprange = row[1];
- drule.name = row[2];
- ZBX_DBROW2UINT64(drule.unique_dcheckid, row[3]);
+ process_rule(&drule);
+ }
- process_rule(&drule);
- }
+ zbx_dc_drule_queue(now, druleid, delay);
+ zbx_free(delay_str);
- if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
- discovery_clean_services(druleid);
+ if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
+ discovery_clean_services(druleid);
- now = (int)time(NULL);
- if (0 > now + delay)
- {
- zabbix_log(LOG_LEVEL_WARNING, "discovery rule \"%s\": nextcheck update causes overflow",
- row[2]);
- DBexecute("update drules set nextcheck=%d where druleid=" ZBX_FS_UI64, ZBX_JAN_2038, druleid);
}
- else
- DBexecute("update drules set nextcheck=%d where druleid=" ZBX_FS_UI64, now + delay, druleid);
+ DBfree_result(result);
+
+ now = time(NULL);
}
- DBfree_result(result);
+ while (ZBX_IS_RUNNING() && SUCCEED == zbx_dc_drule_next(now, &druleid, nextcheck));
zbx_dc_close_user_macros(um_handle);
- zbx_free(delay_str);
-
return rule_count; /* performance metric */
}
-static int get_minnextcheck(void)
-{
- DB_RESULT result;
- DB_ROW row;
- int res = FAIL;
-
- result = DBselect(
- "select count(*),min(nextcheck)"
- " from drules"
- " where status=%d"
- " and " ZBX_SQL_MOD(druleid,%d) "=%d",
- DRULE_STATUS_MONITORED, CONFIG_DISCOVERER_FORKS, process_num - 1);
-
- row = DBfetch(result);
-
- if (NULL == row || DBis_null(row[0]) == SUCCEED || DBis_null(row[1]) == SUCCEED)
- zabbix_log(LOG_LEVEL_DEBUG, "get_minnextcheck(): no items to update");
- else if (0 != atoi(row[0]))
- res = atoi(row[1]);
-
- DBfree_result(result);
-
- return res;
-}
-
/******************************************************************************
* *
* Purpose: periodically try to find new hosts and services *
@@ -869,9 +831,9 @@ ZBX_THREAD_ENTRY(discoverer_thread, args)
{
zbx_thread_discoverer_args *discoverer_args_in = (zbx_thread_discoverer_args *)
(((zbx_thread_args_t *)args)->args);
- int nextcheck = 0, sleeptime = -1, rule_count = 0, old_rule_count = 0;
+ int sleeptime = -1, rule_count = 0, old_rule_count = 0;
double sec, total_sec = 0.0, old_total_sec = 0.0;
- time_t last_stat_time;
+ time_t last_stat_time, nextcheck = 0;
zbx_ipc_async_socket_t rtc;
process_type = ((zbx_thread_args_t *)args)->process_type;
@@ -882,7 +844,7 @@ ZBX_THREAD_ENTRY(discoverer_thread, args)
get_program_type_string(discoverer_args_in->zbx_get_program_type_cb_arg()), server_num,
get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
#define STAT_INTERVAL 5 /* if a process is busy and does not sleep then update status not faster than */
/* once in STAT_INTERVAL seconds */
@@ -914,10 +876,10 @@ ZBX_THREAD_ENTRY(discoverer_thread, args)
if ((int)sec >= nextcheck)
{
- rule_count += process_discovery();
+ rule_count += process_discovery(&nextcheck);
total_sec += zbx_time() - sec;
- if (FAIL == (nextcheck = get_minnextcheck()))
+ if (0 == nextcheck)
nextcheck = time(NULL) + DISCOVERER_DELAY;
}
diff --git a/src/zabbix_server/escalator/escalator.c b/src/zabbix_server/escalator/escalator.c
index 2bb94d9897b..fb2608dbac4 100644
--- a/src/zabbix_server/escalator/escalator.c
+++ b/src/zabbix_server/escalator/escalator.c
@@ -250,7 +250,7 @@ static int check_tag_based_permission(zbx_uint64_t userid, zbx_vector_uint64_t *
DBfree_result(result);
if (0 < tag_filters.values_num)
- condition.op = CONDITION_OPERATOR_EQUAL;
+ condition.op = ZBX_CONDITION_OPERATOR_EQUAL;
else
ret = SUCCEED;
@@ -270,13 +270,13 @@ static int check_tag_based_permission(zbx_uint64_t userid, zbx_vector_uint64_t *
if (NULL != tag_filter->value && 0 != strlen(tag_filter->value))
{
- condition.conditiontype = CONDITION_TYPE_EVENT_TAG_VALUE;
+ condition.conditiontype = ZBX_CONDITION_TYPE_EVENT_TAG_VALUE;
condition.value2 = tag_filter->tag;
condition.value = tag_filter->value;
}
else
{
- condition.conditiontype = CONDITION_TYPE_EVENT_TAG;
+ condition.conditiontype = ZBX_CONDITION_TYPE_EVENT_TAG;
condition.value = tag_filter->tag;
}
@@ -1801,7 +1801,7 @@ static int check_operation_conditions(const ZBX_DB_EVENT *event, zbx_uint64_t op
DB_ROW row;
zbx_condition_t condition;
- int ret = SUCCEED; /* SUCCEED required for CONDITION_EVAL_TYPE_AND_OR */
+ int ret = SUCCEED; /* SUCCEED required for ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR */
int cond, exit = 0;
unsigned char old_type = 0xff;
@@ -1827,7 +1827,7 @@ static int check_operation_conditions(const ZBX_DB_EVENT *event, zbx_uint64_t op
switch (evaltype)
{
- case CONDITION_EVAL_TYPE_AND_OR:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR:
if (old_type == condition.conditiontype) /* OR conditions */
{
if (SUCCEED == check_action_condition(event, &condition))
@@ -1843,7 +1843,7 @@ static int check_operation_conditions(const ZBX_DB_EVENT *event, zbx_uint64_t op
}
old_type = condition.conditiontype;
break;
- case CONDITION_EVAL_TYPE_AND:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_AND:
cond = check_action_condition(event, &condition);
/* Break if any of AND conditions is FALSE */
if (cond == FAIL)
@@ -1854,7 +1854,7 @@ static int check_operation_conditions(const ZBX_DB_EVENT *event, zbx_uint64_t op
else
ret = SUCCEED;
break;
- case CONDITION_EVAL_TYPE_OR:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_OR:
cond = check_action_condition(event, &condition);
/* Break if any of OR conditions is TRUE */
if (cond == SUCCEED)
@@ -3447,7 +3447,7 @@ ZBX_THREAD_ENTRY(escalator_thread, args)
get_program_type_string(escalator_args_in->zbx_get_program_type_cb_arg()), server_num,
get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
#define STAT_INTERVAL 5 /* if a process is busy and does not sleep then update status not faster than */
/* once in STAT_INTERVAL seconds */
diff --git a/src/zabbix_server/events.c b/src/zabbix_server/events.c
index 0a301706578..afda25b219e 100644
--- a/src/zabbix_server/events.c
+++ b/src/zabbix_server/events.c
@@ -749,7 +749,7 @@ static const char *correlation_condition_match_new_event(zbx_corr_condition_t *c
case ZBX_CORR_CONDITION_NEW_EVENT_HOSTGROUP:
ret = correlation_match_event_hostgroup(event, condition->data.group.groupid);
- if (CONDITION_OPERATOR_NOT_EQUAL == condition->data.group.op)
+ if (ZBX_CONDITION_OPERATOR_NOT_EQUAL == condition->data.group.op)
return (SUCCEED == ret ? "0" : "1");
return (SUCCEED == ret ? "1" : "0");
@@ -866,19 +866,19 @@ static int correlation_has_old_event_operation(const zbx_correlation_t *correlat
return FAIL;
}
-/******************************************************************************
- * *
- * Purpose: adds sql statement to match tag according to the defined *
- * matching operation *
- * *
- * Parameters: sql - [IN/OUT] *
- * sql_alloc - [IN/OUT] *
- * sql_offset - [IN/OUT] *
- * tag - [IN] the tag to match *
- * value - [IN] the tag value to match *
- * op - [IN] the matching operation (CONDITION_OPERATOR_)*
- * *
- ******************************************************************************/
+/***********************************************************************************
+ * *
+ * Purpose: adds sql statement to match tag according to the defined *
+ * matching operation *
+ * *
+ * Parameters: sql - [IN/OUT] *
+ * sql_alloc - [IN/OUT] *
+ * sql_offset - [IN/OUT] *
+ * tag - [IN] the tag to match *
+ * value - [IN] the tag value to match *
+ * op - [IN] the matching operation (ZBX_CONDITION_OPERATOR_) *
+ * *
+ ***********************************************************************************/
static void correlation_condition_add_tag_match(char **sql, size_t *sql_alloc, size_t *sql_offset, const char *tag,
const char *value, unsigned char op)
{
@@ -889,8 +889,8 @@ static void correlation_condition_add_tag_match(char **sql, size_t *sql_alloc, s
switch (op)
{
- case CONDITION_OPERATOR_NOT_EQUAL:
- case CONDITION_OPERATOR_NOT_LIKE:
+ case ZBX_CONDITION_OPERATOR_NOT_EQUAL:
+ case ZBX_CONDITION_OPERATOR_NOT_LIKE:
zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "not ");
break;
}
@@ -900,13 +900,13 @@ static void correlation_condition_add_tag_match(char **sql, size_t *sql_alloc, s
switch (op)
{
- case CONDITION_OPERATOR_EQUAL:
- case CONDITION_OPERATOR_NOT_EQUAL:
+ case ZBX_CONDITION_OPERATOR_EQUAL:
+ case ZBX_CONDITION_OPERATOR_NOT_EQUAL:
zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "pt.tag='%s' and pt.value" ZBX_SQL_STRCMP,
tag_esc, ZBX_SQL_STRVAL_EQ(value_esc));
break;
- case CONDITION_OPERATOR_LIKE:
- case CONDITION_OPERATOR_NOT_LIKE:
+ case ZBX_CONDITION_OPERATOR_LIKE:
+ case ZBX_CONDITION_OPERATOR_NOT_LIKE:
zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "pt.tag='%s' and pt.value like '%%%s%%'",
tag_esc, value_esc);
break;
diff --git a/src/zabbix_server/ha/ha.h b/src/zabbix_server/ha/ha.h
index cc4588becba..0f2ae3497fb 100644
--- a/src/zabbix_server/ha/ha.h
+++ b/src/zabbix_server/ha/ha.h
@@ -28,16 +28,27 @@ typedef struct
}
zbx_cuid_t;
+typedef struct
+{
+ char *ha_node_name;
+ char *ha_node_address;
+ char *default_node_ip;
+ int default_node_port;
+ int ha_status;
+}
+zbx_ha_config_t;
+
#define zbx_cuid_empty(a) ('\0' == *(a).str ? SUCCEED : FAIL)
#define zbx_cuid_compare(a, b) (0 == memcmp((a).str, (b).str, CUID_LEN) ? SUCCEED : FAIL)
#define zbx_cuid_clear(a) memset((a).str, 0, CUID_LEN)
-int zbx_ha_start(zbx_rtc_t *rtc, int ha_status, char **error);
+int zbx_ha_start(zbx_rtc_t *rtc, zbx_ha_config_t *ha_config, char **error);
int zbx_ha_pause(char **error);
int zbx_ha_stop(char **error);
void zbx_ha_kill(void);
-int zbx_ha_get_status(int *ha_status, int *ha_failover_delay, char **error);
-int zbx_ha_dispatch_message(zbx_ipc_message_t *message, int *ha_status, int *ha_failover_delay, char **error);
+int zbx_ha_get_status(const char *ha_node_name, int *ha_status, int *ha_failover_delay, char **error);
+int zbx_ha_dispatch_message(const char *ha_node_name, zbx_ipc_message_t *message, int *ha_status,
+ int *ha_failover_delay, char **error);
int zbx_ha_check_pid(pid_t pid);
diff --git a/src/zabbix_server/ha/ha_manager.c b/src/zabbix_server/ha/ha_manager.c
index db38ea955ed..8599c0ca9d6 100644
--- a/src/zabbix_server/ha/ha_manager.c
+++ b/src/zabbix_server/ha/ha_manager.c
@@ -31,6 +31,7 @@
#include "zbxnum.h"
#include "zbxtime.h"
#include "zbxip.h"
+#include "zbxcomms.h"
#define ZBX_HA_POLL_PERIOD 5
@@ -38,9 +39,6 @@
static pid_t ha_pid = ZBX_THREAD_ERROR;
-extern char *CONFIG_HA_NODE_NAME;
-extern char *CONFIG_NODE_ADDRESS;
-
extern zbx_cuid_t ha_sessionid;
typedef struct
@@ -102,6 +100,16 @@ static int ha_db_execute(zbx_ha_info_t *info, const char *sql, ...) __zbx_attr_f
/******************************************************************************
* *
+ * Purpose: check if server is a part of HA cluster *
+ * *
+ ******************************************************************************/
+static int is_ha_cluster(const char *ha_node_name)
+{
+ return (NULL != ha_node_name && '\0' != *ha_node_name) ? 1 : 0;
+}
+
+/******************************************************************************
+ * *
* Purpose: connect, send message and receive response in a given timeout *
* *
* Parameters: service_name - [IN] the IPC service name *
@@ -459,9 +467,30 @@ static zbx_ha_node_t *ha_find_node_by_name(zbx_vector_ha_node_t *nodes, const ch
* Purpose: get server external address and port from configuration *
* *
******************************************************************************/
-static void ha_get_external_address(char **address, unsigned short *port)
+static void ha_get_external_address(char **address, unsigned short *port, zbx_ha_config_t *ha_config)
{
- (void)zbx_parse_serveractive_element(CONFIG_NODE_ADDRESS, address, port, 10051);
+ if (NULL != ha_config->ha_node_address)
+ {
+ (void)zbx_parse_serveractive_element(ha_config->ha_node_address, address, port, 0);
+ }
+ else if (NULL != ha_config->default_node_ip)
+ {
+ char *tmp;
+
+ zbx_strsplit_first(ha_config->default_node_ip, ',', address, &tmp);
+ zbx_free(tmp);
+ }
+
+ if (NULL == *address || 0 == strcmp(*address, "0.0.0.0") || 0 == strcmp(*address, "::"))
+ *address = zbx_strdup(*address, "localhost");
+
+ if (0 == *port)
+ {
+ if (0 != ha_config->default_node_port)
+ *port = (unsigned short)ha_config->default_node_port;
+ else
+ *port = ZBX_DEFAULT_SERVER_PORT;
+ }
}
/******************************************************************************
@@ -641,7 +670,7 @@ static void ha_flush_audit(zbx_ha_info_t *info)
* FAIL - node configuration or database error *
* *
******************************************************************************/
-static void ha_db_create_node(zbx_ha_info_t *info)
+static void ha_db_create_node(zbx_ha_info_t *info, zbx_ha_config_t *ha_config)
{
zbx_vector_ha_node_t nodes;
int i, activate, db_time;
@@ -673,7 +702,7 @@ static void ha_db_create_node(zbx_ha_info_t *info)
if (SUCCEED != ha_db_get_time(info, &db_time))
goto out;
- if (ZBX_HA_IS_CLUSTER())
+ if (0 != is_ha_cluster(ha_config->ha_node_name))
{
if (SUCCEED != ha_check_cluster_config(info, &nodes, db_time, &activate))
goto out;
@@ -786,7 +815,7 @@ static int ha_db_check_unavailable_nodes(zbx_ha_info_t *info, zbx_vector_ha_node
* In the case of critical error the error status will be set. *
* *
******************************************************************************/
-static void ha_db_register_node(zbx_ha_info_t *info)
+static void ha_db_register_node(zbx_ha_info_t *info, zbx_ha_config_t *ha_config)
{
zbx_vector_ha_node_t nodes;
int ha_status = ZBX_NODE_STATUS_UNKNOWN, activate = SUCCEED, db_time;
@@ -799,7 +828,7 @@ static void ha_db_register_node(zbx_ha_info_t *info)
zbx_vector_ha_node_create(&nodes);
- ha_db_create_node(info);
+ ha_db_create_node(info, ha_config);
if (SUCCEED == zbx_cuid_empty(info->ha_nodeid))
goto finish;
@@ -813,7 +842,7 @@ static void ha_db_register_node(zbx_ha_info_t *info)
if (SUCCEED != ha_db_get_time(info, &db_time))
goto out;
- if (ZBX_HA_IS_CLUSTER())
+ if (0 != is_ha_cluster(ha_config->ha_node_name))
{
if (SUCCEED != ha_check_cluster_config(info, &nodes, db_time, &activate))
goto out;
@@ -831,7 +860,7 @@ static void ha_db_register_node(zbx_ha_info_t *info)
}
ha_status = SUCCEED == activate ? ZBX_NODE_STATUS_ACTIVE : ZBX_NODE_STATUS_STANDBY;
- ha_get_external_address(&address, &port);
+ ha_get_external_address(&address, &port, ha_config);
zbx_audit_init(info->auditlog);
zbx_audit_ha_create_entry(ZBX_AUDIT_ACTION_UPDATE, info->ha_nodeid.str, info->name);
@@ -863,14 +892,17 @@ static void ha_db_register_node(zbx_ha_info_t *info)
if (SUCCEED == ha_db_execute(info, "%s where ha_nodeid='%s'", sql, info->ha_nodeid.str))
{
- if (ZBX_HA_IS_CLUSTER())
+ if (0 != is_ha_cluster(ha_config->ha_node_name))
ha_db_execute(info, "delete from ha_node where name=''");
else
ha_db_execute(info, "delete from ha_node where name<>''");
}
- if (ZBX_HA_IS_CLUSTER() && ZBX_NODE_STATUS_ERROR != info->ha_status && ZBX_NODE_STATUS_ACTIVE == ha_status)
+ if (0 != is_ha_cluster(ha_config->ha_node_name) && ZBX_NODE_STATUS_ERROR != info->ha_status &&
+ ZBX_NODE_STATUS_ACTIVE == ha_status)
+ {
ha_db_check_unavailable_nodes(info, &nodes, db_time);
+ }
ha_flush_audit(info);
@@ -975,7 +1007,7 @@ static int ha_check_active_node(zbx_ha_info_t *info, zbx_vector_ha_node_t *nodes
* Comments: Sets error status on critical errors forcing manager to exit *
* *
******************************************************************************/
-static void ha_check_nodes(zbx_ha_info_t *info)
+static void ha_check_nodes(zbx_ha_info_t *info, zbx_ha_config_t *ha_config)
{
zbx_vector_ha_node_t nodes;
zbx_ha_node_t *node;
@@ -1024,7 +1056,7 @@ static void ha_check_nodes(zbx_ha_info_t *info)
if (SUCCEED != ha_db_get_time(info, &db_time))
goto out;
- if (ZBX_HA_IS_CLUSTER())
+ if (0 != is_ha_cluster(ha_config->ha_node_name))
{
if (ZBX_NODE_STATUS_ACTIVE == info->ha_status)
{
@@ -1116,7 +1148,7 @@ out:
* Purpose: get cluster status in lld compatible json format *
* *
******************************************************************************/
-static int ha_db_get_nodes_json(zbx_ha_info_t *info, char **nodes_json, char **error)
+static int ha_db_get_nodes_json(zbx_ha_info_t *info, char **nodes_json, char **error, zbx_ha_config_t *ha_config)
{
zbx_vector_ha_node_t nodes;
int i, db_time, ret = FAIL;
@@ -1126,7 +1158,7 @@ static int ha_db_get_nodes_json(zbx_ha_info_t *info, char **nodes_json, char **e
if (ZBX_DB_OK > info->db_status)
goto out;
- if (0 == ZBX_HA_IS_CLUSTER())
+ if (0 == is_ha_cluster(ha_config->ha_node_name))
{
/* return empty json array in standalone mode */
*nodes_json = zbx_strdup(NULL, "[]");
@@ -1403,7 +1435,7 @@ static void ha_get_failover_delay(zbx_ha_info_t *info, zbx_ipc_client_t *client)
* Purpose: reply to get nodes request *
* *
******************************************************************************/
-static void ha_send_node_list(zbx_ha_info_t *info, zbx_ipc_client_t *client)
+static void ha_send_node_list(zbx_ha_info_t *info, zbx_ipc_client_t *client, zbx_ha_config_t *ha_config)
{
int ret;
char *error = NULL, *nodes_json = NULL, *str;
@@ -1412,7 +1444,7 @@ static void ha_send_node_list(zbx_ha_info_t *info, zbx_ipc_client_t *client)
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
- if (SUCCEED == (ret = ha_db_get_nodes_json(info, &nodes_json, &error)))
+ if (SUCCEED == (ret = ha_db_get_nodes_json(info, &nodes_json, &error, ha_config)))
str = nodes_json;
else
str = error;
@@ -1472,7 +1504,7 @@ out:
* active - for standalone setup *
* *
******************************************************************************/
-int zbx_ha_get_status(int *ha_status, int *ha_failover_delay, char **error)
+int zbx_ha_get_status(const char *ha_node_name, int *ha_status, int *ha_failover_delay, char **error)
{
int ret;
unsigned char *result = NULL;
@@ -1498,7 +1530,7 @@ int zbx_ha_get_status(int *ha_status, int *ha_failover_delay, char **error)
}
else
{
- if (ZBX_HA_IS_CLUSTER())
+ if (0 != is_ha_cluster(ha_node_name))
*ha_status = ZBX_NODE_STATUS_STANDBY;
else
*ha_status = ZBX_NODE_STATUS_ACTIVE;
@@ -1520,7 +1552,8 @@ int zbx_ha_get_status(int *ha_status, int *ha_failover_delay, char **error)
* process to switch to standby mode and initiate teardown process *
* *
******************************************************************************/
-int zbx_ha_dispatch_message(zbx_ipc_message_t *message, int *ha_status, int *ha_failover_delay, char **error)
+int zbx_ha_dispatch_message(const char *ha_node_name, zbx_ipc_message_t *message, int *ha_status,
+ int *ha_failover_delay, char **error)
{
static time_t last_hb;
int ret = SUCCEED, ha_status_old;
@@ -1561,7 +1594,7 @@ int zbx_ha_dispatch_message(zbx_ipc_message_t *message, int *ha_status, int *ha_
}
}
- if (ZBX_HA_IS_CLUSTER() && *ha_status == ZBX_NODE_STATUS_ACTIVE && 0 != last_hb)
+ if (0 != is_ha_cluster(ha_node_name) && *ha_status == ZBX_NODE_STATUS_ACTIVE && 0 != last_hb)
{
if (last_hb + *ha_failover_delay - ZBX_HA_POLL_PERIOD <= now || now < last_hb)
*ha_status = ZBX_NODE_STATUS_STANDBY;
@@ -1575,7 +1608,7 @@ out:
* Purpose: start HA manager *
* *
******************************************************************************/
-int zbx_ha_start(zbx_rtc_t *rtc, int ha_status, char **error)
+int zbx_ha_start(zbx_rtc_t *rtc, zbx_ha_config_t *ha_config, char **error)
{
int ret = FAIL, status;
zbx_uint32_t code = 0;
@@ -1587,7 +1620,7 @@ int zbx_ha_start(zbx_rtc_t *rtc, int ha_status, char **error)
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
- args.args = (void *)(uintptr_t)ha_status;
+ args.args = (void *)ha_config;
zbx_thread_start(ha_manager_thread, &args, &ha_pid);
if (ZBX_THREAD_ERROR == ha_pid)
@@ -1642,6 +1675,8 @@ out:
zbx_ha_kill();
}
+ zbx_free(ha_config);
+
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
return ret;
@@ -1751,11 +1786,14 @@ ZBX_THREAD_ENTRY(ha_manager_thread, args)
double now, tick;
zbx_ha_info_t info;
zbx_timespec_t timeout;
+ zbx_ha_config_t ha_config;
zbx_setproctitle("ha manager");
zabbix_log(LOG_LEVEL_INFORMATION, "starting HA manager");
+ ha_config = *(zbx_ha_config_t *)((zbx_thread_args_t *)args)->args;
+
if (FAIL == zbx_ipc_service_start(&service, ZBX_IPC_SERVICE_HA, &error))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot start HA manager service: %s", error);
@@ -1778,8 +1816,8 @@ ZBX_THREAD_ENTRY(ha_manager_thread, args)
}
zbx_cuid_clear(info.ha_nodeid);
- info.name = ZBX_NULL2EMPTY_STR(CONFIG_HA_NODE_NAME);
- info.ha_status = (int)(uintptr_t)((zbx_thread_args_t *)args)->args;
+ info.name = ZBX_NULL2EMPTY_STR(ha_config.ha_node_name);
+ info.ha_status = ha_config.ha_status;
info.error = NULL;
info.db_status = ZBX_DB_DOWN;
info.offline_ticks_active = 0;
@@ -1791,7 +1829,7 @@ ZBX_THREAD_ENTRY(ha_manager_thread, args)
if (ZBX_NODE_STATUS_UNKNOWN == info.ha_status)
{
- ha_db_register_node(&info);
+ ha_db_register_node(&info, &ha_config);
if (ZBX_NODE_STATUS_ERROR == info.ha_status)
goto pause;
@@ -1817,9 +1855,9 @@ ZBX_THREAD_ENTRY(ha_manager_thread, args)
int old_status = info.ha_status, delay;
if (ZBX_NODE_STATUS_UNKNOWN == info.ha_status)
- ha_db_register_node(&info);
+ ha_db_register_node(&info, &ha_config);
else
- ha_check_nodes(&info);
+ ha_check_nodes(&info, &ha_config);
if (old_status != info.ha_status && ZBX_NODE_STATUS_UNKNOWN != info.ha_status)
ha_update_parent(&rtc_socket, &info);
@@ -1864,7 +1902,7 @@ ZBX_THREAD_ENTRY(ha_manager_thread, args)
pause = SUCCEED;
break;
case ZBX_IPC_SERVICE_HA_GET_NODES:
- ha_send_node_list(&info, client);
+ ha_send_node_list(&info, client, &ha_config);
break;
case ZBX_IPC_SERVICE_HA_REMOVE_NODE:
ha_remove_node(&info, client, message);
diff --git a/src/zabbix_server/housekeeper/housekeeper.c b/src/zabbix_server/housekeeper/housekeeper.c
index 17297735733..cb8a8d260a1 100644
--- a/src/zabbix_server/housekeeper/housekeeper.c
+++ b/src/zabbix_server/housekeeper/housekeeper.c
@@ -27,7 +27,6 @@
#include "zbxnum.h"
#include "zbxtime.h"
#include "history_compress.h"
-#include "../../libs/zbxdbcache/valuecache.h"
extern ZBX_THREAD_LOCAL unsigned char process_type;
extern unsigned char program_type;
@@ -1130,7 +1129,7 @@ ZBX_THREAD_ENTRY(housekeeper_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
if (0 == CONFIG_HOUSEKEEPING_FREQUENCY)
{
@@ -1248,7 +1247,6 @@ ZBX_THREAD_ENTRY(housekeeper_thread, args)
DBclose();
zbx_dc_cleanup_sessions();
- zbx_vc_housekeeping_value_cache();
zbx_setproctitle("%s [deleted %d hist/trends, %d items/triggers, %d events, %d sessions, %d alarms,"
" %d audit items, %d records in " ZBX_FS_DBL " sec, %s]",
diff --git a/src/zabbix_server/housekeeper/trigger_housekeeper.c b/src/zabbix_server/housekeeper/trigger_housekeeper.c
index 44464bb9eed..4915e651fcd 100644
--- a/src/zabbix_server/housekeeper/trigger_housekeeper.c
+++ b/src/zabbix_server/housekeeper/trigger_housekeeper.c
@@ -102,7 +102,7 @@ ZBX_THREAD_ENTRY(trigger_housekeeper_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type));
DBconnect(ZBX_DB_CONNECT_NORMAL);
diff --git a/src/zabbix_server/httppoller/httppoller.c b/src/zabbix_server/httppoller/httppoller.c
index 599757c0df6..8cbcabf2ae8 100644
--- a/src/zabbix_server/httppoller/httppoller.c
+++ b/src/zabbix_server/httppoller/httppoller.c
@@ -26,53 +26,12 @@
#include "httptest.h"
#include "zbxtime.h"
-extern int CONFIG_HTTPPOLLER_FORKS;
extern ZBX_THREAD_LOCAL unsigned char process_type;
extern unsigned char program_type;
extern ZBX_THREAD_LOCAL int server_num, process_num;
/******************************************************************************
* *
- * Purpose: calculate when we have to process earliest httptest *
- * *
- * Return value: timestamp of earliest check or -1 if not found *
- * *
- ******************************************************************************/
-static int get_minnextcheck(void)
-{
- DB_RESULT result;
- DB_ROW row;
- int res;
-
- result = DBselect(
- "select min(t.nextcheck)"
- " from httptest t,hosts h"
- " where t.hostid=h.hostid"
- " and " ZBX_SQL_MOD(t.httptestid,%d) "=%d"
- " and t.status=%d"
- " and h.proxy_hostid is null"
- " and h.status=%d"
- " and (h.maintenance_status=%d or h.maintenance_type=%d)",
- CONFIG_HTTPPOLLER_FORKS, process_num - 1,
- HTTPTEST_STATUS_MONITORED,
- HOST_STATUS_MONITORED,
- HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL);
-
- if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0]))
- {
- zabbix_log(LOG_LEVEL_DEBUG, "No httptests to process in get_minnextcheck.");
- res = FAIL;
- }
- else
- res = atoi(row[0]);
-
- DBfree_result(result);
-
- return res;
-}
-
-/******************************************************************************
- * *
* Purpose: main loop of processing of httptests *
* *
* Comments: never returns *
@@ -80,9 +39,9 @@ static int get_minnextcheck(void)
******************************************************************************/
ZBX_THREAD_ENTRY(httppoller_thread, args)
{
- int now, nextcheck, sleeptime = -1, httptests_count = 0, old_httptests_count = 0;
+ int sleeptime = -1, httptests_count = 0, old_httptests_count = 0;
double sec, total_sec = 0.0, old_total_sec = 0.0;
- time_t last_stat_time;
+ time_t last_stat_time, nextcheck = 0;
process_type = ((zbx_thread_args_t *)args)->process_type;
server_num = ((zbx_thread_args_t *)args)->server_num;
@@ -91,7 +50,7 @@ ZBX_THREAD_ENTRY(httppoller_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
#define STAT_INTERVAL 5 /* if a process is busy and does not sleep then update status not faster than */
/* once in STAT_INTERVAL seconds */
@@ -113,11 +72,15 @@ ZBX_THREAD_ENTRY(httppoller_thread, args)
old_total_sec);
}
- now = time(NULL);
- httptests_count += process_httptests(process_num, now);
- total_sec += zbx_time() - sec;
+ if ((int)sec >= nextcheck)
+ {
+ httptests_count += process_httptests((int)sec, &nextcheck);
+ total_sec += zbx_time() - sec;
+
+ if (0 == nextcheck)
+ nextcheck = time(NULL) + POLLER_DELAY;
+ }
- nextcheck = get_minnextcheck();
sleeptime = zbx_calculate_sleeptime(nextcheck, POLLER_DELAY);
if (0 != sleeptime || STAT_INTERVAL <= time(NULL) - last_stat_time)
diff --git a/src/zabbix_server/httppoller/httptest.c b/src/zabbix_server/httppoller/httptest.c
index 5aebfe284dd..9b57d866836 100644
--- a/src/zabbix_server/httppoller/httptest.c
+++ b/src/zabbix_server/httppoller/httptest.c
@@ -37,8 +37,6 @@ typedef struct
}
zbx_httpstat_t;
-extern int CONFIG_HTTPPOLLER_FORKS;
-
#ifdef HAVE_LIBCURL
typedef struct
@@ -166,7 +164,7 @@ static void process_test_data(zbx_uint64_t httptestid, int lastfailedstep, doubl
continue;
}
- init_result(&value);
+ zbx_init_agent_result(&value);
switch (types[i])
{
@@ -185,7 +183,7 @@ static void process_test_data(zbx_uint64_t httptestid, int lastfailedstep, doubl
zbx_preprocess_item_value(items[i].itemid, items[i].host.hostid, items[i].value_type, 0, &value,
ts, items[i].state, NULL);
- free_result(&value);
+ zbx_free_agent_result(&value);
}
DCconfig_clean_items(items, errcodes, num);
@@ -305,7 +303,7 @@ static void process_step_data(zbx_uint64_t httpstepid, zbx_httpstat_t *stat, zbx
continue;
}
- init_result(&value);
+ zbx_init_agent_result(&value);
switch (types[i])
{
@@ -324,7 +322,7 @@ static void process_step_data(zbx_uint64_t httpstepid, zbx_httpstat_t *stat, zbx
zbx_preprocess_item_value(items[i].itemid, items[i].host.hostid, items[i].value_type, 0, &value,
ts, items[i].state, NULL);
- free_result(&value);
+ zbx_free_agent_result(&value);
}
DCconfig_clean_items(items, errcodes, num);
@@ -609,14 +607,13 @@ out:
* Purpose: process single scenario of http test *
* *
******************************************************************************/
-static void process_httptest(DC_HOST *host, zbx_httptest_t *httptest)
+static void process_httptest(DC_HOST *host, zbx_httptest_t *httptest, int *delay)
{
DB_RESULT result;
DB_HTTPSTEP db_httpstep;
char *err_str = NULL, *buffer = NULL;
int lastfailedstep = 0;
zbx_timespec_t ts;
- int delay;
double speed_download = 0;
int speed_download_num = 0;
#ifdef HAVE_LIBCURL
@@ -640,17 +637,18 @@ static void process_httptest(DC_HOST *host, zbx_httptest_t *httptest)
buffer = zbx_strdup(buffer, httptest->httptest.delay);
zbx_substitute_simple_macros(NULL, NULL, NULL, NULL, &host->hostid, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- &buffer, MACRO_TYPE_COMMON, NULL, 0);
+ &buffer, MACRO_TYPE_COMMON, NULL, 0);
/* Avoid the potential usage of uninitialized values when: */
/* 1) compile without libCURL support */
/* 2) update interval is invalid */
db_httpstep.name = NULL;
- if (SUCCEED != zbx_is_time_suffix(buffer, &delay, ZBX_LENGTH_UNLIMITED))
+ if (SUCCEED != zbx_is_time_suffix(buffer, delay, ZBX_LENGTH_UNLIMITED))
{
err_str = zbx_dsprintf(err_str, "update interval \"%s\" is invalid", buffer);
lastfailedstep = -1;
+ *delay = ZBX_DEFAULT_INTERVAL;
goto httptest_error;
}
@@ -977,24 +975,6 @@ clean:
httptest_error:
zbx_timespec(&ts);
- if (0 > lastfailedstep) /* update interval is invalid, delay is uninitialized */
- {
- DBexecute("update httptest set nextcheck=%d where httptestid=" ZBX_FS_UI64,
- 0 > ts.sec ? ZBX_JAN_2038 : ts.sec + SEC_PER_MIN, httptest->httptest.httptestid);
- }
- else if (0 > ts.sec + delay)
- {
- zabbix_log(LOG_LEVEL_WARNING, "nextcheck update causes overflow for web scenario \"%s\" on host \"%s\"",
- httptest->httptest.name, host->name);
- DBexecute("update httptest set nextcheck=%d where httptestid=" ZBX_FS_UI64,
- ZBX_JAN_2038, httptest->httptest.httptestid);
- }
- else
- {
- DBexecute("update httptest set nextcheck=%d where httptestid=" ZBX_FS_UI64,
- ts.sec + delay, httptest->httptest.httptestid);
- }
-
if (NULL != err_str)
{
if (0 >= lastfailedstep)
@@ -1036,10 +1016,11 @@ httptest_error:
* Comments: always SUCCEED *
* *
******************************************************************************/
-int process_httptests(int httppoller_num, int now)
+int process_httptests(int now, time_t *nextcheck)
{
DB_RESULT result;
DB_ROW row;
+ zbx_uint64_t httptestid;
zbx_httptest_t httptest;
DC_HOST host;
int httptests_count = 0;
@@ -1047,120 +1028,126 @@ int process_httptests(int httppoller_num, int now)
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+ if (SUCCEED != zbx_dc_httptest_next(now, &httptestid, nextcheck))
+ goto out;
+
um_handle = zbx_dc_open_user_macros();
/* create macro cache to use in http tests */
zbx_vector_ptr_pair_create(&httptest.macros);
- result = DBselect(
- "select h.hostid,h.host,h.name,t.httptestid,t.name,t.agent,"
- "t.authentication,t.http_user,t.http_password,t.http_proxy,t.retries,t.ssl_cert_file,"
- "t.ssl_key_file,t.ssl_key_password,t.verify_peer,t.verify_host,t.delay"
- " from httptest t,hosts h"
- " where t.hostid=h.hostid"
- " and t.nextcheck<=%d"
- " and " ZBX_SQL_MOD(t.httptestid,%d) "=%d"
- " and t.status=%d"
- " and h.proxy_hostid is null"
- " and h.status=%d"
- " and (h.maintenance_status=%d or h.maintenance_type=%d)",
- now,
- CONFIG_HTTPPOLLER_FORKS, httppoller_num - 1,
- HTTPTEST_STATUS_MONITORED,
- HOST_STATUS_MONITORED,
- HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL);
-
- while (NULL != (row = DBfetch(result)) && ZBX_IS_RUNNING())
+ do
{
- ZBX_STR2UINT64(host.hostid, row[0]);
- zbx_strscpy(host.host, row[1]);
- zbx_strlcpy_utf8(host.name, row[2], sizeof(host.name));
-
- ZBX_STR2UINT64(httptest.httptest.httptestid, row[3]);
- httptest.httptest.name = row[4];
-
- if (SUCCEED != httptest_load_pairs(&host, &httptest))
+ int delay = 0;
+
+ result = DBselect(
+ "select h.hostid,h.host,h.name,t.httptestid,t.name,t.agent,"
+ "t.authentication,t.http_user,t.http_password,t.http_proxy,t.retries,t.ssl_cert_file,"
+ "t.ssl_key_file,t.ssl_key_password,t.verify_peer,t.verify_host,t.delay"
+ " from httptest t,hosts h"
+ " where t.hostid=h.hostid"
+ " and t.httptestid=" ZBX_FS_UI64,
+ httptestid);
+
+ if (NULL != (row = DBfetch(result)))
{
- zabbix_log(LOG_LEVEL_WARNING, "cannot process web scenario \"%s\" on host \"%s\": "
- "cannot load web scenario data", httptest.httptest.name, host.name);
- THIS_SHOULD_NEVER_HAPPEN;
- continue;
- }
-
- httptest.httptest.agent = zbx_strdup(NULL, row[5]);
- zbx_substitute_simple_macros(NULL, NULL, NULL, NULL, &host.hostid, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, &httptest.httptest.agent, MACRO_TYPE_COMMON, NULL, 0);
+ ZBX_STR2UINT64(host.hostid, row[0]);
+ zbx_strscpy(host.host, row[1]);
+ zbx_strlcpy_utf8(host.name, row[2], sizeof(host.name));
- if (HTTPTEST_AUTH_NONE != (httptest.httptest.authentication = atoi(row[6])))
- {
- httptest.httptest.http_user = zbx_strdup(NULL, row[7]);
- zbx_substitute_simple_macros_unmasked(NULL, NULL, NULL, NULL, &host.hostid, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, &httptest.httptest.http_user, MACRO_TYPE_COMMON, NULL, 0);
+ ZBX_STR2UINT64(httptest.httptest.httptestid, row[3]);
+ httptest.httptest.name = row[4];
- httptest.httptest.http_password = zbx_strdup(NULL, row[8]);
- zbx_substitute_simple_macros_unmasked(NULL, NULL, NULL, NULL, &host.hostid, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, &httptest.httptest.http_password, MACRO_TYPE_COMMON, NULL, 0);
- }
+ if (SUCCEED != httptest_load_pairs(&host, &httptest))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot process web scenario \"%s\" on host \"%s\": "
+ "cannot load web scenario data", httptest.httptest.name, host.name);
+ DBfree_result(result);
+ THIS_SHOULD_NEVER_HAPPEN;
+ continue;
+ }
- if ('\0' != *row[9])
- {
- httptest.httptest.http_proxy = zbx_strdup(NULL, row[9]);
+ httptest.httptest.agent = zbx_strdup(NULL, row[5]);
zbx_substitute_simple_macros(NULL, NULL, NULL, NULL, &host.hostid, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, &httptest.httptest.http_proxy, MACRO_TYPE_COMMON, NULL, 0);
- }
- else
- httptest.httptest.http_proxy = NULL;
+ NULL, NULL, &httptest.httptest.agent, MACRO_TYPE_COMMON, NULL, 0);
- httptest.httptest.retries = atoi(row[10]);
+ if (HTTPTEST_AUTH_NONE != (httptest.httptest.authentication = atoi(row[6])))
+ {
+ httptest.httptest.http_user = zbx_strdup(NULL, row[7]);
+ zbx_substitute_simple_macros_unmasked(NULL, NULL, NULL, NULL, &host.hostid, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, &httptest.httptest.http_user,
+ MACRO_TYPE_COMMON, NULL, 0);
+
+ httptest.httptest.http_password = zbx_strdup(NULL, row[8]);
+ zbx_substitute_simple_macros_unmasked(NULL, NULL, NULL, NULL, &host.hostid, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, &httptest.httptest.http_password,
+ MACRO_TYPE_COMMON, NULL, 0);
+ }
- httptest.httptest.ssl_cert_file = zbx_strdup(NULL, row[11]);
- zbx_substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, &host, NULL, NULL, NULL, NULL, NULL, NULL,
- &httptest.httptest.ssl_cert_file, MACRO_TYPE_HTTPTEST_FIELD, NULL, 0);
+ if ('\0' != *row[9])
+ {
+ httptest.httptest.http_proxy = zbx_strdup(NULL, row[9]);
+ zbx_substitute_simple_macros(NULL, NULL, NULL, NULL, &host.hostid, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, &httptest.httptest.http_proxy,
+ MACRO_TYPE_COMMON, NULL, 0);
+ }
+ else
+ httptest.httptest.http_proxy = NULL;
- httptest.httptest.ssl_key_file = zbx_strdup(NULL, row[12]);
- zbx_substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, &host, NULL, NULL, NULL, NULL, NULL, NULL,
- &httptest.httptest.ssl_key_file, MACRO_TYPE_HTTPTEST_FIELD, NULL, 0);
+ httptest.httptest.retries = atoi(row[10]);
- httptest.httptest.ssl_key_password = zbx_strdup(NULL, row[13]);
- zbx_substitute_simple_macros_unmasked(NULL, NULL, NULL, NULL, &host.hostid, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, &httptest.httptest.ssl_key_password, MACRO_TYPE_COMMON, NULL, 0);
+ httptest.httptest.ssl_cert_file = zbx_strdup(NULL, row[11]);
+ zbx_substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, &host, NULL, NULL, NULL, NULL, NULL,
+ NULL, &httptest.httptest.ssl_cert_file, MACRO_TYPE_HTTPTEST_FIELD, NULL, 0);
- httptest.httptest.verify_peer = atoi(row[14]);
- httptest.httptest.verify_host = atoi(row[15]);
+ httptest.httptest.ssl_key_file = zbx_strdup(NULL, row[12]);
+ zbx_substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, &host, NULL, NULL, NULL, NULL, NULL,
+ NULL, &httptest.httptest.ssl_key_file, MACRO_TYPE_HTTPTEST_FIELD, NULL, 0);
- httptest.httptest.delay = row[16];
+ httptest.httptest.ssl_key_password = zbx_strdup(NULL, row[13]);
+ zbx_substitute_simple_macros_unmasked(NULL, NULL, NULL, NULL, &host.hostid, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, &httptest.httptest.ssl_key_password, MACRO_TYPE_COMMON,
+ NULL, 0);
- /* add httptest variables to the current test macro cache */
- http_process_variables(&httptest, &httptest.variables, NULL, NULL);
+ httptest.httptest.verify_peer = atoi(row[14]);
+ httptest.httptest.verify_host = atoi(row[15]);
- process_httptest(&host, &httptest);
+ httptest.httptest.delay = row[16];
- zbx_free(httptest.httptest.ssl_key_password);
- zbx_free(httptest.httptest.ssl_key_file);
- zbx_free(httptest.httptest.ssl_cert_file);
- zbx_free(httptest.httptest.http_proxy);
+ /* add httptest variables to the current test macro cache */
+ http_process_variables(&httptest, &httptest.variables, NULL, NULL);
- if (HTTPTEST_AUTH_NONE != httptest.httptest.authentication)
- {
- zbx_free(httptest.httptest.http_password);
- zbx_free(httptest.httptest.http_user);
- }
- zbx_free(httptest.httptest.agent);
- zbx_free(httptest.headers);
- httppairs_free(&httptest.variables);
+ process_httptest(&host, &httptest, &delay);
+ zbx_dc_httptest_queue(now, httptestid, delay);
+
+ zbx_free(httptest.httptest.ssl_key_password);
+ zbx_free(httptest.httptest.ssl_key_file);
+ zbx_free(httptest.httptest.ssl_cert_file);
+ zbx_free(httptest.httptest.http_proxy);
+
+ if (HTTPTEST_AUTH_NONE != httptest.httptest.authentication)
+ {
+ zbx_free(httptest.httptest.http_password);
+ zbx_free(httptest.httptest.http_user);
+ }
+ zbx_free(httptest.httptest.agent);
+ zbx_free(httptest.headers);
+ httppairs_free(&httptest.variables);
- /* clear the macro cache used in this http test */
- httptest_remove_macros(&httptest);
+ /* clear the macro cache used in this http test */
+ httptest_remove_macros(&httptest);
- httptests_count++; /* performance metric */
+ httptests_count++; /* performance metric */
+ }
+ DBfree_result(result);
}
+ while (ZBX_IS_RUNNING() && SUCCEED == zbx_dc_httptest_next(now, &httptestid, nextcheck));
+
/* destroy the macro cache used in http tests */
zbx_vector_ptr_pair_destroy(&httptest.macros);
- DBfree_result(result);
-
zbx_dc_close_user_macros(um_handle);
-
+out:
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
return httptests_count;
diff --git a/src/zabbix_server/httppoller/httptest.h b/src/zabbix_server/httppoller/httptest.h
index 8ab9fbd208f..617ceefe029 100644
--- a/src/zabbix_server/httppoller/httptest.h
+++ b/src/zabbix_server/httppoller/httptest.h
@@ -20,6 +20,8 @@
#ifndef ZABBIX_HTTPTEST_H
#define ZABBIX_HTTPTEST_H
-int process_httptests(int httppoller_num, int now);
+#include "zbxcommon.h"
+
+int process_httptests(int now, time_t *nextcheck);
#endif
diff --git a/src/zabbix_server/ipmi/ipmi_manager.c b/src/zabbix_server/ipmi/ipmi_manager.c
index ae42db55f9d..66ac2e9f5ff 100644
--- a/src/zabbix_server/ipmi/ipmi_manager.c
+++ b/src/zabbix_server/ipmi/ipmi_manager.c
@@ -909,12 +909,12 @@ static void ipmi_manager_process_value_result(zbx_ipmi_manager_t *manager, zbx_i
state = ITEM_STATE_NORMAL;
if (NULL != value)
{
- init_result(&result);
+ zbx_init_agent_result(&result);
SET_TEXT_RESULT(&result, value);
value = NULL;
zbx_preprocess_item_value(itemid, poller->request->hostid, ITEM_VALUE_TYPE_TEXT, flags,
&result, &ts, state, NULL);
- free_result(&result);
+ zbx_free_agent_result(&result);
}
break;
@@ -963,7 +963,7 @@ ZBX_THREAD_ENTRY(ipmi_manager_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
if (FAIL == zbx_ipc_service_start(&ipmi_service, ZBX_IPC_SERVICE_IPMI, &error))
{
@@ -1010,9 +1010,9 @@ ZBX_THREAD_ENTRY(ipmi_manager_thread, args)
if (ZBX_IPMI_MANAGER_DELAY < timeout.sec)
timeout.sec = ZBX_IPMI_MANAGER_DELAY;
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
ret = zbx_ipc_service_recv(&ipmi_service, &timeout, &client, &message);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
sec = zbx_time();
zbx_update_env(sec);
diff --git a/src/zabbix_server/ipmi/ipmi_poller.c b/src/zabbix_server/ipmi/ipmi_poller.c
index d16d0df07f1..b0121409a09 100644
--- a/src/zabbix_server/ipmi/ipmi_poller.c
+++ b/src/zabbix_server/ipmi/ipmi_poller.c
@@ -187,7 +187,7 @@ ZBX_THREAD_ENTRY(ipmi_poller_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
if (FAIL == zbx_ipc_async_socket_open(&ipmi_socket, ZBX_IPC_SERVICE_IPMI, SEC_PER_MIN, &error))
{
@@ -221,7 +221,7 @@ ZBX_THREAD_ENTRY(ipmi_poller_thread, args)
polled_num = 0;
}
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
while (ZBX_IS_RUNNING())
{
@@ -240,7 +240,7 @@ ZBX_THREAD_ENTRY(ipmi_poller_thread, args)
zbx_perform_all_openipmi_ops(ipmi_timeout);
}
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
if (NULL == message)
break;
diff --git a/src/zabbix_server/lld/lld.c b/src/zabbix_server/lld/lld.c
index 9d178816006..1d6f22aa7ed 100644
--- a/src/zabbix_server/lld/lld.c
+++ b/src/zabbix_server/lld/lld.c
@@ -116,7 +116,7 @@ static void lld_filter_init(lld_filter_t *filter)
{
zbx_vector_ptr_create(&filter->conditions);
filter->expression = NULL;
- filter->evaltype = CONDITION_EVAL_TYPE_AND_OR;
+ filter->evaltype = ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR;
}
/******************************************************************************
@@ -195,7 +195,7 @@ static int lld_filter_load(lld_filter_t *filter, zbx_uint64_t lld_ruleid, const
;
DBfree_result(result);
- if (CONDITION_EVAL_TYPE_AND_OR == filter->evaltype)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == filter->evaltype)
zbx_vector_ptr_sort(&filter->conditions, lld_condition_compare_by_macro);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
@@ -225,11 +225,11 @@ static int filter_condition_match(const struct zbx_json_parse *jp_row, const zbx
if (SUCCEED == zbx_lld_macro_value_by_name(jp_row, lld_macro_paths, condition->macro, &value))
{
- if (CONDITION_OPERATOR_NOT_EXIST == condition->op)
+ if (ZBX_CONDITION_OPERATOR_NOT_EXIST == condition->op)
{
*result = 0;
}
- if (CONDITION_OPERATOR_EXIST == condition->op)
+ else if (ZBX_CONDITION_OPERATOR_EXIST == condition->op)
{
*result = 1;
}
@@ -238,10 +238,11 @@ static int filter_condition_match(const struct zbx_json_parse *jp_row, const zbx
switch (regexp_match_ex(&condition->regexps, value, condition->regexp, ZBX_CASE_SENSITIVE))
{
case ZBX_REGEXP_MATCH:
- *result = (CONDITION_OPERATOR_REGEXP == condition->op ? 1 : 0);
+ *result = (ZBX_CONDITION_OPERATOR_REGEXP == condition->op ? 1 : 0);
break;
case ZBX_REGEXP_NO_MATCH:
- *result = (CONDITION_OPERATOR_NOT_REGEXP == condition->op ? 1 : 0);
+ *result = (ZBX_CONDITION_OPERATOR_NOT_REGEXP == condition->op ? 1 : 0);
+ break;
break;
default:
*info = zbx_strdcatf(*info, "Cannot accurately apply filter: invalid regular "
@@ -254,10 +255,10 @@ static int filter_condition_match(const struct zbx_json_parse *jp_row, const zbx
{
switch (condition->op)
{
- case CONDITION_OPERATOR_NOT_EXIST:
+ case ZBX_CONDITION_OPERATOR_NOT_EXIST:
*result = 1;
break;
- case CONDITION_OPERATOR_EXIST:
+ case ZBX_CONDITION_OPERATOR_EXIST:
*result = 0;
break;
default:
@@ -306,7 +307,7 @@ static int filter_evaluate_and_or_andor(const lld_filter_t *filter, const struct
switch (filter->evaltype)
{
- case CONDITION_EVAL_TYPE_AND_OR:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR:
if (NULL == lastmacro)
{
zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, '(');
@@ -320,8 +321,8 @@ static int filter_evaluate_and_or_andor(const lld_filter_t *filter, const struct
lastmacro = condition->macro;
break;
- case CONDITION_EVAL_TYPE_AND:
- case CONDITION_EVAL_TYPE_OR:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_AND:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_OR:
if (0 != i)
{
zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ' ');
@@ -350,7 +351,7 @@ static int filter_evaluate_and_or_andor(const lld_filter_t *filter, const struct
if (filter->conditions.values_num == i + 1)
{
- if (CONDITION_EVAL_TYPE_AND_OR == filter->evaltype)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == filter->evaltype)
zbx_chrcpy_alloc(&expression, &expression_alloc, &expression_offset, ')');
expression_offset++;
@@ -484,13 +485,13 @@ static int filter_evaluate(const lld_filter_t *filter, const struct zbx_json_par
switch (filter->evaltype)
{
- case CONDITION_EVAL_TYPE_AND_OR:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR:
ZBX_FALLTHROUGH;
- case CONDITION_EVAL_TYPE_AND:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_AND:
ZBX_FALLTHROUGH;
- case CONDITION_EVAL_TYPE_OR:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_OR:
return filter_evaluate_and_or_andor(filter, jp_row, lld_macro_paths, info);
- case CONDITION_EVAL_TYPE_EXPRESSION:
+ case ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION:
return filter_evaluate_expression(filter, jp_row, lld_macro_paths, info);
}
@@ -541,7 +542,7 @@ static int lld_override_conditions_load(zbx_vector_ptr_t *overrides, const zbx_v
{
override = (lld_override_t *)overrides->values[i];
- if (CONDITION_EVAL_TYPE_AND_OR == override->filter.evaltype)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == override->filter.evaltype)
zbx_vector_ptr_sort(&override->filter.conditions, lld_condition_compare_by_macro);
}
@@ -715,11 +716,11 @@ static int regexp_strmatch_condition(const char *value, const char *pattern, uns
{
switch (op)
{
- case CONDITION_OPERATOR_REGEXP:
+ case ZBX_CONDITION_OPERATOR_REGEXP:
if (NULL != zbx_regexp_match(value, pattern, NULL))
return SUCCEED;
break;
- case CONDITION_OPERATOR_NOT_REGEXP:
+ case ZBX_CONDITION_OPERATOR_NOT_REGEXP:
if (NULL == zbx_regexp_match(value, pattern, NULL))
return SUCCEED;
break;
diff --git a/src/zabbix_server/lld/lld_item.c b/src/zabbix_server/lld/lld_item.c
index 7db84c0b3ae..d1cf75e32b7 100644
--- a/src/zabbix_server/lld/lld_item.c
+++ b/src/zabbix_server/lld/lld_item.c
@@ -3654,7 +3654,7 @@ static int lld_items_param_save(zbx_uint64_t hostid, zbx_vector_ptr_t *items, in
for (j = 0; j < item->item_params.values_num; j++)
{
- item_param = (zbx_item_param_t *)item->item_params.values[j];
+ item_param = item->item_params.values[j];
if (0 != (item_param->flags & ZBX_FLAG_ITEM_PARAM_DELETE))
{
@@ -3715,7 +3715,7 @@ static int lld_items_param_save(zbx_uint64_t hostid, zbx_vector_ptr_t *items, in
{
char delim = ' ';
- item_param = (zbx_item_param_t *)item->item_params.values[j];
+ item_param = item->item_params.values[j];
if (0 == item_param->item_parameterid)
{
diff --git a/src/zabbix_server/lld/lld_manager.c b/src/zabbix_server/lld/lld_manager.c
index 312dcb9a9cf..845b6dbc596 100644
--- a/src/zabbix_server/lld/lld_manager.c
+++ b/src/zabbix_server/lld/lld_manager.c
@@ -591,7 +591,7 @@ ZBX_THREAD_ENTRY(lld_manager_thread, args)
zbx_setproctitle("%s #%d started", get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
while (ZBX_IS_RUNNING())
{
@@ -609,9 +609,9 @@ ZBX_THREAD_ENTRY(lld_manager_thread, args)
processed_num = 0;
}
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
ret = zbx_ipc_service_recv(&lld_service, &timeout, &client, &message);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
sec = zbx_time();
zbx_update_env(sec);
diff --git a/src/zabbix_server/lld/lld_worker.c b/src/zabbix_server/lld/lld_worker.c
index 74038b6b5c7..72ec4c6b059 100644
--- a/src/zabbix_server/lld/lld_worker.c
+++ b/src/zabbix_server/lld/lld_worker.c
@@ -202,7 +202,7 @@ ZBX_THREAD_ENTRY(lld_worker_thread, args)
zbx_setproctitle("%s #%d started", get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
while (ZBX_IS_RUNNING())
{
@@ -219,13 +219,13 @@ ZBX_THREAD_ENTRY(lld_worker_thread, args)
processed_num = 0;
}
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
if (SUCCEED != zbx_ipc_socket_read(&lld_socket, &message))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot read LLD manager service request");
exit(EXIT_FAILURE);
}
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
time_read = zbx_time();
time_idle += time_read - time_now;
diff --git a/src/zabbix_server/odbc/odbc.c b/src/zabbix_server/odbc/odbc.c
index b6010192a5d..ff2a45897cb 100644
--- a/src/zabbix_server/odbc/odbc.c
+++ b/src/zabbix_server/odbc/odbc.c
@@ -23,13 +23,14 @@
#include "odbc.h"
-#include <sql.h>
-#include <sqlext.h>
-
#include "log.h"
#include "zbxjson.h"
#include "zbxalgo.h"
#include "zbxstr.h"
+#include "zbxexpr.h"
+
+#include <sql.h>
+#include <sqlext.h>
struct zbx_odbc_data_source
{
@@ -628,7 +629,7 @@ static int odbc_query_result_to_json(zbx_odbc_query_result_t *query_result, int
if (0 != isalpha((unsigned char)*p))
*p = toupper((unsigned char)*p);
- if (SUCCEED != is_macro_char(*p))
+ if (SUCCEED != zbx_is_macro_char(*p))
{
*error = zbx_dsprintf(*error, "Cannot convert column #%d name to macro.", i + 1);
goto out;
diff --git a/src/zabbix_server/operations.c b/src/zabbix_server/operations.c
index a45881b1524..be44b3055a6 100644
--- a/src/zabbix_server/operations.c
+++ b/src/zabbix_server/operations.c
@@ -368,7 +368,7 @@ static zbx_uint64_t add_discovered_host(const ZBX_DB_EVENT *event, int *status,
DBfree_result(result3);
/* for host uniqueness purposes */
- make_hostname(host); /* replace not-allowed symbols */
+ zbx_make_hostname(host); /* replace not-allowed symbols */
host_unique = DBget_unique_hostname_by_sample(host, "host");
zbx_free(host);
@@ -422,7 +422,7 @@ static zbx_uint64_t add_discovered_host(const ZBX_DB_EVENT *event, int *status,
DBfree_result(result3);
zbx_free(sql);
- make_hostname(host_visible); /* replace not-allowed symbols */
+ zbx_make_hostname(host_visible); /* replace not-allowed symbols */
zbx_free(hostname);
hostname = DBget_unique_hostname_by_sample(host_visible, "name");
zbx_free(host_visible);
diff --git a/src/zabbix_server/pinger/pinger.c b/src/zabbix_server/pinger/pinger.c
index 00df813928a..a79a86b6caf 100644
--- a/src/zabbix_server/pinger/pinger.c
+++ b/src/zabbix_server/pinger/pinger.c
@@ -74,7 +74,7 @@ static void process_value(zbx_uint64_t itemid, zbx_uint64_t *value_ui64, double
}
else
{
- init_result(&value);
+ zbx_init_agent_result(&value);
if (NULL != value_ui64)
SET_UI64_RESULT(&value, *value_ui64);
@@ -85,7 +85,7 @@ static void process_value(zbx_uint64_t itemid, zbx_uint64_t *value_ui64, double
zbx_preprocess_item_value(item.itemid, item.host.hostid, item.value_type, item.flags, &value, ts,
item.state, NULL);
- free_result(&value);
+ zbx_free_agent_result(&value);
}
clean:
DCrequeue_items(&item.itemid, &ts->sec, &errcode, 1);
@@ -182,30 +182,31 @@ static void process_values(icmpitem_t *items, int first_index, int last_index, Z
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
}
-static int parse_key_params(const char *key, const char *host_addr, icmpping_t *icmpping, char **addr, int *count,
- int *interval, int *size, int *timeout, icmppingsec_type_t *type, char *error, int max_error_len)
+static int zbx_parse_key_params(const char *key, const char *host_addr, icmpping_t *icmpping, char **addr,
+ int *count, int *interval, int *size, int *timeout, icmppingsec_type_t *type, char *error,
+ int max_error_len)
{
const char *tmp;
int ret = NOTSUPPORTED;
AGENT_REQUEST request;
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED != parse_item_key(key, &request))
+ if (SUCCEED != zbx_parse_item_key(key, &request))
{
zbx_snprintf(error, max_error_len, "Invalid item key format.");
goto out;
}
- if (0 == strcmp(get_rkey(&request), SERVER_ICMPPING_KEY))
+ if (0 == strcmp(get_rkey(&request), ZBX_SERVER_ICMPPING_KEY))
{
*icmpping = ICMPPING;
}
- else if (0 == strcmp(get_rkey(&request), SERVER_ICMPPINGLOSS_KEY))
+ else if (0 == strcmp(get_rkey(&request), ZBX_SERVER_ICMPPINGLOSS_KEY))
{
*icmpping = ICMPPINGLOSS;
}
- else if (0 == strcmp(get_rkey(&request), SERVER_ICMPPINGSEC_KEY))
+ else if (0 == strcmp(get_rkey(&request), ZBX_SERVER_ICMPPINGSEC_KEY))
{
*icmpping = ICMPPINGSEC;
}
@@ -303,7 +304,7 @@ static int parse_key_params(const char *key, const char *host_addr, icmpping_t *
ret = SUCCEED;
out:
- free_request(&request);
+ zbx_free_agent_request(&request);
return ret;
}
@@ -412,7 +413,7 @@ static void get_pinger_hosts(icmpitem_t **icmp_items, int *icmp_items_alloc, int
if (SUCCEED == rc)
{
- rc = parse_key_params(items[i].key, items[i].interface.addr, &icmpping, &addr, &count,
+ rc = zbx_parse_key_params(items[i].key, items[i].interface.addr, &icmpping, &addr, &count,
&interval, &size, &timeout, &type, error, sizeof(error));
}
@@ -550,7 +551,7 @@ ZBX_THREAD_ENTRY(pinger_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
if (NULL == items)
items = (icmpitem_t *)zbx_malloc(items, sizeof(icmpitem_t) * items_alloc);
diff --git a/src/zabbix_server/poller/checks_agent.c b/src/zabbix_server/poller/checks_agent.c
index f5b282f9734..edcbcf120ac 100644
--- a/src/zabbix_server/poller/checks_agent.c
+++ b/src/zabbix_server/poller/checks_agent.c
@@ -127,7 +127,7 @@ int get_value_agent(const DC_ITEM *item, AGENT_RESULT *result)
ret = NETWORK_ERROR;
}
else
- set_result_type(result, ITEM_VALUE_TYPE_TEXT, s.buffer);
+ zbx_set_agent_result_type(result, ITEM_VALUE_TYPE_TEXT, s.buffer);
}
else
SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Get value from agent failed: %s", zbx_socket_strerror()));
diff --git a/src/zabbix_server/poller/checks_db.c b/src/zabbix_server/poller/checks_db.c
index 3a51e5ea107..51136df1de2 100644
--- a/src/zabbix_server/poller/checks_db.c
+++ b/src/zabbix_server/poller/checks_db.c
@@ -49,9 +49,9 @@ int get_value_db(const DC_ITEM *item, AGENT_RESULT *result)
zabbix_log(LOG_LEVEL_DEBUG, "In %s() key_orig:'%s' query:'%s'", __func__, item->key_orig, item->params);
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED != parse_item_key(item->key, &request))
+ if (SUCCEED != zbx_parse_item_key(item->key, &request))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid item key format."));
goto out;
@@ -116,7 +116,7 @@ int get_value_db(const DC_ITEM *item, AGENT_RESULT *result)
if (SUCCEED != ret)
SET_MSG_RESULT(result, error);
out:
- free_request(&request);
+ zbx_free_agent_request(&request);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
diff --git a/src/zabbix_server/poller/checks_external.c b/src/zabbix_server/poller/checks_external.c
index a851d661eca..ecba2012e22 100644
--- a/src/zabbix_server/poller/checks_external.c
+++ b/src/zabbix_server/poller/checks_external.c
@@ -45,9 +45,9 @@ int get_value_external(const DC_ITEM *item, AGENT_RESULT *result)
zabbix_log(LOG_LEVEL_DEBUG, "In %s() key:'%s'", __func__, item->key);
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED != parse_item_key(item->key, &request))
+ if (SUCCEED != zbx_parse_item_key(item->key, &request))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid item key format."));
goto out;
@@ -79,7 +79,7 @@ int get_value_external(const DC_ITEM *item, AGENT_RESULT *result)
{
zbx_rtrim(buf, ZBX_WHITESPACE);
- set_result_type(result, ITEM_VALUE_TYPE_TEXT, buf);
+ zbx_set_agent_result_type(result, ITEM_VALUE_TYPE_TEXT, buf);
zbx_free(buf);
}
else
@@ -92,7 +92,7 @@ int get_value_external(const DC_ITEM *item, AGENT_RESULT *result)
out:
zbx_free(cmd);
- free_request(&request);
+ zbx_free_agent_request(&request);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
diff --git a/src/zabbix_server/poller/checks_internal.c b/src/zabbix_server/poller/checks_internal.c
index 833b49e7a79..9d1b5feeb20 100644
--- a/src/zabbix_server/poller/checks_internal.c
+++ b/src/zabbix_server/poller/checks_internal.c
@@ -18,7 +18,7 @@
**/
#include "checks_internal.h"
-#include "zbxserver.h"
+#include "zbxstats.h"
#include "checks_java.h"
#include "zbxself.h"
@@ -173,21 +173,23 @@ static int zbx_host_interfaces_discovery(zbx_uint64_t hostid, struct zbx_json *j
* *
* Purpose: retrieve data from Zabbix server (internally supported items) *
* *
- * Parameters: item - item we are interested in *
+ * Parameters: item - [IN] item we are interested in *
+ * result - [OUT] value of the requested item *
+ * zbx_config - [IN] Zabbix server/proxy config *
* *
* 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)
+int get_value_internal(const DC_ITEM *item, AGENT_RESULT *result, const zbx_config_comms_args_t *zbx_config)
{
AGENT_REQUEST request;
int ret = NOTSUPPORTED, nparams;
const char *tmp, *tmp1;
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED != parse_item_key(item->key, &request))
+ if (SUCCEED != zbx_parse_item_key(item->key, &request))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid item key format."));
goto out;
@@ -463,7 +465,6 @@ int get_value_internal(const DC_ITEM *item, AGENT_RESULT *result)
process_type = ZBX_PROCESS_TYPE_UNKNOWN;
break;
case ZBX_PROCESS_TYPE_DATASENDER:
- case ZBX_PROCESS_TYPE_HEARTBEAT:
if (0 == (program_type & ZBX_PROGRAM_TYPE_PROXY))
process_type = ZBX_PROCESS_TYPE_UNKNOWN;
break;
@@ -532,7 +533,7 @@ int get_value_internal(const DC_ITEM *item, AGENT_RESULT *result)
goto out;
}
- get_selfmon_stats(process_type, aggr_func, process_num, state, &value);
+ zbx_get_selfmon_stats(process_type, aggr_func, process_num, state, &value);
SET_DBL_RESULT(result, value);
}
@@ -764,11 +765,11 @@ int get_value_internal(const DC_ITEM *item, AGENT_RESULT *result)
/* work for both data received from internal and external source. */
zbx_json_addobject(&json, ZBX_PROTO_TAG_DATA);
- zbx_get_zabbix_stats(&json);
+ zbx_zabbix_stats_get(&json, zbx_config);
zbx_json_close(&json);
- set_result_type(result, ITEM_VALUE_TYPE_TEXT, json.buffer);
+ zbx_set_agent_result_type(result, ITEM_VALUE_TYPE_TEXT, json.buffer);
zbx_json_free(&json);
}
@@ -814,7 +815,7 @@ int get_value_internal(const DC_ITEM *item, AGENT_RESULT *result)
zbx_json_adduint64(&json, ZBX_PROTO_VALUE_ZABBIX_STATS_QUEUE,
DCget_item_queue(NULL, from, to));
- set_result_type(result, ITEM_VALUE_TYPE_TEXT, json.buffer);
+ zbx_set_agent_result_type(result, ITEM_VALUE_TYPE_TEXT, json.buffer);
zbx_json_free(&json);
}
@@ -929,7 +930,7 @@ out:
if (NOTSUPPORTED == ret && !ZBX_ISSET_MSG(result))
SET_MSG_RESULT(result, zbx_strdup(NULL, "Internal check is not supported."));
- free_request(&request);
+ zbx_free_agent_request(&request);
return ret;
}
diff --git a/src/zabbix_server/poller/checks_internal.h b/src/zabbix_server/poller/checks_internal.h
index b9a84b058af..b381f8c4ee3 100644
--- a/src/zabbix_server/poller/checks_internal.h
+++ b/src/zabbix_server/poller/checks_internal.h
@@ -21,10 +21,11 @@
#define ZABBIX_CHECKS_INTERNAL_H
#include "dbcache.h"
+#include "zbxcomms.h"
extern int CONFIG_SERVER_STARTUP_TIME;
-int get_value_internal(const DC_ITEM *item, AGENT_RESULT *result);
+int get_value_internal(const DC_ITEM *item, AGENT_RESULT *result, const zbx_config_comms_args_t *zbx_config);
int zbx_get_value_internal_ext(const char *param1, const AGENT_REQUEST *request, AGENT_RESULT *result);
diff --git a/src/zabbix_server/poller/checks_internal_server.c b/src/zabbix_server/poller/checks_internal_server.c
index f5abdfcd63f..7dd548db690 100644
--- a/src/zabbix_server/poller/checks_internal_server.c
+++ b/src/zabbix_server/poller/checks_internal_server.c
@@ -22,6 +22,8 @@
#include "zbxlld.h"
#include "dbcache.h"
#include "zbxha.h"
+#include "zbxjson.h"
+#include "zbxtime.h"
#include "checks_internal.h"
@@ -59,48 +61,75 @@ int zbx_get_value_internal_ext(const char *param1, const AGENT_REQUEST *request,
SET_UI64_RESULT(result, DCget_trigger_count());
}
else if (0 == strcmp(param1, "proxy")) /* zabbix["proxy",<hostname>,"lastaccess" OR "delay"] */
- {
+ { /* zabbix["proxy","discovery"] */
int value, res;
char *error = NULL;
/* this item is always processed by server */
- if (3 != nparams)
+ if (2 > nparams || 3 < nparams)
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
goto out;
}
- param2 = get_rparam(request, 2);
-
- if (0 == strcmp(param2, "lastaccess"))
+ if (2 == nparams)
{
- res = DCget_proxy_lastaccess_by_name(get_rparam(request, 1), &value, &error);
- }
- else if (0 == strcmp(param2, "delay"))
- {
- int lastaccess;
+ param2 = get_rparam(request, 1);
+
+ if (0 == strcmp(param2, "discovery"))
+ {
+ char *data;
+
+ if (SUCCEED == (res = zbx_proxy_discovery_get(&data, &error)))
+ SET_STR_RESULT(result, data);
+ else
+ SET_MSG_RESULT(result, error);
- if (SUCCEED == (res = DCget_proxy_delay_by_name(get_rparam(request, 1), &value, &error)) &&
- SUCCEED == (res = DCget_proxy_lastaccess_by_name(get_rparam(request, 1),
- &lastaccess, &error)))
+ if (SUCCEED != res)
+ goto out;
+ }
+ else
{
- value += (int)time(NULL) - lastaccess;
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
+ goto out;
}
}
else
{
- SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
- goto out;
- }
+ const char *param3 = get_rparam(request, 2);
- if (SUCCEED != res)
- {
- SET_MSG_RESULT(result, error);
- goto out;
- }
+ if (0 == strcmp(param3, "lastaccess"))
+ {
+ res = DCget_proxy_lastaccess_by_name(get_rparam(request, 1), &value, &error);
+ }
+ else if (0 == strcmp(param3, "delay"))
+ {
+ int lastaccess;
- SET_UI64_RESULT(result, value);
+ param2 = get_rparam(request, 1);
+
+ if (SUCCEED == (res = DCget_proxy_delay_by_name(param2, &value, &error)) &&
+ SUCCEED == (res = DCget_proxy_lastaccess_by_name(param2, &lastaccess,
+ &error)))
+ {
+ value += zbx_time() - lastaccess;
+ }
+ }
+ else
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
+ goto out;
+ }
+
+ if (SUCCEED != res)
+ {
+ SET_MSG_RESULT(result, error);
+ goto out;
+ }
+
+ SET_UI64_RESULT(result, value);
+ }
}
else if (0 == strcmp(param1, "vcache"))
{
diff --git a/src/zabbix_server/poller/checks_java.c b/src/zabbix_server/poller/checks_java.c
index eaf1a453a94..deb84ada900 100644
--- a/src/zabbix_server/poller/checks_java.c
+++ b/src/zabbix_server/poller/checks_java.c
@@ -70,7 +70,7 @@ static int parse_response(AGENT_RESULT *results, int *errcodes, int num, char *r
if (SUCCEED == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_VALUE, &value,
&value_alloc, NULL))
{
- set_result_type(&results[i], ITEM_VALUE_TYPE_TEXT, value);
+ zbx_set_agent_result_type(&results[i], ITEM_VALUE_TYPE_TEXT, value);
errcodes[i] = SUCCEED;
}
else if (SUCCEED == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_ERROR, &value,
diff --git a/src/zabbix_server/poller/checks_simple.c b/src/zabbix_server/poller/checks_simple.c
index d0eeb30a464..10ea6280a43 100644
--- a/src/zabbix_server/poller/checks_simple.c
+++ b/src/zabbix_server/poller/checks_simple.c
@@ -205,9 +205,9 @@ int get_value_simple(const DC_ITEM *item, AGENT_RESULT *result, zbx_vector_ptr_t
zabbix_log(LOG_LEVEL_DEBUG, "In %s() key_orig:'%s' addr:'%s'", __func__, item->key_orig, item->interface.addr);
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED != parse_item_key(item->key, &request))
+ if (SUCCEED != zbx_parse_item_key(item->key, &request))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid item key format."));
goto out;
@@ -254,7 +254,7 @@ int get_value_simple(const DC_ITEM *item, AGENT_RESULT *result, zbx_vector_ptr_t
else
{
/* it will execute item from a loadable module if any */
- if (SUCCEED == process(item->key, ZBX_PROCESS_MODULE_COMMAND, result))
+ if (SUCCEED == zbx_execute_agent_check(item->key, ZBX_PROCESS_MODULE_COMMAND, result))
ret = SUCCEED;
}
@@ -262,7 +262,7 @@ int get_value_simple(const DC_ITEM *item, AGENT_RESULT *result, zbx_vector_ptr_t
SET_MSG_RESULT(result, zbx_strdup(NULL, "Simple check is not supported."));
out:
- free_request(&request);
+ zbx_free_agent_request(&request);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
diff --git a/src/zabbix_server/poller/checks_simple_vmware.c b/src/zabbix_server/poller/checks_simple_vmware.c
index 7af91418100..03eb3548802 100644
--- a/src/zabbix_server/poller/checks_simple_vmware.c
+++ b/src/zabbix_server/poller/checks_simple_vmware.c
@@ -1012,11 +1012,11 @@ static void vmware_get_events(const zbx_vector_ptr_t *events, zbx_uint64_t event
continue;
add_result = (AGENT_RESULT *)zbx_malloc(add_result, sizeof(AGENT_RESULT));
- init_result(add_result);
+ zbx_init_agent_result(add_result);
- if (SUCCEED == set_result_type(add_result, item->value_type, event->message))
+ if (SUCCEED == zbx_set_agent_result_type(add_result, item->value_type, event->message))
{
- set_result_meta(add_result, event->key, 0);
+ zbx_set_agent_result_meta(add_result, event->key, 0);
if (ITEM_VALUE_TYPE_LOG == item->value_type)
{
diff --git a/src/zabbix_server/poller/checks_snmp.c b/src/zabbix_server/poller/checks_snmp.c
index 319dc472de0..c9691969525 100644
--- a/src/zabbix_server/poller/checks_snmp.c
+++ b/src/zabbix_server/poller/checks_snmp.c
@@ -355,6 +355,14 @@ end:
static int zbx_snmpv3_set_auth_protocol(const DC_ITEM *item, struct snmp_session *session)
{
+/* item snmpv3 authentication protocol */
+/* SYNC WITH PHP! */
+#define ITEM_SNMPV3_AUTHPROTOCOL_MD5 0
+#define ITEM_SNMPV3_AUTHPROTOCOL_SHA1 1
+#define ITEM_SNMPV3_AUTHPROTOCOL_SHA224 2
+#define ITEM_SNMPV3_AUTHPROTOCOL_SHA256 3
+#define ITEM_SNMPV3_AUTHPROTOCOL_SHA384 4
+#define ITEM_SNMPV3_AUTHPROTOCOL_SHA512 5
int ret = SUCCEED;
switch (item->snmpv3_authprotocol)
@@ -390,6 +398,12 @@ static int zbx_snmpv3_set_auth_protocol(const DC_ITEM *item, struct snmp_session
}
return ret;
+#undef ITEM_SNMPV3_AUTHPROTOCOL_MD5
+#undef ITEM_SNMPV3_AUTHPROTOCOL_SHA1
+#undef ITEM_SNMPV3_AUTHPROTOCOL_SHA224
+#undef ITEM_SNMPV3_AUTHPROTOCOL_SHA256
+#undef ITEM_SNMPV3_AUTHPROTOCOL_SHA384
+#undef ITEM_SNMPV3_AUTHPROTOCOL_SHA512
}
static char *zbx_get_snmp_type_error(u_char type)
@@ -451,6 +465,14 @@ static int zbx_get_snmp_response_error(const struct snmp_session *ss, const DC_I
static struct snmp_session *zbx_snmp_open_session(const DC_ITEM *item, char *error, size_t max_error_len)
{
+/* item snmpv3 privacy protocol */
+/* SYNC WITH PHP! */
+#define ITEM_SNMPV3_PRIVPROTOCOL_DES 0
+#define ITEM_SNMPV3_PRIVPROTOCOL_AES128 1
+#define ITEM_SNMPV3_PRIVPROTOCOL_AES192 2
+#define ITEM_SNMPV3_PRIVPROTOCOL_AES256 3
+#define ITEM_SNMPV3_PRIVPROTOCOL_AES192C 4
+#define ITEM_SNMPV3_PRIVPROTOCOL_AES256C 5
struct snmp_session session, *ss = NULL;
char addr[128];
#ifdef HAVE_IPV6
@@ -531,10 +553,10 @@ static struct snmp_session *zbx_snmp_open_session(const DC_ITEM *item, char *err
/* set the security level to authenticated, but not encrypted */
switch (item->snmpv3_securitylevel)
{
- case ITEM_SNMPV3_SECURITYLEVEL_NOAUTHNOPRIV:
+ case ZBX_ITEM_SNMPV3_SECURITYLEVEL_NOAUTHNOPRIV:
session.securityLevel = SNMP_SEC_LEVEL_NOAUTH;
break;
- case ITEM_SNMPV3_SECURITYLEVEL_AUTHNOPRIV:
+ case ZBX_ITEM_SNMPV3_SECURITYLEVEL_AUTHNOPRIV:
session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
if (FAIL == zbx_snmpv3_set_auth_protocol(item, &session))
@@ -556,7 +578,7 @@ static struct snmp_session *zbx_snmp_open_session(const DC_ITEM *item, char *err
goto end;
}
break;
- case ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV:
+ case ZBX_ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV:
session.securityLevel = SNMP_SEC_LEVEL_AUTHPRIV;
if (FAIL == zbx_snmpv3_set_auth_protocol(item, &session))
@@ -664,6 +686,12 @@ end:
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
return ss;
+#undef ITEM_SNMPV3_PRIVPROTOCOL_DES
+#undef ITEM_SNMPV3_PRIVPROTOCOL_AES128
+#undef ITEM_SNMPV3_PRIVPROTOCOL_AES192
+#undef ITEM_SNMPV3_PRIVPROTOCOL_AES256
+#undef ITEM_SNMPV3_PRIVPROTOCOL_AES192C
+#undef ITEM_SNMPV3_PRIVPROTOCOL_AES256C
}
static void zbx_snmp_close_session(struct snmp_session *session)
@@ -753,7 +781,7 @@ static int zbx_snmp_set_result(const struct variable_list *var, AGENT_RESULT *re
}
else
{
- set_result_type(result, ITEM_VALUE_TYPE_TEXT, strval_dyn);
+ zbx_set_agent_result_type(result, ITEM_VALUE_TYPE_TEXT, strval_dyn);
zbx_free(strval_dyn);
}
}
@@ -786,7 +814,7 @@ static int zbx_snmp_set_result(const struct variable_list *var, AGENT_RESULT *re
zbx_snprintf(buffer, sizeof(buffer), "%ld", *var->val.integer);
- set_result_type(result, ITEM_VALUE_TYPE_TEXT, buffer);
+ zbx_set_agent_result_type(result, ITEM_VALUE_TYPE_TEXT, buffer);
}
#ifdef OPAQUE_SPECIAL_TYPES
else if (ASN_OPAQUE_FLOAT == var->type)
@@ -1229,7 +1257,7 @@ static int zbx_snmp_walk(struct snmp_session *ss, const DC_ITEM *item, const cha
}
str_res = NULL;
- init_result(&snmp_result);
+ zbx_init_agent_result(&snmp_result);
if (SUCCEED == zbx_snmp_set_result(var, &snmp_result, &val_type))
{
@@ -1251,7 +1279,7 @@ static int zbx_snmp_walk(struct snmp_session *ss, const DC_ITEM *item, const cha
else
walk_cb_func(walk_cb_arg, snmp_oid, oid_index, snmp_result.str);
- free_result(&snmp_result);
+ zbx_free_agent_result(&snmp_result);
/* go to next variable */
memcpy((char *)anOID, (char *)var->name, var->name_length * sizeof(oid));
@@ -1680,9 +1708,9 @@ static int zbx_snmp_ddata_init(zbx_snmp_ddata_t *data, const char *key, char *er
{
int i, j, ret = CONFIG_ERROR;
- init_request(&data->request);
+ zbx_init_agent_request(&data->request);
- if (SUCCEED != parse_item_key(key, &data->request))
+ if (SUCCEED != zbx_parse_item_key(key, &data->request))
{
zbx_strlcpy(error, "Invalid SNMP OID: cannot parse expression.", max_error_len);
goto out;
@@ -1696,7 +1724,7 @@ static int zbx_snmp_ddata_init(zbx_snmp_ddata_t *data, const char *key, char *er
for (i = 0; i < data->request.nparam; i += 2)
{
- if (SUCCEED != is_discovery_macro(data->request.params[i]))
+ if (SUCCEED != zbx_is_discovery_macro(data->request.params[i]))
{
zbx_snprintf(error, max_error_len, "Invalid SNMP OID: macro \"%s\" is invalid",
data->request.params[i]);
@@ -1728,7 +1756,7 @@ static int zbx_snmp_ddata_init(zbx_snmp_ddata_t *data, const char *key, char *er
ret = SUCCEED;
out:
if (SUCCEED != ret)
- free_request(&data->request);
+ zbx_free_agent_request(&data->request);
return ret;
}
@@ -1760,7 +1788,7 @@ static void zbx_snmp_ddata_clean(zbx_snmp_ddata_t *data)
zbx_hashset_destroy(&data->objects);
- free_request(&data->request);
+ zbx_free_agent_request(&data->request);
}
static void zbx_snmp_walk_discovery_cb(void *arg, const char *snmp_oid, const char *index, const char *value)
@@ -1953,7 +1981,7 @@ static int zbx_snmp_process_dynamic(struct snmp_session *ss, const DC_ITEM *item
zbx_strlcat(oids_translated[j], to_verify_oids[j] + len, sizeof(oids_translated[j]));
}
- free_result(&results[j]);
+ zbx_free_agent_result(&results[j]);
}
}
diff --git a/src/zabbix_server/poller/checks_ssh.c b/src/zabbix_server/poller/checks_ssh.c
index 32ad5c78723..e53f9f0b414 100644
--- a/src/zabbix_server/poller/checks_ssh.c
+++ b/src/zabbix_server/poller/checks_ssh.c
@@ -30,9 +30,9 @@ int get_value_ssh(DC_ITEM *item, AGENT_RESULT *result)
int ret = NOTSUPPORTED;
const char *port, *encoding, *dns;
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED != parse_item_key(item->key, &request))
+ if (SUCCEED != zbx_parse_item_key(item->key, &request))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid item key format."));
goto out;
@@ -80,7 +80,7 @@ int get_value_ssh(DC_ITEM *item, AGENT_RESULT *result)
ret = ssh_run(item, result, ZBX_NULL2EMPTY_STR(encoding));
out:
- free_request(&request);
+ zbx_free_agent_request(&request);
return ret;
}
diff --git a/src/zabbix_server/poller/checks_telnet.c b/src/zabbix_server/poller/checks_telnet.c
index 4121d9b56d5..87279a24c55 100644
--- a/src/zabbix_server/poller/checks_telnet.c
+++ b/src/zabbix_server/poller/checks_telnet.c
@@ -28,9 +28,9 @@ int get_value_telnet(DC_ITEM *item, AGENT_RESULT *result)
int ret = NOTSUPPORTED;
const char *port, *encoding, *dns;
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED != parse_item_key(item->key, &request))
+ if (SUCCEED != zbx_parse_item_key(item->key, &request))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid item key format."));
goto out;
@@ -78,7 +78,7 @@ int get_value_telnet(DC_ITEM *item, AGENT_RESULT *result)
ret = telnet_run(item, result, ZBX_NULL2EMPTY_STR(encoding));
out:
- free_request(&request);
+ zbx_free_agent_request(&request);
return ret;
}
diff --git a/src/zabbix_server/poller/poller.c b/src/zabbix_server/poller/poller.c
index 09a7f3993c9..3feed6f1dbd 100644
--- a/src/zabbix_server/poller/poller.c
+++ b/src/zabbix_server/poller/poller.c
@@ -279,13 +279,14 @@ out:
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
}
-void zbx_free_result_ptr(AGENT_RESULT *result)
+void zbx_free_agent_result_ptr(AGENT_RESULT *result)
{
- free_result(result);
+ zbx_free_agent_result(result);
zbx_free(result);
}
-static int get_value(DC_ITEM *item, AGENT_RESULT *result, zbx_vector_ptr_t *add_results)
+static int get_value(DC_ITEM *item, AGENT_RESULT *result, zbx_vector_ptr_t *add_results,
+ const zbx_config_comms_args_t *zbx_config)
{
int res = FAIL;
@@ -303,7 +304,7 @@ static int get_value(DC_ITEM *item, AGENT_RESULT *result, zbx_vector_ptr_t *add_
res = get_value_simple(item, result, add_results);
break;
case ITEM_TYPE_INTERNAL:
- res = get_value_internal(item, result);
+ res = get_value_internal(item, result, zbx_config);
break;
case ITEM_TYPE_DB_MONITOR:
#ifdef HAVE_UNIXODBC
@@ -446,7 +447,7 @@ void zbx_prepare_items(DC_ITEM *items, int *errcodes, int num, AGENT_RESULT *res
for (i = 0; i < num; i++)
{
- init_result(&results[i]);
+ zbx_init_agent_result(&results[i]);
errcodes[i] = SUCCEED;
if (MACRO_EXPAND_YES == expand_macros)
@@ -697,7 +698,7 @@ void zbx_prepare_items(DC_ITEM *items, int *errcodes, int num, AGENT_RESULT *res
}
void zbx_check_items(DC_ITEM *items, int *errcodes, int num, AGENT_RESULT *results, zbx_vector_ptr_t *add_results,
- unsigned char poller_type)
+ unsigned char poller_type, const zbx_config_comms_args_t *zbx_config)
{
if (ITEM_TYPE_SNMP == items[0].type)
{
@@ -728,7 +729,7 @@ void zbx_check_items(DC_ITEM *items, int *errcodes, int num, AGENT_RESULT *resul
else if (1 == num)
{
if (SUCCEED == errcodes[0])
- errcodes[0] = get_value(&items[0], &results[0], add_results);
+ errcodes[0] = get_value(&items[0], &results[0], add_results, zbx_config);
}
else
THIS_SHOULD_NEVER_HAPPEN;
@@ -788,7 +789,7 @@ void zbx_clean_items(DC_ITEM *items, int num, AGENT_RESULT *results)
break;
}
- free_result(&results[i]);
+ zbx_free_agent_result(&results[i]);
}
}
@@ -798,6 +799,7 @@ void zbx_clean_items(DC_ITEM *items, int num, AGENT_RESULT *results)
* *
* Parameters: poller_type - [IN] poller type (ZBX_POLLER_TYPE_...) *
* nextcheck - [OUT] item nextcheck *
+ * zbx_config - [IN] server/proxy config *
* *
* Return value: number of items processed *
* *
@@ -805,7 +807,7 @@ void zbx_clean_items(DC_ITEM *items, int num, AGENT_RESULT *results)
* see DCconfig_get_poller_items() *
* *
******************************************************************************/
-static int get_values(unsigned char poller_type, int *nextcheck)
+static int get_values(unsigned char poller_type, int *nextcheck, const zbx_config_comms_args_t *zbx_config)
{
DC_ITEM item, *items;
AGENT_RESULT results[MAX_POLLER_ITEMS];
@@ -830,7 +832,7 @@ static int get_values(unsigned char poller_type, int *nextcheck)
zbx_vector_ptr_create(&add_results);
zbx_prepare_items(items, errcodes, num, results, MACRO_EXPAND_YES);
- zbx_check_items(items, errcodes, num, results, &add_results, poller_type);
+ zbx_check_items(items, errcodes, num, results, &add_results, poller_type, zbx_config);
zbx_timespec(&timespec);
@@ -927,7 +929,7 @@ static int get_values(unsigned char poller_type, int *nextcheck)
zbx_preprocessor_flush();
zbx_clean_items(items, num, results);
DCconfig_clean_items(items, NULL, num);
- zbx_vector_ptr_clear_ext(&add_results, (zbx_mem_free_func_t)zbx_free_result_ptr);
+ zbx_vector_ptr_clear_ext(&add_results, (zbx_mem_free_func_t)zbx_free_agent_result_ptr);
zbx_vector_ptr_destroy(&add_results);
if (NULL != data)
@@ -966,12 +968,12 @@ ZBX_THREAD_ENTRY(poller_thread, args)
get_program_type_string(poller_args_in->zbx_get_program_type_cb_arg()), server_num,
get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
scriptitem_es_engine_init();
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
- zbx_tls_init_child(poller_args_in->zbx_config_tls, poller_args_in->zbx_get_program_type_cb_arg);
+ zbx_tls_init_child(poller_args_in->zbx_config->zbx_config_tls, poller_args_in->zbx_get_program_type_cb_arg);
#endif
if (ZBX_POLLER_TYPE_HISTORY == poller_type)
{
@@ -999,7 +1001,7 @@ ZBX_THREAD_ENTRY(poller_thread, args)
old_total_sec);
}
- processed += get_values(poller_type, &nextcheck);
+ processed += get_values(poller_type, &nextcheck, poller_args_in->zbx_config);
total_sec += zbx_time() - sec;
sleeptime = zbx_calculate_sleeptime(nextcheck, POLLER_DELAY);
diff --git a/src/zabbix_server/poller/poller.h b/src/zabbix_server/poller/poller.h
index bacc7afeae6..3d71f519bc9 100644
--- a/src/zabbix_server/poller/poller.h
+++ b/src/zabbix_server/poller/poller.h
@@ -22,10 +22,11 @@
#include "zbxthreads.h"
#include "dbcache.h"
+#include "zbxcomms.h"
typedef struct
{
- zbx_config_tls_t *zbx_config_tls;
+ zbx_config_comms_args_t *zbx_config;
zbx_get_program_type_f zbx_get_program_type_cb_arg;
unsigned char poller_type;
}
@@ -44,8 +45,8 @@ void zbx_deactivate_item_interface(zbx_timespec_t *ts, DC_ITEM *item, unsigned
size_t *data_offset, const char *error);
void zbx_prepare_items(DC_ITEM *items, int *errcodes, int num, AGENT_RESULT *results, unsigned char expand_macros);
void zbx_check_items(DC_ITEM *items, int *errcodes, int num, AGENT_RESULT *results, zbx_vector_ptr_t *add_results,
- unsigned char poller_type);
+ unsigned char poller_type, const zbx_config_comms_args_t *zbx_config);
void zbx_clean_items(DC_ITEM *items, int num, AGENT_RESULT *results);
-void zbx_free_result_ptr(AGENT_RESULT *result);
+void zbx_free_agent_result_ptr(AGENT_RESULT *result);
#endif
diff --git a/src/zabbix_server/postinit.c b/src/zabbix_server/postinit.c
index 54779694589..c18a917214f 100644
--- a/src/zabbix_server/postinit.c
+++ b/src/zabbix_server/postinit.c
@@ -24,6 +24,7 @@
#include "zbxtasks.h"
#include "log.h"
#include "zbxnum.h"
+#include "valuecache.h"
#define ZBX_HIST_MACRO_NONE (-1)
#define ZBX_HIST_MACRO_ITEM_VALUE 0
@@ -442,6 +443,9 @@ int zbx_check_postinit_tasks(char **error)
DB_ROW row;
int ret = SUCCEED;
+ /* avoid filling value cache with unnecessary data during event name update */
+ zbx_vc_disable();
+
result = DBselect("select taskid from task where type=%d and status=%d", ZBX_TM_TASK_UPDATE_EVENTNAMES,
ZBX_TM_STATUS_NEW);
@@ -463,5 +467,7 @@ int zbx_check_postinit_tasks(char **error)
if (SUCCEED != ret)
*error = zbx_strdup(*error, "cannot update event names");
+ zbx_vc_enable();
+
return ret;
}
diff --git a/src/zabbix_server/preprocessor/preproc_manager.c b/src/zabbix_server/preprocessor/preproc_manager.c
index 262e79a41e8..fe77732b603 100644
--- a/src/zabbix_server/preprocessor/preproc_manager.c
+++ b/src/zabbix_server/preprocessor/preproc_manager.c
@@ -136,7 +136,7 @@ typedef struct
zbx_hashset_t item_config; /* item configuration L2 cache */
zbx_hashset_t history_cache; /* item value history cache */
zbx_hashset_t linked_items; /* linked items placed in queue */
- int cache_ts; /* cache timestamp */
+ zbx_uint64_t revision; /* the configuration revision */
zbx_uint64_t processed_num; /* processed value counter */
zbx_uint64_t queued_num; /* queued value counter */
zbx_uint64_t preproc_num; /* queued values with preprocessing steps */
@@ -192,16 +192,16 @@ static void request_free_steps(zbx_preprocessing_request_t *request)
static void preprocessor_sync_configuration(zbx_preprocessing_manager_t *manager)
{
zbx_hashset_iter_t iter;
- int ts;
+ zbx_uint64_t old_revision;
zbx_preproc_history_t *vault;
zbx_preproc_item_t *item;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
- ts = manager->cache_ts;
- DCconfig_get_preprocessable_items(&manager->item_config, &manager->cache_ts);
+ old_revision = manager->revision;
+ DCconfig_get_preprocessable_items(&manager->item_config, &manager->revision);
- if (ts != manager->cache_ts)
+ if (old_revision != manager->revision)
{
/* drop items with removed preprocessing steps from preprocessing history cache */
zbx_hashset_iter_reset(&manager->history_cache, &iter);
@@ -219,11 +219,9 @@ static void preprocessor_sync_configuration(zbx_preprocessing_manager_t *manager
zbx_hashset_iter_reset(&manager->item_config, &iter);
while (NULL != (item = (zbx_preproc_item_t *)zbx_hashset_iter_next(&iter)))
{
- if (ts >= item->update_time && ZBX_PREPROC_MACRO_UPDATE_FALSE == item->macro_update)
+ if (item->preproc_revision < manager->revision)
continue;
- item->macro_update = ZBX_PREPROC_MACRO_UPDATE_FALSE;
-
if (NULL == (vault = (zbx_preproc_history_t *)zbx_hashset_search(&manager->history_cache,
&item->itemid)))
{
@@ -641,7 +639,7 @@ static void preproc_item_value_clear(zbx_preproc_item_value_t *value)
if (NULL != value->result)
{
- free_result(value->result);
+ zbx_free_agent_result(value->result);
zbx_free(value->result);
}
}
@@ -1173,7 +1171,7 @@ static int preprocessor_set_variant_result(zbx_preprocessing_request_t *request,
if (ZBX_VARIANT_NONE == value->type)
{
if (NULL != request->value.result)
- free_result(request->value.result);
+ zbx_free_agent_result(request->value.result);
zbx_free(request->value.error);
@@ -1203,13 +1201,13 @@ static int preprocessor_set_variant_result(zbx_preprocessing_request_t *request,
if (NULL == request->value.result)
{
request->value.result = (AGENT_RESULT *)zbx_malloc(NULL, sizeof(AGENT_RESULT));
- init_result(request->value.result);
+ zbx_init_agent_result(request->value.result);
}
else
{
/* preserve eventlog related information */
if (ITEM_VALUE_TYPE_LOG != request->value_type)
- free_result(request->value.result);
+ zbx_free_agent_result(request->value.result);
}
if (ITEM_STATE_NOTSUPPORTED == request->value.state)
@@ -1974,7 +1972,7 @@ ZBX_THREAD_ENTRY(preprocessing_manager_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
if (FAIL == zbx_ipc_service_start(&service, ZBX_IPC_SERVICE_PREPROCESSING, &error))
{
@@ -2007,9 +2005,9 @@ ZBX_THREAD_ENTRY(preprocessing_manager_thread, args)
manager.processed_num = 0;
}
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
ret = zbx_ipc_service_recv(&service, &timeout, &client, &message);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
sec = zbx_time();
zbx_update_env(sec);
diff --git a/src/zabbix_server/preprocessor/preproc_worker.c b/src/zabbix_server/preprocessor/preproc_worker.c
index 983bf0ce25a..c33a85c509e 100644
--- a/src/zabbix_server/preprocessor/preproc_worker.c
+++ b/src/zabbix_server/preprocessor/preproc_worker.c
@@ -607,7 +607,7 @@ ZBX_THREAD_ENTRY(preprocessing_worker_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
memset(&dep_request, 0, sizeof(dep_request));
zbx_variant_set_none(&dep_request.value);
@@ -616,7 +616,7 @@ ZBX_THREAD_ENTRY(preprocessing_worker_thread, args)
while (ZBX_IS_RUNNING())
{
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
if (SUCCEED != zbx_ipc_socket_read(&socket, &message))
{
@@ -624,7 +624,7 @@ ZBX_THREAD_ENTRY(preprocessing_worker_thread, args)
exit(EXIT_FAILURE);
}
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
zbx_update_env(zbx_time());
switch (message.code)
diff --git a/src/zabbix_server/preprocessor/preprocessing.c b/src/zabbix_server/preprocessor/preprocessing.c
index 73d028ba909..b026d83248e 100644
--- a/src/zabbix_server/preprocessor/preprocessing.c
+++ b/src/zabbix_server/preprocessor/preprocessing.c
@@ -683,7 +683,7 @@ void zbx_preprocessor_free_dep_results(zbx_preproc_dep_result_t *results, int re
for (i = 0; i < results_num; i++)
{
- free_result(&results[i].value);
+ zbx_free_agent_result(&results[i].value);
zbx_free(results[i].error);
zbx_vector_ptr_clear_ext(&results[i].history, (zbx_clean_func_t)zbx_preproc_op_history_free);
zbx_vector_ptr_destroy(&results[i].history);
@@ -1220,7 +1220,7 @@ static void agent_result_set_value(zbx_variant_t *value, zbx_item_value_type_t v
unsigned char type;
zbx_log_t *log;
- init_result(result);
+ zbx_init_agent_result(result);
if (NULL != *error)
return;
diff --git a/src/zabbix_server/proxyconfigread/Makefile.am b/src/zabbix_server/proxyconfigread/Makefile.am
new file mode 100644
index 00000000000..729575b5f3b
--- /dev/null
+++ b/src/zabbix_server/proxyconfigread/Makefile.am
@@ -0,0 +1,9 @@
+## Process this file with automake to produce Makefile.in
+
+noinst_LIBRARIES = libzbxproxyconfigread.a
+
+libzbxproxyconfigread_a_SOURCES = \
+ proxyconfig_read.c \
+ proxyconfig_read.h
+
+libzbxproxyconfigread_a_CFLAGS = -I$(top_srcdir)/src
diff --git a/src/zabbix_server/proxyconfigread/proxyconfig_read.c b/src/zabbix_server/proxyconfigread/proxyconfig_read.c
new file mode 100644
index 00000000000..4948ad076e4
--- /dev/null
+++ b/src/zabbix_server/proxyconfigread/proxyconfig_read.c
@@ -0,0 +1,1201 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2022 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 "proxyconfig_read.h"
+
+#include "proxy.h"
+#include "zbxdbhigh.h"
+#include "libs/zbxkvs/kvs.h"
+#include "libs/zbxvault/vault.h"
+#include "log.h"
+#include "zbxcommshigh.h"
+#include "zbxcompress.h"
+#include "zbxcrypto.h"
+
+extern char *CONFIG_VAULTDBPATH;
+extern int CONFIG_TRAPPER_TIMEOUT;
+
+typedef struct
+{
+ char *path;
+ zbx_hashset_t keys;
+}
+zbx_keys_path_t;
+
+
+static int keys_path_compare(const void *d1, const void *d2)
+{
+ const zbx_keys_path_t *ptr1 = *((const zbx_keys_path_t * const *)d1);
+ const zbx_keys_path_t *ptr2 = *((const zbx_keys_path_t * const *)d2);
+
+ return strcmp(ptr1->path, ptr2->path);
+}
+
+static zbx_hash_t keys_hash(const void *data)
+{
+ return ZBX_DEFAULT_STRING_HASH_ALGO(*(const char * const *)data, strlen(*(const char * const *)data),
+ ZBX_DEFAULT_HASH_SEED);
+}
+
+static int keys_compare(const void *d1, const void *d2)
+{
+ return strcmp(*(const char * const *)d1, *(const char * const *)d2);
+}
+
+static void key_path_free(void *data)
+{
+ zbx_hashset_iter_t iter;
+ char **ptr;
+ zbx_keys_path_t *keys_path = (zbx_keys_path_t *)data;
+
+ zbx_hashset_iter_reset(&keys_path->keys, &iter);
+ while (NULL != (ptr = (char **)zbx_hashset_iter_next(&iter)))
+ zbx_free(*ptr);
+ zbx_hashset_destroy(&keys_path->keys);
+
+ zbx_free(keys_path->path);
+ zbx_free(keys_path);
+}
+
+static void get_macro_secrets(const zbx_vector_ptr_t *keys_paths, struct zbx_json *j)
+{
+ int i;
+ zbx_kvs_t kvs;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ zbx_kvs_create(&kvs, 100);
+
+ zbx_json_addobject(j, ZBX_PROTO_TAG_MACRO_SECRETS);
+
+ for (i = 0; i < keys_paths->values_num; i++)
+ {
+ zbx_keys_path_t *keys_path;
+ char *error = NULL, **ptr;
+ zbx_hashset_iter_t iter;
+
+ keys_path = (zbx_keys_path_t *)keys_paths->values[i];
+ if (FAIL == zbx_vault_kvs_get(keys_path->path, &kvs, &error))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot get secrets for path \"%s\": %s", keys_path->path, error);
+ zbx_free(error);
+ continue;
+ }
+
+ zbx_json_addobject(j, keys_path->path);
+
+ zbx_hashset_iter_reset(&keys_path->keys, &iter);
+ while (NULL != (ptr = (char **)zbx_hashset_iter_next(&iter)))
+ {
+ zbx_kv_t *kv, kv_local;
+
+ kv_local.key = *ptr;
+
+ if (NULL != (kv = zbx_kvs_search(&kvs, &kv_local)))
+ zbx_json_addstring(j, kv->key, kv->value, ZBX_JSON_TYPE_STRING);
+ }
+ zbx_json_close(j);
+
+ zbx_kvs_clear(&kvs);
+ }
+
+ zbx_json_close(j);
+ zbx_kvs_destroy(&kvs);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: add database row to the proxy config json data *
+ * *
+ * Parameters: j - [OUT] the output json *
+ * row - [IN] the database row to add *
+ * table - [IN] the table configuration *
+ * recids - [OUT] the record identifiers (optional) *
+ * *
+ ******************************************************************************/
+static void proxyconfig_add_row(struct zbx_json *j, const DB_ROW row, const ZBX_TABLE *table,
+ zbx_vector_uint64_t *recids)
+{
+ int fld = 0, i;
+
+ zbx_json_addstring(j, NULL, row[fld++], ZBX_JSON_TYPE_INT);
+
+ if (NULL != recids)
+ {
+ zbx_uint64_t recid;
+
+ ZBX_STR2UINT64(recid, row[0]);
+ zbx_vector_uint64_append(recids, recid);
+ }
+
+ for (i = 0; 0 != table->fields[i].name; i++)
+ {
+ if (0 == (table->fields[i].flags & ZBX_PROXY))
+ continue;
+
+ switch (table->fields[i].type)
+ {
+ case ZBX_TYPE_INT:
+ case ZBX_TYPE_UINT:
+ case ZBX_TYPE_ID:
+ if (SUCCEED != DBis_null(row[fld]))
+ zbx_json_addstring(j, NULL, row[fld], ZBX_JSON_TYPE_INT);
+ else
+ zbx_json_addstring(j, NULL, NULL, ZBX_JSON_TYPE_NULL);
+ break;
+ default:
+ zbx_json_addstring(j, NULL, row[fld], ZBX_JSON_TYPE_STRING);
+ break;
+ }
+ fld++;
+ }
+}
+
+/******************************************************************************
+ * *
+ * Purpose: get table fields, add them to output json and sql select *
+ * *
+ * Parameters: sql - [IN/OUT] the sql select string *
+ * sql_alloc - [IN/OUT] *
+ * sql_offset - [IN/OUT] *
+ * table - [IN] the table *
+ * j - [OUT] the output json *
+ * *
+ ******************************************************************************/
+static void proxyconfig_get_fields(char **sql, size_t *sql_alloc, size_t *sql_offset, const ZBX_TABLE *table,
+ struct zbx_json *j)
+{
+ int i;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "select %s", table->recid);
+
+ zbx_json_addarray(j, "fields");
+ zbx_json_addstring(j, NULL, table->recid, ZBX_JSON_TYPE_STRING);
+
+ for (i = 0; 0 != table->fields[i].name; i++)
+ {
+ if (0 == (table->fields[i].flags & ZBX_PROXY))
+ continue;
+
+ zbx_chrcpy_alloc(sql, sql_alloc, sql_offset, ',');
+ zbx_strcpy_alloc(sql, sql_alloc, sql_offset, table->fields[i].name);
+
+ zbx_json_addstring(j, NULL, table->fields[i].name, ZBX_JSON_TYPE_STRING);
+ }
+
+ zbx_json_close(j);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+}
+
+/******************************************************************************
+ * *
+ * Purpose: get global/host macro data of the specified hosts from database *
+ * *
+ * Parameters: table_name - [IN] table name - globalmacro/hostmacro *
+ * hostids - [IN] the target hostids for hostmacro table and *
+ * NULL for globalmacro table *
+ * keys_paths - [OUT] the vault macro path/key *
+ * j - [OUT] the output json *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the data was read successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_get_macro_updates(const char *table_name, const zbx_vector_uint64_t *hostids,
+ zbx_vector_ptr_t *keys_paths, struct zbx_json *j, char **error)
+{
+ DB_RESULT result;
+ DB_ROW row;
+ const ZBX_TABLE *table;
+ char *sql;
+ size_t sql_alloc = 4 * ZBX_KIBIBYTE, sql_offset = 0;
+ int i, ret = FAIL, offset;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ table = DBget_table(table_name);
+ zbx_json_addobject(j, table->table);
+
+ sql = (char *)zbx_malloc(NULL, sql_alloc);
+
+ proxyconfig_get_fields(&sql, &sql_alloc, &sql_offset, table, j);
+ zbx_json_addarray(j, "data");
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " from %s", table->table);
+
+ if (NULL != hostids)
+ {
+ /* no hosts to get macros from, send empty data */
+ if (0 == hostids->values_num)
+ goto end;
+
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", hostids->values, hostids->values_num);
+ offset = 1;
+ }
+ else
+ offset = 0;
+
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by ");
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, table->recid);
+
+ if (NULL == (result = DBselect("%s", sql)))
+ {
+ *error = zbx_dsprintf(*error, "failed to get data from table \"%s\"", table->table);
+ goto out;
+ }
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " from %s", table->table);
+
+ while (NULL != (row = DBfetch(result)))
+ {
+ zbx_keys_path_t *keys_path, keys_path_local;
+ unsigned char type;
+ char *path, *key;
+
+ zbx_json_addarray(j, NULL);
+ proxyconfig_add_row(j, row, table, NULL);
+ zbx_json_close(j);
+
+ ZBX_STR2UCHAR(type, row[3 + offset]);
+
+ if (ZBX_MACRO_VALUE_VAULT != type)
+ continue;
+
+ zbx_strsplit_last(row[2 + offset], ':', &path, &key);
+
+ if (NULL == key)
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot parse macro \"%s\" value \"%s\"",
+ row[1 + offset], row[2 + offset]);
+ goto next;
+ }
+
+ if (NULL != CONFIG_VAULTDBPATH && 0 == strcasecmp(CONFIG_VAULTDBPATH, path) &&
+ (0 == strcasecmp(key, ZBX_PROTO_TAG_PASSWORD)
+ || 0 == strcasecmp(key, ZBX_PROTO_TAG_USERNAME)))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot parse macro \"%s\" value \"%s\":"
+ " database credentials should not be used with Vault macros",
+ row[1 + offset], row[2 + offset]);
+ goto next;
+ }
+
+ keys_path_local.path = path;
+
+ if (FAIL == (i = zbx_vector_ptr_search(keys_paths, &keys_path_local, keys_path_compare)))
+ {
+ keys_path = zbx_malloc(NULL, sizeof(zbx_keys_path_t));
+ keys_path->path = path;
+
+ zbx_hashset_create(&keys_path->keys, 0, keys_hash, keys_compare);
+ zbx_hashset_insert(&keys_path->keys, &key, sizeof(char *));
+
+ zbx_vector_ptr_append(keys_paths, keys_path);
+ path = key = NULL;
+ }
+ else
+ {
+ keys_path = (zbx_keys_path_t *)keys_paths->values[i];
+ if (NULL == zbx_hashset_search(&keys_path->keys, &key))
+ {
+ zbx_hashset_insert(&keys_path->keys, &key, sizeof(char **));
+ key = NULL;
+ }
+ }
+next:
+ zbx_free(key);
+ zbx_free(path);
+ }
+ DBfree_result(result);
+end:
+ zbx_json_close(j);
+ zbx_json_close(j);
+
+ ret = SUCCEED;
+out:
+ zbx_free(sql);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: get table data from database *
+ * *
+ * Parameters: table_name - [IN] table name - *
+ * key_name - [IN] the key field name used to select rows *
+ * (all rows selected when NULL) *
+ * key_ids - [IN] the key values used to select rows (optional)*
+ * filter - [IN] custom filter to apply when selecting rows *
+ * (optional) *
+ * recids - [OUT] the selected record identifiers, sorted *
+ * (optional) *
+ * j - [OUT] the output json *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the data was read successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_get_table_data(const char *table_name, const char *key_name,
+ const zbx_vector_uint64_t *key_ids, const char *filter, zbx_vector_uint64_t *recids, struct zbx_json *j,
+ char **error)
+{
+ DB_RESULT result;
+ DB_ROW row;
+ const ZBX_TABLE *table;
+ char *sql = NULL;
+ size_t sql_alloc = 4 * ZBX_KIBIBYTE, sql_offset = 0;
+ int ret = FAIL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ table = DBget_table(table_name);
+ zbx_json_addobject(j, table->table);
+
+ sql = (char *)zbx_malloc(NULL, sql_alloc);
+ proxyconfig_get_fields(&sql, &sql_alloc, &sql_offset, table, j);
+
+ zbx_json_addarray(j, ZBX_PROTO_TAG_DATA);
+
+ if (NULL == key_ids || 0 != key_ids->values_num)
+ {
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " from %s", table->table);
+
+ if (NULL != key_ids || NULL != filter)
+ {
+ const char *keyword = " where";
+
+ if (NULL != key_ids)
+ {
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, keyword);
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, key_name, key_ids->values,
+ key_ids->values_num);
+ keyword = " and";
+ }
+
+ if (NULL != filter)
+ {
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, keyword);
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, filter);
+ }
+ }
+
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by ");
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, table->recid);
+
+ if (NULL == (result = DBselect("%s", sql)))
+ {
+ *error = zbx_dsprintf(*error, "failed to get data from table \"%s\"", table->table);
+ goto out;
+ }
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " from %s", table->table);
+
+ while (NULL != (row = DBfetch(result)))
+ {
+ zbx_json_addarray(j, NULL);
+ proxyconfig_add_row(j, row, table, recids);
+ zbx_json_close(j);
+ }
+ DBfree_result(result);
+ }
+
+ zbx_json_close(j);
+ zbx_json_close(j);
+
+ if (NULL != recids)
+ zbx_vector_uint64_sort(recids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
+ ret = SUCCEED;
+out:
+ zbx_free(sql);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+
+ return ret;
+}
+
+typedef struct
+{
+ zbx_uint64_t itemid;
+ zbx_uint64_t master_itemid;
+ DB_ROW row;
+ int cols_num;
+}
+zbx_proxyconfig_dep_item_t;
+
+ZBX_PTR_VECTOR_DECL(proxyconfig_dep_item_ptr, zbx_proxyconfig_dep_item_t *)
+ZBX_PTR_VECTOR_IMPL(proxyconfig_dep_item_ptr, zbx_proxyconfig_dep_item_t *)
+
+static void proxyconfig_dep_item_free(zbx_proxyconfig_dep_item_t *item)
+{
+ int i;
+
+ for (i = 0; i < item->cols_num; i++)
+ zbx_free(item->row[i]);
+
+ zbx_free(item->row);
+ zbx_free(item);
+}
+
+static zbx_proxyconfig_dep_item_t *proxyconfig_dep_item_create(zbx_uint64_t itemid, zbx_uint64_t master_itemid,
+ const DB_ROW row, int cols_num)
+{
+ zbx_proxyconfig_dep_item_t *item;
+ int i;
+
+ item = (zbx_proxyconfig_dep_item_t *)zbx_malloc(NULL, sizeof(zbx_proxyconfig_dep_item_t));
+ item->itemid = itemid;
+ item->master_itemid = master_itemid;
+ item->cols_num = cols_num;
+ item->row = (DB_ROW)zbx_malloc(NULL, sizeof(char *) * (size_t)cols_num);
+
+ for (i = 0; i < cols_num; i++)
+ {
+ if (NULL == row[i])
+ item->row[i] = NULL;
+ else
+ item->row[i] = zbx_strdup(NULL, row[i]);
+ }
+
+ return item;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: get item data from items table *
+ * *
+ * Parameters: hostids - [IN] the target host identifiers *
+ * itemids - [IN] the selected item identifiers, sorted *
+ * j - [OUT] the output json *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the data was read successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_get_item_data(const zbx_vector_uint64_t *hostids, zbx_vector_uint64_t *itemids,
+ struct zbx_json *j, char **error)
+{
+ DB_RESULT result;
+ DB_ROW row;
+ const ZBX_TABLE *table;
+ char *sql;
+ size_t sql_alloc = 4 * ZBX_KIBIBYTE, sql_offset = 0;
+ int ret = FAIL, fld_key = -1, fld_type = -1, fld_master_itemid = -1, i, fld, dep_items_num;
+ zbx_uint64_t itemid, master_itemid;
+
+ zbx_vector_proxyconfig_dep_item_ptr_t dep_items;
+ zbx_hashset_t items;
+ zbx_proxyconfig_dep_item_t *dep_item;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ zbx_hashset_create(&items, 1000, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+ zbx_vector_proxyconfig_dep_item_ptr_create(&dep_items);
+
+ table = DBget_table("items");
+
+ /* get type, key_ field indexes used to check if item is processed by server */
+ for (i = 0, fld = 1; 0 != table->fields[i].name; i++)
+ {
+ if (0 == (table->fields[i].flags & ZBX_PROXY))
+ continue;
+
+ if (0 == strcmp(table->fields[i].name, "type"))
+ fld_type = fld;
+ else if (0 == strcmp(table->fields[i].name, "key_"))
+ fld_key = fld;
+ else if (0 == strcmp(table->fields[i].name, "master_itemid"))
+ fld_master_itemid = fld;
+ fld++;
+ }
+
+ if (-1 == fld_type || -1 == fld_key || -1 == fld_master_itemid)
+ {
+ THIS_SHOULD_NEVER_HAPPEN;
+ exit(EXIT_FAILURE);
+ }
+
+ zbx_json_addobject(j, table->table);
+
+ sql = (char *)zbx_malloc(NULL, sql_alloc);
+ proxyconfig_get_fields(&sql, &sql_alloc, &sql_offset, table, j);
+
+ zbx_json_addarray(j, ZBX_PROTO_TAG_DATA);
+
+ if (0 != hostids->values_num)
+ {
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " from %s where", table->table);
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", hostids->values, hostids->values_num);
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " and flags<>%d and type<>%d",
+ ZBX_FLAG_DISCOVERY_PROTOTYPE, ITEM_TYPE_CALCULATED);
+
+ if (NULL == (result = DBselect("%s", sql)))
+ {
+ *error = zbx_dsprintf(*error, "failed to get data from table \"%s\"", table->table);
+ goto out;
+ }
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " from %s", table->table);
+
+ while (NULL != (row = DBfetch(result)))
+ {
+ unsigned char type;
+
+ ZBX_STR2UCHAR(type, row[fld_type]);
+ if (SUCCEED == is_item_processed_by_server(type, row[fld_key]))
+ continue;
+
+ ZBX_DBROW2UINT64(itemid, row[0]);
+
+ if (ITEM_TYPE_DEPENDENT != atoi(row[fld_type]))
+ {
+ zbx_json_addarray(j, NULL);
+ proxyconfig_add_row(j, row, table, itemids);
+ zbx_json_close(j);
+
+ zbx_hashset_insert(&items, &itemid, sizeof(itemid));
+ }
+ else
+ {
+ ZBX_DBROW2UINT64(master_itemid, row[fld_master_itemid]);
+ dep_item = proxyconfig_dep_item_create(itemid, master_itemid, row, fld);
+ zbx_vector_proxyconfig_dep_item_ptr_append(&dep_items, dep_item);
+ }
+ }
+ DBfree_result(result);
+
+ /* add dependent items processed by proxy */
+ if (0 != dep_items.values_num)
+ {
+ do
+ {
+ dep_items_num = dep_items.values_num;
+
+ for (i = 0; i < dep_items.values_num; )
+ {
+ dep_item = dep_items.values[i];
+
+ if (NULL != zbx_hashset_search(&items, &dep_item->master_itemid))
+ {
+ zbx_json_addarray(j, NULL);
+ proxyconfig_add_row(j, dep_item->row, table, itemids);
+ zbx_json_close(j);
+
+ zbx_hashset_insert(&items, &dep_item->itemid, sizeof(zbx_uint64_t));
+ proxyconfig_dep_item_free(dep_item);
+ zbx_vector_proxyconfig_dep_item_ptr_remove_noorder(&dep_items, i);
+ }
+ else
+ i++;
+ }
+ }
+ while (dep_items_num != dep_items.values_num);
+ }
+ }
+
+ zbx_json_close(j);
+ zbx_json_close(j);
+
+ zbx_vector_uint64_sort(itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
+ ret = SUCCEED;
+out:
+ zbx_free(sql);
+
+ zbx_vector_proxyconfig_dep_item_ptr_clear_ext(&dep_items, proxyconfig_dep_item_free);
+ zbx_vector_proxyconfig_dep_item_ptr_destroy(&dep_items);
+ zbx_hashset_destroy(&items);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: get host and related table data from database *
+ * *
+ * Parameters: hostids - [IN] the target host identifiers *
+ * j - [OUT] the output json *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the data was read successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_get_host_data(const zbx_vector_uint64_t *hostids, struct zbx_json *j, char **error)
+{
+ zbx_vector_uint64_t interfaceids, itemids;
+ int ret = FAIL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ zbx_vector_uint64_create(&interfaceids);
+ zbx_vector_uint64_create(&itemids);
+
+ if (SUCCEED != proxyconfig_get_table_data("hosts", "hostid", hostids, NULL, NULL, j, error))
+ goto out;
+
+ if (SUCCEED != proxyconfig_get_table_data("interface", "hostid", hostids, NULL, &interfaceids, j, error))
+ goto out;
+
+ if (SUCCEED != proxyconfig_get_table_data("interface_snmp", "interfaceid", &interfaceids, NULL, NULL,
+ j, error))
+ {
+ goto out;
+ }
+
+ if (SUCCEED != proxyconfig_get_table_data("host_inventory", "hostid", hostids, NULL, NULL, j, error))
+ goto out;
+
+ if (SUCCEED != proxyconfig_get_item_data(hostids, &itemids, j, error))
+ goto out;
+
+ if (SUCCEED != proxyconfig_get_table_data("item_rtdata", "itemid", &itemids, NULL, NULL, j, error))
+ goto out;
+
+ if (SUCCEED != proxyconfig_get_table_data("item_preproc", "itemid", &itemids, NULL, NULL, j, error))
+ goto out;
+
+ if (SUCCEED != proxyconfig_get_table_data("item_parameter", "itemid", &itemids, NULL, NULL, j, error))
+ goto out;
+
+ ret = SUCCEED;
+out:
+ zbx_vector_uint64_destroy(&itemids);
+ zbx_vector_uint64_destroy(&interfaceids);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: get discovery rule and checks data from database *
+ * *
+ * Parameters: proxy - [IN] the target proxy *
+ * j - [OUT] the output json *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the data was read successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_get_drules_data(const DC_PROXY *proxy, struct zbx_json *j, char **error)
+{
+ zbx_vector_uint64_t druleids;
+ zbx_vector_uint64_t proxy_hostids;
+ int ret = FAIL;
+ char *filter = NULL;
+ size_t filter_alloc = 0, filter_offset = 0;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ zbx_vector_uint64_create(&druleids);
+ zbx_vector_uint64_create(&proxy_hostids);
+
+ zbx_vector_uint64_append(&proxy_hostids, proxy->hostid);
+
+ zbx_snprintf_alloc(&filter, &filter_alloc, &filter_offset, " status=%d", DRULE_STATUS_MONITORED);
+
+ if (SUCCEED != proxyconfig_get_table_data("drules", "proxy_hostid", &proxy_hostids, filter, &druleids, j,
+ error))
+ {
+ goto out;
+ }
+
+ if (SUCCEED != proxyconfig_get_table_data("dchecks", "druleid", &druleids, NULL, NULL, j, error))
+ goto out;
+
+ ret = SUCCEED;
+out:
+ zbx_free(filter);
+ zbx_vector_uint64_destroy(&proxy_hostids);
+ zbx_vector_uint64_destroy(&druleids);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: get global regular expression (regexps/expressions) data from *
+ * database *
+ * *
+ * Parameters: j - [OUT] the output json *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the data was read successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_get_expression_data(struct zbx_json *j, char **error)
+{
+ zbx_vector_uint64_t regexpids;
+ int ret = FAIL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ zbx_vector_uint64_create(&regexpids);
+
+ if (SUCCEED != proxyconfig_get_table_data("regexps", NULL, NULL, NULL, &regexpids, j, error))
+ goto out;
+
+ if (SUCCEED != proxyconfig_get_table_data("expressions", "regexpid", &regexpids, NULL, NULL, j, error))
+ goto out;
+
+ ret = SUCCEED;
+out:
+ zbx_vector_uint64_destroy(&regexpids);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: get httptest and related data from database *
+ * *
+ * Parameters: httptestids - [IN] the httptest identifiers *
+ * j - [OUT] the output json *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - the data was read successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int proxyconfig_get_httptest_data(const zbx_vector_uint64_t *httptestids, struct zbx_json *j, char **error)
+{
+ zbx_vector_uint64_t httpstepids;
+ int ret = FAIL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ zbx_vector_uint64_create(&httpstepids);
+
+ if (SUCCEED != proxyconfig_get_table_data("httptest", "httptestid", httptestids, NULL, NULL, j, error))
+ goto out;
+
+ if (SUCCEED != proxyconfig_get_table_data("httptestitem", "httptestid", httptestids, NULL, NULL, j, error))
+ goto out;
+
+ if (SUCCEED != proxyconfig_get_table_data("httptest_field", "httptestid", httptestids, NULL, NULL, j, error))
+ goto out;
+
+ if (SUCCEED != proxyconfig_get_table_data("httpstep", "httptestid", httptestids, NULL, &httpstepids, j, error))
+ goto out;
+
+ if (SUCCEED != proxyconfig_get_table_data("httpstepitem", "httpstepid", &httpstepids, NULL, NULL, j, error))
+ goto out;
+
+ if (SUCCEED != proxyconfig_get_table_data("httpstep_field", "httpstepid", &httpstepids, NULL, NULL, j, error))
+ goto out;
+
+ ret = SUCCEED;
+out:
+ zbx_vector_uint64_destroy(&httpstepids);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+
+ return ret;
+}
+
+static int proxyconfig_get_tables(const DC_PROXY *proxy, zbx_uint64_t proxy_config_revision,
+ const zbx_dc_revision_t *dc_revision, struct zbx_json *j, zbx_proxyconfig_status_t *status,
+ char **error)
+{
+#define ZBX_PROXYCONFIG_SYNC_HOSTS 0x0001
+#define ZBX_PROXYCONFIG_SYNC_GMACROS 0x0002
+#define ZBX_PROXYCONFIG_SYNC_HMACROS 0x0004
+#define ZBX_PROXYCONFIG_SYNC_DRULES 0x0008
+#define ZBX_PROXYCONFIG_SYNC_EXPRESSIONS 0x0010
+#define ZBX_PROXYCONFIG_SYNC_CONFIG 0x0020
+#define ZBX_PROXYCONFIG_SYNC_HTTPTESTS 0x0040
+#define ZBX_PROXYCONFIG_SYNC_AUTOREG 0x0080
+
+#define ZBX_PROXYCONFIG_SYNC_ALL (ZBX_PROXYCONFIG_SYNC_HOSTS | ZBX_PROXYCONFIG_SYNC_GMACROS | \
+ ZBX_PROXYCONFIG_SYNC_HMACROS |ZBX_PROXYCONFIG_SYNC_DRULES | \
+ ZBX_PROXYCONFIG_SYNC_EXPRESSIONS | ZBX_PROXYCONFIG_SYNC_CONFIG | \
+ ZBX_PROXYCONFIG_SYNC_HTTPTESTS | ZBX_PROXYCONFIG_SYNC_AUTOREG)
+
+ zbx_vector_uint64_t hostids, httptestids, updated_hostids, removed_hostids, del_macro_hostids,
+ macro_hostids;
+ zbx_vector_ptr_t keys_paths;
+ int global_macros = FAIL, ret = FAIL, i;
+ zbx_uint64_t flags = 0;
+
+ zbx_vector_uint64_create(&hostids);
+ zbx_vector_uint64_create(&updated_hostids);
+ zbx_vector_uint64_create(&removed_hostids);
+ zbx_vector_uint64_create(&httptestids);
+ zbx_vector_uint64_create(&macro_hostids);
+ zbx_vector_uint64_create(&del_macro_hostids);
+ zbx_vector_ptr_create(&keys_paths);
+
+ if (proxy_config_revision < proxy->revision || proxy_config_revision < proxy->macro_revision)
+ {
+ zbx_vector_uint64_reserve(&hostids, 1000);
+ zbx_vector_uint64_reserve(&updated_hostids, 1000);
+ zbx_vector_uint64_reserve(&removed_hostids, 100);
+ zbx_vector_uint64_reserve(&httptestids, 100);
+ zbx_vector_uint64_reserve(&macro_hostids, 1000);
+ zbx_vector_uint64_reserve(&del_macro_hostids, 100);
+
+ zbx_dc_get_proxy_config_updates(proxy->hostid, proxy_config_revision, &hostids, &updated_hostids,
+ &removed_hostids, &httptestids);
+
+ zbx_dc_get_macro_updates(&hostids, &updated_hostids, proxy_config_revision, &macro_hostids,
+ &global_macros, &del_macro_hostids);
+ }
+
+ if (0 != proxy_config_revision)
+ {
+ if (0 != updated_hostids.values_num)
+ flags |= ZBX_PROXYCONFIG_SYNC_HOSTS;
+
+ if (SUCCEED == global_macros)
+ flags |= ZBX_PROXYCONFIG_SYNC_GMACROS;
+
+ if(0 != macro_hostids.values_num)
+ flags |= ZBX_PROXYCONFIG_SYNC_HMACROS;
+
+ if (proxy_config_revision < proxy->revision)
+ flags |= ZBX_PROXYCONFIG_SYNC_DRULES;
+
+ if (proxy_config_revision < dc_revision->expression)
+ flags |= ZBX_PROXYCONFIG_SYNC_EXPRESSIONS;
+
+ if (proxy_config_revision < dc_revision->config_table)
+ flags |= ZBX_PROXYCONFIG_SYNC_CONFIG;
+
+ if (0 != httptestids.values_num)
+ flags |= ZBX_PROXYCONFIG_SYNC_HTTPTESTS;
+
+ if (proxy_config_revision < dc_revision->autoreg_tls)
+ flags |= ZBX_PROXYCONFIG_SYNC_AUTOREG;
+ }
+ else
+ flags = ZBX_PROXYCONFIG_SYNC_ALL;
+
+ zbx_json_addobject(j, ZBX_PROTO_TAG_DATA);
+
+ if (0 != flags)
+ {
+ DBbegin();
+
+ if (0 != (flags & ZBX_PROXYCONFIG_SYNC_HOSTS) &&
+ SUCCEED != proxyconfig_get_host_data(&updated_hostids, j, error))
+ {
+ goto out;
+ }
+
+ if (0 != (flags & ZBX_PROXYCONFIG_SYNC_GMACROS) &&
+ SUCCEED != proxyconfig_get_macro_updates("globalmacro", NULL, &keys_paths, j, error))
+ {
+ goto out;
+ }
+
+ if (0 != (flags & ZBX_PROXYCONFIG_SYNC_HMACROS))
+ {
+ if (SUCCEED != proxyconfig_get_table_data("hosts_templates", "hostid", &macro_hostids, NULL,
+ NULL, j, error))
+ {
+ goto out;
+ }
+
+ if (SUCCEED != proxyconfig_get_macro_updates("hostmacro", &macro_hostids, &keys_paths, j, error))
+ goto out;
+ }
+
+ if (0 != (flags & ZBX_PROXYCONFIG_SYNC_DRULES) &&
+ SUCCEED != proxyconfig_get_drules_data(proxy, j, error))
+ {
+ goto out;
+ }
+
+ if (0 != (flags & ZBX_PROXYCONFIG_SYNC_EXPRESSIONS) &&
+ SUCCEED != proxyconfig_get_expression_data(j, error))
+ {
+ goto out;
+ }
+
+ if (0 != (flags & ZBX_PROXYCONFIG_SYNC_CONFIG) &&
+ SUCCEED != proxyconfig_get_table_data("config", NULL, NULL, NULL, NULL, j, error))
+ {
+ goto out;
+ }
+
+ if (0 != (flags & ZBX_PROXYCONFIG_SYNC_HTTPTESTS) &&
+ SUCCEED != proxyconfig_get_httptest_data(&httptestids, j, error))
+ {
+ goto out;
+ }
+
+ if (0 != (flags & ZBX_PROXYCONFIG_SYNC_AUTOREG) &&
+ SUCCEED != proxyconfig_get_table_data("config_autoreg_tls", NULL, NULL, NULL, NULL, j,
+ error))
+ {
+ goto out;
+ }
+ }
+
+ zbx_json_close(j);
+
+ if (0 != removed_hostids.values_num)
+ {
+ zbx_json_addarray(j, ZBX_PROTO_TAG_REMOVED_HOSTIDS);
+
+ for (i = 0; i < removed_hostids.values_num; i++)
+ zbx_json_adduint64(j, NULL, removed_hostids.values[i]);
+
+ zbx_json_close(j);
+ }
+
+ if (0 != del_macro_hostids.values_num)
+ {
+ zbx_json_addarray(j, ZBX_PROTO_TAG_REMOVED_MACRO_HOSTIDS);
+
+ for (i = 0; i < del_macro_hostids.values_num; i++)
+ zbx_json_adduint64(j, NULL, del_macro_hostids.values[i]);
+
+ zbx_json_close(j);
+ }
+
+ if (0 != keys_paths.values_num)
+ get_macro_secrets(&keys_paths, j);
+
+ if (0 == flags && 0 == removed_hostids.values_num && 0 == del_macro_hostids.values_num)
+ *status = ZBX_PROXYCONFIG_STATUS_EMPTY;
+ else
+ *status = ZBX_PROXYCONFIG_STATUS_DATA;
+
+ ret = SUCCEED;
+out:
+ if (0 != flags)
+ DBcommit();
+
+ zbx_vector_ptr_clear_ext(&keys_paths, key_path_free);
+ zbx_vector_ptr_destroy(&keys_paths);
+ zbx_vector_uint64_destroy(&httptestids);
+ zbx_vector_uint64_destroy(&macro_hostids);
+ zbx_vector_uint64_destroy(&del_macro_hostids);
+ zbx_vector_uint64_destroy(&removed_hostids);
+ zbx_vector_uint64_destroy(&updated_hostids);
+ zbx_vector_uint64_destroy(&hostids);
+
+ return ret;
+
+#undef ZBX_PROXYCONFIG_SYNC_HOSTS
+#undef ZBX_PROXYCONFIG_SYNC_GMACROS
+#undef ZBX_PROXYCONFIG_SYNC_HMACROS
+#undef ZBX_PROXYCONFIG_SYNC_DRULES
+#undef ZBX_PROXYCONFIG_SYNC_EXPRESSIONS
+#undef ZBX_PROXYCONFIG_SYNC_CONFIG
+#undef ZBX_PROXYCONFIG_SYNC_HTTPTESTS
+#undef ZBX_PROXYCONFIG_SYNC_AUTOREG
+}
+
+/******************************************************************************
+ * *
+ * Purpose: prepare proxy configuration data *
+ * *
+ ******************************************************************************/
+int zbx_proxyconfig_get_data(DC_PROXY *proxy, const struct zbx_json_parse *jp_request, struct zbx_json *j,
+ zbx_proxyconfig_status_t *status, char **error)
+{
+ int ret = FAIL;
+ char token[ZBX_SESSION_TOKEN_SIZE + 1], tmp[ZBX_MAX_UINT64_LEN + 1];
+ zbx_uint64_t proxy_config_revision;
+ zbx_dc_revision_t dc_revision;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() proxy_hostid:" ZBX_FS_UI64, __func__, proxy->hostid);
+
+ if (SUCCEED != zbx_json_value_by_name(jp_request, ZBX_PROTO_TAG_SESSION, token, sizeof(token), NULL))
+ {
+ *error = zbx_strdup(NULL, "cannot get session from proxy configuration request");
+ goto out;
+ }
+
+ if (SUCCEED != zbx_json_value_by_name(jp_request, ZBX_PROTO_TAG_CONFIG_REVISION, tmp, sizeof(tmp), NULL))
+ {
+ *error = zbx_strdup(NULL, "cannot get revision from proxy configuration request");
+ goto out;
+ }
+
+ if (SUCCEED != zbx_is_uint64(tmp, &proxy_config_revision))
+ {
+ *error = zbx_dsprintf(NULL, "invalid proxy configuration revision: %s", tmp);
+ goto out;
+ }
+
+ if (0 != zbx_dc_register_config_session(proxy->hostid, token, proxy_config_revision, &dc_revision) ||
+ 0 == proxy_config_revision)
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() forcing full proxy configuration sync", __func__);
+ proxy_config_revision = 0;
+ zbx_json_addint64(j, ZBX_PROTO_TAG_FULL_SYNC, 1);
+ }
+ else
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() updating proxy configuration " ZBX_FS_UI64 "->" ZBX_FS_UI64,
+ __func__, proxy_config_revision, dc_revision.config);
+ }
+
+ if (proxy_config_revision != dc_revision.config)
+ {
+ if (SUCCEED != (ret = proxyconfig_get_tables(proxy, proxy_config_revision, &dc_revision, j, status,
+ error)))
+ {
+ goto out;
+ }
+
+ zbx_json_adduint64(j, ZBX_PROTO_TAG_CONFIG_REVISION, dc_revision.config);
+
+ zabbix_log(LOG_LEVEL_TRACE, "%s() configuration: %s", __func__, j->buffer);
+ }
+ else
+ {
+ *status = ZBX_PROXYCONFIG_STATUS_EMPTY;
+ ret = SUCCEED;
+ }
+out:
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: send configuration tables to the proxy from server *
+ * (for active proxies) *
+ * *
+ ******************************************************************************/
+void zbx_send_proxyconfig(zbx_socket_t *sock, const struct zbx_json_parse *jp)
+{
+ char *error = NULL, *buffer = NULL, *version_str = NULL;
+ struct zbx_json j;
+ DC_PROXY proxy;
+ int ret, flags = ZBX_TCP_PROTOCOL, loglevel, version_int;
+ size_t buffer_size, reserved = 0;
+ zbx_proxyconfig_status_t status;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ if (SUCCEED != get_active_proxy_from_request(jp, &proxy, &error))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot parse proxy configuration data request from active proxy at"
+ " \"%s\": %s", sock->peer, error);
+ goto out;
+ }
+
+ if (SUCCEED != zbx_proxy_check_permissions(&proxy, sock, &error))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot accept connection from proxy \"%s\" at \"%s\", allowed address:"
+ " \"%s\": %s", proxy.host, sock->peer, proxy.proxy_address, error);
+ goto out;
+ }
+
+ version_str = zbx_get_proxy_protocol_version_str(jp);
+ version_int = zbx_get_proxy_protocol_version_int(version_str);
+
+ zbx_update_proxy_data(&proxy, version_str, version_int, (int)time(NULL),
+ (0 != (sock->protocol & ZBX_TCP_COMPRESS) ? 1 : 0), ZBX_FLAGS_PROXY_DIFF_UPDATE_CONFIG);
+
+ if (0 != proxy.auto_compress)
+ flags |= ZBX_TCP_COMPRESS;
+
+ if (ZBX_PROXY_VERSION_CURRENT != proxy.compatibility)
+ {
+ error = zbx_strdup(error, "proxy and server major versions do not match");
+ (void)zbx_send_response_ext(sock, NOTSUPPORTED, error, ZABBIX_VERSION, flags, CONFIG_TIMEOUT);
+ zabbix_log(LOG_LEVEL_WARNING, "configuration update is disabled for this version of proxy \"%s\" at"
+ " \"%s\": %s", proxy.host, sock->peer, error);
+ goto out;
+ }
+
+ zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN);
+
+ if (SUCCEED != zbx_proxyconfig_get_data(&proxy, jp, &j, &status, &error))
+ {
+ (void)zbx_send_response_ext(sock, FAIL, error, NULL, flags, CONFIG_TIMEOUT);
+ zabbix_log(LOG_LEVEL_WARNING, "cannot collect configuration data for proxy \"%s\" at \"%s\": %s",
+ proxy.host, sock->peer, error);
+ goto clean;
+ }
+
+ loglevel = (ZBX_PROXYCONFIG_STATUS_DATA == status ? LOG_LEVEL_WARNING : LOG_LEVEL_DEBUG);
+
+ if (0 != proxy.auto_compress)
+ {
+ if (SUCCEED != zbx_compress(j.buffer, j.buffer_size, &buffer, &buffer_size))
+ {
+ zabbix_log(LOG_LEVEL_ERR,"cannot compress data: %s", zbx_compress_strerror());
+ goto clean;
+ }
+
+ reserved = j.buffer_size;
+
+ zbx_json_free(&j); /* json buffer can be large, free as fast as possible */
+
+ zabbix_log(loglevel, "sending configuration data to proxy \"%s\" at \"%s\", datalen "
+ ZBX_FS_SIZE_T ", bytes " ZBX_FS_SIZE_T " with compression ratio %.1f", proxy.host,
+ sock->peer, (zbx_fs_size_t)reserved, (zbx_fs_size_t)buffer_size,
+ (double)reserved / (double)buffer_size);
+
+ ret = zbx_tcp_send_ext(sock, buffer, buffer_size, reserved, (unsigned char)flags,
+ CONFIG_TRAPPER_TIMEOUT);
+ }
+ else
+ {
+ zabbix_log(loglevel, "sending configuration data to proxy \"%s\" at \"%s\", datalen "
+ ZBX_FS_SIZE_T, proxy.host, sock->peer, (zbx_fs_size_t)j.buffer_size);
+
+ ret = zbx_tcp_send_ext(sock, j.buffer, strlen(j.buffer), 0, (unsigned char)flags,
+ CONFIG_TRAPPER_TIMEOUT);
+ }
+
+ if (SUCCEED != ret)
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot send configuration data to proxy \"%s\" at \"%s\": %s",
+ proxy.host, sock->peer, zbx_socket_strerror());
+ }
+clean:
+ zbx_json_free(&j);
+out:
+ zbx_free(error);
+ zbx_free(buffer);
+ zbx_free(version_str);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
+}
diff --git a/src/zabbix_server/proxyconfigread/proxyconfig_read.h b/src/zabbix_server/proxyconfigread/proxyconfig_read.h
new file mode 100644
index 00000000000..e77b7de6980
--- /dev/null
+++ b/src/zabbix_server/proxyconfigread/proxyconfig_read.h
@@ -0,0 +1,36 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2022 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.
+**/
+
+#ifndef ZABBIX_PROXYCONFIG_READ_H
+#define ZABBIX_PROXYCONFIG_READ_H
+
+#include "dbcache.h"
+
+typedef enum {
+ ZBX_PROXYCONFIG_STATUS_EMPTY,
+ ZBX_PROXYCONFIG_STATUS_DATA
+}
+zbx_proxyconfig_status_t;
+
+int zbx_proxyconfig_get_data(DC_PROXY *proxy, const struct zbx_json_parse *jp_request, struct zbx_json *j,
+ zbx_proxyconfig_status_t *status, char **error);
+
+void zbx_send_proxyconfig(zbx_socket_t *sock, const struct zbx_json_parse *jp);
+
+#endif
diff --git a/src/zabbix_server/proxypoller/Makefile.am b/src/zabbix_server/proxypoller/Makefile.am
index c988506594f..a2dfa58e1d1 100644
--- a/src/zabbix_server/proxypoller/Makefile.am
+++ b/src/zabbix_server/proxypoller/Makefile.am
@@ -6,3 +6,4 @@ libzbxproxypoller_a_SOURCES = \
proxypoller.c \
proxypoller.h
+libzbxproxypoller_a_CFLAGS = -I$(top_srcdir)/src/zabbix_server
diff --git a/src/zabbix_server/proxypoller/proxypoller.c b/src/zabbix_server/proxypoller/proxypoller.c
index 5096e44007e..f9fce0b1faf 100644
--- a/src/zabbix_server/proxypoller/proxypoller.c
+++ b/src/zabbix_server/proxypoller/proxypoller.c
@@ -32,6 +32,8 @@
#include "zbxcommshigh.h"
#include "zbxnum.h"
#include "zbxtime.h"
+#include "proxyconfigread/proxyconfig_read.h"
+#include "zbxversion.h"
static zbx_get_program_type_f zbx_get_program_type_cb = NULL;
extern ZBX_THREAD_LOCAL unsigned char process_type;
@@ -91,7 +93,7 @@ static int send_data_to_proxy(const DC_PROXY *proxy, zbx_socket_t *sock, const c
{
int ret;
- zabbix_log(LOG_LEVEL_DEBUG, "In %s() data:'%s'", __func__, data);
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
if (FAIL == (ret = zbx_tcp_send_ext(sock, data, size, reserved, flags, 0)))
{
@@ -254,22 +256,45 @@ out:
******************************************************************************/
static int proxy_send_configuration(DC_PROXY *proxy)
{
- char *error = NULL, *buffer = NULL;
- int ret, flags = ZBX_TCP_PROTOCOL;
- zbx_socket_t s;
- struct zbx_json j;
- size_t buffer_size, reserved = 0;
+ char *error = NULL, *buffer = NULL;
+ int ret, flags = ZBX_TCP_PROTOCOL, loglevel;
+ zbx_socket_t s;
+ struct zbx_json j;
+ struct zbx_json_parse jp;
+ size_t buffer_size, reserved = 0;
+ zbx_proxyconfig_status_t status;
- zbx_json_init(&j, 512 * ZBX_KIBIBYTE);
+ zbx_json_init(&j, 512 * ZBX_KIBIBYTE);
zbx_json_addstring(&j, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_PROXY_CONFIG, ZBX_JSON_TYPE_STRING);
- zbx_json_addobject(&j, ZBX_PROTO_TAG_DATA);
- if (SUCCEED != (ret = get_proxyconfig_data(proxy->hostid, &j, &error)))
+ if (SUCCEED != (ret = connect_to_proxy(proxy, &s, CONFIG_TRAPPER_TIMEOUT)))
+ goto out;
+
+ if (SUCCEED != (ret = send_data_to_proxy(proxy, &s, j.buffer, j.buffer_size, reserved, ZBX_TCP_PROTOCOL)))
+ goto clean;
+
+ if (FAIL == (ret = zbx_tcp_recv_ext(&s, 0, 0)))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot receive configuration information from proxy \"%s\": %s",
+ proxy->host, zbx_socket_strerror());
+ goto clean;
+ }
+
+ if (SUCCEED != (ret = zbx_json_open(s.buffer, &jp)))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot parse configuration information from proxy \"%s\": %s",
+ proxy->host, zbx_socket_strerror());
+ goto clean;
+ }
+
+ zbx_json_clean(&j);
+
+ if (SUCCEED != (ret = zbx_proxyconfig_get_data(proxy, &jp, &j, &status, &error)))
{
zabbix_log(LOG_LEVEL_ERR, "cannot collect configuration data for proxy \"%s\": %s",
proxy->host, error);
- goto out;
+ goto clean;
}
if (0 != proxy->auto_compress)
@@ -278,7 +303,7 @@ static int proxy_send_configuration(DC_PROXY *proxy)
{
zabbix_log(LOG_LEVEL_ERR,"cannot compress data: %s", zbx_compress_strerror());
ret = FAIL;
- goto out;
+ goto clean;
}
flags |= ZBX_TCP_COMPRESS;
@@ -286,12 +311,11 @@ static int proxy_send_configuration(DC_PROXY *proxy)
zbx_json_free(&j); /* json buffer can be large, free as fast as possible */
}
- if (SUCCEED != (ret = connect_to_proxy(proxy, &s, CONFIG_TRAPPER_TIMEOUT)))
- goto out;
+ loglevel = (ZBX_PROXYCONFIG_STATUS_DATA == status ? LOG_LEVEL_WARNING : LOG_LEVEL_DEBUG);
if (0 != proxy->auto_compress)
{
- zabbix_log(LOG_LEVEL_WARNING, "sending configuration data to proxy \"%s\" at \"%s\", datalen "
+ zabbix_log(loglevel, "sending configuration data to proxy \"%s\" at \"%s\", datalen "
ZBX_FS_SIZE_T ", bytes " ZBX_FS_SIZE_T " with compression ratio %.1f", proxy->host,
s.peer, (zbx_fs_size_t)reserved, (zbx_fs_size_t)buffer_size,
(double)reserved / buffer_size);
@@ -301,7 +325,7 @@ static int proxy_send_configuration(DC_PROXY *proxy)
}
else
{
- zabbix_log(LOG_LEVEL_WARNING, "sending configuration data to proxy \"%s\" at \"%s\", datalen "
+ zabbix_log(loglevel, "sending configuration data to proxy \"%s\" at \"%s\", datalen "
ZBX_FS_SIZE_T, proxy->host, s.peer, (zbx_fs_size_t)j.buffer_size);
ret = send_data_to_proxy(proxy, &s, j.buffer, j.buffer_size, reserved, flags);
@@ -317,8 +341,6 @@ static int proxy_send_configuration(DC_PROXY *proxy)
}
else
{
- struct zbx_json_parse jp;
-
if (SUCCEED != zbx_json_open(s.buffer, &jp))
{
zabbix_log(LOG_LEVEL_WARNING, "invalid configuration data response received from proxy"
@@ -326,13 +348,18 @@ static int proxy_send_configuration(DC_PROXY *proxy)
}
else
{
- proxy->version = zbx_get_proxy_protocol_version(&jp);
+ char *version_str;
+
+ version_str = zbx_get_proxy_protocol_version_str(&jp);
+ zbx_strlcpy(proxy->version_str, version_str, sizeof(proxy->version_str));
+ proxy->version_int = zbx_get_proxy_protocol_version_int(version_str);
proxy->auto_compress = (0 != (s.protocol & ZBX_TCP_COMPRESS) ? 1 : 0);
proxy->lastaccess = time(NULL);
+ zbx_free(version_str);
}
}
}
-
+clean:
disconnect_proxy(&s);
out:
zbx_free(buffer);
@@ -362,8 +389,8 @@ out:
static int proxy_process_proxy_data(DC_PROXY *proxy, const char *answer, zbx_timespec_t *ts, int *more)
{
struct zbx_json_parse jp;
- char *error = NULL;
- int ret = FAIL, version;
+ char *error = NULL, *version_str = NULL;
+ int version_int, ret = FAIL;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
@@ -383,15 +410,17 @@ static int proxy_process_proxy_data(DC_PROXY *proxy, const char *answer, zbx_tim
goto out;
}
- version = zbx_get_proxy_protocol_version(&jp);
+ version_str = zbx_get_proxy_protocol_version_str(&jp);
+ version_int = zbx_get_proxy_protocol_version_int(version_str);
- if (SUCCEED != zbx_check_protocol_version(proxy, version))
+ zbx_strlcpy(proxy->version_str, version_str, sizeof(proxy->version_str));
+ proxy->version_int = version_int;
+
+ if (SUCCEED != zbx_check_protocol_version(proxy, version_int))
{
goto out;
}
- proxy->version = version;
-
if (SUCCEED != (ret = process_proxy_data(proxy, &jp, ts, HOST_STATUS_PROXY_PASSIVE, more, &error)))
{
zabbix_log(LOG_LEVEL_WARNING, "proxy \"%s\" at \"%s\" returned invalid proxy data: %s",
@@ -400,6 +429,7 @@ static int proxy_process_proxy_data(DC_PROXY *proxy, const char *answer, zbx_tim
out:
zbx_free(error);
+ zbx_free(version_str);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
@@ -431,10 +461,11 @@ static int proxy_get_data(DC_PROXY *proxy, int *more)
if (SUCCEED != (ret = get_data_from_proxy(proxy, ZBX_PROTO_VALUE_PROXY_DATA, &answer, &ts)))
goto out;
- /* handle pre 3.4 proxies that did not support proxy data request */
+ /* handle pre 3.4 proxies that did not support proxy data request and active/passive configuration mismatch */
if ('\0' == *answer)
{
- proxy->version = ZBX_COMPONENT_VERSION(3, 2);
+ zbx_strlcpy(proxy->version_str, ZBX_VERSION_UNDEFINED_STR, sizeof(proxy->version_str));
+ proxy->version_int = ZBX_COMPONENT_VERSION_UNDEFINED;
zbx_free(answer);
ret = FAIL;
goto out;
@@ -473,11 +504,18 @@ static int proxy_get_tasks(DC_PROXY *proxy)
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
- if (ZBX_COMPONENT_VERSION(3, 2) >= proxy->version)
+ if (SUCCEED != (ret = get_data_from_proxy(proxy, ZBX_PROTO_VALUE_PROXY_TASKS, &answer, &ts)))
goto out;
- if (SUCCEED != (ret = get_data_from_proxy(proxy, ZBX_PROTO_VALUE_PROXY_TASKS, &answer, &ts)))
+ /* handle pre 3.4 proxies that did not support proxy data request and active/passive configuration mismatch */
+ if ('\0' == *answer)
+ {
+ zbx_strlcpy(proxy->version_str, ZBX_VERSION_UNDEFINED_STR, sizeof(proxy->version_str));
+ proxy->version_int = ZBX_COMPONENT_VERSION_UNDEFINED;
+ zbx_free(answer);
+ ret = FAIL;
goto out;
+ }
proxy->lastaccess = time(NULL);
@@ -547,7 +585,7 @@ static int process_proxy(void)
}
zbx_free(port);
- if (proxy.proxy_config_nextcheck <= now)
+ if (proxy.proxy_config_nextcheck <= now && proxy.compatibility == ZBX_PROXY_VERSION_CURRENT)
{
if (SUCCEED != (ret = proxy_send_configuration(&proxy)))
goto error;
@@ -556,7 +594,8 @@ static int process_proxy(void)
if (proxy.proxy_tasks_nextcheck <= now)
check_tasks = 1;
- if (proxy.proxy_data_nextcheck <= now)
+ if (proxy.proxy_data_nextcheck <= now && (proxy.compatibility == ZBX_PROXY_VERSION_CURRENT ||
+ proxy.compatibility == ZBX_PROXY_VERSION_OUTDATED))
{
int more;
@@ -580,11 +619,11 @@ static int process_proxy(void)
}
}
error:
-
- if (proxy_old.version != proxy.version || proxy_old.auto_compress != proxy.auto_compress ||
+ if (0 != strcmp(proxy_old.version_str, proxy.version_str) ||
+ proxy_old.auto_compress != proxy.auto_compress ||
proxy_old.lastaccess != proxy.lastaccess)
{
- zbx_update_proxy_data(&proxy_old, proxy.version, proxy.lastaccess, proxy.auto_compress, 0);
+ zbx_update_proxy_data(&proxy_old, proxy.version_str, proxy.version_int, proxy.lastaccess, proxy.auto_compress, 0);
}
DCrequeue_proxy(proxy.hostid, update_nextcheck, ret);
@@ -615,7 +654,7 @@ ZBX_THREAD_ENTRY(proxypoller_thread, args)
get_program_type_string(zbx_get_program_type_cb()), server_num,
get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
#define STAT_INTERVAL 5 /* if a process is busy and does not sleep then update status not faster than */
/* once in STAT_INTERVAL seconds */
diff --git a/src/zabbix_server/reporter/report_manager.c b/src/zabbix_server/reporter/report_manager.c
index 045aff35198..4bb016ec032 100644
--- a/src/zabbix_server/reporter/report_manager.c
+++ b/src/zabbix_server/reporter/report_manager.c
@@ -25,7 +25,6 @@
#include "zbxnix.h"
#include "base64.h"
#include "../zbxreport.h"
-#include "zbxhash.h"
#include "zbxcrypto.h"
#include "zbxalert.h"
#include "report_protocol.h"
@@ -2312,7 +2311,7 @@ ZBX_THREAD_ENTRY(report_manager_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
if (FAIL == rm_init(&manager, &error))
{
@@ -2385,9 +2384,9 @@ ZBX_THREAD_ENTRY(report_manager_thread, args)
time_now = sec;
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
ret = zbx_ipc_service_recv(&manager.ipc, &timeout, &client, &message);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
sec = zbx_time();
zbx_update_env(sec);
diff --git a/src/zabbix_server/reporter/report_writer.c b/src/zabbix_server/reporter/report_writer.c
index a569c47962b..671349b906f 100644
--- a/src/zabbix_server/reporter/report_writer.c
+++ b/src/zabbix_server/reporter/report_writer.c
@@ -438,7 +438,7 @@ ZBX_THREAD_ENTRY(report_writer_thread, args)
get_program_type_string(poller_args_in->zbx_get_program_type_cb_arg()), server_num,
get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
zbx_setproctitle("%s #%d started", get_process_type_string(process_type), process_num);
@@ -462,7 +462,7 @@ ZBX_THREAD_ENTRY(report_writer_thread, args)
finished_num = 0;
}
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
if (SUCCEED != zbx_ipc_socket_read(&socket, &message))
{
@@ -470,7 +470,7 @@ ZBX_THREAD_ENTRY(report_writer_thread, args)
exit(EXIT_FAILURE);
}
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
time_wake = zbx_time();
zbx_update_env(time_wake);
diff --git a/src/zabbix_server/scripts/scripts.c b/src/zabbix_server/scripts/scripts.c
index 18fc14d3072..412230a80b7 100644
--- a/src/zabbix_server/scripts/scripts.c
+++ b/src/zabbix_server/scripts/scripts.c
@@ -66,7 +66,7 @@ static int zbx_execute_script_on_agent(const DC_HOST *host, const char *command,
}
param = zbx_strdup(param, command);
- if (SUCCEED != (ret = quote_key_param(&param, 0)))
+ if (SUCCEED != (ret = zbx_quote_key_param(&param, 0)))
{
zbx_snprintf(error, max_error_len, "Invalid param [%s]", param);
goto fail;
@@ -75,7 +75,7 @@ static int zbx_execute_script_on_agent(const DC_HOST *host, const char *command,
item.key = zbx_dsprintf(item.key, "system.run[%s%s]", param, NULL == result ? ",nowait" : "");
item.value_type = ITEM_VALUE_TYPE_TEXT;
- init_result(&agent_result);
+ zbx_init_agent_result(&agent_result);
zbx_alarm_on(CONFIG_TIMEOUT);
@@ -90,7 +90,7 @@ static int zbx_execute_script_on_agent(const DC_HOST *host, const char *command,
zbx_alarm_off();
- free_result(&agent_result);
+ zbx_free_agent_result(&agent_result);
zbx_free(item.key);
fail:
@@ -167,7 +167,7 @@ static int zbx_execute_script_on_terminal(const DC_HOST *host, const zbx_script_
item.value_type = ITEM_VALUE_TYPE_TEXT;
item.params = zbx_strdup(item.params, script->command);
- init_result(&agent_result);
+ zbx_init_agent_result(&agent_result);
zbx_alarm_on(CONFIG_TIMEOUT);
@@ -182,7 +182,7 @@ static int zbx_execute_script_on_terminal(const DC_HOST *host, const zbx_script_
zbx_alarm_off();
- free_result(&agent_result);
+ zbx_free_agent_result(&agent_result);
zbx_free(item.params);
zbx_free(item.key);
diff --git a/src/zabbix_server/selfmon/selfmon.c b/src/zabbix_server/selfmon/selfmon.c
index 27aaa716d9c..a2f845394e5 100644
--- a/src/zabbix_server/selfmon/selfmon.c
+++ b/src/zabbix_server/selfmon/selfmon.c
@@ -39,7 +39,7 @@ ZBX_THREAD_ENTRY(selfmon_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
while (ZBX_IS_RUNNING())
{
@@ -48,7 +48,7 @@ ZBX_THREAD_ENTRY(selfmon_thread, args)
zbx_setproctitle("%s [processing data]", get_process_type_string(process_type));
- collect_selfmon_stats();
+ zbx_collect_selfmon_stats();
sec = zbx_time() - sec;
zbx_setproctitle("%s [processed data in " ZBX_FS_DBL " sec, idle 1 sec]",
diff --git a/src/zabbix_server/server.c b/src/zabbix_server/server.c
index 1fa9bb786d5..cad237df3fa 100644
--- a/src/zabbix_server/server.c
+++ b/src/zabbix_server/server.c
@@ -19,8 +19,6 @@
#include "config.h"
-#include "zbxserver.h"
-
#ifdef HAVE_SQLITE3
# error SQLite is not supported as a main Zabbix database backend.
#endif
@@ -75,6 +73,7 @@
#include "ha/ha.h"
#include "zbxrtc.h"
#include "zbxha.h"
+#include "zbxstats.h"
#include "stats/zabbix_stats.h"
#include "zbxdiag.h"
#include "diag/diag_server.h"
@@ -209,7 +208,6 @@ int CONFIG_JAVAPOLLER_FORKS = 0;
int CONFIG_ESCALATOR_FORKS = 1;
int CONFIG_SELFMON_FORKS = 1;
int CONFIG_DATASENDER_FORKS = 0;
-int CONFIG_HEARTBEAT_FORKS = 0;
int CONFIG_COLLECTOR_FORKS = 0;
int CONFIG_PASSIVE_FORKS = 0;
int CONFIG_ACTIVE_FORKS = 0;
@@ -240,7 +238,7 @@ int CONFIG_MAX_HOUSEKEEPER_DELETE = 5000; /* applies for every separate field v
int CONFIG_HISTSYNCER_FORKS = 4;
int CONFIG_HISTSYNCER_FREQUENCY = 1;
int CONFIG_CONFSYNCER_FORKS = 1;
-int CONFIG_CONFSYNCER_FREQUENCY = 60;
+int CONFIG_CONFSYNCER_FREQUENCY = 10;
int CONFIG_PROBLEMHOUSEKEEPING_FREQUENCY = 60;
@@ -307,7 +305,7 @@ int CONFIG_SERVER_STARTUP_TIME = 0; /* zabbix server startup time */
int CONFIG_PROXYPOLLER_FORKS = 1; /* parameters for passive proxies */
/* how often Zabbix server sends configuration data to passive proxy, in seconds */
-int CONFIG_PROXYCONFIG_FREQUENCY = SEC_PER_MIN * 5;
+int CONFIG_PROXYCONFIG_FREQUENCY = 10;
int CONFIG_PROXYDATA_FREQUENCY = 1; /* 1s */
char *CONFIG_LOAD_MODULE_PATH = NULL;
@@ -1031,7 +1029,7 @@ static void zbx_on_exit(int ret)
if (ZBX_NODE_STATUS_ACTIVE == ha_status)
{
- free_metrics();
+ zbx_free_metrics();
zbx_ipc_service_free_env();
free_configuration_cache();
@@ -1041,7 +1039,7 @@ static void zbx_on_exit(int ret)
/* free vmware support */
zbx_vmware_destroy();
- free_selfmon_collector();
+ zbx_free_selfmon_collector();
}
zbx_uninitialize_events();
@@ -1152,7 +1150,7 @@ int main(int argc, char **argv)
CONFIG_FILE = zbx_strdup(NULL, DEFAULT_CONFIG_FILE);
/* required for simple checks */
- init_metrics();
+ zbx_init_metrics();
zbx_load_config(&t);
if (ZBX_TASK_RUNTIME_CONTROL == t.task)
@@ -1241,6 +1239,31 @@ static void zbx_check_db(void)
/******************************************************************************
* *
+ * Purpose: save Zabbix server status to database *
+ * *
+ ******************************************************************************/
+static void zbx_db_save_server_status(void)
+{
+ struct zbx_json json;
+
+ zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN);
+
+ zbx_json_addstring(&json, "version", ZABBIX_VERSION, ZBX_JSON_TYPE_STRING);
+
+ zbx_json_close(&json);
+
+ DBconnect(ZBX_DB_CONNECT_NORMAL);
+
+ if (ZBX_DB_OK > DBexecute("update config set server_status='%s'", json.buffer))
+ zabbix_log(LOG_LEVEL_WARNING, "Failed to save server status to database");
+
+ DBclose();
+
+ zbx_json_free(&json);
+}
+
+/******************************************************************************
+ * *
* Purpose: initialize shared resources and start processes *
* *
******************************************************************************/
@@ -1249,9 +1272,11 @@ static int server_startup(zbx_socket_t *listen_sock, int *ha_stat, int *ha_failo
int i, ret = SUCCEED;
char *error = NULL;
+ zbx_config_comms_args_t zbx_config = {zbx_config_tls, NULL, 0};
+
zbx_thread_args_t thread_args;
- zbx_thread_poller_args poller_args = {zbx_config_tls, get_program_type, ZBX_NO_POLLER};
- zbx_thread_trapper_args trapper_args = {zbx_config_tls, get_program_type, listen_sock};
+ zbx_thread_poller_args poller_args = {&zbx_config, get_program_type, ZBX_NO_POLLER};
+ zbx_thread_trapper_args trapper_args = {&zbx_config, get_program_type, listen_sock};
zbx_thread_escalator_args escalator_args = {zbx_config_tls, get_program_type};
zbx_thread_proxy_poller_args proxy_poller_args = {zbx_config_tls, get_program_type};
zbx_thread_discoverer_args discoverer_args = {zbx_config_tls, get_program_type};
@@ -1272,7 +1297,7 @@ static int server_startup(zbx_socket_t *listen_sock, int *ha_stat, int *ha_failo
return FAIL;
}
- if (SUCCEED != init_selfmon_collector(&error))
+ if (SUCCEED != zbx_init_selfmon_collector(&error))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot initialize self-monitoring: %s", error);
zbx_free(error);
@@ -1346,11 +1371,13 @@ static int server_startup(zbx_socket_t *listen_sock, int *ha_stat, int *ha_failo
zbx_thread_start(service_manager_thread, &thread_args, &threads[i]);
break;
case ZBX_PROCESS_TYPE_CONFSYNCER:
+ zbx_vc_enable();
zbx_thread_start(dbconfig_thread, &thread_args, &threads[i]);
if (FAIL == (ret = zbx_rtc_wait_config_sync(rtc)))
goto out;
- if (SUCCEED != (ret = zbx_ha_get_status(ha_stat, ha_failover, &error)))
+ if (SUCCEED != (ret = zbx_ha_get_status(CONFIG_HA_NODE_NAME, ha_stat, ha_failover,
+ &error)))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot obtain HA status: %s", error);
zbx_free(error);
@@ -1377,8 +1404,6 @@ static int server_startup(zbx_socket_t *listen_sock, int *ha_stat, int *ha_failo
zbx_dc_update_maintenances();
DBclose();
-
- zbx_vc_enable();
break;
case ZBX_PROCESS_TYPE_POLLER:
poller_args.poller_type = ZBX_POLLER_TYPE_NORMAL;
@@ -1496,7 +1521,7 @@ static int server_startup(zbx_socket_t *listen_sock, int *ha_stat, int *ha_failo
}
/* startup/postinit tasks can take a long time, update status */
- if (SUCCEED != (ret = zbx_ha_get_status(ha_stat, ha_failover, &error)))
+ if (SUCCEED != (ret = zbx_ha_get_status(CONFIG_HA_NODE_NAME, ha_stat, ha_failover, &error)))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot obtain HA status: %s", error);
zbx_free(error);
@@ -1528,8 +1553,9 @@ static int server_restart_logger(char **error)
******************************************************************************/
static void server_teardown(zbx_rtc_t *rtc, zbx_socket_t *listen_sock)
{
- int i;
- char *error = NULL;
+ int i;
+ char *error = NULL;
+ zbx_ha_config_t *ha_config = NULL;
/* hard kill all zabbix processes, no logging or other */
@@ -1580,7 +1606,7 @@ static void server_teardown(zbx_rtc_t *rtc, zbx_socket_t *listen_sock)
zbx_tfc_destroy();
zbx_vc_destroy();
zbx_vmware_destroy();
- free_selfmon_collector();
+ zbx_free_selfmon_collector();
free_configuration_cache();
free_database_cache(ZBX_SYNC_NONE);
@@ -1588,7 +1614,14 @@ static void server_teardown(zbx_rtc_t *rtc, zbx_socket_t *listen_sock)
zbx_locks_enable();
#endif
- if (SUCCEED != zbx_ha_start(rtc, ZBX_NODE_STATUS_STANDBY, &error))
+ ha_config = zbx_malloc(NULL, sizeof(zbx_ha_config_t));
+ ha_config->ha_node_name = CONFIG_HA_NODE_NAME;
+ ha_config->ha_node_address = CONFIG_NODE_ADDRESS;
+ ha_config->default_node_ip = CONFIG_LISTEN_IP;
+ ha_config->default_node_port = CONFIG_LISTEN_PORT;
+ ha_config->ha_status = ZBX_NODE_STATUS_STANDBY;
+
+ if (SUCCEED != zbx_ha_start(rtc, ha_config, &error))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot start HA manager: %s", error);
zbx_free(error);
@@ -1605,6 +1638,7 @@ int MAIN_ZABBIX_ENTRY(int flags)
time_t standby_warning_time;
zbx_rtc_t rtc;
zbx_timespec_t rtc_timeout = {1, 0};
+ zbx_ha_config_t *ha_config = NULL;
if (0 != (flags & ZBX_TASK_FLAG_FOREGROUND))
{
@@ -1765,6 +1799,7 @@ int MAIN_ZABBIX_ENTRY(int flags)
DBcheck_character_set();
zbx_check_db();
+ zbx_db_save_server_status();
if (SUCCEED != DBcheck_double_type())
{
@@ -1792,7 +1827,14 @@ int MAIN_ZABBIX_ENTRY(int flags)
zbx_unset_exit_on_terminate();
- if (SUCCEED != zbx_ha_start(&rtc, ZBX_NODE_STATUS_UNKNOWN, &error))
+ ha_config = zbx_malloc(NULL, sizeof(zbx_ha_config_t));
+ ha_config->ha_node_name = CONFIG_HA_NODE_NAME;
+ ha_config->ha_node_address = CONFIG_NODE_ADDRESS;
+ ha_config->default_node_ip = CONFIG_LISTEN_IP;
+ ha_config->default_node_port = CONFIG_LISTEN_PORT;
+ ha_config->ha_status = ZBX_NODE_STATUS_UNKNOWN;
+
+ if (SUCCEED != zbx_ha_start(&rtc, ha_config, &error))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot start HA manager: %s", error);
zbx_free(error);
@@ -1808,14 +1850,14 @@ int MAIN_ZABBIX_ENTRY(int flags)
if (SUCCEED == zbx_is_export_enabled(ZBX_FLAG_EXPTYPE_TRENDS))
zbx_trends_export_init("main-process", 0);
- if (SUCCEED != zbx_ha_get_status(&ha_status, &ha_failover_delay, &error))
+ if (SUCCEED != zbx_ha_get_status(CONFIG_HA_NODE_NAME, &ha_status, &ha_failover_delay, &error))
{
zabbix_log(LOG_LEVEL_CRIT, "cannot start server: %s", error);
zbx_free(error);
zbx_set_exiting_with_fail();
}
- zbx_zabbix_stats_init(zbx_get_zabbix_stats_ext);
+ zbx_zabbix_stats_init(zbx_zabbix_stats_ext_get);
zbx_diag_init(diag_add_section_info);
if (ZBX_NODE_STATUS_ACTIVE == ha_status)
@@ -1835,7 +1877,7 @@ int MAIN_ZABBIX_ENTRY(int flags)
if (ZBX_NODE_STATUS_ERROR != ha_status)
{
- if (ZBX_HA_IS_CLUSTER())
+ if (NULL != CONFIG_HA_NODE_NAME && '\0' != *CONFIG_HA_NODE_NAME)
{
zabbix_log(LOG_LEVEL_INFORMATION, "\"%s\" node started in \"%s\" mode", CONFIG_HA_NODE_NAME,
zbx_ha_status_str(ha_status));
@@ -1858,7 +1900,8 @@ int MAIN_ZABBIX_ENTRY(int flags)
if (NULL == message || ZBX_IPC_SERVICE_HA_RTC_FIRST <= message->code)
{
- if (SUCCEED != zbx_ha_dispatch_message(message, &ha_status, &ha_failover_delay, &error))
+ if (SUCCEED != zbx_ha_dispatch_message(CONFIG_HA_NODE_NAME, message, &ha_status,
+ &ha_failover_delay, &error))
{
zabbix_log(LOG_LEVEL_CRIT, "HA manager error: %s", error);
zbx_set_exiting_with_fail();
diff --git a/src/zabbix_server/service/service_actions.c b/src/zabbix_server/service/service_actions.c
index 5edb14734be..fcd8ab56a55 100644
--- a/src/zabbix_server/service/service_actions.c
+++ b/src/zabbix_server/service/service_actions.c
@@ -58,7 +58,7 @@ static int condition_match_service_name(const zbx_service_action_condition_t *co
* name - [IN] the target tag name *
* value - [IN] the target tag value (NULL if only tag name are *
* being matched *
- * op - [IN] the matching operator (CONDITION_OPERATOR_*) *
+ * op - [IN] the matching operator (ZBX_CONDITION_OPERATOR_*) *
* *
* Return value: SUCCEED - the tags matches *
* FAIL - otherwise *
@@ -71,7 +71,7 @@ static int match_tags(const zbx_vector_ptr_t *tags, const char *name, const char
{
int i, ret, expected_ret;
- if (CONDITION_OPERATOR_EQUAL == op || CONDITION_OPERATOR_LIKE == op)
+ if (ZBX_CONDITION_OPERATOR_EQUAL == op || ZBX_CONDITION_OPERATOR_LIKE == op)
{
expected_ret = SUCCEED;
ret = FAIL;
@@ -137,16 +137,16 @@ static const char *service_update_match_condition(const zbx_service_update_t *up
switch (condition->conditiontype)
{
- case CONDITION_TYPE_SERVICE:
+ case ZBX_CONDITION_TYPE_SERVICE:
ret = condition_match_service(condition, update);
break;
- case CONDITION_TYPE_SERVICE_NAME:
+ case ZBX_CONDITION_TYPE_SERVICE_NAME:
ret = condition_match_service_name(condition, update);
break;
- case CONDITION_TYPE_EVENT_TAG:
+ case ZBX_CONDITION_TYPE_EVENT_TAG:
ret = condition_match_service_tag(condition, update);
break;
- case CONDITION_TYPE_EVENT_TAG_VALUE:
+ case ZBX_CONDITION_TYPE_EVENT_TAG_VALUE:
ret = condition_match_service_tag_value(condition, update);
break;
default:
diff --git a/src/zabbix_server/service/service_manager.c b/src/zabbix_server/service/service_manager.c
index 0d4fd9210b2..1176eb38b01 100644
--- a/src/zabbix_server/service/service_manager.c
+++ b/src/zabbix_server/service/service_manager.c
@@ -352,6 +352,8 @@ static void values_eq_clean(void *data)
static void add_service_problem_tag_index(zbx_hashset_t *service_problem_tags_index,
zbx_service_problem_tag_t *service_problem_tag)
{
+/* service problem tag operators */
+#define ZBX_SERVICE_TAG_OPERATOR_LIKE 2
zbx_tag_services_t tag_services_local, *tag_services;
zbx_values_eq_t value_eq_local, *value_eq;
@@ -441,6 +443,7 @@ static void remove_service_problem_tag_index(zbx_hashset_t *service_problem_tags
if (0 == tag_services->values.num_data && 0 == tag_services->service_problem_tags_like.values_num)
zbx_hashset_remove_direct(service_problem_tags_index, tag_services);
}
+#undef ZBX_SERVICE_TAG_OPERATOR_LIKE
}
static void sync_service_problem_tags(zbx_service_manager_t *service_manager, int *updated, int revision)
@@ -954,29 +957,29 @@ static int condition_type_compare(const void *d1, const void *d2)
static void update_action_formula(zbx_service_action_t *action)
{
-#define CONDITION_TYPE_NONE 255
+#define ZBX_CONDITION_TYPE_NONE 255
char *formula = NULL;
size_t formula_alloc = 0, formula_offset = 0;
int i;
zbx_service_action_condition_t *condition;
- unsigned char last_type = CONDITION_TYPE_NONE;
+ unsigned char last_type = ZBX_CONDITION_TYPE_NONE;
char *ops[] = {NULL, "and", "or"};
zabbix_log(LOG_LEVEL_DEBUG, "In %s() actionid:" ZBX_FS_UI64, __func__, action->actionid);
- if (0 == action->conditions.values_num || CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
+ if (0 == action->conditions.values_num || ZBX_ACTION_CONDITION_EVAL_TYPE_EXPRESSION == action->evaltype)
goto out;
for (i = 0; i < action->conditions.values_num; i++)
{
condition = (zbx_service_action_condition_t *)action->conditions.values[i];
- if (CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
{
if (last_type != condition->conditiontype)
{
- if (CONDITION_TYPE_NONE != last_type)
+ if (ZBX_CONDITION_TYPE_NONE != last_type)
zbx_strcpy_alloc(&formula, &formula_alloc, &formula_offset, ") and ");
zbx_chrcpy_alloc(&formula, &formula_alloc, &formula_offset, '(');
@@ -986,7 +989,7 @@ static void update_action_formula(zbx_service_action_t *action)
}
else
{
- if (CONDITION_TYPE_NONE != last_type)
+ if (ZBX_CONDITION_TYPE_NONE != last_type)
{
zbx_chrcpy_alloc(&formula, &formula_alloc, &formula_offset, ' ');
zbx_strcpy_alloc(&formula, &formula_alloc, &formula_offset, ops[action->evaltype]);
@@ -999,7 +1002,7 @@ static void update_action_formula(zbx_service_action_t *action)
last_type = condition->conditiontype;
}
- if (CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
+ if (ZBX_ACTION_CONDITION_EVAL_TYPE_AND_OR == action->evaltype)
zbx_chrcpy_alloc(&formula, &formula_alloc, &formula_offset, ')');
zbx_free(action->formula);
@@ -1007,7 +1010,7 @@ static void update_action_formula(zbx_service_action_t *action)
out:
zabbix_log(LOG_LEVEL_DEBUG, "End of %s() formula:%s", __func__, action->formula);
-#undef CONDITION_TYPE_NONE
+#undef ZBX_CONDITION_TYPE_NONE
}
static void sync_action_conditions(zbx_service_manager_t *service_manager, int revision)
@@ -3275,7 +3278,7 @@ ZBX_THREAD_ENTRY(service_manager_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num);
@@ -3325,10 +3328,7 @@ ZBX_THREAD_ENTRY(service_manager_thread, args)
int updated = 0, revision;
if (1 == service_cache_reload_requested)
- {
zabbix_log(LOG_LEVEL_WARNING, "forced reloading of the service manager cache");
- service_cache_reload_requested = 0;
- }
do
{
@@ -3355,6 +3355,13 @@ ZBX_THREAD_ENTRY(service_manager_thread, args)
if (0 != updated)
recalculate_services(&service_manager);
+ if (1 == service_cache_reload_requested)
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "finished forced reloading of the service manager cache");
+ service_cache_reload_requested = 0;
+ }
+
+
service_update_num += updated;
time_flush = time_now;
time_now = zbx_time();
@@ -3368,9 +3375,9 @@ ZBX_THREAD_ENTRY(service_manager_thread, args)
time_now = zbx_time();
}
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
ret = zbx_ipc_service_recv(&service, &timeout, &client, &message);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
sec = zbx_time();
zbx_update_env(sec);
diff --git a/src/zabbix_server/snmptrapper/snmptrapper.c b/src/zabbix_server/snmptrapper/snmptrapper.c
index 7dd3da84ec3..efe668a4f51 100644
--- a/src/zabbix_server/snmptrapper/snmptrapper.c
+++ b/src/zabbix_server/snmptrapper/snmptrapper.c
@@ -104,7 +104,7 @@ static int process_trap_for_interface(zbx_uint64_t interfaceid, char *trap, zbx_
for (i = 0; i < num; i++)
{
- init_result(&results[i]);
+ zbx_init_agent_result(&results[i]);
errcodes[i] = FAIL;
items[i].key = zbx_strdup(items[i].key, items[i].key_orig);
@@ -122,9 +122,9 @@ static int process_trap_for_interface(zbx_uint64_t interfaceid, char *trap, zbx_
continue;
}
- init_request(&request);
+ zbx_init_agent_request(&request);
- if (SUCCEED != parse_item_key(items[i].key, &request))
+ if (SUCCEED != zbx_parse_item_key(items[i].key, &request))
goto next;
if (0 != strcmp(get_rkey(&request), "snmptrap"))
@@ -163,17 +163,17 @@ static int process_trap_for_interface(zbx_uint64_t interfaceid, char *trap, zbx_
}
value_type = (ITEM_VALUE_TYPE_LOG == items[i].value_type ? ITEM_VALUE_TYPE_LOG : ITEM_VALUE_TYPE_TEXT);
- set_result_type(&results[i], value_type, trap);
+ zbx_set_agent_result_type(&results[i], value_type, trap);
errcodes[i] = SUCCEED;
ret = SUCCEED;
next:
- free_request(&request);
+ zbx_free_agent_request(&request);
}
if (FAIL == ret && -1 != fb)
{
value_type = (ITEM_VALUE_TYPE_LOG == items[fb].value_type ? ITEM_VALUE_TYPE_LOG : ITEM_VALUE_TYPE_TEXT);
- set_result_type(&results[fb], value_type, trap);
+ zbx_set_agent_result_type(&results[fb], value_type, trap);
errcodes[fb] = SUCCEED;
ret = SUCCEED;
}
@@ -207,7 +207,7 @@ next:
}
zbx_free(items[i].key);
- free_result(&results[i]);
+ zbx_free_agent_result(&results[i]);
}
zbx_free(results);
@@ -600,7 +600,7 @@ ZBX_THREAD_ENTRY(snmptrapper_thread, args)
zabbix_log(LOG_LEVEL_DEBUG, "In %s() trapfile:'%s'", __func__, CONFIG_SNMPTRAP_FILE);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type));
diff --git a/src/zabbix_server/stats/zabbix_stats.h b/src/zabbix_server/stats/zabbix_stats.h
index 10b610ef9f0..608d63ad1f5 100644
--- a/src/zabbix_server/stats/zabbix_stats.h
+++ b/src/zabbix_server/stats/zabbix_stats.h
@@ -21,7 +21,8 @@
#define ZABBIX_ZABBIX_STATS_H_
#include "zbxjson.h"
+#include "zbxstats.h"
-void zbx_get_zabbix_stats_ext(struct zbx_json *json);
+void zbx_zabbix_stats_ext_get(struct zbx_json *json, const zbx_config_comms_args_t *zbx_config);
#endif /* ZABBIX_ZABBIX_STATS_H_ */
diff --git a/src/zabbix_server/stats/zabbix_stats_server.c b/src/zabbix_server/stats/zabbix_stats_server.c
index 9efcd61a7b4..566c6405279 100644
--- a/src/zabbix_server/stats/zabbix_stats_server.c
+++ b/src/zabbix_server/stats/zabbix_stats_server.c
@@ -26,24 +26,28 @@
#include "log.h"
#include "zbxtrends.h"
#include "zbxha.h"
+#include "zbxcomms.h"
/******************************************************************************
* *
* Purpose: get program type (server) specific internal statistics *
* *
- * Parameters: json - [IN/OUT] the json data *
+ * Parameters: json - [IN/OUT] the json data *
+ * zbx_config - [IN] server config *
* *
* Comments: This function is used to gather server specific internal *
* statistics. *
* *
******************************************************************************/
-void zbx_get_zabbix_stats_ext(struct zbx_json *json)
+void zbx_zabbix_stats_ext_get(struct zbx_json *json, const zbx_config_comms_args_t *zbx_config)
{
zbx_vc_stats_t vc_stats;
zbx_uint64_t queue_size;
char *value, *error = NULL;
zbx_tfc_stats_t tcache_stats;
+ ZBX_UNUSED(zbx_config);
+
/* zabbix[lld_queue] */
if (SUCCEED == zbx_lld_get_queue_size(&queue_size, &error))
{
@@ -111,7 +115,20 @@ void zbx_get_zabbix_stats_ext(struct zbx_json *json)
}
else
{
- zabbix_log(LOG_LEVEL_DEBUG, "cannot get HA node data: %s", error);
+ zabbix_log(LOG_LEVEL_WARNING, "cannot get HA node data: %s", error);
+ zbx_free(error);
+ }
+
+ if (SUCCEED == zbx_proxy_discovery_get(&value, &error))
+ {
+ zbx_json_addraw(json, "proxy", value);
+ zbx_free(value);
+ }
+ else
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot get proxy data: %s", error);
zbx_free(error);
}
+
+ zbx_json_close(json);
}
diff --git a/src/zabbix_server/taskmanager/proxy_tasks.c b/src/zabbix_server/taskmanager/proxy_tasks.c
index 8e6a75880bf..7cc65089b59 100644
--- a/src/zabbix_server/taskmanager/proxy_tasks.c
+++ b/src/zabbix_server/taskmanager/proxy_tasks.c
@@ -20,24 +20,32 @@
#include "zbxdbhigh.h"
#include "zbxnum.h"
#include "zbxtasks.h"
+#include "zbxversion.h"
/******************************************************************************
* *
* Purpose: get tasks scheduled to be executed on a proxy *
* *
- * Parameters: tasks - [OUT] the tasks to execute *
- * proxy_hostid - [IN] the target proxy *
+ * Parameters: tasks - [OUT] the tasks to execute *
+ * proxy_hostid - [IN] the target proxy *
+ * compatibility - [IN] proxy version compatibility with server *
* *
* Comments: This function is used by server to get tasks to be sent to the *
* specified proxy. Expired tasks are ignored and handled by the *
* server task manager. *
+ * All tasks are disabled on unsupported proxies. Only remote *
+ * command and check now are supported by outdated proxies. *
* *
******************************************************************************/
-void zbx_tm_get_remote_tasks(zbx_vector_ptr_t *tasks, zbx_uint64_t proxy_hostid)
+void zbx_tm_get_remote_tasks(zbx_vector_ptr_t *tasks, zbx_uint64_t proxy_hostid,
+ zbx_proxy_compatibility_t compatibility)
{
DB_RESULT result;
DB_ROW row;
+ if (ZBX_PROXY_VERSION_UNDEFINED == compatibility || ZBX_PROXY_VERSION_UNSUPPORTED == compatibility)
+ return;
+
/* skip tasks past expiry data - task manager will handle them */
result = DBselect(
"select t.taskid,t.type,t.clock,t.ttl,"
@@ -94,7 +102,7 @@ void zbx_tm_get_remote_tasks(zbx_vector_ptr_t *tasks, zbx_uint64_t proxy_hostid)
task->data = (void *)zbx_tm_check_now_create(itemid);
break;
case ZBX_TM_TASK_DATA:
- if (SUCCEED == DBis_null(row[17]))
+ if (ZBX_PROXY_VERSION_OUTDATED == compatibility || SUCCEED == DBis_null(row[17]))
{
zbx_free(task);
continue;
diff --git a/src/zabbix_server/taskmanager/taskmanager.c b/src/zabbix_server/taskmanager/taskmanager.c
index acf14696ee5..ac1a5d5e845 100644
--- a/src/zabbix_server/taskmanager/taskmanager.c
+++ b/src/zabbix_server/taskmanager/taskmanager.c
@@ -37,6 +37,7 @@
#include "dbcache.h"
#include "zbxnum.h"
#include "zbxtime.h"
+#include "zbxversion.h"
#define ZBX_TM_PROCESS_PERIOD 5
#define ZBX_TM_CLEANUP_PERIOD SEC_PER_HOUR
@@ -1010,6 +1011,34 @@ static int tm_expire_generic_tasks(zbx_vector_uint64_t *taskids)
/******************************************************************************
* *
+ * Purpose: get proxy version compatibility with server version *
+ * *
+ ******************************************************************************/
+static zbx_proxy_compatibility_t tm_get_proxy_compatibility(zbx_uint64_t proxy_hostid)
+{
+ zbx_proxy_compatibility_t compatibility = ZBX_PROXY_VERSION_UNDEFINED;
+
+ if (0 < proxy_hostid)
+ {
+ DB_ROW row;
+ DB_RESULT result;
+
+ result = DBselect(
+ "select compatibility"
+ " from host_rtdata"
+ " where hostid=" ZBX_FS_UI64, proxy_hostid);
+
+ if (NULL != (row = DBfetch(result)))
+ compatibility = (zbx_proxy_compatibility_t)atoi(row[0]);
+
+ DBfree_result(result);
+ }
+
+ return compatibility;
+}
+
+/******************************************************************************
+ * *
* Purpose: process task manager tasks depending on task type *
* *
* Return value: The number of successfully processed tasks *
@@ -1020,7 +1049,7 @@ static int tm_process_tasks(zbx_ipc_async_socket_t *rtc, int now)
DB_ROW row;
DB_RESULT result;
int type, processed_num = 0, expired_num = 0, clock, ttl;
- zbx_uint64_t taskid;
+ zbx_uint64_t taskid, proxy_hostid;
zbx_vector_uint64_t ack_taskids, check_now_taskids, expire_taskids, data_taskids;
zbx_vector_uint64_create(&ack_taskids);
@@ -1028,7 +1057,7 @@ static int tm_process_tasks(zbx_ipc_async_socket_t *rtc, int now)
zbx_vector_uint64_create(&expire_taskids);
zbx_vector_uint64_create(&data_taskids);
- result = DBselect("select taskid,type,clock,ttl"
+ result = DBselect("select taskid,type,clock,ttl,proxy_hostid"
" from task"
" where status in (%d,%d)"
" order by taskid",
@@ -1036,10 +1065,13 @@ static int tm_process_tasks(zbx_ipc_async_socket_t *rtc, int now)
while (NULL != (row = DBfetch(result)))
{
+ zbx_proxy_compatibility_t compatibility;
+
ZBX_STR2UINT64(taskid, row[0]);
ZBX_STR2UCHAR(type, row[1]);
clock = atoi(row[2]);
ttl = atoi(row[3]);
+ ZBX_DBROW2UINT64(proxy_hostid, row[4]);
switch (type)
{
@@ -1049,8 +1081,23 @@ static int tm_process_tasks(zbx_ipc_async_socket_t *rtc, int now)
processed_num++;
break;
case ZBX_TM_TASK_REMOTE_COMMAND:
+ compatibility = tm_get_proxy_compatibility(proxy_hostid);
+
+ if (ZBX_PROXY_VERSION_UNSUPPORTED == compatibility)
+ {
+ zbx_tm_task_t *task;
+ const char *error = "Remote commands are disabled on unsupported proxies.";
+
+ zabbix_log(LOG_LEVEL_WARNING, "%s", error);
+ task = zbx_tm_task_create(0, ZBX_TM_TASK_REMOTE_COMMAND_RESULT,
+ ZBX_TM_STATUS_NEW, zbx_time(), 0, 0);
+ task->data = zbx_tm_remote_command_result_create(taskid, FAIL, error);
+ zbx_tm_save_task(task);
+ zbx_tm_task_free(task);
+ }
+
/* both - 'new' and 'in progress' remote tasks should expire */
- if (0 != ttl && clock + ttl < now)
+ if ((0 != ttl && clock + ttl < now) || (ZBX_PROXY_VERSION_UNSUPPORTED == compatibility))
{
tm_expire_remote_command(taskid);
expired_num++;
@@ -1065,13 +1112,44 @@ static int tm_process_tasks(zbx_ipc_async_socket_t *rtc, int now)
zbx_vector_uint64_append(&ack_taskids, taskid);
break;
case ZBX_TM_TASK_CHECK_NOW:
- if (0 != ttl && clock + ttl < now)
+ compatibility = tm_get_proxy_compatibility(proxy_hostid);
+
+ if (ZBX_PROXY_VERSION_UNSUPPORTED == compatibility)
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "Execute now task is disabled on unsupported"
+ " proxies.");
+ }
+
+ if ((0 != ttl && clock + ttl < now) || (ZBX_PROXY_VERSION_UNSUPPORTED == compatibility))
zbx_vector_uint64_append(&expire_taskids, taskid);
else
zbx_vector_uint64_append(&check_now_taskids, taskid);
break;
case ZBX_TM_TASK_DATA:
case ZBX_TM_PROXYDATA:
+ if (ZBX_TM_TASK_DATA == type)
+ {
+ compatibility = tm_get_proxy_compatibility(proxy_hostid);
+
+ if (ZBX_PROXY_VERSION_OUTDATED == compatibility ||
+ ZBX_PROXY_VERSION_UNSUPPORTED == compatibility)
+ {
+ zbx_tm_task_t *task;
+ const char *error = "The requested task is disabled. Proxy major"
+ " version does not match server major version.";
+
+ zabbix_log(LOG_LEVEL_WARNING, "%s", error);
+ task = zbx_tm_task_create(0, ZBX_TM_TASK_DATA_RESULT, ZBX_TM_STATUS_NEW,
+ zbx_time(), 0, 0);
+ task->data = zbx_tm_data_result_create(taskid, FAIL, error);
+ zbx_tm_save_task(task);
+ zbx_tm_task_free(task);
+
+ zbx_vector_uint64_append(&expire_taskids, taskid);
+ break;
+ }
+ }
+
/* both - 'new' and 'in progress' tasks should expire */
if (0 != ttl && clock + ttl < now)
zbx_vector_uint64_append(&expire_taskids, taskid);
@@ -1110,12 +1188,6 @@ static int tm_process_tasks(zbx_ipc_async_socket_t *rtc, int now)
return processed_num + expired_num;
}
-static void zbx_cached_proxy_free(zbx_cached_proxy_t *proxy)
-{
- zbx_free(proxy->name);
- zbx_free(proxy);
-}
-
/******************************************************************************
* *
* Purpose: remove old done/expired tasks *
@@ -1132,10 +1204,10 @@ static void tm_remove_old_tasks(int now)
static void tm_reload_each_proxy_cache(zbx_ipc_async_socket_t *rtc)
{
int i, notify_proxypollers = 0;
- zbx_vector_cached_proxy_t proxies;
+ zbx_vector_cached_proxy_ptr_t proxies;
zbx_vector_ptr_t tasks_active;
- zbx_vector_cached_proxy_create(&proxies);
+ zbx_vector_cached_proxy_ptr_create(&proxies);
zbx_vector_ptr_create(&tasks_active);
@@ -1187,8 +1259,8 @@ static void tm_reload_each_proxy_cache(zbx_ipc_async_socket_t *rtc)
zbx_vector_ptr_destroy(&tasks_active);
- zbx_vector_cached_proxy_clear_ext(&proxies, zbx_cached_proxy_free);
- zbx_vector_cached_proxy_destroy(&proxies);
+ zbx_vector_cached_proxy_ptr_clear_ext(&proxies, zbx_cached_proxy_free);
+ zbx_vector_cached_proxy_ptr_destroy(&proxies);
}
/******************************************************************************
@@ -1321,7 +1393,7 @@ ZBX_THREAD_ENTRY(taskmanager_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type));
DBconnect(ZBX_DB_CONNECT_NORMAL);
diff --git a/src/zabbix_server/timer/timer.c b/src/zabbix_server/timer/timer.c
index bc783a70a10..345a387236a 100644
--- a/src/zabbix_server/timer/timer.c
+++ b/src/zabbix_server/timer/timer.c
@@ -572,7 +572,7 @@ ZBX_THREAD_ENTRY(timer_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num);
zbx_strcpy_alloc(&info, &info_alloc, &info_offset, "started");
diff --git a/src/zabbix_server/trapper/Makefile.am b/src/zabbix_server/trapper/Makefile.am
index 05947d08f9e..1b5a820967a 100644
--- a/src/zabbix_server/trapper/Makefile.am
+++ b/src/zabbix_server/trapper/Makefile.am
@@ -5,8 +5,6 @@ noinst_LIBRARIES = libzbxtrapper.a libzbxtrapper_server.a libzbxtrapper_proxy.a
libzbxtrapper_a_SOURCES = \
active.c \
active.h \
- proxyconfig.c \
- proxyconfig.h \
trapper_auth.c \
trapper_auth.h \
nodecommand.c \
@@ -33,3 +31,7 @@ libzbxtrapper_proxy_a_SOURCES = \
libzbxtrapper_a_CFLAGS = \
$(LIBXML2_CFLAGS)
+
+libzbxtrapper_server_a_CFLAGS = -I$(top_srcdir)/src/zabbix_server
+
+libzbxtrapper_proxy_a_CFLAGS = -I$(top_srcdir)/src/zabbix_proxy
diff --git a/src/zabbix_server/trapper/active.c b/src/zabbix_server/trapper/active.c
index 8c51a26b200..ccb8117ecf6 100644
--- a/src/zabbix_server/trapper/active.c
+++ b/src/zabbix_server/trapper/active.c
@@ -28,6 +28,7 @@
#include "zbxcomms.h"
#include "zbxip.h"
#include "zbxsysinfo.h"
+#include "zbxversion.h"
extern unsigned char program_type;
@@ -172,7 +173,7 @@ out:
******************************************************************************/
static int get_hostid_by_host(const zbx_socket_t *sock, const char *host, const char *ip, unsigned short port,
const char *host_metadata, zbx_conn_flags_t flag, const char *interface, zbx_uint64_t *hostid,
- zbx_uint32_t *revision, char *error)
+ zbx_uint64_t *revision, char *error)
{
#define PROXY_AUTO_REGISTRATION_HEARTBEAT 120
char *ch_error;
@@ -256,8 +257,7 @@ int send_list_of_active_checks(zbx_socket_t *sock, char *request)
char *host = NULL, *p, *buffer = NULL, error[MAX_STRING_LEN];
size_t buffer_alloc = 8 * ZBX_KIBIBYTE, buffer_offset = 0;
int ret = FAIL, i, num = 0;
- zbx_uint64_t hostid;
- zbx_uint32_t revision;
+ zbx_uint64_t hostid, revision;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
@@ -392,9 +392,9 @@ static void zbx_itemkey_extract_global_regexps(const char *key, zbx_vector_str_t
else
return;
- init_request(&request);
+ zbx_init_agent_request(&request);
- if(SUCCEED != parse_item_key(key, &request))
+ if(SUCCEED != zbx_parse_item_key(key, &request))
goto out;
/* "params" parameter */
@@ -416,7 +416,7 @@ static void zbx_itemkey_extract_global_regexps(const char *key, zbx_vector_str_t
zbx_vector_str_append_uniq(regexps, param + 1);
}
out:
- free_request(&request);
+ zbx_free_agent_request(&request);
}
/******************************************************************************
@@ -436,8 +436,7 @@ int send_list_of_active_checks_json(zbx_socket_t *sock, struct zbx_json_parse *j
error[MAX_STRING_LEN], *host_metadata = NULL, *interface = NULL, *buffer = NULL;
struct zbx_json json;
int ret = FAIL, i, version, num = 0;
- zbx_uint64_t hostid;
- zbx_uint32_t revision, agent_config_revision;
+ zbx_uint64_t hostid, revision, agent_config_revision;
size_t host_metadata_alloc = 1; /* for at least NUL-terminated string */
size_t interface_alloc = 1; /* for at least NUL-terminated string */
size_t buffer_size, reserved = 0;
@@ -510,29 +509,26 @@ int send_list_of_active_checks_json(zbx_socket_t *sock, struct zbx_json_parse *j
{
agent_config_revision = 0;
}
- else if (FAIL == zbx_is_uint32(tmp, &agent_config_revision))
+ else if (FAIL == zbx_is_uint64(tmp, &agent_config_revision))
{
zbx_snprintf(error, MAX_STRING_LEN, "\"%s\" is not a valid revision", tmp);
goto error;
}
- if (FAIL == get_hostid_by_host(sock, host, ip, port, host_metadata, flag, interface, &hostid, &revision,
- error))
- {
+ if (FAIL == get_hostid_by_host(sock, host, ip, port, host_metadata, flag, interface, &hostid, &revision, error))
goto error;
- }
if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_VERSION, tmp, sizeof(tmp), NULL) ||
- FAIL == (version = zbx_get_component_version(tmp)))
+ FAIL == (version = zbx_get_component_version_without_patch(tmp)))
{
- version = ZBX_COMPONENT_VERSION(4, 2);
+ version = ZBX_COMPONENT_VERSION(4, 2, 0);
}
if (SUCCEED == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_SESSION, tmp, sizeof(tmp), NULL))
{
size_t token_len;
- if (zbx_get_token_len() != (token_len = strlen(tmp)))
+ if (ZBX_SESSION_TOKEN_SIZE != (token_len = strlen(tmp)))
{
zbx_snprintf(error, MAX_STRING_LEN, "invalid session token length %d", (int)token_len);
goto error;
@@ -593,7 +589,7 @@ int send_list_of_active_checks_json(zbx_socket_t *sock, struct zbx_json_parse *j
zbx_json_addobject(&json, NULL);
zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, dc_items[i].key, ZBX_JSON_TYPE_STRING);
- if (ZBX_COMPONENT_VERSION(4,4) > version)
+ if (ZBX_COMPONENT_VERSION(4, 4, 0) > version)
{
if (0 != strcmp(dc_items[i].key, dc_items[i].key_orig))
{
@@ -635,7 +631,7 @@ int send_list_of_active_checks_json(zbx_socket_t *sock, struct zbx_json_parse *j
zbx_json_close(&json);
- if (ZBX_COMPONENT_VERSION(4,4) == version || ZBX_COMPONENT_VERSION(5,0) == version)
+ if (ZBX_COMPONENT_VERSION(4, 4, 0) == version || ZBX_COMPONENT_VERSION(5, 0, 0) == version)
zbx_json_adduint64(&json, ZBX_PROTO_TAG_REFRESH_UNSUPPORTED, 600);
DCget_expressions_by_names(&regexps, (const char * const *)names.values, names.values_num);
diff --git a/src/zabbix_server/trapper/proxyconfig.c b/src/zabbix_server/trapper/proxyconfig.c
deleted file mode 100644
index 618d976453a..00000000000
--- a/src/zabbix_server/trapper/proxyconfig.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
-** Zabbix
-** Copyright (C) 2001-2022 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 "proxyconfig.h"
-
-#include "zbxdbhigh.h"
-#include "log.h"
-#include "proxy.h"
-#include "zbxrtc.h"
-#include "zbxcommshigh.h"
-
-#include "zbxcompress.h"
-
-/******************************************************************************
- * *
- * Purpose: send configuration tables to the proxy from server *
- * (for active proxies) *
- * *
- ******************************************************************************/
-void send_proxyconfig(zbx_socket_t *sock, struct zbx_json_parse *jp)
-{
- char *error = NULL, *buffer = NULL;
- struct zbx_json j;
- DC_PROXY proxy;
- int ret, flags = ZBX_TCP_PROTOCOL;
- size_t buffer_size, reserved = 0;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
-
- if (SUCCEED != get_active_proxy_from_request(jp, &proxy, &error))
- {
- zabbix_log(LOG_LEVEL_WARNING, "cannot parse proxy configuration data request from active proxy at"
- " \"%s\": %s", sock->peer, error);
- goto out;
- }
-
- if (SUCCEED != zbx_proxy_check_permissions(&proxy, sock, &error))
- {
- zabbix_log(LOG_LEVEL_WARNING, "cannot accept connection from proxy \"%s\" at \"%s\", allowed address:"
- " \"%s\": %s", proxy.host, sock->peer, proxy.proxy_address, error);
- goto out;
- }
-
- zbx_update_proxy_data(&proxy, zbx_get_proxy_protocol_version(jp), (int)time(NULL),
- (0 != (sock->protocol & ZBX_TCP_COMPRESS) ? 1 : 0), ZBX_FLAGS_PROXY_DIFF_UPDATE_CONFIG);
-
- if (0 != proxy.auto_compress)
- flags |= ZBX_TCP_COMPRESS;
-
- zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN);
-
- if (SUCCEED != get_proxyconfig_data(proxy.hostid, &j, &error))
- {
- zbx_send_response_ext(sock, FAIL, error, NULL, flags, CONFIG_TIMEOUT);
- zabbix_log(LOG_LEVEL_WARNING, "cannot collect configuration data for proxy \"%s\" at \"%s\": %s",
- proxy.host, sock->peer, error);
- goto clean;
- }
-
- zabbix_log(LOG_LEVEL_DEBUG, "%s", j.buffer);
-
- if (0 != proxy.auto_compress)
- {
- if (SUCCEED != zbx_compress(j.buffer, j.buffer_size, &buffer, &buffer_size))
- {
- zabbix_log(LOG_LEVEL_ERR,"cannot compress data: %s", zbx_compress_strerror());
- goto clean;
- }
-
- reserved = j.buffer_size;
-
- zbx_json_free(&j); /* json buffer can be large, free as fast as possible */
-
- zabbix_log(LOG_LEVEL_WARNING, "sending configuration data to proxy \"%s\" at \"%s\", datalen "
- ZBX_FS_SIZE_T ", bytes " ZBX_FS_SIZE_T " with compression ratio %.1f", proxy.host,
- sock->peer, (zbx_fs_size_t)reserved, (zbx_fs_size_t)buffer_size,
- (double)reserved / (double)buffer_size);
-
- ret = zbx_tcp_send_ext(sock, buffer, buffer_size, reserved, (unsigned char)flags,
- CONFIG_TRAPPER_TIMEOUT);
- }
- else
- {
- zabbix_log(LOG_LEVEL_WARNING, "sending configuration data to proxy \"%s\" at \"%s\", datalen "
- ZBX_FS_SIZE_T, proxy.host, sock->peer, (zbx_fs_size_t)j.buffer_size);
-
- ret = zbx_tcp_send_ext(sock, j.buffer, strlen(j.buffer), 0, (unsigned char)flags,
- CONFIG_TRAPPER_TIMEOUT);
- }
-
- if (SUCCEED != ret)
- {
- zabbix_log(LOG_LEVEL_WARNING, "cannot send configuration data to proxy \"%s\" at \"%s\": %s",
- proxy.host, sock->peer, zbx_socket_strerror());
- }
-clean:
- zbx_json_free(&j);
-out:
- zbx_free(error);
- zbx_free(buffer);
-
- zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
-}
-
-/******************************************************************************
- * *
- * Purpose: receive configuration tables from server (passive proxies) *
- * *
- ******************************************************************************/
-void recv_proxyconfig(zbx_socket_t *sock, struct zbx_json_parse *jp, const zbx_config_tls_t *zbx_config_tls)
-{
- struct zbx_json_parse jp_data, jp_kvs_paths = {0};
- int ret;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
-
- if (SUCCEED != (ret = zbx_json_brackets_by_name(jp, ZBX_PROTO_TAG_DATA, &jp_data)))
- {
- zabbix_log(LOG_LEVEL_WARNING, "cannot parse proxy configuration data received from server at"
- " \"%s\": %s", sock->peer, zbx_json_strerror());
- zbx_send_proxy_response(sock, ret, zbx_json_strerror(), CONFIG_TIMEOUT);
- goto out;
- }
-
- if (SUCCEED != check_access_passive_proxy(sock, ZBX_SEND_RESPONSE, "configuration update", zbx_config_tls))
- {
- goto out;
- }
-
- if (SUCCEED == process_proxyconfig(&jp_data, &jp_kvs_paths))
- {
- char *error = NULL;
-
- if (SUCCEED == zbx_rtc_reload_config_cache(&error))
- {
- if (NULL != jp_kvs_paths.start)
- DCsync_kvs_paths(&jp_kvs_paths);
- }
- else
- {
- THIS_SHOULD_NEVER_HAPPEN;
- zabbix_log(LOG_LEVEL_WARNING, "cannot send message to configuration syncer: %s", error);
- zbx_free(error);
- }
- }
- zbx_send_proxy_response(sock, ret, NULL, CONFIG_TIMEOUT);
-out:
- zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
-}
diff --git a/src/zabbix_server/trapper/proxydata.c b/src/zabbix_server/trapper/proxydata.c
index 99a3cceded6..e964a3ff40b 100644
--- a/src/zabbix_server/trapper/proxydata.c
+++ b/src/zabbix_server/trapper/proxydata.c
@@ -62,7 +62,7 @@ int zbx_send_proxy_data_response(const DC_PROXY *proxy, zbx_socket_t *sock, cons
if (SUCCEED == status)
{
zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING);
- zbx_tm_get_remote_tasks(&tasks, proxy->hostid);
+ zbx_tm_get_remote_tasks(&tasks, proxy->hostid, proxy->compatibility);
}
else
zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING);
@@ -128,8 +128,8 @@ static int proxy_data_no_history(const struct zbx_json_parse *jp)
******************************************************************************/
void zbx_recv_proxy_data(zbx_socket_t *sock, struct zbx_json_parse *jp, zbx_timespec_t *ts)
{
- int ret = FAIL, upload_status = 0, status, version, responded = 0;
- char *error = NULL;
+ int ret = FAIL, upload_status = 0, status, version_int, responded = 0;
+ char *error = NULL, *version_str = NULL;
DC_PROXY proxy;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
@@ -148,11 +148,14 @@ void zbx_recv_proxy_data(zbx_socket_t *sock, struct zbx_json_parse *jp, zbx_time
goto out;
}
- version = zbx_get_proxy_protocol_version(jp);
+ version_str = zbx_get_proxy_protocol_version_str(jp);
+ version_int = zbx_get_proxy_protocol_version_int(version_str);
- if (SUCCEED != zbx_check_protocol_version(&proxy, version))
+ if (SUCCEED != zbx_check_protocol_version(&proxy, version_int))
{
- goto out;
+ upload_status = ZBX_PROXY_UPLOAD_DISABLED;
+ error = zbx_strdup(error, "current proxy version is not supported by server");
+ goto reply;
}
if (FAIL == (ret = zbx_hc_check_proxy(proxy.hostid)))
@@ -181,10 +184,9 @@ void zbx_recv_proxy_data(zbx_socket_t *sock, struct zbx_json_parse *jp, zbx_time
ret = FAIL;
goto out;
}
-
+reply:
zbx_send_proxy_data_response(&proxy, sock, error, ret, upload_status);
responded = 1;
-
out:
if (SUCCEED == status) /* moved the unpredictable long operation to the end */
/* we are trying to save info about lastaccess to detect communication problem */
@@ -196,7 +198,7 @@ out:
else
lastaccess = ts->sec;
- zbx_update_proxy_data(&proxy, version, lastaccess,
+ zbx_update_proxy_data(&proxy, version_str, version_int, lastaccess,
(0 != (sock->protocol & ZBX_TCP_COMPRESS) ? 1 : 0), 0);
}
@@ -211,6 +213,7 @@ out:
}
zbx_free(error);
+ zbx_free(version_str);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
}
@@ -248,10 +251,10 @@ static int send_data_to_server(zbx_socket_t *sock, char **buffer, size_t buffer_
* *
* Parameters: sock - [IN] the connection socket *
* ts - [IN] the connection timestamp *
- * zbx_config_tls - [IN] *
+ * zbx_config - [IN] proxy config *
* *
******************************************************************************/
-void zbx_send_proxy_data(zbx_socket_t *sock, zbx_timespec_t *ts, const zbx_config_tls_t *zbx_config_tls)
+void zbx_send_proxy_data(zbx_socket_t *sock, zbx_timespec_t *ts, const zbx_config_comms_args_t *zbx_config)
{
struct zbx_json j;
zbx_uint64_t areg_lastid = 0, history_lastid = 0, discovery_lastid = 0;
@@ -263,7 +266,8 @@ void zbx_send_proxy_data(zbx_socket_t *sock, zbx_timespec_t *ts, const zbx_confi
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
- if (SUCCEED != check_access_passive_proxy(sock, ZBX_DO_NOT_SEND_RESPONSE, "proxy data request", zbx_config_tls))
+ if (SUCCEED != check_access_passive_proxy(sock, ZBX_DO_NOT_SEND_RESPONSE, "proxy data request",
+ zbx_config->zbx_config_tls))
{
/* do not send any reply to server in this case as the server expects proxy data */
goto out;
@@ -280,7 +284,7 @@ void zbx_send_proxy_data(zbx_socket_t *sock, zbx_timespec_t *ts, const zbx_confi
proxy_get_host_active_availability(&j);
zbx_vector_ptr_create(&tasks);
- zbx_tm_get_remote_tasks(&tasks, 0);
+ zbx_tm_get_remote_tasks(&tasks, 0, 0);
if (0 != tasks.values_num)
zbx_tm_json_serialize_tasks(&j, &tasks);
@@ -377,10 +381,10 @@ out:
* *
* Parameters: sock - [IN] the connection socket *
* ts - [IN] the connection timestamp *
- * zbx_config_tls - [IN] *
+ * zbx_config - [IN] proxy config *
* *
******************************************************************************/
-void zbx_send_task_data(zbx_socket_t *sock, zbx_timespec_t *ts, const zbx_config_tls_t *zbx_config_tls)
+void zbx_send_task_data(zbx_socket_t *sock, zbx_timespec_t *ts, const zbx_config_comms_args_t *zbx_config)
{
struct zbx_json j;
char *error = NULL, *buffer = NULL;
@@ -390,7 +394,8 @@ void zbx_send_task_data(zbx_socket_t *sock, zbx_timespec_t *ts, const zbx_config
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
- if (SUCCEED != check_access_passive_proxy(sock, ZBX_DO_NOT_SEND_RESPONSE, "proxy data request", zbx_config_tls))
+ if (SUCCEED != check_access_passive_proxy(sock, ZBX_DO_NOT_SEND_RESPONSE, "proxy data request",
+ zbx_config->zbx_config_tls))
{
/* do not send any reply to server in this case as the server expects proxy data */
goto out;
@@ -399,7 +404,7 @@ void zbx_send_task_data(zbx_socket_t *sock, zbx_timespec_t *ts, const zbx_config
zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN);
zbx_vector_ptr_create(&tasks);
- zbx_tm_get_remote_tasks(&tasks, 0);
+ zbx_tm_get_remote_tasks(&tasks, 0, 0);
if (0 != tasks.values_num)
zbx_tm_json_serialize_tasks(&j, &tasks);
diff --git a/src/zabbix_server/trapper/proxydata.h b/src/zabbix_server/trapper/proxydata.h
index af7f0323332..b7ee7f6b3ad 100644
--- a/src/zabbix_server/trapper/proxydata.h
+++ b/src/zabbix_server/trapper/proxydata.h
@@ -27,8 +27,8 @@ extern int CONFIG_TIMEOUT;
extern int CONFIG_TRAPPER_TIMEOUT;
void zbx_recv_proxy_data(zbx_socket_t *sock, struct zbx_json_parse *jp, zbx_timespec_t *ts);
-void zbx_send_proxy_data(zbx_socket_t *sock, zbx_timespec_t *ts, const zbx_config_tls_t *zbx_config_tls);
-void zbx_send_task_data(zbx_socket_t *sock, zbx_timespec_t *ts, const zbx_config_tls_t *zbx_config_tls);
+void zbx_send_proxy_data(zbx_socket_t *sock, zbx_timespec_t *ts, const zbx_config_comms_args_t *zbx_config);
+void zbx_send_task_data(zbx_socket_t *sock, zbx_timespec_t *ts, const zbx_config_comms_args_t *zbx_config);
int zbx_send_proxy_data_response(const DC_PROXY *proxy, zbx_socket_t *sock, const char *info, int status,
int upload_status);
diff --git a/src/zabbix_server/trapper/trapper.c b/src/zabbix_server/trapper/trapper.c
index c747ba8618c..2dcbf7ae59e 100644
--- a/src/zabbix_server/trapper/trapper.c
+++ b/src/zabbix_server/trapper/trapper.c
@@ -25,7 +25,6 @@
#include "zbxself.h"
#include "active.h"
#include "nodecommand.h"
-#include "proxyconfig.h"
#include "proxydata.h"
#include "zbxnix.h"
#include "zbxcommshigh.h"
@@ -39,6 +38,7 @@
#include "zbxxml.h"
#include "base64.h"
#include "zbxtime.h"
+#include "zbxstats.h"
#ifdef HAVE_NETSNMP
# include "zbxrtc.h"
@@ -47,8 +47,9 @@
#define ZBX_MAX_SECTION_ENTRIES 4
#define ZBX_MAX_ENTRY_ATTRIBUTES 3
+static zbx_get_program_type_f zbx_get_program_type_cb = NULL;
+
extern ZBX_THREAD_LOCAL unsigned char process_type;
-extern unsigned char program_type;
extern ZBX_THREAD_LOCAL int server_num, process_num;
extern size_t (*find_psk_in_cache)(const unsigned char *, unsigned char *, unsigned int *);
@@ -164,43 +165,31 @@ static void recv_senderhistory(zbx_socket_t *sock, struct zbx_json_parse *jp, zb
* *
* Purpose: process heartbeat sent by proxy servers *
* *
- * Return value: SUCCEED - processed successfully *
- * FAIL - an error occurred *
- * *
******************************************************************************/
static void recv_proxy_heartbeat(zbx_socket_t *sock, struct zbx_json_parse *jp)
{
char *error = NULL;
- int ret, flags = ZBX_TCP_PROTOCOL;
DC_PROXY proxy;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
- if (SUCCEED != (ret = get_active_proxy_from_request(jp, &proxy, &error)))
+ if (SUCCEED != get_active_proxy_from_request(jp, &proxy, &error))
{
zabbix_log(LOG_LEVEL_WARNING, "cannot parse heartbeat from active proxy at \"%s\": %s",
sock->peer, error);
goto out;
}
- if (SUCCEED != (ret = zbx_proxy_check_permissions(&proxy, sock, &error)))
+ if (SUCCEED != zbx_proxy_check_permissions(&proxy, sock, &error))
{
zabbix_log(LOG_LEVEL_WARNING, "cannot accept connection from proxy \"%s\" at \"%s\", allowed address:"
" \"%s\": %s", proxy.host, sock->peer, proxy.proxy_address, error);
goto out;
}
- zbx_update_proxy_data(&proxy, zbx_get_proxy_protocol_version(jp), time(NULL),
- (0 != (sock->protocol & ZBX_TCP_COMPRESS) ? 1 : 0), ZBX_FLAGS_PROXY_DIFF_UPDATE_HEARTBEAT);
-
- if (0 != proxy.auto_compress)
- flags |= ZBX_TCP_COMPRESS;
+ zabbix_log(LOG_LEVEL_DEBUG, "ignoring heartbeat from active proxy \"%s\" at \"%s\": proxy heartbeats"
+ " are deprecated", proxy.host, sock->peer);
out:
- if (FAIL == ret && 0 != (sock->protocol & ZBX_TCP_COMPRESS))
- flags |= ZBX_TCP_COMPRESS;
-
- zbx_send_response_ext(sock, ret, error, NULL, flags, CONFIG_TIMEOUT);
-
zbx_free(error);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
@@ -856,14 +845,16 @@ out:
* *
* Purpose: process Zabbix stats request *
* *
- * Parameters: sock - [IN] the request socket *
- * jp - [IN] the request data *
+ * Parameters: sock - [IN] the request socket *
+ * jp - [IN] the request data *
+* zbx_config - [IN] server/proxy config *
* *
* Return value: SUCCEED - processed successfully *
* FAIL - an error occurred *
* *
******************************************************************************/
-static int send_internal_stats_json(zbx_socket_t *sock, const struct zbx_json_parse *jp)
+static int send_internal_stats_json(zbx_socket_t *sock, const struct zbx_json_parse *jp,
+ const zbx_config_comms_args_t *zbx_config)
{
struct zbx_json json;
char type[MAX_STRING_LEN], error[MAX_STRING_LEN];
@@ -923,7 +914,7 @@ static int send_internal_stats_json(zbx_socket_t *sock, const struct zbx_json_pa
zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING);
zbx_json_addobject(&json, ZBX_PROTO_TAG_DATA);
- zbx_get_zabbix_stats(&json);
+ zbx_zabbix_stats_get(&json, zbx_config);
zbx_json_close(&json);
}
@@ -941,18 +932,6 @@ out:
return ret;
}
-static void active_passive_misconfig(zbx_socket_t *sock)
-{
- char *msg = NULL;
-
- msg = zbx_dsprintf(msg, "misconfiguration error: the proxy is running in the active mode but server at \"%s\""
- " sends requests to it as to proxy in passive mode", sock->peer);
-
- zabbix_log(LOG_LEVEL_WARNING, "%s", msg);
- zbx_send_proxy_response(sock, FAIL, msg, CONFIG_TIMEOUT);
- zbx_free(msg);
-}
-
static int process_active_check_heartbeat(struct zbx_json_parse *jp)
{
char host[ZBX_MAX_HOSTNAME_LEN * ZBX_MAX_BYTES_IN_UTF8_CHAR + 1],
@@ -1077,7 +1056,7 @@ static int comms_parse_response(char *xml, char *host, size_t host_len, char *ke
}
static int process_trap(zbx_socket_t *sock, char *s, ssize_t bytes_received, zbx_timespec_t *ts,
- const zbx_config_tls_t *zbx_config_tls)
+ const zbx_config_comms_args_t *zbx_config)
{
int ret = SUCCEED;
@@ -1101,111 +1080,86 @@ static int process_trap(zbx_socket_t *sock, char *s, ssize_t bytes_received, zbx
if (SUCCEED != zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_REQUEST, value, sizeof(value), NULL))
return FAIL;
- if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_CONFIG))
+ if (ZBX_GIBIBYTE < bytes_received && 0 != strcmp(value, ZBX_PROTO_VALUE_PROXY_CONFIG))
{
- if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
- {
- send_proxyconfig(sock, &jp);
- }
- else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
- {
- zabbix_log(LOG_LEVEL_WARNING, "received configuration data from server"
- " at \"%s\", datalen " ZBX_FS_SIZE_T,
- sock->peer, (zbx_fs_size_t)(jp.end - jp.start + 1));
- recv_proxyconfig(sock, &jp, zbx_config_tls);
- }
- else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_ACTIVE))
- {
- /* This is a misconfiguration: the proxy is configured in active mode */
- /* but server sends requests to it as to a proxy in passive mode. To */
- /* prevent logging of this problem for every request we report it */
- /* only when the server sends configuration to the proxy and ignore */
- /* it for other requests. */
- active_passive_misconfig(sock);
- }
+ zabbix_log(LOG_LEVEL_WARNING, "message size " ZBX_FS_I64 " exceeds the maximum size "
+ ZBX_FS_UI64 " for request \"%s\" received from \"%s\"", bytes_received,
+ (zbx_uint64_t)ZBX_GIBIBYTE, value, sock->peer);
+ return FAIL;
}
- else
- {
- if (ZBX_GIBIBYTE < bytes_received)
- {
- zabbix_log(LOG_LEVEL_WARNING, "message size " ZBX_FS_I64 " exceeds the maximum size "
- ZBX_FS_UI64 " for request \"%s\" received from \"%s\"", bytes_received,
- (zbx_uint64_t)ZBX_GIBIBYTE, value, sock->peer);
- return FAIL;
- }
- if (0 == strcmp(value, ZBX_PROTO_VALUE_AGENT_DATA))
- {
- recv_agenthistory(sock, &jp, ts);
- }
- else if (0 == strcmp(value, ZBX_PROTO_VALUE_SENDER_DATA))
- {
- recv_senderhistory(sock, &jp, ts);
- }
- else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_TASKS))
- {
- if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
- zbx_send_task_data(sock, ts, zbx_config_tls);
- }
- else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_DATA))
- {
- if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
- zbx_recv_proxy_data(sock, &jp, ts);
- else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
- zbx_send_proxy_data(sock, ts, zbx_config_tls);
- }
- else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_HEARTBEAT))
- {
- if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
- recv_proxy_heartbeat(sock, &jp);
- }
- else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS))
- {
- ret = send_list_of_active_checks_json(sock, &jp);
- }
- else if (0 == strcmp(value, ZBX_PROTO_VALUE_COMMAND))
- {
- if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
- ret = node_process_command(sock, s, &jp);
- }
- else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_QUEUE))
- {
- if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
- ret = recv_getqueue(sock, &jp);
- }
- else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_STATUS))
- {
- if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
- ret = recv_getstatus(sock, &jp);
- }
- else if (0 == strcmp(value, ZBX_PROTO_VALUE_ZABBIX_STATS))
- {
- ret = send_internal_stats_json(sock, &jp);
- }
- else if (0 == strcmp(value, ZBX_PROTO_VALUE_PREPROCESSING_TEST))
- {
- if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
- ret = zbx_trapper_preproc_test(sock, &jp);
- }
- else if (0 == strcmp(value, ZBX_PROTO_VALUE_EXPRESSIONS_EVALUATE))
- {
- if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
- ret = zbx_trapper_expressions_evaluate(sock, &jp);
- }
- else if (0 == strcmp(value, ZBX_PROTO_VALUE_ZABBIX_ITEM_TEST))
- {
- if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
- zbx_trapper_item_test(sock, &jp);
- }
- else if (0 == strcmp(value, ZBX_PROTO_VALUE_ACTIVE_CHECK_HEARTBEAT))
- {
- ret = process_active_check_heartbeat(&jp);
- }
- else if (SUCCEED != trapper_process_request(value, sock, &jp))
- {
- zabbix_log(LOG_LEVEL_WARNING, "unknown request received from \"%s\": [%s]", sock->peer,
- value);
- }
+ if (0 == strcmp(value, ZBX_PROTO_VALUE_AGENT_DATA))
+ {
+ recv_agenthistory(sock, &jp, ts);
+ }
+ else if (0 == strcmp(value, ZBX_PROTO_VALUE_SENDER_DATA))
+ {
+ recv_senderhistory(sock, &jp, ts);
+ }
+ else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_TASKS))
+ {
+ if (0 != (zbx_get_program_type_cb() & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
+ zbx_send_task_data(sock, ts, zbx_config);
+ }
+ else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_DATA))
+ {
+ if (0 != (zbx_get_program_type_cb() & ZBX_PROGRAM_TYPE_SERVER))
+ zbx_recv_proxy_data(sock, &jp, ts);
+ else if (0 != (zbx_get_program_type_cb() & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
+ zbx_send_proxy_data(sock, ts, zbx_config);
+ }
+ else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_HEARTBEAT))
+ {
+ if (0 != (zbx_get_program_type_cb() & ZBX_PROGRAM_TYPE_SERVER))
+ recv_proxy_heartbeat(sock, &jp);
+ }
+ else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS))
+ {
+ ret = send_list_of_active_checks_json(sock, &jp);
+ }
+ else if (0 == strcmp(value, ZBX_PROTO_VALUE_COMMAND))
+ {
+ if (0 != (zbx_get_program_type_cb() & ZBX_PROGRAM_TYPE_SERVER))
+ ret = node_process_command(sock, s, &jp);
+ }
+ else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_QUEUE))
+ {
+ if (0 != (zbx_get_program_type_cb() & ZBX_PROGRAM_TYPE_SERVER))
+ ret = recv_getqueue(sock, &jp);
+ }
+ else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_STATUS))
+ {
+ if (0 != (zbx_get_program_type_cb() & ZBX_PROGRAM_TYPE_SERVER))
+ ret = recv_getstatus(sock, &jp);
+ }
+ else if (0 == strcmp(value, ZBX_PROTO_VALUE_ZABBIX_STATS))
+ {
+ ret = send_internal_stats_json(sock, &jp, zbx_config);
+ }
+ else if (0 == strcmp(value, ZBX_PROTO_VALUE_PREPROCESSING_TEST))
+ {
+ if (0 != (zbx_get_program_type_cb() & ZBX_PROGRAM_TYPE_SERVER))
+ ret = zbx_trapper_preproc_test(sock, &jp);
+ }
+ else if (0 == strcmp(value, ZBX_PROTO_VALUE_EXPRESSIONS_EVALUATE))
+ {
+ if (0 != (zbx_get_program_type_cb() & ZBX_PROGRAM_TYPE_SERVER))
+ ret = zbx_trapper_expressions_evaluate(sock, &jp);
+ }
+ else if (0 == strcmp(value, ZBX_PROTO_VALUE_ZABBIX_ITEM_TEST))
+ {
+ if (0 != (zbx_get_program_type_cb() & ZBX_PROGRAM_TYPE_SERVER))
+ zbx_trapper_item_test(sock, &jp, zbx_config);
+ }
+ else if (0 == strcmp(value, ZBX_PROTO_VALUE_ACTIVE_CHECK_HEARTBEAT))
+ {
+ ret = process_active_check_heartbeat(&jp);
+ }
+ else if (SUCCEED != trapper_process_request(value, sock, &jp, zbx_config->zbx_config_tls,
+ zbx_get_program_type_cb))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "unknown request received from \"%s\": [%s]", sock->peer,
+ value);
}
}
else if (0 == strncmp(s, "ZBX_GET_ACTIVE_CHECKS", 21)) /* request for list of active checks */
@@ -1288,14 +1242,14 @@ static int process_trap(zbx_socket_t *sock, char *s, ssize_t bytes_received, zbx
return ret;
}
-static void process_trapper_child(zbx_socket_t *sock, zbx_timespec_t *ts, const zbx_config_tls_t *zbx_config_tls)
+static void process_trapper_child(zbx_socket_t *sock, zbx_timespec_t *ts, const zbx_config_comms_args_t *zbx_config)
{
ssize_t bytes_received;
if (FAIL == (bytes_received = zbx_tcp_recv_ext(sock, CONFIG_TRAPPER_TIMEOUT, ZBX_TCP_LARGE)))
return;
- process_trap(sock, sock->buffer, bytes_received, ts, zbx_config_tls);
+ process_trap(sock, sock->buffer, bytes_received, ts, zbx_config);
}
ZBX_THREAD_ENTRY(trapper_thread, args)
@@ -1313,17 +1267,18 @@ ZBX_THREAD_ENTRY(trapper_thread, args)
process_type = ((zbx_thread_args_t *)args)->process_type;
server_num = ((zbx_thread_args_t *)args)->server_num;
process_num = ((zbx_thread_args_t *)args)->process_num;
+ zbx_get_program_type_cb = trapper_args_in->zbx_get_program_type_cb_arg;
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]",
get_program_type_string(trapper_args_in->zbx_get_program_type_cb_arg()),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
memcpy(&s, trapper_args_in->listen_sock, sizeof(zbx_socket_t));
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
- zbx_tls_init_child(trapper_args_in->zbx_config_tls, trapper_args_in->zbx_get_program_type_cb_arg);
+ zbx_tls_init_child(trapper_args_in->zbx_config->zbx_config_tls, zbx_get_program_type_cb);
find_psk_in_cache = DCget_psk_by_identity;
#endif
zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num);
@@ -1345,7 +1300,7 @@ ZBX_THREAD_ENTRY(trapper_thread, args)
zbx_setproctitle("%s #%d [processed data in " ZBX_FS_DBL " sec, waiting for connection]",
get_process_type_string(process_type), process_num, sec);
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
/* Trapper has to accept all types of connections it can accept with the specified configuration. */
/* Only after receiving data it is known who has sent them and one can decide to accept or discard */
@@ -1360,7 +1315,7 @@ ZBX_THREAD_ENTRY(trapper_thread, args)
/* get connection timestamp */
zbx_timespec(&ts);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
zbx_setproctitle("%s #%d [processing data]", get_process_type_string(process_type),
process_num);
@@ -1382,7 +1337,7 @@ ZBX_THREAD_ENTRY(trapper_thread, args)
}
#endif
sec = zbx_time();
- process_trapper_child(&s, &ts, trapper_args_in->zbx_config_tls);
+ process_trapper_child(&s, &ts, trapper_args_in->zbx_config);
sec = zbx_time() - sec;
zbx_tcp_unaccept(&s);
diff --git a/src/zabbix_server/trapper/trapper.h b/src/zabbix_server/trapper/trapper.h
index 0b947354ba5..9f7a7548022 100644
--- a/src/zabbix_server/trapper/trapper.h
+++ b/src/zabbix_server/trapper/trapper.h
@@ -32,7 +32,7 @@ extern char *CONFIG_STATS_ALLOWED_IP;
typedef struct
{
- zbx_config_tls_t *zbx_config_tls;
+ zbx_config_comms_args_t *zbx_config;
zbx_get_program_type_f zbx_get_program_type_cb_arg;
zbx_socket_t *listen_sock;
}
diff --git a/src/zabbix_server/trapper/trapper_auth.c b/src/zabbix_server/trapper/trapper_auth.c
index f294906ff2b..ea77965d834 100644
--- a/src/zabbix_server/trapper/trapper_auth.c
+++ b/src/zabbix_server/trapper/trapper_auth.c
@@ -19,7 +19,6 @@
#include "trapper_auth.h"
-#include <string.h>
#include "zbxdbhigh.h"
#include "log.h"
#include "zbxhash.h"
diff --git a/src/zabbix_server/trapper/trapper_item_test.c b/src/zabbix_server/trapper/trapper_item_test.c
index 555e633d91e..07577414935 100644
--- a/src/zabbix_server/trapper/trapper_item_test.c
+++ b/src/zabbix_server/trapper/trapper_item_test.c
@@ -126,7 +126,8 @@ static void db_uchar_from_json(const struct zbx_json_parse *jp, const char *name
ZBX_STR2UCHAR(*string, DBget_field(table, fieldname)->default_value);
}
-int zbx_trapper_item_test_run(const struct zbx_json_parse *jp_data, zbx_uint64_t proxy_hostid, char **info)
+int zbx_trapper_item_test_run(const struct zbx_json_parse *jp_data, zbx_uint64_t proxy_hostid, char **info,
+ const zbx_config_comms_args_t *zbx_config)
{
char tmp[MAX_STRING_LEN + 1], **pvalue;
DC_ITEM item;
@@ -300,7 +301,7 @@ int zbx_trapper_item_test_run(const struct zbx_json_parse *jp_data, zbx_uint64_t
if (ITEM_TYPE_IPMI == item.type)
{
- init_result(&result);
+ zbx_init_agent_result(&result);
if (FAIL == zbx_is_ushort(item.interface.port_orig, &item.interface.port))
{
@@ -350,7 +351,7 @@ int zbx_trapper_item_test_run(const struct zbx_json_parse *jp_data, zbx_uint64_t
zbx_eval_clear(&ctx);
}
- zbx_check_items(&item, &errcode, 1, &result, &add_results, ZBX_NO_POLLER);
+ zbx_check_items(&item, &errcode, 1, &result, &add_results, ZBX_NO_POLLER, zbx_config);
switch (errcode)
{
@@ -372,7 +373,7 @@ int zbx_trapper_item_test_run(const struct zbx_json_parse *jp_data, zbx_uint64_t
*info = zbx_strdup(NULL, *pvalue);
}
- zbx_vector_ptr_clear_ext(&add_results, (zbx_mem_free_func_t)zbx_free_result_ptr);
+ zbx_vector_ptr_clear_ext(&add_results, (zbx_mem_free_func_t)zbx_free_agent_result_ptr);
zbx_vector_ptr_destroy(&add_results);
}
@@ -409,7 +410,7 @@ out:
return ret;
}
-void zbx_trapper_item_test(zbx_socket_t *sock, const struct zbx_json_parse *jp)
+void zbx_trapper_item_test(zbx_socket_t *sock, const struct zbx_json_parse *jp, const zbx_config_comms_args_t *zbx_config)
{
zbx_user_t user;
struct zbx_json_parse jp_data;
@@ -446,7 +447,7 @@ void zbx_trapper_item_test(zbx_socket_t *sock, const struct zbx_json_parse *jp)
else
proxy_hostid = 0;
- ret = zbx_trapper_item_test_run(&jp_data, proxy_hostid, &info);
+ ret = zbx_trapper_item_test_run(&jp_data, proxy_hostid, &info, zbx_config);
zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, "success", ZBX_JSON_TYPE_STRING);
zbx_json_addobject(&json, ZBX_PROTO_TAG_DATA);
diff --git a/src/zabbix_server/trapper/trapper_item_test.h b/src/zabbix_server/trapper/trapper_item_test.h
index 960425bb01f..d58dd0e3a8c 100644
--- a/src/zabbix_server/trapper/trapper_item_test.h
+++ b/src/zabbix_server/trapper/trapper_item_test.h
@@ -23,7 +23,9 @@
#include "zbxcomms.h"
#include "zbxjson.h"
-void zbx_trapper_item_test(zbx_socket_t *sock, const struct zbx_json_parse *jp);
-int zbx_trapper_item_test_run(const struct zbx_json_parse *jp_data, zbx_uint64_t proxy_hostid, char **info);
+void zbx_trapper_item_test(zbx_socket_t *sock, const struct zbx_json_parse *jp,
+ const zbx_config_comms_args_t *zbx_config);
+int zbx_trapper_item_test_run(const struct zbx_json_parse *jp_data, zbx_uint64_t proxy_hostid, char **info,
+ const zbx_config_comms_args_t *zbx_config);
#endif
diff --git a/src/zabbix_server/trapper/trapper_proxy.c b/src/zabbix_server/trapper/trapper_proxy.c
index 2f5a0cb3183..0e362c22632 100644
--- a/src/zabbix_server/trapper/trapper_proxy.c
+++ b/src/zabbix_server/trapper/trapper_proxy.c
@@ -19,8 +19,44 @@
#include "trapper_request.h"
-int trapper_process_request(const char *request, zbx_socket_t *sock, const struct zbx_json_parse *jp)
+#include "zbxcommshigh.h"
+#include "proxyconfigwrite/proxyconfig_write.h"
+
+extern int CONFIG_TIMEOUT;
+
+static void active_passive_misconfig(zbx_socket_t *sock)
+{
+ char *msg = NULL;
+
+ msg = zbx_dsprintf(msg, "misconfiguration error: the proxy is running in the active mode but server at \"%s\""
+ " sends requests to it as to proxy in passive mode", sock->peer);
+
+ zabbix_log(LOG_LEVEL_WARNING, "%s", msg);
+ zbx_send_proxy_response(sock, FAIL, msg, CONFIG_TIMEOUT);
+ zbx_free(msg);
+}
+
+int trapper_process_request(const char *request, zbx_socket_t *sock, const struct zbx_json_parse *jp,
+ const zbx_config_tls_t *zbx_config_tls, zbx_get_program_type_f get_program_type_cb)
{
+ if (0 == strcmp(request, ZBX_PROTO_VALUE_PROXY_CONFIG))
+ {
+ if (0 != (get_program_type_cb() & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
+ {
+ zbx_recv_proxyconfig(sock, zbx_config_tls);
+ return SUCCEED;
+ }
+ else if (0 != (get_program_type_cb() & ZBX_PROGRAM_TYPE_PROXY_ACTIVE))
+ {
+ /* This is a misconfiguration: the proxy is configured in active mode */
+ /* but server sends requests to it as to a proxy in passive mode. To */
+ /* prevent logging of this problem for every request we report it */
+ /* only when the server sends configuration to the proxy and ignore */
+ /* it for other requests. */
+ active_passive_misconfig(sock);
+ return SUCCEED;
+ }
+ }
ZBX_UNUSED(request);
ZBX_UNUSED(sock);
ZBX_UNUSED(jp);
diff --git a/src/zabbix_server/trapper/trapper_request.h b/src/zabbix_server/trapper/trapper_request.h
index ffea592e67c..336e6ded36e 100644
--- a/src/zabbix_server/trapper/trapper_request.h
+++ b/src/zabbix_server/trapper/trapper_request.h
@@ -23,6 +23,7 @@
#include "zbxcomms.h"
#include "zbxjson.h"
-int trapper_process_request(const char *request, zbx_socket_t *sock, const struct zbx_json_parse *jp);
+int trapper_process_request(const char *request, zbx_socket_t *sock, const struct zbx_json_parse *jp,
+ const zbx_config_tls_t *zbx_config_tls, zbx_get_program_type_f get_program_type_cb);
#endif
diff --git a/src/zabbix_server/trapper/trapper_server.c b/src/zabbix_server/trapper/trapper_server.c
index c963a795898..f91142e02b3 100644
--- a/src/zabbix_server/trapper/trapper_server.c
+++ b/src/zabbix_server/trapper/trapper_server.c
@@ -28,6 +28,7 @@
#include "zbxipcservice.h"
#include "zbxcommshigh.h"
#include "zbxnum.h"
+#include "proxyconfigread/proxyconfig_read.h"
extern int CONFIG_REPORTMANAGER_FORKS;
@@ -214,8 +215,12 @@ fail:
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
}
-int trapper_process_request(const char *request, zbx_socket_t *sock, const struct zbx_json_parse *jp)
+int trapper_process_request(const char *request, zbx_socket_t *sock, const struct zbx_json_parse *jp,
+ const zbx_config_tls_t *zbx_config_tls, zbx_get_program_type_f get_program_type_cb)
{
+ ZBX_UNUSED(zbx_config_tls);
+ ZBX_UNUSED(get_program_type_cb);
+
if (0 == strcmp(request, ZBX_PROTO_VALUE_REPORT_TEST))
{
trapper_process_report_test(sock, jp);
@@ -226,6 +231,11 @@ int trapper_process_request(const char *request, zbx_socket_t *sock, const struc
trapper_process_alert_send(sock, jp);
return SUCCEED;
}
+ else if (0 == strcmp(request, ZBX_PROTO_VALUE_PROXY_CONFIG))
+ {
+ zbx_send_proxyconfig(sock, jp);
+ return SUCCEED;
+ }
return FAIL;
}
diff --git a/src/zabbix_server/vmware/vmware_manager.c b/src/zabbix_server/vmware/vmware_manager.c
index 2c00bca40e0..7b2d5663e19 100644
--- a/src/zabbix_server/vmware/vmware_manager.c
+++ b/src/zabbix_server/vmware/vmware_manager.c
@@ -200,7 +200,7 @@ ZBX_THREAD_ENTRY(vmware_thread, args)
zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
server_num, get_process_type_string(process_type), process_num);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
#define JOB_TIMEOUT 1
#define STAT_INTERVAL 5 /* if a process is busy and does not sleep then update status not faster than */
@@ -243,9 +243,9 @@ ZBX_THREAD_ENTRY(vmware_thread, args)
if (zbx_time() - time_now <= JOB_TIMEOUT)
{
time_idle += JOB_TIMEOUT;
- update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_IDLE);
zbx_sleep_loop(JOB_TIMEOUT);
- update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
+ zbx_update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
}
}