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
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--include/common.h12
-rw-r--r--include/zbxjson.h10
-rw-r--r--include/zbxtasks.h145
-rw-r--r--include/zbxtypes.h7
-rw-r--r--src/libs/Makefile.am9
-rw-r--r--src/libs/zbxjson/json.c8
-rw-r--r--src/libs/zbxtasks/Makefile.am9
-rw-r--r--src/libs/zbxtasks/zbx_task.h36
-rw-r--r--src/libs/zbxtasks/zbx_task_remote_command.c564
-rw-r--r--src/libs/zbxtasks/zbx_task_remote_command_result.c282
-rw-r--r--src/libs/zbxtasks/zbx_task_remote_command_result_set.c223
-rw-r--r--src/libs/zbxtasks/zbx_task_remote_command_set.c236
-rw-r--r--src/zabbix_proxy/Makefile.am7
-rw-r--r--src/zabbix_proxy/proxy.c13
-rw-r--r--src/zabbix_proxy/taskmanager/Makefile.am5
-rw-r--r--src/zabbix_proxy/taskmanager/taskmanager.c104
-rw-r--r--src/zabbix_proxy/taskmanager/taskmanager.h27
-rw-r--r--src/zabbix_server/Makefile.am3
-rw-r--r--src/zabbix_server/pinger/pinger.c2
-rw-r--r--src/zabbix_server/poller/poller.c6
-rw-r--r--src/zabbix_server/taskmanager/taskmanager.c2
22 files changed, 1697 insertions, 15 deletions
diff --git a/configure.ac b/configure.ac
index 3489dfd14be..758fbb8cd76 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1572,6 +1572,7 @@ AC_OUTPUT([
src/libs/zbxself/Makefile
src/libs/zbxmodules/Makefile
src/libs/zbxregexp/Makefile
+ src/libs/zbxtasks/Makefile
src/zabbix_agent/Makefile
src/zabbix_get/Makefile
src/zabbix_sender/Makefile
@@ -1598,6 +1599,7 @@ AC_OUTPUT([
src/zabbix_proxy/housekeeper/Makefile
src/zabbix_proxy/proxyconfig/Makefile
src/zabbix_proxy/datasender/Makefile
+ src/zabbix_proxy/taskmanager/Makefile
src/zabbix_java/Makefile
upgrades/Makefile
man/Makefile
diff --git a/include/common.h b/include/common.h
index 60ff3bc9d84..aa3eff36b5d 100644
--- a/include/common.h
+++ b/include/common.h
@@ -672,8 +672,16 @@ const char *zbx_item_logtype_string(unsigned char logtype);
#define ZBX_TRIGGER_CORRELATION_NONE 0
#define ZBX_TRIGGER_CORRELATION_TAG 1
-/* task manager task types */
-#define ZBX_TM_TASK_CLOSE_PROBLEM 1
+/* task manager task types */
+#define ZBX_TM_TASK_CLOSE_PROBLEM 1
+#define ZBX_TM_TASK_SEND_REMOTE_COMMAND 2
+#define ZBX_TM_TASK_SEND_REMOTE_COMMAND_RESULT 3
+
+/* task manager task states */
+#define ZBX_TM_STATUS_NEW 1
+#define ZBX_TM_STATUS_INPROGRESS 2
+#define ZBX_TM_STATUS_DONE 3
+#define ZBX_TM_STATUS_EXPIRED 4
/* acknowledgment actions (flags) */
#define ZBX_ACKNOWLEDGE_ACTION_NONE 0x0000
diff --git a/include/zbxjson.h b/include/zbxjson.h
index 04aec1ecb4c..acbd238c489 100644
--- a/include/zbxjson.h
+++ b/include/zbxjson.h
@@ -72,6 +72,14 @@
#define ZBX_PROTO_TAG_AUTO_REGISTRATION "auto registration"
#define ZBX_PROTO_TAG_MORE "more"
#define ZBX_PROTO_TAG_ITEMID "itemid"
+#define ZBX_PROTO_TAG_TTL "ttl"
+#define ZBX_PROTO_TAG_COMMANDTYPE "commandtype"
+#define ZBX_PROTO_TAG_COMMAND "command"
+#define ZBX_PROTO_TAG_EXECUTE_ON "execute_on"
+#define ZBX_PROTO_TAG_AUTHTYPE "authtype"
+#define ZBX_PROTO_TAG_PUBLICKEY "publickey"
+#define ZBX_PROTO_TAG_PRIVATEKEY "privatekey"
+#define ZBX_PROTO_TAG_PARENT_TASKID "parent_taskid"
#define ZBX_PROTO_VALUE_FAILED "failed"
#define ZBX_PROTO_VALUE_SUCCESS "success"
@@ -82,6 +90,7 @@
#define ZBX_PROTO_VALUE_DISCOVERY_DATA "discovery data"
#define ZBX_PROTO_VALUE_HOST_AVAILABILITY "host availability"
#define ZBX_PROTO_VALUE_HISTORY_DATA "history data"
+#define ZBX_PROTO_VALUE_TASK_DATA "task data"
#define ZBX_PROTO_VALUE_AUTO_REGISTRATION_DATA "auto registration"
#define ZBX_PROTO_VALUE_SENDER_DATA "sender data"
#define ZBX_PROTO_VALUE_AGENT_DATA "agent data"
@@ -141,6 +150,7 @@ void zbx_json_addobject(struct zbx_json *j, const char *name);
void zbx_json_addarray(struct zbx_json *j, const char *name);
void zbx_json_addstring(struct zbx_json *j, const char *name, const char *string, zbx_json_type_t type);
void zbx_json_adduint64(struct zbx_json *j, const char *name, zbx_uint64_t value);
+void zbx_json_addint64(struct zbx_json *j, const char *name, zbx_int64_t value);
int zbx_json_close(struct zbx_json *j);
int zbx_json_open(const char *buffer, struct zbx_json_parse *jp);
diff --git a/include/zbxtasks.h b/include/zbxtasks.h
new file mode 100644
index 00000000000..2f2741f1c88
--- /dev/null
+++ b/include/zbxtasks.h
@@ -0,0 +1,145 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2016 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_ZBXTASKS_H
+#define ZABBIX_ZBXTASKS_H
+
+#include "db.h"
+#include "zbxjson.h"
+
+#define ZBX_REMOTE_COMMAND_TTL 600
+
+/******************/
+/* */
+/* remote command */
+/* */
+/******************/
+struct zbx_task_remote_command;
+
+struct zbx_task_remote_command *zbx_task_remote_command_new(void);
+void zbx_task_remote_command_free(struct zbx_task_remote_command *cmd);
+
+int zbx_task_remote_command_init(struct zbx_task_remote_command *cmd,
+ zbx_uint64_t taskid,
+ int type,
+ int status,
+ int clock,
+ int ttl,
+ int commandtype,
+ const char *command,
+ int execute_on,
+ int port,
+ int authtype,
+ const char *username,
+ const char *password,
+ const char *publickey,
+ const char *privatekey,
+ zbx_uint64_t parent_taskid,
+ zbx_uint64_t hostid,
+ zbx_uint64_t alertid);
+int zbx_task_remote_command_init_from_json(struct zbx_task_remote_command *cmd,
+ zbx_uint64_t taskid,
+ const char *opening_brace);
+void zbx_task_remote_command_clear(struct zbx_task_remote_command *cmd);
+
+void zbx_task_remote_command_db_insert_prepare(zbx_db_insert_t *db_task_insert, zbx_db_insert_t *db_task_remote_command_insert);
+void zbx_task_remote_command_db_insert_add_values(const struct zbx_task_remote_command *cmd,
+ zbx_db_insert_t *db_task_insert,
+ zbx_db_insert_t *db_task_remote_command_insert);
+void zbx_task_remote_command_serialize_json(const struct zbx_task_remote_command *cmd, struct zbx_json *json);
+
+void zbx_task_remote_command_process_task(struct zbx_task_remote_command *cmd);
+void zbx_task_remote_command_log(const struct zbx_task_remote_command *cmd);
+
+/*************************/
+/* */
+/* remote command result */
+/* */
+/*************************/
+struct zbx_task_remote_command_result;
+
+struct zbx_task_remote_command_result *zbx_task_remote_command_result_new(void);
+void zbx_task_remote_command_result_free(struct zbx_task_remote_command_result *res);
+
+int zbx_task_remote_command_result_init(struct zbx_task_remote_command_result *res,
+ zbx_uint64_t taskid,
+ int type,
+ int task_status,
+ int clock,
+ int ttl,
+ int status,
+ const char *error,
+ zbx_uint64_t parent_taskid);
+int zbx_task_remote_command_result_init_from_json(struct zbx_task_remote_command_result *res,
+ zbx_uint64_t taskid,
+ int clock,
+ const char *opening_brace);
+void zbx_task_remote_command_result_clear(struct zbx_task_remote_command_result *res);
+
+void zbx_task_remote_command_result_db_insert_prepare(zbx_db_insert_t *db_task_insert,
+ zbx_db_insert_t *db_task_remote_command_result_insert);
+void zbx_task_remote_command_result_db_insert_add_values(const struct zbx_task_remote_command_result *res,
+ zbx_db_insert_t *db_task_insert,
+ zbx_db_insert_t *db_task_remote_command_result_insert);
+void zbx_task_remote_command_result_serialize_json(const struct zbx_task_remote_command_result *res, struct zbx_json *json);
+
+void zbx_task_remote_command_result_process_task(struct zbx_task_remote_command_result *res);
+void zbx_task_remote_command_result_log(const struct zbx_task_remote_command_result *res);
+
+/**********************/
+/* */
+/* remote command set */
+/* */
+/**********************/
+struct zbx_task_remote_command_set;
+
+struct zbx_task_remote_command_set *zbx_task_remote_command_set_new(void);
+void zbx_task_remote_command_set_free(struct zbx_task_remote_command_set *set);
+
+int zbx_task_remote_command_set_init_from_db(struct zbx_task_remote_command_set *set, int status);
+int zbx_task_remote_command_set_init_from_json(struct zbx_task_remote_command_set *set,
+ const struct zbx_json_parse *jp);
+void zbx_task_remote_command_set_clear(struct zbx_task_remote_command_set *set);
+
+void zbx_task_remote_command_set_insert_into_db(const struct zbx_task_remote_command_set *set);
+void zbx_task_remote_command_set_serialize_json(const struct zbx_task_remote_command_set *set, struct zbx_json *json);
+
+void zbx_task_remote_command_set_process_tasks(const struct zbx_task_remote_command_set *set);
+
+/*****************************/
+/* */
+/* remote command result set */
+/* */
+/*****************************/
+struct zbx_task_remote_command_result_set;
+
+struct zbx_task_remote_command_result_set *zbx_task_remote_command_result_set_new(void);
+void zbx_task_remote_command_result_set_free(struct zbx_task_remote_command_result_set *set);
+
+int zbx_task_remote_command_result_set_init_from_db(struct zbx_task_remote_command_result_set *set, int status);
+int zbx_task_remote_command_result_set_init_from_json(struct zbx_task_remote_command_result_set *set,
+ const struct zbx_json_parse *jp);
+void zbx_task_remote_command_result_set_clear(struct zbx_task_remote_command_result_set *set);
+
+void zbx_task_remote_command_result_set_insert_into_db(const struct zbx_task_remote_command_result_set *set);
+void zbx_task_remote_command_result_set_serialize_json(const struct zbx_task_remote_command_result_set *set, struct zbx_json *json);
+
+void zbx_task_remote_command_result_set_process_tasks(const struct zbx_task_remote_command_result_set *set);
+
+#endif
diff --git a/include/zbxtypes.h b/include/zbxtypes.h
index 38cc3df2549..87d85b3dd63 100644
--- a/include/zbxtypes.h
+++ b/include/zbxtypes.h
@@ -65,6 +65,12 @@ typedef unsigned __int32 zbx_uint32_t;
typedef uint32_t zbx_uint32_t;
# endif
+# ifndef int32_t
+typedef __int32 zbx_int32_t;
+# else
+typedef int32_t zbx_int32_t;
+# endif
+
# ifndef PATH_SEPARATOR
# define PATH_SEPARATOR '\\'
# endif
@@ -130,6 +136,7 @@ typedef __int64 zbx_offset_t;
# endif
typedef uint32_t zbx_uint32_t;
+typedef int32_t zbx_int32_t;
# ifndef PATH_SEPARATOR
# define PATH_SEPARATOR '/'
diff --git a/src/libs/Makefile.am b/src/libs/Makefile.am
index 7ff0d4d8fac..358059a78e3 100644
--- a/src/libs/Makefile.am
+++ b/src/libs/Makefile.am
@@ -23,7 +23,8 @@ DIST_SUBDIRS = \
zbxexec \
zbxself \
zbxmodules \
- zbxregexp
+ zbxregexp \
+ zbxtasks
if SERVER
SERVER_SUBDIRS = \
@@ -36,7 +37,8 @@ SERVER_SUBDIRS = \
zbxserver \
zbxicmpping \
zbxmedia \
- zbxself
+ zbxself \
+ zbxtasks
else
if PROXY
PROXY_SUBDIRS = \
@@ -48,7 +50,8 @@ PROXY_SUBDIRS = \
zbxmemory \
zbxserver \
zbxicmpping \
- zbxself
+ zbxself \
+ zbxtasks
else
if AGENT
AGENT_SUBDIRS = \
diff --git a/src/libs/zbxjson/json.c b/src/libs/zbxjson/json.c
index ce8f91afd29..59402ba8486 100644
--- a/src/libs/zbxjson/json.c
+++ b/src/libs/zbxjson/json.c
@@ -338,6 +338,14 @@ void zbx_json_adduint64(struct zbx_json *j, const char *name, zbx_uint64_t value
zbx_json_addstring(j, name, buffer, ZBX_JSON_TYPE_INT);
}
+void zbx_json_addint64(struct zbx_json *j, const char *name, zbx_int64_t value)
+{
+ char buffer[MAX_ID_LEN];
+
+ zbx_snprintf(buffer, sizeof(buffer), ZBX_FS_I64, value);
+ zbx_json_addstring(j, name, buffer, ZBX_JSON_TYPE_INT);
+}
+
int zbx_json_close(struct zbx_json *j)
{
if (1 == j->level)
diff --git a/src/libs/zbxtasks/Makefile.am b/src/libs/zbxtasks/Makefile.am
new file mode 100644
index 00000000000..6802c0d5479
--- /dev/null
+++ b/src/libs/zbxtasks/Makefile.am
@@ -0,0 +1,9 @@
+## Process this file with automake to produce Makefile.in
+
+noinst_LIBRARIES = libzbxtasks.a
+
+libzbxtasks_a_SOURCES = \
+ zbx_task_remote_command.c \
+ zbx_task_remote_command_result.c \
+ zbx_task_remote_command_set.c \
+ zbx_task_remote_command_result_set.c
diff --git a/src/libs/zbxtasks/zbx_task.h b/src/libs/zbxtasks/zbx_task.h
new file mode 100644
index 00000000000..ed7f074b749
--- /dev/null
+++ b/src/libs/zbxtasks/zbx_task.h
@@ -0,0 +1,36 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2016 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_ZBX_TASK_H
+#define ZABBIX_ZBX_TASK_H
+
+/********/
+/* */
+/* task */
+/* */
+/********/
+struct zbx_task {
+ zbx_uint64_t taskid;
+ int type;
+ int status;
+ int clock;
+ int ttl;
+};
+
+#endif
diff --git a/src/libs/zbxtasks/zbx_task_remote_command.c b/src/libs/zbxtasks/zbx_task_remote_command.c
new file mode 100644
index 00000000000..3c1c629c081
--- /dev/null
+++ b/src/libs/zbxtasks/zbx_task_remote_command.c
@@ -0,0 +1,564 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2016 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 <assert.h>
+
+#include "common.h"
+#include "log.h"
+
+#include "db.h"
+#include "zbxjson.h"
+#include "zbxtasks.h"
+
+#include "zbx_task.h"
+
+#define INT_UNSPECIFIED 0
+#define UINT64_UNSPECIFIED 0
+#define STRING_UNSPECIFIED ""
+#define MAX_PORT_NUMBER 65535
+
+/******************/
+/* */
+/* remote command */
+/* */
+/******************/
+struct zbx_task_remote_command {
+ struct zbx_task task;
+ int commandtype;
+ char *command;
+ int execute_on;
+ int port;
+ int authtype;
+ char *username;
+ char *password;
+ char *publickey;
+ char *privatekey;
+ zbx_uint64_t parent_taskid;
+ zbx_uint64_t hostid;
+ zbx_uint64_t alertid;
+};
+
+struct zbx_task_remote_command *zbx_task_remote_command_new(void)
+{
+ struct zbx_task_remote_command *cmd = NULL;
+
+ cmd = zbx_calloc(cmd, 1, sizeof(struct zbx_task_remote_command));
+
+ return cmd;
+}
+
+void zbx_task_remote_command_free(struct zbx_task_remote_command *cmd)
+{
+ assert(NULL != cmd);
+
+ /* call zbx_task_remote_command_clear() before freeing the cmd */
+ assert(NULL == cmd->command);
+ assert(NULL == cmd->username);
+ assert(NULL == cmd->password);
+ assert(NULL == cmd->publickey);
+ assert(NULL == cmd->privatekey);
+
+ zbx_free(cmd);
+}
+
+static int zbx_task_remote_command_validate(const struct zbx_task_remote_command *cmd)
+{
+ int ret = FAIL;
+
+ assert(NULL != cmd);
+ assert(NULL != cmd->command); /* cmd is initialized */
+ assert(NULL != cmd->username);
+ assert(NULL != cmd->password);
+ assert(NULL != cmd->publickey);
+ assert(NULL != cmd->privatekey);
+
+ if (ZBX_TM_TASK_SEND_REMOTE_COMMAND != cmd->task.type)
+ goto err;
+
+ if (0 >= cmd->task.clock)
+ goto err;
+
+ if (0 > cmd->task.ttl)
+ goto err;
+
+ switch (cmd->commandtype) {
+ case ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT:
+ case ZBX_SCRIPT_TYPE_IPMI:
+ case ZBX_SCRIPT_TYPE_SSH:
+ case ZBX_SCRIPT_TYPE_TELNET:
+ case ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT:
+ break;
+ default:
+ goto err;
+ }
+
+ if (0 == strcmp(cmd->command, STRING_UNSPECIFIED)) /* command must be specified */
+ goto err;
+
+ if (ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT == cmd->commandtype || ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT == cmd->commandtype)
+ {
+ switch (cmd->execute_on) {
+ case ZBX_SCRIPT_EXECUTE_ON_AGENT:
+ case ZBX_SCRIPT_EXECUTE_ON_SERVER:
+ break;
+ default:
+ goto err;
+ }
+ }
+ else if (ZBX_SCRIPT_TYPE_SSH == cmd->commandtype)
+ {
+ switch (cmd->authtype) {
+ case ITEM_AUTHTYPE_PASSWORD:
+ case ITEM_AUTHTYPE_PUBLICKEY:
+ break;
+ default:
+ goto err;
+ }
+
+ if (cmd->port > MAX_PORT_NUMBER || cmd->port <= 0) /* port 0 is reserved */
+ goto err;
+
+ if (0 == strcmp(cmd->username, STRING_UNSPECIFIED))
+ goto err;
+
+ else if (ITEM_AUTHTYPE_PUBLICKEY == cmd->authtype)
+ {
+ if (0 == strcmp(cmd->publickey, STRING_UNSPECIFIED))
+ goto err;
+
+ if (0 == strcmp(cmd->privatekey, STRING_UNSPECIFIED))
+ goto err;
+ }
+ }
+ else if (ZBX_SCRIPT_TYPE_TELNET == cmd->commandtype)
+ {
+ if (cmd->port > MAX_PORT_NUMBER || cmd->port <= 0) /* port 0 is reserved */
+ goto err;
+
+ if (0 == strcmp(cmd->username, STRING_UNSPECIFIED))
+ goto err;
+ }
+
+ ret = SUCCEED;
+
+err:
+ return ret;
+}
+
+int zbx_task_remote_command_init(struct zbx_task_remote_command *cmd,
+ zbx_uint64_t taskid,
+ int type,
+ int status,
+ int clock,
+ int ttl,
+ int commandtype,
+ const char *command,
+ int execute_on,
+ int port,
+ int authtype,
+ const char *username,
+ const char *password,
+ const char *publickey,
+ const char *privatekey,
+ zbx_uint64_t parent_taskid,
+ zbx_uint64_t hostid,
+ zbx_uint64_t alertid)
+{
+ int ret = FAIL;
+
+ assert(NULL != cmd);
+ assert(NULL == cmd->command); /* the cmd is cleared - detect memory leak */
+ assert(NULL == cmd->username);
+ assert(NULL == cmd->password);
+ assert(NULL == cmd->publickey);
+ assert(NULL == cmd->privatekey);
+
+ assert(NULL != command);
+ assert(NULL != username);
+ assert(NULL != password);
+ assert(NULL != publickey);
+ assert(NULL != privatekey);
+
+ cmd->task.taskid = taskid,
+ cmd->task.type = type,
+ cmd->task.status = status;
+ cmd->task.clock = clock;
+ cmd->task.ttl = ttl;
+ cmd->commandtype = commandtype;
+ cmd->command = zbx_strdup(cmd->command, command);
+ cmd->execute_on = execute_on;
+ cmd->port = port;
+ cmd->authtype = authtype;
+ cmd->username = zbx_strdup(cmd->username, username);
+ cmd->password = zbx_strdup(cmd->password, password);
+ cmd->publickey = zbx_strdup(cmd->publickey, publickey);
+ cmd->privatekey = zbx_strdup(cmd->privatekey, privatekey);
+ cmd->parent_taskid = parent_taskid;
+ cmd->hostid = hostid;
+ cmd->alertid = alertid;
+
+ ret = zbx_task_remote_command_validate(cmd);
+
+ return ret;
+}
+
+int zbx_task_remote_command_init_from_json(struct zbx_task_remote_command *cmd,
+ zbx_uint64_t taskid,
+ const char *opening_brace)
+{
+ int ret = FAIL;
+ struct zbx_json_parse jp_row;
+
+ char *type = NULL;
+ char *clock = NULL;
+ char *ttl = NULL;
+ char *commandtype = NULL;
+ char *command = NULL;
+ char *execute_on = NULL;
+ char *port = NULL;
+ char *authtype = NULL;
+ char *username = NULL;
+ char *password = NULL;
+ char *publickey = NULL;
+ char *privatekey = NULL;
+ char *parent_taskid = NULL;
+ char *hostid = NULL;
+ size_t tmp_alloc = 0;
+
+ zbx_uint64_t parent_taskid_num;
+ zbx_uint64_t hostid_num;
+
+ assert(NULL != cmd);
+ assert(NULL == cmd->command); /* cmd must be cleared - to avoid memory leaks */
+ assert(NULL == cmd->username);
+ assert(NULL == cmd->password);
+ assert(NULL == cmd->publickey);
+ assert(NULL == cmd->privatekey);
+
+ if (FAIL == (ret = zbx_json_brackets_open(opening_brace, &jp_row)))
+ goto err;
+
+ /* get values as strings from JSON object */
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_TYPE, &type, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_CLOCK, &clock, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_TTL, &ttl, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_COMMANDTYPE, &commandtype, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_COMMAND, &command, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_EXECUTE_ON, &execute_on, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_PORT, &port, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_AUTHTYPE, &authtype, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_USERNAME, &username, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_PASSWORD, &password, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_PUBLICKEY, &publickey, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_PRIVATEKEY, &privatekey, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_PARENT_TASKID, &parent_taskid, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_HOSTID, &hostid, &tmp_alloc))
+ goto err;
+
+ /* initialize object */
+ ZBX_STR2UINT64(parent_taskid_num, parent_taskid);
+ ZBX_STR2UINT64(hostid_num, hostid);
+
+ ret = zbx_task_remote_command_init(cmd,
+ /* t.taskid */ taskid,
+ /* t.type */ ZBX_TM_TASK_SEND_REMOTE_COMMAND,
+ /* t.status */ ZBX_TM_STATUS_NEW,
+ /* t.clock */ atoi(clock),
+ /* t.ttl */ atoi(ttl),
+ /* c.command_type */ atoi(commandtype),
+ /* c,command */ command,
+ /* c.execute_on */ atoi(execute_on),
+ /* c.port */ atoi(port),
+ /* c.authtype */ atoi(authtype),
+ /* c.username */ username,
+ /* c.password */ password,
+ /* c.publickey */ publickey,
+ /* c.privatekey */ privatekey,
+ /* c.parent_taskid */ parent_taskid_num,
+ /* c.hostid */ hostid_num,
+ /* c.alertid */ 0);
+
+err:
+ zbx_free(type);
+ zbx_free(clock);
+ zbx_free(ttl);
+ zbx_free(commandtype);
+ zbx_free(command);
+ zbx_free(execute_on);
+ zbx_free(port);
+ zbx_free(authtype);
+ zbx_free(username);
+ zbx_free(password);
+ zbx_free(publickey);
+ zbx_free(privatekey);
+ zbx_free(parent_taskid);
+ zbx_free(hostid);
+
+ return ret;
+}
+
+void zbx_task_remote_command_clear(struct zbx_task_remote_command *cmd)
+{
+ assert(NULL != cmd);
+ /* not asserting that members are not NULL since partially initialized cmd can be cleared as well */
+
+ zbx_free(cmd->command);
+ zbx_free(cmd->username);
+ zbx_free(cmd->password);
+ zbx_free(cmd->publickey);
+ zbx_free(cmd->privatekey);
+
+ memset(cmd, 0, sizeof(struct zbx_task_remote_command));
+}
+
+/* class method */
+void zbx_task_remote_command_db_insert_prepare(zbx_db_insert_t *db_task_insert,
+ zbx_db_insert_t *db_task_remote_command_insert)
+{
+ assert(NULL != db_task_insert);
+ assert(NULL != db_task_remote_command_insert);
+
+ zbx_db_insert_prepare(db_task_insert, "task",
+ "taskid",
+ "type",
+ "status",
+ "clock",
+ "ttl",
+ NULL);
+
+ zbx_db_insert_prepare(db_task_remote_command_insert, "task_remote_command",
+ "taskid",
+ "command_type",
+ "execute_on",
+ "port",
+ "authtype",
+ "username",
+ "password",
+ "publickey",
+ "privatekey",
+ "command",
+ "alertid",
+ "parent_taskid",
+ "hostid",
+ NULL);
+}
+
+void zbx_task_remote_command_db_insert_add_values(const struct zbx_task_remote_command *cmd,
+ zbx_db_insert_t *db_task_insert,
+ zbx_db_insert_t *db_task_remote_command_insert)
+{
+ assert(NULL != cmd);
+ assert(NULL != cmd->command); /* cmd is initialized */
+ assert(NULL != cmd->username);
+ assert(NULL != cmd->password);
+ assert(NULL != cmd->publickey);
+ assert(NULL != cmd->privatekey);
+
+ assert(NULL != db_task_insert);
+ assert(NULL != db_task_remote_command_insert);
+
+ zbx_db_insert_add_values(db_task_insert,
+ cmd->task.taskid,
+ cmd->task.type,
+ cmd->task.status,
+ cmd->task.clock,
+ cmd->task.ttl);
+
+ zbx_db_insert_add_values(db_task_remote_command_insert,
+ cmd->task.taskid,
+ cmd->commandtype,
+ cmd->execute_on,
+ cmd->port,
+ cmd->authtype,
+ cmd->username,
+ cmd->password,
+ cmd->publickey,
+ cmd->privatekey,
+ cmd->command,
+ cmd->alertid,
+ cmd->parent_taskid,
+ cmd->hostid);
+}
+
+void zbx_task_remote_command_serialize_json(const struct zbx_task_remote_command *cmd, struct zbx_json *json)
+{
+ assert(NULL != cmd);
+ assert(NULL != json);
+
+ assert(NULL != cmd->command);
+ assert(NULL != cmd->username);
+ assert(NULL != cmd->password);
+ assert(NULL != cmd->publickey);
+ assert(NULL != cmd->privatekey);
+
+ zbx_json_addobject(json, NULL);
+
+ zbx_json_addint64(json, ZBX_PROTO_TAG_TYPE, cmd->task.type);
+ zbx_json_addint64(json, ZBX_PROTO_TAG_CLOCK, cmd->task.clock);
+ zbx_json_addint64(json, ZBX_PROTO_TAG_TTL, cmd->task.ttl);
+ zbx_json_addint64(json, ZBX_PROTO_TAG_COMMANDTYPE, cmd->commandtype);
+ zbx_json_addstring(json, ZBX_PROTO_TAG_COMMAND, cmd->command, ZBX_JSON_TYPE_STRING);
+ zbx_json_addint64(json, ZBX_PROTO_TAG_EXECUTE_ON, cmd->execute_on);
+ zbx_json_addint64(json, ZBX_PROTO_TAG_PORT, cmd->port);
+ zbx_json_addint64(json, ZBX_PROTO_TAG_AUTHTYPE, cmd->authtype);
+ zbx_json_addstring(json, ZBX_PROTO_TAG_USERNAME, cmd->username, ZBX_JSON_TYPE_STRING);
+ zbx_json_addstring(json, ZBX_PROTO_TAG_PASSWORD, cmd->password, ZBX_JSON_TYPE_STRING);
+ zbx_json_addstring(json, ZBX_PROTO_TAG_PUBLICKEY, cmd->publickey, ZBX_JSON_TYPE_STRING);
+ zbx_json_addstring(json, ZBX_PROTO_TAG_PRIVATEKEY, cmd->privatekey, ZBX_JSON_TYPE_STRING);
+ zbx_json_adduint64(json, ZBX_PROTO_TAG_PARENT_TASKID, cmd->parent_taskid);
+ zbx_json_adduint64(json, ZBX_PROTO_TAG_HOSTID, cmd->hostid);
+
+ zbx_json_close(json);
+}
+
+
+static void zbx_task_remote_command_process_new_task(struct zbx_task_remote_command *cmd)
+{
+ zbx_uint64_t taskid;
+ struct zbx_task_remote_command_result *res;
+ zbx_db_insert_t db_task_insert;
+ zbx_db_insert_t db_task_remote_command_insert;
+ int status = SUCCEED;
+ char *error = "";
+
+ assert(NULL != cmd);
+ assert(NULL != cmd->command); /* cmd is initialized */
+ assert(NULL != cmd->username);
+ assert(NULL != cmd->password);
+ assert(NULL != cmd->publickey);
+ assert(NULL != cmd->privatekey);
+
+ /* task in progress */
+ DBexecute("update tasks set status=%d where taskid=" ZBX_FS_UI64,
+ ZBX_TM_STATUS_INPROGRESS, cmd->task.taskid);
+
+ /* execute command */
+ zabbix_log(LOG_LEVEL_ERR, "processing command task, taskid: " ZBX_FS_UI64, cmd->task.taskid);
+
+ /* insert result task */
+ taskid = DBget_maxid("task");
+
+ res = zbx_task_remote_command_result_new();
+
+ zbx_task_remote_command_result_init(res,
+ /* t.taskid */ taskid,
+ /* t.type */ ZBX_TM_TASK_SEND_REMOTE_COMMAND_RESULT,
+ /* t.status */ ZBX_TM_STATUS_NEW,
+ /* t.clock */ time(NULL),
+ /* t.ttl */ 0,
+ /* r.status */ status,
+ /* r.error */ error,
+ /* r.parent_taskid */ cmd->parent_taskid);
+
+ zbx_task_remote_command_result_db_insert_prepare(&db_task_insert,
+ &db_task_remote_command_insert);
+ zbx_task_remote_command_result_db_insert_add_values(res,
+ &db_task_insert, &db_task_remote_command_insert);
+
+ zbx_task_remote_command_result_clear(res);
+ zbx_task_remote_command_result_free(res);
+
+ DBbegin();
+ zbx_db_insert_execute(&db_task_insert);
+ zbx_db_insert_execute(&db_task_remote_command_insert);
+ DBcommit();
+
+ /* task is done */
+ DBexecute("update tasks set status=%d where taskid=" ZBX_FS_UI64,
+ ZBX_TM_STATUS_DONE, cmd->task.taskid);
+}
+
+void zbx_task_remote_command_process_task(struct zbx_task_remote_command *cmd)
+{
+ switch (cmd->task.status) {
+ case ZBX_TM_STATUS_NEW:
+ zbx_task_remote_command_process_new_task(cmd);
+ break;
+ default:
+ THIS_SHOULD_NEVER_HAPPEN;
+ }
+}
+
+void zbx_task_remote_command_log(const struct zbx_task_remote_command *cmd)
+{
+ assert(NULL != cmd);
+ assert(NULL != cmd->command); /* cmd is initialized */
+ assert(NULL != cmd->username);
+ assert(NULL != cmd->password);
+ assert(NULL != cmd->publickey);
+ assert(NULL != cmd->privatekey);
+
+ zabbix_log(LOG_LEVEL_ERR, "cmd->task.taskid: " ZBX_FS_UI64, cmd->task.taskid);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->task.type: %d", cmd->task.type);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->task.status: %d", cmd->task.status);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->task.clock: %d", cmd->task.clock);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->task.ttl: %d", cmd->task.ttl);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->commandtype: %d", cmd->commandtype);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->command: %s", cmd->command);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->execute_on: %d", cmd->execute_on);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->port: %d", cmd->port);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->authtype: %d", cmd->authtype);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->username: %s", cmd->username);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->password: %s", cmd->password);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->publickey: %s", cmd->publickey);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->privatekey: %s", cmd->privatekey);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->parent_taskid: " ZBX_FS_UI64, cmd->parent_taskid);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->hostid: " ZBX_FS_UI64, cmd->hostid);
+ zabbix_log(LOG_LEVEL_ERR, "cmd->alertid: " ZBX_FS_UI64, cmd->hostid);
+}
diff --git a/src/libs/zbxtasks/zbx_task_remote_command_result.c b/src/libs/zbxtasks/zbx_task_remote_command_result.c
new file mode 100644
index 00000000000..e64085953b6
--- /dev/null
+++ b/src/libs/zbxtasks/zbx_task_remote_command_result.c
@@ -0,0 +1,282 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2016 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 <assert.h>
+
+#include "common.h"
+#include "log.h"
+
+#include "db.h"
+#include "zbxjson.h"
+#include "zbxtasks.h"
+
+#include "zbx_task.h"
+
+/*************************/
+/* */
+/* remote command result */
+/* */
+/*************************/
+struct zbx_task_remote_command_result {
+ struct zbx_task task;
+ int status;
+ char *error;
+ zbx_uint64_t parent_taskid;
+};
+
+struct zbx_task_remote_command_result *zbx_task_remote_command_result_new(void)
+{
+ struct zbx_task_remote_command_result *res = NULL;
+
+ res = zbx_calloc(res, 1, sizeof(struct zbx_task_remote_command_result));
+
+ return res;
+}
+
+void zbx_task_remote_command_result_free(struct zbx_task_remote_command_result *res)
+{
+ assert(NULL != res);
+ assert(NULL == res->error); /* error must be cleared - detecting memory leak */
+
+ zbx_free(res);
+}
+
+static int zbx_task_remote_command_result_validate(const struct zbx_task_remote_command_result *res)
+{
+ int ret = FAIL;
+
+ if (ZBX_TM_TASK_SEND_REMOTE_COMMAND_RESULT != res->task.type)
+ goto err;
+
+ ret = SUCCEED;
+
+err:
+ return ret;
+}
+
+int zbx_task_remote_command_result_init(struct zbx_task_remote_command_result *res,
+ zbx_uint64_t taskid,
+ int type,
+ int task_status,
+ int clock,
+ int ttl,
+ int status,
+ const char *error,
+ zbx_uint64_t parent_taskid)
+{
+ int ret = FAIL;
+
+ assert(NULL != res);
+ assert(NULL != error);
+
+ res->task.taskid = taskid;
+ res->task.type = type;
+ res->task.status = task_status;
+ res->task.clock = clock;
+ res->task.ttl = ttl;
+ res->status = status;
+ res->error = zbx_strdup(res->error, error);
+ res->parent_taskid = parent_taskid;
+
+ ret = zbx_task_remote_command_result_validate(res);
+
+ return ret;
+}
+
+int zbx_task_remote_command_result_init_from_json(struct zbx_task_remote_command_result *res,
+ zbx_uint64_t taskid,
+ int clock,
+ const char *opening_brace)
+{
+ struct zbx_json_parse jp_row;
+ int ret = FAIL;
+ char *type = NULL;
+ char *status = NULL;
+ char *error = NULL;
+ char *parent_taskid = NULL;
+ size_t tmp_alloc = 0;
+
+ zbx_uint64_t parent_taskid_num;
+
+ assert(NULL != res);
+ assert(NULL == res->error); /* must be cleared - detecting memory leaks */
+
+ /* get values as strings from JSON object */
+ if (FAIL == (ret = zbx_json_brackets_open(opening_brace, &jp_row)))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_TYPE, &type, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_STATUS, &status, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_ERROR, &error, &tmp_alloc))
+ goto err;
+
+ tmp_alloc = 0;
+ if (FAIL == zbx_json_value_by_name_dyn(&jp_row, ZBX_PROTO_TAG_PARENT_TASKID, &parent_taskid, &tmp_alloc))
+ goto err;
+
+ /* initialize object */
+ ZBX_STR2UINT64(parent_taskid_num, parent_taskid);
+
+ ret = zbx_task_remote_command_result_init(res,
+ /* t.taskid */ taskid,
+ /* t.type */ ZBX_TM_TASK_SEND_REMOTE_COMMAND_RESULT,
+ /* t.status */ ZBX_TM_STATUS_NEW,
+ /* t.clock */ clock,
+ /* t.ttl */ 0,
+ /* r.status */ atoi(status),
+ /* r.error */ error,
+ /* r.parent_taskid */ parent_taskid_num);
+
+err:
+ zbx_free(type);
+ zbx_free(status);
+ zbx_free(error);
+ zbx_free(parent_taskid);
+
+ return ret;
+}
+
+void zbx_task_remote_command_result_clear(struct zbx_task_remote_command_result *res)
+{
+ assert(NULL != res);
+ /* not asserting that members are not NULL since partially initialized res can be cleared as well */
+
+ zbx_free(res->error);
+
+ memset(res, 0, sizeof(struct zbx_task_remote_command_result));
+}
+
+void zbx_task_remote_command_result_serialize_json(const struct zbx_task_remote_command_result *res, struct zbx_json *json)
+{
+ assert(NULL != res);
+ assert(NULL != res->error);
+ assert(NULL != json);
+
+ zbx_json_addobject(json, NULL);
+
+ zbx_json_addint64(json, ZBX_PROTO_TAG_TYPE, res->task.type);
+ zbx_json_addint64(json, ZBX_PROTO_TAG_STATUS, res->status);
+ zbx_json_addstring(json, ZBX_PROTO_TAG_ERROR, res->error, ZBX_JSON_TYPE_STRING);
+ zbx_json_adduint64(json, ZBX_PROTO_TAG_PARENT_TASKID, res->parent_taskid);
+
+ zbx_json_close(json);
+}
+
+
+/* class method */
+void zbx_task_remote_command_result_db_insert_prepare(zbx_db_insert_t *db_task_insert,
+ zbx_db_insert_t *db_task_remote_command_result_insert)
+{
+ assert(NULL != db_task_insert);
+ assert(NULL != db_task_remote_command_result_insert);
+
+ zbx_db_insert_prepare(db_task_insert, "task",
+ "taskid",
+ "type",
+ "status",
+ "clock",
+ "ttl",
+ NULL);
+
+ zbx_db_insert_prepare(db_task_remote_command_result_insert, "task_remote_command_result",
+ "taskid",
+ "status",
+ "parent_taskid",
+ "error",
+ NULL);
+}
+
+void zbx_task_remote_command_result_db_insert_add_values(const struct zbx_task_remote_command_result *res,
+ zbx_db_insert_t *db_task_insert,
+ zbx_db_insert_t *db_task_remote_command_result_insert)
+{
+ assert(NULL != res);
+ assert(NULL != res->error);
+
+ assert(NULL != db_task_insert);
+ assert(NULL != db_task_remote_command_result_insert);
+
+ zbx_db_insert_add_values(db_task_insert,
+ res->task.taskid,
+ res->task.type,
+ res->task.status,
+ res->task.clock,
+ res->task.ttl);
+
+ zbx_db_insert_add_values(db_task_remote_command_result_insert,
+ res->task.taskid,
+ res->status,
+ res->parent_taskid,
+ res->error);
+}
+
+void zbx_task_remote_command_result_process_new_task(struct zbx_task_remote_command_result *res)
+{
+ assert(NULL != res);
+ assert(NULL != res->error);
+
+ /* task in progress */
+ DBexecute("update tasks set status=%d where taskid=" ZBX_FS_UI64,
+ ZBX_TM_STATUS_INPROGRESS, res->task.taskid);
+
+ zabbix_log(LOG_LEVEL_ERR, "processing command result task..taskid: " ZBX_FS_UI64, res->task.taskid);
+
+ /* update alert */
+
+ /* parent task is done */
+ DBexecute("update tasks set status=%d where taskid=" ZBX_FS_UI64,
+ ZBX_TM_STATUS_DONE, res->parent_taskid);
+
+ /* command result task is done */
+ DBexecute("update tasks set status=%d where taskid=" ZBX_FS_UI64,
+ ZBX_TM_STATUS_DONE, res->task.taskid);
+}
+
+void zbx_task_remote_command_result_process_task(struct zbx_task_remote_command_result *res)
+{
+ switch (res->task.status) {
+ case ZBX_TM_STATUS_NEW:
+ zbx_task_remote_command_result_process_new_task(res);
+ break;
+ default:
+ THIS_SHOULD_NEVER_HAPPEN;
+ }
+}
+
+void zbx_task_remote_command_result_log(const struct zbx_task_remote_command_result *res)
+{
+ assert(NULL != res);
+ assert(NULL != res->error);
+
+ zabbix_log(LOG_LEVEL_ERR, "res->task.taskid: " ZBX_FS_UI64, res->task.taskid);
+ zabbix_log(LOG_LEVEL_ERR, "res->task.type: %d", res->task.type);
+ zabbix_log(LOG_LEVEL_ERR, "res->task.status: %d", res->task.status);
+ zabbix_log(LOG_LEVEL_ERR, "res->task.clock: %d", res->task.clock);
+ zabbix_log(LOG_LEVEL_ERR, "res->task.ttl: %d", res->task.ttl);
+ zabbix_log(LOG_LEVEL_ERR, "res->status: %d", res->status);
+ zabbix_log(LOG_LEVEL_ERR, "res->error: %s", res->error);
+ zabbix_log(LOG_LEVEL_ERR, "res->parent_taskid: " ZBX_FS_UI64, res->parent_taskid);
+}
diff --git a/src/libs/zbxtasks/zbx_task_remote_command_result_set.c b/src/libs/zbxtasks/zbx_task_remote_command_result_set.c
new file mode 100644
index 00000000000..64ac4a2ee54
--- /dev/null
+++ b/src/libs/zbxtasks/zbx_task_remote_command_result_set.c
@@ -0,0 +1,223 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2016 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 <assert.h>
+
+#include "common.h"
+#include "log.h"
+
+#include "db.h"
+#include "zbxjson.h"
+#include "zbxtasks.h"
+
+/*****************************/
+/* */
+/* remote command result set */
+/* */
+/*****************************/
+struct zbx_task_remote_command_result_set {
+ zbx_vector_ptr_t results;
+ int state;
+};
+
+struct zbx_task_remote_command_result_set *zbx_task_remote_command_result_set_new(void)
+{
+ struct zbx_task_remote_command_result_set *set = NULL;
+
+ set = zbx_calloc(set, 1, sizeof(struct zbx_task_remote_command_result_set));
+
+ return set;
+}
+
+void zbx_task_remote_command_result_set_free(struct zbx_task_remote_command_result_set *set)
+{
+ assert(NULL != set);
+
+ /* call zbx_task_remote_command_result_set_clear() before freeing the set */
+ assert(NULL == set->results.values); /* vector must be destroyed */
+
+ zbx_free(set);
+}
+
+int zbx_task_remote_command_result_set_init_from_json(struct zbx_task_remote_command_result_set *set,
+ const struct zbx_json_parse *jp)
+{
+ int ret = FAIL;
+ struct zbx_json_parse jp_data;
+ const char *opening_brace = NULL;
+
+ assert(NULL != set);
+ assert(NULL == set->results.values);
+
+ zbx_vector_ptr_create(&(set->results));
+
+ /* open array "data": [...] */
+ if (SUCCEED != (ret = zbx_json_brackets_by_name(jp, ZBX_PROTO_TAG_DATA, &jp_data)))
+ goto err;
+
+ /* iterate over objects in array "data": [{obj0}, {obj1}, ...] */
+ /* ^ */
+ while (NULL != (opening_brace = zbx_json_next(&jp_data, opening_brace)))
+ {
+ zbx_uint64_t taskid;
+ struct zbx_task_remote_command_result *res;
+
+ res = zbx_task_remote_command_result_new();
+
+ taskid = DBget_maxid("task");
+
+ ret = zbx_task_remote_command_result_init_from_json(res, taskid, time(NULL), opening_brace);
+
+ /* the res will be cleared and freed with the rest of the set */
+ zbx_vector_ptr_append(&(set->results), res);
+
+ if (SUCCEED != ret)
+ goto err;
+ }
+
+err:
+ return ret;
+}
+
+int zbx_task_remote_command_result_set_init_from_db(struct zbx_task_remote_command_result_set *set, int status)
+{
+ DB_RESULT result;
+ DB_ROW row;
+ int ret = FAIL;
+
+ assert(NULL != set);
+ assert(NULL == set->results.values);
+ assert(ZBX_TM_STATUS_NEW == status || ZBX_TM_STATUS_INPROGRESS == status ||\
+ ZBX_TM_STATUS_DONE == status || ZBX_TM_STATUS_EXPIRED == status);
+
+ zbx_vector_ptr_create(&(set->results));
+
+ result = DBselect(
+ "select t.taskid,t.status,t.clock,t.ttl,"
+ "r.status,r.parent_taskid,r.error"
+ " from task t, task_remote_command_result r"
+ " where t.taskid=r.taskid"
+ " order by taskid");
+
+ while (NULL != (row = DBfetch(result)))
+ {
+ zbx_uint64_t taskid;
+ zbx_uint64_t parent_taskid;
+ struct zbx_task_remote_command_result *res;
+
+ res = zbx_task_remote_command_result_new();
+
+ ZBX_STR2UINT64(taskid, row[0]);
+ ZBX_STR2UINT64(parent_taskid, row[5]);
+
+ ret = zbx_task_remote_command_result_init(res,
+ /* t.taskid */ taskid,
+ /* t.type */ ZBX_TM_TASK_SEND_REMOTE_COMMAND_RESULT,
+ /* t.status */ atoi(row[1]),
+ /* t.clock */ atoi(row[2]),
+ /* t.ttl */ atoi(row[3]),
+ /* r.status */ atoi(row[4]),
+ /* r.error */ ZBX_NULL2EMPTY_STR(row[6]),
+ /* r.parent_taskid */ parent_taskid);
+
+ /* the res will be cleared and freed with the rest of the set */
+ zbx_vector_ptr_append(&(set->results), res);
+
+ if (SUCCEED != ret)
+ goto err;
+ }
+
+err:
+ return ret;
+}
+
+void zbx_task_remote_command_result_set_clear(struct zbx_task_remote_command_result_set *set)
+{
+ int i;
+
+ assert(NULL != set);
+ /* not asserting that members are initialized since partially initialized set can be cleared as well */
+
+ for (i = 0; i < set->results.values_num; i++)
+ {
+ zbx_task_remote_command_result_clear(set->results.values[i]);
+ zbx_task_remote_command_result_free(set->results.values[i]);
+ }
+
+ zbx_vector_ptr_destroy(&(set->results));
+}
+
+void zbx_task_remote_command_result_set_insert_into_db(const struct zbx_task_remote_command_result_set *set)
+{
+ zbx_db_insert_t db_task_insert;
+ zbx_db_insert_t db_task_remote_command_insert;
+ int i;
+
+ assert(NULL != set);
+ assert(NULL != set->results.values);
+
+ zbx_task_remote_command_result_db_insert_prepare(&db_task_insert,
+ &db_task_remote_command_insert);
+
+ for (i = 0; i < set->results.values_num; i++)
+ {
+ zbx_task_remote_command_result_log(set->results.values[i]);
+ zbx_task_remote_command_result_db_insert_add_values(set->results.values[i],
+ &db_task_insert, &db_task_remote_command_insert);
+ }
+
+ DBbegin();
+ zbx_db_insert_execute(&db_task_insert);
+ zbx_db_insert_execute(&db_task_remote_command_insert);
+ DBcommit();
+
+ zbx_db_insert_clean(&db_task_insert);
+ zbx_db_insert_clean(&db_task_remote_command_insert);
+}
+
+void zbx_task_remote_command_result_set_serialize_json(const struct zbx_task_remote_command_result_set *set, struct zbx_json *json)
+{
+ int i;
+
+ assert(NULL != set);
+ assert(NULL != set->results.values);
+ assert(NULL != json);
+
+ zbx_json_addarray(json, ZBX_PROTO_TAG_DATA);
+
+ for (i = 0; i < set->results.values_num; i++)
+ {
+ zbx_task_remote_command_result_serialize_json(set->results.values[i], json);
+ }
+
+ zbx_json_close(json);
+}
+
+void zbx_task_remote_command_result_set_process_tasks(const struct zbx_task_remote_command_result_set *set)
+{
+ int i;
+
+ assert(NULL != set);
+ assert(NULL != set->results.values);
+
+ for (i = 0; i < set->results.values_num; i++)
+ {
+ zbx_task_remote_command_result_process_task(set->results.values[i]);
+ }
+}
diff --git a/src/libs/zbxtasks/zbx_task_remote_command_set.c b/src/libs/zbxtasks/zbx_task_remote_command_set.c
new file mode 100644
index 00000000000..ca877a20d8b
--- /dev/null
+++ b/src/libs/zbxtasks/zbx_task_remote_command_set.c
@@ -0,0 +1,236 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2016 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 <assert.h>
+
+#include "common.h"
+#include "log.h"
+
+#include "db.h"
+#include "zbxjson.h"
+#include "zbxtasks.h"
+
+/**********************/
+/* */
+/* remote command set */
+/* */
+/**********************/
+struct zbx_task_remote_command_set {
+ zbx_vector_ptr_t commands;
+ int state;
+};
+
+struct zbx_task_remote_command_set *zbx_task_remote_command_set_new(void)
+{
+ struct zbx_task_remote_command_set *set = NULL;
+
+ set = zbx_calloc(set, 1, sizeof(struct zbx_task_remote_command_set));
+
+ return set;
+}
+
+void zbx_task_remote_command_set_free(struct zbx_task_remote_command_set *set)
+{
+ assert(NULL != set);
+
+ /* call zbx_task_remote_command_set_clear() before freeing the set */
+ assert(NULL == set->commands.values); /* vector must be destroyed */
+
+ zbx_free(set);
+}
+
+int zbx_task_remote_command_set_init_from_json(struct zbx_task_remote_command_set *set, const struct zbx_json_parse *jp)
+{
+ int ret = FAIL;
+ struct zbx_json_parse jp_data;
+ const char *opening_brace = NULL;
+
+ assert(NULL != set);
+ assert(NULL == set->commands.values);
+
+ zbx_vector_ptr_create(&(set->commands));
+
+ /* open array "data": [...] */
+ if (SUCCEED != (ret = zbx_json_brackets_by_name(jp, ZBX_PROTO_TAG_DATA, &jp_data)))
+ goto err;
+
+ /* iterate over objects in array "data": [{obj0}, {obj1}, ...] */
+ /* ^ */
+ while (NULL != (opening_brace = zbx_json_next(&jp_data, opening_brace)))
+ {
+ zbx_uint64_t taskid;
+ struct zbx_task_remote_command *cmd;
+
+ cmd = zbx_task_remote_command_new();
+
+ taskid = DBget_maxid("task");
+
+ ret = zbx_task_remote_command_init_from_json(cmd, taskid, opening_brace);
+
+ /* the cmd will be cleared and freed with the rest of the set */
+ zbx_vector_ptr_append(&(set->commands), cmd);
+
+ if (SUCCEED != ret)
+ goto err;
+ }
+
+err:
+ return ret;
+}
+
+int zbx_task_remote_command_set_init_from_db(struct zbx_task_remote_command_set *set, int status)
+{
+ DB_RESULT result;
+ DB_ROW row;
+ int ret = FAIL;
+
+ assert(NULL != set);
+ assert(NULL == set->commands.values);
+ assert(ZBX_TM_STATUS_NEW == status || ZBX_TM_STATUS_INPROGRESS == status ||\
+ ZBX_TM_STATUS_DONE == status || ZBX_TM_STATUS_EXPIRED == status);
+
+ zbx_vector_ptr_create(&(set->commands));
+
+ result = DBselect(
+ "select t.taskid,t.status,t.clock,t.ttl,"
+ "c.command_type,c.execute_on,c.port,c.authtype,c.username,c.password,c.publickey,c.privatekey,"
+ "c.command,c.alertid,c.parent_taskid,c.hostid"
+ " from task t, task_remote_command c"
+ " where t.taskid=c.taskid"
+ " order by taskid");
+
+ while (NULL != (row = DBfetch(result)))
+ {
+ zbx_uint64_t taskid;
+ zbx_uint64_t alertid;
+ zbx_uint64_t parent_taskid;
+ zbx_uint64_t hostid;
+ struct zbx_task_remote_command *cmd;
+
+ cmd = zbx_task_remote_command_new();
+
+ ZBX_STR2UINT64(taskid, row[0]);
+ ZBX_STR2UINT64(alertid, row[13]);
+ ZBX_STR2UINT64(parent_taskid, row[14]);
+ ZBX_STR2UINT64(hostid, row[15]);
+
+ zbx_task_remote_command_init(cmd,
+ /* t.taskid */ taskid,
+ /* t.type */ ZBX_TM_TASK_SEND_REMOTE_COMMAND,
+ /* t.status */ atoi(row[1]),
+ /* t.clock */ atoi(row[2]),
+ /* t.ttl */ atoi(row[3]),
+ /* c.command_type */ atoi(row[4]),
+ /* c,command */ ZBX_NULL2EMPTY_STR(row[12]),
+ /* c.execute_on */ atoi(row[5]),
+ /* c.port */ atoi(row[6]),
+ /* c.authtype */ atoi(row[7]),
+ /* c.username */ ZBX_NULL2EMPTY_STR(row[8]),
+ /* c.password */ ZBX_NULL2EMPTY_STR(row[9]),
+ /* c.publickey */ ZBX_NULL2EMPTY_STR(row[10]),
+ /* c.privatekey */ ZBX_NULL2EMPTY_STR(row[11]),
+ /* c.parent_taskid */ parent_taskid,
+ /* c.hostid */ hostid,
+ /* c.alertid */ alertid);
+
+ zbx_vector_ptr_append(&(set->commands), cmd);
+
+ /* the cmd will be cleared and freed with the rest of the set */
+ if (SUCCEED != ret)
+ goto err;
+ }
+
+err:
+ return ret;
+}
+
+void zbx_task_remote_command_set_clear(struct zbx_task_remote_command_set *set)
+{
+ int i;
+
+ assert(NULL != set);
+ /* not asserting that members are initialized since partially initialized set can be cleared as well */
+
+ for (i = 0; i < set->commands.values_num; i++)
+ {
+ zbx_task_remote_command_clear(set->commands.values[i]);
+ zbx_task_remote_command_free(set->commands.values[i]);
+ }
+
+ zbx_vector_ptr_destroy(&(set->commands));
+}
+
+void zbx_task_remote_command_set_insert_into_db(const struct zbx_task_remote_command_set *set)
+{
+ zbx_db_insert_t db_task_insert;
+ zbx_db_insert_t db_task_remote_command_insert;
+ int i;
+
+ assert(NULL != set);
+ assert(NULL != set->commands.values);
+
+ zbx_task_remote_command_db_insert_prepare(&db_task_insert,
+ &db_task_remote_command_insert);
+
+ for (i = 0; i < set->commands.values_num; i++)
+ {
+ zbx_task_remote_command_log(set->commands.values[i]);
+ zbx_task_remote_command_db_insert_add_values(set->commands.values[i],
+ &db_task_insert, &db_task_remote_command_insert);
+ }
+
+ DBbegin();
+ zbx_db_insert_execute(&db_task_insert);
+ zbx_db_insert_execute(&db_task_remote_command_insert);
+ DBcommit();
+
+ zbx_db_insert_clean(&db_task_insert);
+ zbx_db_insert_clean(&db_task_remote_command_insert);
+}
+
+void zbx_task_remote_command_set_serialize_json(const struct zbx_task_remote_command_set *set, struct zbx_json *json)
+{
+ int i;
+
+ assert(NULL != set);
+ assert(NULL != set->commands.values);
+ assert(NULL != json);
+
+ zbx_json_addarray(json, ZBX_PROTO_TAG_DATA);
+
+ for (i = 0; i < set->commands.values_num; i++)
+ {
+ zbx_task_remote_command_serialize_json(set->commands.values[i], json);
+ }
+
+ zbx_json_close(json);
+}
+
+void zbx_task_remote_command_set_process_tasks(const struct zbx_task_remote_command_set *set)
+{
+ int i;
+
+ assert(NULL != set);
+ assert(NULL != set->commands.values);
+
+ for (i = 0; i < set->commands.values_num; i++)
+ {
+ zbx_task_remote_command_process_task(set->commands.values[i]);
+ }
+}
diff --git a/src/zabbix_proxy/Makefile.am b/src/zabbix_proxy/Makefile.am
index 303108a3956..e7a3cf5eddf 100644
--- a/src/zabbix_proxy/Makefile.am
+++ b/src/zabbix_proxy/Makefile.am
@@ -4,7 +4,8 @@ SUBDIRS = \
heart \
housekeeper \
proxyconfig \
- datasender
+ datasender \
+ taskmanager
sbin_PROGRAMS = zabbix_proxy
@@ -26,6 +27,7 @@ zabbix_proxy_LDADD = \
$(top_srcdir)/src/zabbix_server/trapper/libzbxtrapper.a \
$(top_srcdir)/src/zabbix_server/snmptrapper/libzbxsnmptrapper.a \
datasender/libzbxdatasender.a \
+ taskmanager/libzbxtaskmanager.a \
$(top_srcdir)/src/zabbix_server/selfmon/libzbxselfmon.a \
$(top_srcdir)/src/zabbix_server/vmware/libzbxvmware.a \
$(top_srcdir)/src/libs/zbxsysinfo/libzbxproxysysinfo.a \
@@ -52,7 +54,8 @@ zabbix_proxy_LDADD = \
$(top_srcdir)/src/libs/zbxdbupgrade/libzbxdbupgrade.a \
$(top_srcdir)/src/libs/zbxdbhigh/libzbxdbhigh.a \
$(top_srcdir)/src/libs/zbxdb/libzbxdb.a \
- $(top_srcdir)/src/libs/zbxmodules/libzbxmodules.a
+ $(top_srcdir)/src/libs/zbxmodules/libzbxmodules.a \
+ $(top_srcdir)/src/libs/zbxtasks/libzbxtasks.a
zabbix_proxy_LDADD += @PROXY_LIBS@
diff --git a/src/zabbix_proxy/proxy.c b/src/zabbix_proxy/proxy.c
index dfc0baa7eae..3dc3f298f5a 100644
--- a/src/zabbix_proxy/proxy.c
+++ b/src/zabbix_proxy/proxy.c
@@ -50,6 +50,7 @@
#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"
#include "setproctitle.h"
@@ -145,7 +146,7 @@ int CONFIG_HEARTBEAT_FORKS = 1;
int CONFIG_COLLECTOR_FORKS = 0;
int CONFIG_PASSIVE_FORKS = 0;
int CONFIG_ACTIVE_FORKS = 0;
-int CONFIG_TASKMANAGER_FORKS = 0;
+int CONFIG_TASKMANAGER_FORKS = 1;
int CONFIG_LISTEN_PORT = ZBX_DEFAULT_SERVER_PORT;
char *CONFIG_LISTEN_IP = NULL;
@@ -331,6 +332,11 @@ int get_process_info_by_thread(int local_server_num, unsigned char *local_proces
*local_process_type = ZBX_PROCESS_TYPE_VMWARE;
*local_process_num = local_server_num - server_count + CONFIG_VMWARE_FORKS;
}
+ else if (local_server_num <= (server_count += CONFIG_TASKMANAGER_FORKS))
+ {
+ *local_process_type = ZBX_PROCESS_TYPE_TASKMANAGER;
+ *local_process_num = local_server_num - server_count + CONFIG_TASKMANAGER_FORKS;
+ }
else
return FAIL;
@@ -927,7 +933,7 @@ int MAIN_ZABBIX_ENTRY(int flags)
+ CONFIG_PINGER_FORKS + CONFIG_HOUSEKEEPER_FORKS + CONFIG_HTTPPOLLER_FORKS
+ CONFIG_DISCOVERER_FORKS + CONFIG_HISTSYNCER_FORKS + CONFIG_IPMIPOLLER_FORKS
+ CONFIG_JAVAPOLLER_FORKS + CONFIG_SNMPTRAPPER_FORKS + CONFIG_SELFMON_FORKS
- + CONFIG_VMWARE_FORKS;
+ + CONFIG_VMWARE_FORKS + CONFIG_TASKMANAGER_FORKS;
threads = zbx_calloc(threads, threads_num, sizeof(pid_t));
if (0 != CONFIG_TRAPPER_FORKS)
@@ -1017,6 +1023,9 @@ int MAIN_ZABBIX_ENTRY(int flags)
case ZBX_PROCESS_TYPE_VMWARE:
threads[i] = zbx_thread_start(vmware_thread, &thread_args);
break;
+ case ZBX_PROCESS_TYPE_TASKMANAGER:
+ threads[i] = zbx_thread_start(taskmanager_thread, &thread_args);
+ break;
}
}
diff --git a/src/zabbix_proxy/taskmanager/Makefile.am b/src/zabbix_proxy/taskmanager/Makefile.am
new file mode 100644
index 00000000000..ec1722243e1
--- /dev/null
+++ b/src/zabbix_proxy/taskmanager/Makefile.am
@@ -0,0 +1,5 @@
+## Process this file with automake to produce Makefile.in
+
+noinst_LIBRARIES = libzbxtaskmanager.a
+
+libzbxtaskmanager_a_SOURCES = taskmanager.c taskmanager.h
diff --git a/src/zabbix_proxy/taskmanager/taskmanager.c b/src/zabbix_proxy/taskmanager/taskmanager.c
new file mode 100644
index 00000000000..f1c7e2089f0
--- /dev/null
+++ b/src/zabbix_proxy/taskmanager/taskmanager.c
@@ -0,0 +1,104 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2016 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 "common.h"
+#include "daemon.h"
+#include "zbxself.h"
+#include "zbxtasks.h"
+#include "log.h"
+#include "db.h"
+#include "dbcache.h"
+
+#define ZBX_TASKMANAGER_TIMEOUT 5
+
+extern unsigned char process_type, program_type;
+extern int server_num, process_num;
+
+/******************************************************************************
+ * *
+ * Function: tm_process_tasks *
+ * *
+ * Purpose: process task manager tasks depending on task type *
+ * *
+ * Return value: The number of successfully processed tasks *
+ * *
+ ******************************************************************************/
+static int tm_process_tasks()
+{
+ struct zbx_task_remote_command_set *cmd_set;
+ int ret = FAIL;
+
+ cmd_set = zbx_task_remote_command_set_new();
+ ret = zbx_task_remote_command_set_init_from_db(cmd_set, ZBX_TM_STATUS_NEW);
+
+ if (SUCCEED != ret)
+ goto err;
+
+ zbx_task_remote_command_set_process_tasks(cmd_set);
+
+err:
+ zbx_task_remote_command_set_clear(cmd_set);
+ zbx_task_remote_command_set_free(cmd_set);
+
+ return 0;
+}
+
+ZBX_THREAD_ENTRY(taskmanager_thread, args)
+{
+ double sec1, sec2;
+ int tasks_num = 0, sleeptime, nextcheck;
+
+ 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(program_type),
+ server_num, get_process_type_string(process_type), process_num);
+
+ zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type));
+ DBconnect(ZBX_DB_CONNECT_NORMAL);
+
+ sec1 = zbx_time();
+ sec2 = sec1;
+
+ sleeptime = ZBX_TASKMANAGER_TIMEOUT - (int)sec1 % ZBX_TASKMANAGER_TIMEOUT;
+
+ zbx_setproctitle("%s [started, idle %d sec]", get_process_type_string(process_type), sleeptime);
+
+ for (;;)
+ {
+ zbx_sleep_loop(sleeptime);
+
+ zbx_handle_log();
+
+ zbx_setproctitle("%s [processing tasks]", get_process_type_string(process_type));
+
+ sec1 = zbx_time();
+ tasks_num = tm_process_tasks();
+ sec2 = zbx_time();
+
+ nextcheck = (int)sec1 - (int)sec1 % ZBX_TASKMANAGER_TIMEOUT + ZBX_TASKMANAGER_TIMEOUT;
+
+ if (0 > (sleeptime = nextcheck - (int)sec2))
+ sleeptime = 0;
+
+ zbx_setproctitle("%s [processed %d task(s) in " ZBX_FS_DBL " sec, idle %d sec]",
+ get_process_type_string(process_type), tasks_num, sec2 - sec1, sleeptime);
+ }
+}
diff --git a/src/zabbix_proxy/taskmanager/taskmanager.h b/src/zabbix_proxy/taskmanager/taskmanager.h
new file mode 100644
index 00000000000..615121f1115
--- /dev/null
+++ b/src/zabbix_proxy/taskmanager/taskmanager.h
@@ -0,0 +1,27 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2016 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_TASKMANAGER_H
+#define ZABBIX_TASKMANAGER_H
+
+#include "threads.h"
+
+ZBX_THREAD_ENTRY(taskmanager_thread, args);
+
+#endif
diff --git a/src/zabbix_server/Makefile.am b/src/zabbix_server/Makefile.am
index 5cd1c16dbfd..852abb2be2c 100644
--- a/src/zabbix_server/Makefile.am
+++ b/src/zabbix_server/Makefile.am
@@ -70,7 +70,8 @@ zabbix_server_LDADD = \
$(top_srcdir)/src/libs/zbxdbupgrade/libzbxdbupgrade.a \
$(top_srcdir)/src/libs/zbxdbhigh/libzbxdbhigh.a \
$(top_srcdir)/src/libs/zbxdb/libzbxdb.a \
- $(top_srcdir)/src/libs/zbxmodules/libzbxmodules.a
+ $(top_srcdir)/src/libs/zbxmodules/libzbxmodules.a \
+ $(top_srcdir)/src/libs/zbxtasks/libzbxtasks.a
zabbix_server_LDADD += @SERVER_LIBS@
diff --git a/src/zabbix_server/pinger/pinger.c b/src/zabbix_server/pinger/pinger.c
index 1e1fa83f0a5..47f5cd34817 100644
--- a/src/zabbix_server/pinger/pinger.c
+++ b/src/zabbix_server/pinger/pinger.c
@@ -410,7 +410,7 @@ static void add_icmpping_item(icmpitem_t **items, int *items_alloc, int *items_c
static void get_pinger_hosts(icmpitem_t **icmp_items, int *icmp_items_alloc, int *icmp_items_count)
{
const char *__function_name = "get_pinger_hosts";
- DC_ITEM items[MAX_PINGER_ITEMS];
+ static DC_ITEM items[MAX_PINGER_ITEMS];
int i, num, count, interval, size, timeout, rc, errcode = SUCCEED;
char error[MAX_STRING_LEN], *addr = NULL;
icmpping_t icmpping;
diff --git a/src/zabbix_server/poller/poller.c b/src/zabbix_server/poller/poller.c
index 3c6e3cbe840..c1c69abc7de 100644
--- a/src/zabbix_server/poller/poller.c
+++ b/src/zabbix_server/poller/poller.c
@@ -370,9 +370,9 @@ static int get_value(DC_ITEM *item, AGENT_RESULT *result, zbx_vector_ptr_t *add_
static int get_values(unsigned char poller_type, int *nextcheck)
{
const char *__function_name = "get_values";
- DC_ITEM items[MAX_POLLER_ITEMS];
- AGENT_RESULT results[MAX_POLLER_ITEMS];
- int errcodes[MAX_POLLER_ITEMS];
+ static DC_ITEM items[MAX_POLLER_ITEMS];
+ static AGENT_RESULT results[MAX_POLLER_ITEMS];
+ static int errcodes[MAX_POLLER_ITEMS];
zbx_timespec_t timespec;
char *port = NULL, error[ITEM_ERROR_LEN_MAX];
int i, num, last_available = HOST_AVAILABLE_UNKNOWN;
diff --git a/src/zabbix_server/taskmanager/taskmanager.c b/src/zabbix_server/taskmanager/taskmanager.c
index 95596d2126d..22e5b6e2804 100644
--- a/src/zabbix_server/taskmanager/taskmanager.c
+++ b/src/zabbix_server/taskmanager/taskmanager.c
@@ -181,7 +181,7 @@ static int tm_process_tasks()
int type, ret, processed_num = 0;
zbx_uint64_t taskid;
- result = DBselect("select taskid,type from task order by taskid");
+ result = DBselect("select taskid,type from task where type=%d order by taskid", ZBX_TM_TASK_CLOSE_PROBLEM);
while (NULL != (row = DBfetch(result)))
{