diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | include/common.h | 12 | ||||
-rw-r--r-- | include/zbxjson.h | 10 | ||||
-rw-r--r-- | include/zbxtasks.h | 145 | ||||
-rw-r--r-- | include/zbxtypes.h | 7 | ||||
-rw-r--r-- | src/libs/Makefile.am | 9 | ||||
-rw-r--r-- | src/libs/zbxjson/json.c | 8 | ||||
-rw-r--r-- | src/libs/zbxtasks/Makefile.am | 9 | ||||
-rw-r--r-- | src/libs/zbxtasks/zbx_task.h | 36 | ||||
-rw-r--r-- | src/libs/zbxtasks/zbx_task_remote_command.c | 564 | ||||
-rw-r--r-- | src/libs/zbxtasks/zbx_task_remote_command_result.c | 282 | ||||
-rw-r--r-- | src/libs/zbxtasks/zbx_task_remote_command_result_set.c | 223 | ||||
-rw-r--r-- | src/libs/zbxtasks/zbx_task_remote_command_set.c | 236 | ||||
-rw-r--r-- | src/zabbix_proxy/Makefile.am | 7 | ||||
-rw-r--r-- | src/zabbix_proxy/proxy.c | 13 | ||||
-rw-r--r-- | src/zabbix_proxy/taskmanager/Makefile.am | 5 | ||||
-rw-r--r-- | src/zabbix_proxy/taskmanager/taskmanager.c | 104 | ||||
-rw-r--r-- | src/zabbix_proxy/taskmanager/taskmanager.h | 27 | ||||
-rw-r--r-- | src/zabbix_server/Makefile.am | 3 | ||||
-rw-r--r-- | src/zabbix_server/pinger/pinger.c | 2 | ||||
-rw-r--r-- | src/zabbix_server/poller/poller.c | 6 | ||||
-rw-r--r-- | src/zabbix_server/taskmanager/taskmanager.c | 2 |
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))) { |